/** * Gets the menu items indexed by their name with a value of the title * * @param array $configMenu (used for recursion) * * @return array */ public static function getMenu($configMenu = null) { $menu = array(); if (!$configMenu) { $configMenu = Config::get('administrator::administrator.menu', null); } //iterate over the menu to build the return array of valid menu items foreach ($configMenu as $key => $item) { //if the item is a string, find its config if (is_string($item)) { $isSettings = strpos($item, 'settings.') !== false; $config = $isSettings ? SettingsConfig::find($item) : ModelConfig::find($item); if ($config) { $permission = array_get($config, 'permission'); if (is_callable($permission) && !$permission()) { continue; } $menu[$item] = array_get($config, 'title', $item); } } else { if (is_array($item)) { $menu[$key] = static::getMenu($item); } } } return $menu; }
/** * Helper that builds a results array (with results and pagination info) * * @param ModelConfig $config * @param array $sort (with 'field' and 'direction' keys) * @param array $filters (see Field::getFilters method for the value types) */ public static function getRows($config, $sort = null, $filters = null) { //grab the model instance $model = $config->model; //update the config sort options $config->setSort($sort); $sort = $config->sort; //get things going by grouping the set $query = $model::group_by($model->table() . '.' . $model::$key); //set up initial array states for the selects $selects = array(DB::raw($model->table() . '.' . $model::$key), DB::raw($model->table() . '.*')); //then we set the filters if ($filters && is_array($filters)) { foreach ($filters as $filter) { if (!($fieldObject = Field::get($filter['field'], $filter, $config))) { continue; } $fieldObject->filterQuery($query, $model); } } //determines if the sort should have the table prefixed to it $sortOnTable = true; //iterate over the columns to check if we need to join any values or add any extra columns foreach ($config->columns['columns'] as $field => $column) { //if this is a related column, we'll need to add some joins $column->filterQuery($query, $selects, $model); //if this is a related field or if (($column->isRelated || $column->select) && $column->field === $sort['field']) { $sortOnTable = false; } } //if the sort is on the model's table, prefix the table name to it if ($sortOnTable) { $sort['field'] = $model->table() . '.' . $sort['field']; } /** * We need to do our own pagination since there is a bug in the L3 paginator when using groupings :( * When L4 is released, this problem will go away and we'll be able to use the paginator again */ //first get the sql sans selects $sql = $query->table->grammar->select($query->table); //then we need to round out the inner select $sql = "SELECT {$model->table()}.{$model::$key} " . $sql; //then wrap the inner table and perform the count $sql = "SELECT COUNT({$model::$key}) AS aggregate FROM ({$sql}) AS agg"; //then perform the count query $results = $query->table->connection->query($sql, $query->table->bindings); $num_rows = $results[0]->aggregate; $page = (int) \Input::get('page', 1); $last = (int) ceil($num_rows / $config->rowsPerPage); //if the current page is greater than the last page, set the current page to the last page $page = $page > $last ? $last : $page; //now we need to limit and offset the rows in remembrance of our dear lost friend paginate() $query->take($config->rowsPerPage); $query->skip($config->rowsPerPage * ($page === 0 ? $page : $page - 1)); //order the set by the model table's id $query->order_by($sort['field'], $sort['direction']); //then retrieve the rows $rows = $query->distinct()->get($selects); $results = array(); //convert the resulting set into arrays foreach ($rows as $item) { //iterate over the included and related columns $onTableColumns = array_merge($config->columns['includedColumns'], $config->columns['relatedColumns']); $arr = array(); foreach ($onTableColumns as $field => $col) { //if this column is in our objects array, render the output with the given value if (isset($config->columns['columnObjects'][$field])) { $arr[$field] = $config->columns['columnObjects'][$field]->renderOutput($item->get_attribute($field)); } else { $arr[$field] = $item->get_attribute($field); } } //then grab the computed, unsortable columns foreach ($config->columns['computedColumns'] as $col) { $arr[$col] = $config->columns['columnObjects'][$col]->renderOutput($item->{$col}); } $results[] = $arr; } return array('page' => $page, 'last' => $last, 'total' => $num_rows, 'results' => $results); }
<?php use Admin\Libraries\ModelHelper; use Admin\Libraries\Fields\Field; use Admin\Libraries\ModelConfig; //View Composers //admin index view View::composer('administrator::index', function ($view) { //get a model instance that we'll use for constructing stuff $config = $view->config; $model = $config->model; $baseUrl = URL::to_route('admin_index'); $route = parse_url($baseUrl); //get the edit fields $editFields = Field::getEditFields($config); //add the view fields $view->primaryKey = $model::$key; $view->rows = ModelHelper::getRows($config, $config->sort); $view->editFields = $editFields; $view->actions = $config->actions; $view->filters = Field::getFilters($config); $view->baseUrl = $baseUrl; $view->assetUrl = URL::to('bundles/administrator/'); $view->route = $route['path'] . '/'; $view->model = isset($view->model) ? $view->model : false; }); //header view View::composer(array('administrator::partials.header', 'administrator::dashboard'), function ($view) { $view->menu = ModelConfig::getMenu(); });
Config::set('administrator::administrator.' . $key, Config::get('administrator.' . $key)); } } //get the admin check closure that should be supplied in the config $permission = Config::get('administrator::administrator.permission'); if (!$permission()) { $loginUrl = URL::to(Config::get('administrator::administrator.login_path', 'user/login')); $redirectKey = Config::get('administrator::administrator.login_redirect_key', 'redirect'); $redirectUri = URL::to_route('admin_dashboard'); return Redirect::to($loginUrl)->with($redirectKey, $redirectUri); } }); //validate_model filter Route::filter('validate_model', function () { $modelName = Request::route()->parameters[0]; $config = ModelConfig::get($modelName); //if the model doesn't exist at all, redirect to 404 if (!$config) { return Response::error('404'); } Request::route()->parameters[0] = $config; }); //validate_settings filter Route::filter('validate_settings', function () { $settingsName = Request::route()->parameters[0]; $config = SettingsConfig::get(SettingsConfig::$prefix . $settingsName); //if the model doesn't exist at all, redirect to 404 if (!$config) { return Response::error('404'); } Request::route()->parameters[0] = $config;
/** * The POST method for setting a user's rows per page * * @param ModelConfig $config * * @return JSON */ public function action_rows_per_page($config) { //get the inputted rows and the model rows $rows = (int) Input::get('rows', 20); $config->setRowsPerPage($rows); return Response::JSON(array('success' => true)); }