Guest User

Untitled

a guest
Jun 22nd, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 9.89 KB | None | 0 0
  1. // Сохранение объекта древовидного модуля
  2.    public function saveItem($args, $currentPage) {
  3.       // Сначала смотрим, что пытаемся сохранить вообще, и валиден ли урл
  4.       $alias = $args['alias'][count($args['alias'])-1];
  5.       $item_id = $this->master->getItemIdByAlias($alias);
  6.      
  7.       // Получаем реальные данные
  8.       $item = $this->master->item = $this->master->getOne($item_id);
  9.       if (is_object($item)) $item = $item->fields;
  10.      
  11.       if (FALSE === $item_id) {
  12.          throw new AF_Exception_404;
  13.          exit;
  14.       }
  15.  
  16.      
  17.       // Довольно тупая проверка на то, наши ли это данные
  18.       if (isset($_POST[md5('module')]) && $_POST[md5('module')] === md5($this->master->name)) {
  19.          
  20.          
  21.          $post = $_POST;
  22.          $this->master->fireEvent($this->master->name.'BeforeEntrySave', new AF_Event_Context($currentPage, $args));
  23.          
  24.          // Смотрим поля, которые можно заполнять:
  25.          $defined_fields = $this->master->getOptions('modules.'.$this->master->getPathToModule().'.fields');
  26.  
  27.          //Если вообще есть поля:
  28.          if (count($defined_fields)>0) {
  29.            
  30.             // Отсеиваем редактируемые поля
  31.             $editable_fields = array_filter(array_keys($defined_fields),
  32.                                             function($f) use ($defined_fields) {
  33.                                                          return $defined_fields[$f]['is_editable'];
  34.                                                          });
  35.            
  36.             // Поля, которые получили:
  37.             foreach ($post as $field=>$value) {
  38.                if (FALSE === array_search($field, $editable_fields)) unset ($post[$field]);
  39.             }
  40.            
  41.             // Оставляем только те поля, которые изменились
  42.             $post = array_diff_assoc($post, $item);
  43.  
  44.             if (count($post) === 0) { // ничего не менялось
  45.                throw new AF_Redirect_Exception($this->buildUrlByMethod('editItem', $item_id).'?success=true');
  46.                exit;
  47.             }
  48.  
  49.             // Заполняем правила валидации
  50.             $rules = array();
  51.            
  52.             foreach ($editable_fields as $field) {
  53.                
  54.                // Если нам пришло значения этого поля в $_POST и оно требует валидации
  55.                if (isset($post[$field]) && isset($defined_fields[$field]['validate'])) {
  56.                  
  57.                   // Добавляем новое правило валидации
  58.                   $rules[$field] = $defined_fields[$field]['validate'];
  59.                }
  60.             }
  61.            
  62.             // Если пользователь очистил поле "алиас", то сгенерируем новый алиас (по только что введенному названию
  63.             // или, если его нет, по старому)
  64.             if (
  65.                    isset($post[$this->master->service_fields['alias_field']]) &&
  66.                    $post[$this->master->service_fields['alias_field']]===''
  67.                 ) {
  68.                   $name = (isset($post[$this->master->service_fields['name_field']])) ?
  69.                                                                                        $post[$this->master->service_fields['name_field']] : // берем из введенных только что данных
  70.                                                                                        $item[$this->master->service_fields['name_field']]; // берем из старых данных
  71.  
  72.                   $post[$this->master->service_fields['alias_field']] = $this->master->createAlias($name);          
  73.             }
  74.  
  75.  
  76.             // Запускаем валидатор c только что заполненными правилами
  77.             $errors = AF_Validator::validate($post, $rules);
  78.            
  79.             if (count($errors) > 0) { // есть ошибки
  80.                
  81.                // Отдаем обратно те значения, которые пытались ввести
  82.                $currentPage->raw_data_invalid[$this->master->name] = $post;
  83.                
  84.                // Отдаем отформатированные сообщения об ошибках
  85.                $error_messages = array();
  86.                foreach($errors as $field=>$rules) {
  87.                      foreach ($rules as $rule=>$marker) {
  88.  
  89.                         // Находим шаблон сообщения, в который подставим всякую гадость
  90.                         $text = (isset(AF_Validator::$messages[$rule]) ? AF_Validator::$messages[$rule] : AF_Validator::$messages['default_message']);
  91.  
  92.                         // Дополнительные параметры, которые подставляются в шаблон (к примеру, для правила minlength - минимальное значение)
  93.                         if (is_array($defined_fields[$field]['validate'])) $additional_params = (array)$defined_fields[$field]['validate'][$rule];
  94.                         else  $additional_params = array();
  95.                        
  96.                         $text_params = array($text, $defined_fields[$field]['comment']);
  97.                         $params = array_merge($text_params, $additional_params);
  98.  
  99.  
  100.                         $error_messages[$field] = call_user_func_array('sprintf', $params);
  101.                      }
  102.                   }
  103.                $currentPage->error_messages = $error_messages;
  104.                $this->editItem($args, $currentPage);
  105.             }
  106.             else { // Данные прошли валидацию, победа!
  107.            
  108.                $this->master->item[$this->master->service_fields['key_field']] = $item_id;
  109.                
  110.                // Теперь смотрим, какие из полей наследуются, и их надо перезаписать у дочерних элементов.
  111.                // Параллельно заполним основной сохраняемый объект и таки сохраним его
  112.                
  113.                // как в switchItemVisibility, все сделаем через.. анонимную функцию
  114.                // чтобы _отделить алгоритм сохранения от внешних проверок и выполнять это сохранение несколько раз
  115.                $clone = clone $this;
  116.                $updateItemsCharacteristic = function($ids, $field, $new_value) use ($clone) {
  117.                                               // для оптимизации здесь не используется метод save объекта,
  118.                                               // а сохранение новых данных идет одним запросом
  119.  
  120.                                               // напишем условие для апдейта
  121.                                               $where_statement = "`".$this->getMaster()->service_fields['key_field']."` IN ('".implode("', '", $ids)."')";
  122.                                              
  123.                                               sql_update($this->getMaster()->getTable(), // делаем банальный апдейт
  124.                                                               array(
  125.                                                                    $field, // название поля
  126.                                                                    $new_value // новое значение
  127.                                                                    ),
  128.                                                               $where_statement
  129.                                                               );
  130.                                           };
  131.                                              
  132.                
  133.                // Соберем детей этого элемента:
  134.                $children = $this->master->getChildrenIdsRecursive($item_id);
  135.                
  136.                // берем все определенные поля
  137.                $defined_fields = $this->master->getOptions('modules.'.$this->master->getPathToModule().'.fields');
  138.                // проходим пришедшие значения
  139.                foreach ($post as $field=>$val) {
  140.                   $this->master->item[$field] = $val;
  141.                  
  142.                   // это поле наследуется?
  143.                   if (isset($defined_fields[$field]['inherited'] && $defined_fields[$field]['inherited'] === TRUE) {
  144.                      // значит, выставим у всех детей новое значение
  145.                      if (count($children)>0) {
  146.                         // вот тут-то нам и пригодится та анонимная функция
  147.                         call_user_func($updateItemsCharacteristic, $children, $field, $val);
  148.                      }
  149.                   }
  150.                }
  151.  
  152.                
  153.                // Наконец-то сохраняем объект, с которого все заварилось
  154.                $this->master->item->save();
  155.    
  156.                $this->master->fireEvent($this->master->name.'AfterEntrySave', new AF_Event_Context($currentPage, $args));
  157.            
  158.             // Кидаем на страницу редактирования
  159.             throw new AF_Redirect_Exception($this->buildUrlByMethod('editItem', $item_id).'?success=true');
  160.             }
  161.          }
  162.       }
  163.    }
Add Comment
Please, Sign In to add comment