public function index($dic_id)
 {
     $dic = Dictionary::where(is_numeric($dic_id) ? 'id' : 'slug', $dic_id)->first();
     if (!$this->checkDicPermission($dic)) {
         App::abort(404);
     }
     $this->dicval_permission($dic, 'dicval_view');
     $dic->settings = json_decode($dic->settings, 1);
     $this->checkDicUrl($dic, $dic_id);
     $this->callHook('before_all', $dic);
     $this->callHook('before_index', $dic);
     ## Get element
     $elements = new DicVal();
     $tbl_dicval = $elements->getTable();
     $elements = $elements->where($tbl_dicval . '.dic_id', (int) $dic->id)->where($tbl_dicval . '.version_of', '=', NULL)->with('fields');
     #$elements = DB::table('dictionary_values')->where('dic_id', $dic->id)->select('dictionary_values.*');
     if (NULL !== ($filter = Input::get('filter'))) {
         #Helper::d($filter);
         if (isset($filter['fields']) && is_array($filter) && count($filter)) {
             $tbl_fields = new DicFieldVal();
             $tbl_fields = $tbl_fields->getTable();
             #Helper::d($filter['fields']);
             foreach ($filter['fields'] as $key => $value) {
                 $rand_tbl_alias = md5(rand(99999, 999999));
                 $elements = $elements->join($tbl_fields . ' AS ' . $rand_tbl_alias, function ($join) use($tbl_dicval, $tbl_fields, $key, $value, $rand_tbl_alias) {
                     $join->on($rand_tbl_alias . '.dicval_id', '=', $tbl_dicval . '.id')->where($rand_tbl_alias . '.key', '=', $key)->where($rand_tbl_alias . '.value', '=', $value);
                 })->addSelect($rand_tbl_alias . '.value AS ' . $key);
             }
         }
     }
     ## Ordering
     $sort_order = $dic->sort_order_reverse ? 'DESC' : 'ASC';
     #Helper::dd($dic->sort_by);
     /**
      * Кол-во элементов, подпадающих под условия, но без учета пагинации
      */
     $total_elements_current_selection = clone $elements;
     $total_elements_current_selection = (int) $total_elements_current_selection->count();
     #Helper::tad($total_elements_current_selection);
     switch ($dic->sort_by) {
         case '':
             /*
             $elements = $elements
                 ->orderBy($tbl_dicval.'.order', $sort_order)
                 ->orderBy($tbl_dicval.'.name', $sort_order);
             */
             $elements = $elements->orderBy(DB::raw('-' . $tbl_dicval . '.lft'), 'DESC')->orderBy($tbl_dicval . '.id', $sort_order);
             break;
         case 'name':
             $elements = $elements->orderBy($tbl_dicval . '.name', $sort_order);
             break;
         case 'slug':
             $elements = $elements->orderBy($tbl_dicval . '.slug', $sort_order);
             break;
         case 'created_at':
             $elements = $elements->orderBy($tbl_dicval . '.created_at', $sort_order);
             break;
         case 'updated_at':
             $elements = $elements->orderBy($tbl_dicval . '.updated_at', $sort_order);
             break;
         default:
             /**
              * ORDER BY по произвольному полю
              */
             /*
             #Helper::dd($dic->sort_by);
             #$dic->sort_by .= '2';
             $tbl_fields = (new DicFieldVal())->getTable();
             
             $rand_tbl_alias = md5(rand(99999, 999999));
             $elements = $elements
                 ->leftJoin($tbl_fields . ' AS ' . $rand_tbl_alias, function ($join) use ($tbl_dicval, $tbl_fields, $rand_tbl_alias, $dic, $sort_order) {
                     $join
                         ->on($rand_tbl_alias . '.dicval_id', '=', $tbl_dicval . '.id')
             
                     ;
                 })
                 ### !!! WHERE должно быть именно здесь, а не внутри JOIN-а !!! ###
                 ### !!! Иначе происходит неведомая хрень: dic_id = 'field' !!! ###
                 ->where($rand_tbl_alias . '.key', '=', $dic->sort_by)
                 ->addSelect($rand_tbl_alias . '.value AS ' . $dic->sort_by)
                 #->orderBy($dic->sort_by, $sort_order)
                 ->orderBy($rand_tbl_alias.'.value', $sort_order)
                 ->orderBy($tbl_dicval.'.created_at', 'DESC') ## default
             ;
             */
             $elements = $elements->order_by_field($dic->sort_by, $sort_order);
             break;
     }
     #Helper::tad($dic->pagination);
     ## Search
     $search_query = NULL;
     if (NULL !== ($search_query = Input::get('q'))) {
         $elements = $elements->where('name', 'LIKE', '%' . $search_query . '%')->orWhere('slug', 'LIKE', '%' . $search_query . '%');
     }
     ## Dic settings
     $dic_settings = Config::get('dic/' . $dic->slug);
     #Helper::dd($dic_settings);
     ## Sortable settings
     $sortable = $dic->sortable && $dic->pagination == 0 && $dic->sort_by == null ? true : false;
     ## Disable sortable without needable filter options
     if ($sortable && isset($dic_settings['disable_ordering_without_filter']) && $dic_settings['disable_ordering_without_filter']) {
         $dic_settings['disable_ordering_without_filter'] = (array) $dic_settings['disable_ordering_without_filter'];
         #Helper::ta($dic_settings['disable_ordering_without_filter']);
         if (count($dic_settings['disable_ordering_without_filter'])) {
             foreach ($dic_settings['disable_ordering_without_filter'] as $condition) {
                 if (!Input::get('filter.fields.' . $condition)) {
                     $sortable = false;
                     break;
                 }
             }
         }
     }
     ## Disable listing without needable filter options
     $listing = true;
     if (isset($dic_settings['disable_listing_without_filter']) && $dic_settings['disable_listing_without_filter']) {
         $dic_settings['disable_listing_without_filter']['fields'] = (array) $dic_settings['disable_listing_without_filter']['fields'];
         #Helper::ta($dic_settings['disable_listing_without_filter']['fields']);
         if (count($dic_settings['disable_listing_without_filter']['fields'])) {
             foreach ($dic_settings['disable_listing_without_filter']['fields'] as $condition) {
                 if (!Input::get('filter.fields.' . $condition)) {
                     $listing = false;
                     break;
                 }
             }
         }
     }
     if (isset($dic_settings['sortable']) && is_callable($dic_settings['sortable'])) {
         $sortable = $dic_settings['sortable']($dic, $elements);
     }
     ## Pagination
     if ($dic->pagination > 0) {
         $elements = $elements->paginate($dic->pagination);
     } else {
         $elements = $elements->get();
     }
     #Helper::tad($elements);
     #Helper::smartQueries(1);
     $elements_pagination = clone $elements;
     DicVal::extracts($elements, null, true, true);
     #$elements = Dic::modifyKeys($elements, 'id');
     if (Config::get('debug') == 1 || Input::get('debug') == 1) {
         Helper::smartQueries(1);
         Helper::tad($elements);
     }
     $actions_column = false;
     if (Allow::action($this->module['group'], 'dicval_edit') || Allow::action($this->module['group'], 'dicval_delete') || isset($dic_settings['actions']) && is_callable($dic_settings['actions'])) {
         $actions_column = true;
     }
     $total_elements = DicVal::where('dic_id', $dic->id)->where('version_of', '=', NULL)->count();
     $this->callHook('before_index_view_create_edit', $dic, $elements);
     $this->callHook('before_index_view', $dic, $elements);
     $id_left_right = array();
     if (count($elements)) {
         foreach ($elements as $element) {
             $id_left_right[$element->id] = array();
             $id_left_right[$element->id]['left'] = $element->lft;
             $id_left_right[$element->id]['right'] = $element->rgt;
         }
     }
     $hierarchy = (new NestedSetModel())->get_hierarchy_from_id_left_right($id_left_right);
     #Helper::ta($dic);
     #Helper::tad($elements);
     #Helper::dd($hierarchy);
     #Helper::dd($dic_settings['actions']());
     #return View::make(Helper::acclayout());
     #return View::make($this->module['tpl'].'index_old', compact('elements', 'dic', 'dic_id', 'sortable', 'dic_settings', 'actions_column', 'total_elements', 'total_elements_current_selection'));
     return View::make($this->module['tpl'] . 'index', compact('elements', 'elements_pagination', 'hierarchy', 'dic', 'dic_id', 'sortable', 'dic_settings', 'actions_column', 'total_elements', 'total_elements_current_selection', 'search_query', 'listing'));
 }