public function postSave($dic_id, $id = false)
 {
     if (!Request::ajax()) {
         App::abort(404);
     }
     $dic = Dictionary::where(is_numeric($dic_id) ? 'id' : 'slug', $dic_id)->first();
     if (!$this->checkDicPermission($dic)) {
         App::abort(404);
     }
     $this->dicval_permission($dic, @$id ? 'dicval_edit' : 'dicval_create');
     $element = new DicVal();
     if ($id) {
         $element = DicVal::find($id);
     }
     if (!is_object($element)) {
         $element = new DicVal();
     }
     $this->callHook('before_all', $dic);
     $this->callHook('before_store_update', $dic);
     #Helper::tad($dic);
     $versions = Config::get('dic/' . $dic->slug . '.versions');
     $input = Input::all();
     #dd($input);
     $locales = Input::get('locales');
     $fields = Helper::withdraw($input, 'fields');
     #Input::get('fields');
     #$fields_i18n = Input::get('fields_i18n');
     $fields_i18n = @$input['fields_i18n'];
     #dd($fields_i18n);
     $seo = Input::get('seo');
     /*
     if (!@$input['slug'] && $dic->make_slug_from_name)
         $input['slug'] = Helper::translit($input['name']);
     */
     if (!isset($input['name']) || !mb_strlen($input['name'])) {
         $input['name'] = '';
     }
     $input['name'] = trim($input['name']);
     /**
      * Генерация системного имени в зависимости от настроек словаря
      */
     switch ((int) $dic->make_slug_from_name) {
         case 1:
             $input['slug'] = Helper::translit($input['name']);
             break;
         case 2:
             if (!$dic->hide_slug && !@$input['slug']) {
                 $input['slug'] = Helper::translit($input['name']);
             }
             break;
         case 3:
             if ($dic->hide_slug && $element->slug == '') {
                 $input['slug'] = Helper::translit($input['name']);
             }
             break;
         case 4:
             $input['slug'] = Helper::translit($input['name'], false);
             break;
         case 5:
             if (!$dic->hide_slug && !@$input['slug']) {
                 $input['slug'] = Helper::translit($input['name'], false);
             }
             break;
         case 6:
             if ($dic->hide_slug && $element->slug == '') {
                 $input['slug'] = Helper::translit($input['name'], false);
             }
             break;
         case 7:
             $input['slug'] = $input['name'];
             break;
         case 8:
             if (!$dic->hide_slug && !@$input['slug']) {
                 $input['slug'] = $input['name'];
             }
             break;
         case 9:
             if ($dic->hide_slug && $element->slug == '') {
                 $input['slug'] = $input['name'];
             }
             break;
     }
     if (isset($input['slug'])) {
         $input['slug'] = @Helper::translit($input['slug'], false);
     }
     #Helper::dd($input['slug']);
     #$json_request['responseText'] = "<pre>" . print_r(Input::get('seo'), 1) . "</pre>";
     $json_request['responseText'] = "<pre>" . print_r(Input::all(), 1) . "</pre>";
     #return Response::json($json_request,200);
     #dd(Input::all());
     #Helper::dd(Input::all());
     #Helper::dd($input);
     $json_request = array('status' => FALSE, 'responseText' => '', 'responseErrorText' => '', 'redirect' => FALSE);
     $validator = Validator::make($input, array());
     if ($validator->passes()) {
         $redirect = false;
         #Helper::d($id);
         $mode = '';
         if (isset($element) && is_object($element) && $element->id) {
             $mode = 'update';
             $this->callHook('before_update', $dic, $element);
             /**
              * Версионность
              * Если в конфиге задано кол-во хранимых резервных копий > 0
              */
             if ($versions > 0) {
                 $this->create_backup($element->id, true);
             }
             ## UPDATE DICVAL
             $element->update($input);
             $element->touch();
             ## Важно! Для версионности
         } else {
             $mode = 'store';
             $this->callHook('before_store', $dic);
             if (@(!$input['dic_id'])) {
                 $input['dic_id'] = $dic->id;
             }
             #$json_request['responseText'] = "<pre>" . print_r($input, 1) . "</pre>";
             #return Response::json($json_request,200);
             /**
              * Ставим элемент в конец списка
              */
             $temp = DicVal::selectRaw('max(rgt) AS max_rgt')->where('dic_id', $dic->id)->first();
             $input['lft'] = $temp->max_rgt + 1;
             $input['rgt'] = $temp->max_rgt + 2;
             ## CREATE DICVAL
             $element = new DicVal();
             #$element = DicVal::insert($input);
             $element->save();
             $element->update($input);
             $id = $element->id;
             $redirect = true;
         }
         /**
          * Доп. поля, не зависящие от языка
          */
         $element_fields = Config::get('dic/' . $dic->slug . '.fields');
         if (isset($element_fields) && is_callable($element_fields)) {
             $element_fields = $element_fields($element);
         }
         #Helper::dd($element_fields);
         ## FIELDS
         if (isset($element_fields) && is_array($element_fields) && count($element_fields)) {
             #Helper::d($fields);
             foreach ($element_fields as $key => $_value) {
                 if (is_numeric($key) || !@$_value['type']) {
                     continue;
                 }
                 #Helper::dd($key . ' - ' . $_value['type']);
                 $value = @$fields[$key];
                 #Helper::d($key);
                 #Helper::d($value);
                 #continue;
                 ## If handler of field is defined
                 if (is_callable($handler = @$element_fields[$key]['handler'])) {
                     #Helper::d($handler);
                     $value = $handler($value, $element);
                 }
                 #Helper::d($key . ' => ' . print_r($value, 1));
                 if ($value === false) {
                     continue;
                 }
                 $field_model = in_array(@$_value['type'], array('textarea', 'textarea_redactor')) ? new DicTextFieldVal() : new DicFieldVal();
                 $field = $field_model->firstOrNew(array('dicval_id' => $id, 'key' => $key, 'language' => NULL));
                 $field->value = $value;
                 $field->save();
                 unset($field);
             }
         }
         /**
          * Доп. поля, имеющие версии для каждого языка
          */
         $element_fields_i18n = Config::get('dic/' . $dic->slug . '.fields_i18n');
         if (isset($element_fields_i18n) && is_callable($element_fields_i18n)) {
             $element_fields_i18n = $element_fields_i18n($element);
         }
         #Helper::d($element_fields_i18n);
         #Helper::dd($fields_i18n);
         ## FIELDS I18N
         #if (@is_array($fields_i18n) && count($fields_i18n)) {
         if (isset($element_fields_i18n) && is_array($element_fields_i18n) && count($element_fields_i18n) && is_array($fields_i18n) && count($fields_i18n)) {
             #Helper::d('Перебираем все $element_fields_i18n...');
             #Helper::dd($fields_i18n);
             #Helper::dd($element_fields_i18n);
             /**
              * Перебираем все доп. поля из конфига
              */
             foreach ($element_fields_i18n as $field_name => $field_params) {
                 #Helper::d($field_name);
                 #Helper::d($field_params);
                 #Helper::dd($fields_i18n);
                 #continue;
                 /**
                  * Перебираем все локали, и выбираем значение текущего доп. поля для каждого языка
                  */
                 foreach ($fields_i18n as $locale_sign => $values) {
                     #dd($values);
                     #Helper::d($field_name . ' => ' . @$values[$field_name]);
                     #var_dump(@$values[$field_name]);
                     #if (!isset($values[$field_name]))
                     #    continue;
                     $value = @$values[$field_name];
                     #Helper::d($field_name . ' => ' . $value);
                     #Helper::d($field_name);
                     #Helper::d($value);
                     ## If handler of field is defined
                     if (is_callable($handler = @$element_fields_i18n[$field_name]['handler'])) {
                         #Helper::dd($handler);
                         $value = $handler($value, $element);
                     }
                     #Helper::d($field_name . ' => ' . $value);
                     if ($value === false) {
                         continue;
                     }
                     $field_model = in_array(@$field_params['type'], array('textarea', 'textarea_redactor')) ? new DicTextFieldVal() : new DicFieldVal();
                     $field = $field_model->firstOrNew(array('dicval_id' => $id, 'key' => $field_name, 'language' => $locale_sign));
                     $field->value = $value;
                     $field->save();
                     #Helper::ta($field);
                     unset($field);
                 }
             }
         }
         /**
          * DicValMeta
          */
         ## LOCALES
         #Helper::dd($locales);
         if (@is_array($locales) && count($locales)) {
             foreach ($locales as $locale_sign => $array) {
                 $element_meta = DicValMeta::firstOrNew(array('dicval_id' => $id, 'language' => $locale_sign));
                 $element_meta->update($array);
                 $element_meta->save();
                 #Helper::tad($element_meta);
                 unset($element_meta);
             }
         }
         ## SEO
         if (@is_array($seo) && count($seo)) {
             #Helper::ta($element);
             #Helper::d($seo);
             foreach ($seo as $locale_sign => $seo_array) {
                 ## SEO
                 if (is_array($seo_array) && count($seo_array)) {
                     ###############################
                     ## Process SEO
                     ###############################
                     $seo_result = ExtForm::process('seo', array('module' => 'DicVal', 'unit_id' => $element->id, 'data' => $seo_array, 'locale' => $locale_sign));
                     #Helper::tad($seo_result);
                     ###############################
                 }
             }
         }
         $element->load('metas', 'allfields', 'seos');
         $element = $element->extract(1);
         $this->callHook('after_store_update', $dic, $element);
         if ($mode == 'update') {
             $this->callHook('after_update', $dic, $element);
         } elseif ($mode == 'store') {
             $this->callHook('after_store', $dic, $element);
         }
         $this->callHook('after_store_update_destroy', $dic, $element);
         $this->callHook('after_store_update_destroy_order', $dic, $element);
         $json_request['responseText'] = 'Сохранено';
         if ($redirect) {
             $redirect_url = NULL;
             if (@$dic_settings['new_element_redirect'] == 'list') {
                 #$redirect_url = URL::route(is_numeric($dic_id) ? 'dicval.index' : 'entity.index', array('dic_id' => $dic_id)) . (Request::getQueryString() ? '?' . Request::getQueryString() : '');
                 $redirect_url = Input::get('redirect');
             } elseif (@is_array($dic_settings['new_element_redirect']) && isset($dic_settings['new_element_redirect']['route_name'])) {
                 $redirect_url = URL::route($dic_settings['new_element_redirect']['route_name'], (array) @$dic_settings['new_element_redirect']['route_params']) . (@$dic_settings['new_element_redirect']['add_query_string'] && Input::get('query_string') ? Input::get('query_string') : '');
                 #} elseif (@$dic_settings['new_element_redirect'] == 'new' || !@$dic_settings['new_element_redirect']) {
             } else {
                 $redirect_url = URL::route(is_numeric($dic_id) ? 'dicval.edit' : 'entity.edit', array('dic_id' => $dic_id, 'id' => $element->id)) . (Input::get('query_string') ? Input::get('query_string') : '');
             }
         }
         if ($redirect && $redirect_url) {
             $json_request['redirect'] = $redirect_url;
         }
         $json_request['status'] = TRUE;
     } else {
         $json_request['responseText'] = 'Неверно заполнены поля';
         $json_request['responseErrorText'] = $validator->messages()->all();
     }
     return Response::json($json_request, 200);
 }