diff --git a/docs/README.md b/docs/README.md index 0c2546c..e73bfd4 100644 --- a/docs/README.md +++ b/docs/README.md @@ -349,6 +349,79 @@ And use it as a regular object in the `pages.home` template: As you can see, for convenience regular attributes (= defined fields) can be directly retrieved as properties of the `Whitecube\NovaPage\Pages\Template` instances. +## Extending the Resources +Nova Page uses two classes for the Page and Options. They can be extended to customize their functionality. + +### Page Resource +Nova Page uses `Whitecube\NovaPage\Pages\PageResource` as the Nova Resource for Page's. + +You can customize it's behaviour by extending the class. For example in `app\Nova\PageResource.php`: +``` +namespace App\Nova; + +use Whitecube\NovaPage\Pages\PageResource as BasePageResource; + +class PageResource extends BasePageResource +{ + /** + * Overrwrites the Page Resource's fields + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function fields(Request $request) + { + return parent::fields($request); + } +} +``` +And then in the config file, change the 'default_page_resource' option to your own class name. For example: +``` +'default_page_resource' => \App\Nova\PageResource::class, +``` +### Option Resource +Nova Page uses `Whitecube\NovaPage\Pages\OptionResource` as the Nova Resource for Option's. + +You can customize it's behaviour by extending the class. For example in `app\Nova\OptionResource.php`: +``` +namespace App\Nova; + +use Whitecube\NovaPage\Pages\OptionResource as BaseOptionResource; + +class OptionResource extends BaseOptionResource +{ + /** + * Overrwrites the Option Resource's fields + * + * @param \Illuminate\Http\Request $request + * @return array + */ + public function fields(Request $request) + { + return parent::fields($request); + } +} +``` +And then in the config file, change the 'default_option_resource' option to your own class name. For example: +``` +'default_option_resource' => \App\Nova\OptionResource::class, +``` + +### Resource Index Queries +Each Resource is provided a method `novaPageIndexQuery` to mimic the core `indexQuery` on Nova Resource's. + +After extending either the Page or Option Resource classes you can override the `novaPageIndexQuery` method. For example: +``` +public static function novaPageIndexQuery(\Whitecube\NovaPage\Pages\Query $query) +{ + return $query->orderBy(function ($item) { + return $item->getTitle(); + }, 'ASC'); +} +``` + +Take note: The first parameter given to `novaPageIndexQuery` is an instance of `Whitecube\NovaPage\Pages\Query` and has own set of methods. + ## Advanced features ### Working with JSON fields @@ -371,4 +444,4 @@ class Home extends Template */ protected $jsonAttributes = ['my_json_attribute', 'another_json_attribute']; } -``` \ No newline at end of file +``` diff --git a/src/Pages/Concerns/QueriesResources.php b/src/Pages/Concerns/QueriesResources.php index 341fb44..3e62b32 100644 --- a/src/Pages/Concerns/QueriesResources.php +++ b/src/Pages/Concerns/QueriesResources.php @@ -3,6 +3,7 @@ namespace Whitecube\NovaPage\Pages\Concerns; use Route; +use Whitecube\NovaPage\Pages\Query; use Whitecube\NovaPage\Pages\Template; use Whitecube\NovaPage\Pages\OptionResource; use Laravel\Nova\Http\Requests\ResourceIndexRequest; @@ -18,7 +19,9 @@ trait QueriesResources */ public function queryIndexResources(ResourceIndexRequest $request, $type) { $query = $this->newQueryWithoutScopes(); - return $query->whereType($type)->get(false)->map(function($template) use ($type) { + $query->whereType($type); + $this->applyIndexQueryForType($type, $query); + return $query->get(false)->map(function($template) use ($type) { return $this->getResourceForType($type, $template); }); } @@ -43,11 +46,20 @@ public function queryResourcesCount(ResourceIndexRequest $request, $type) * @return \Laravel\Nova\Resource */ protected function getResourceForType($type, Template $resource) { - $page_resource_class = config('novapage.default_page_resource'); - $option_resource_class = config('novapage.default_option_resource'); + $page_resource_class = config('novapage.default_page_resource', \Whitecube\NovaPage\Pages\PageResource::class); + $option_resource_class = config('novapage.default_option_resource', \Whitecube\NovaPage\Pages\OptionResource::class); switch ($type) { case 'route': return new $page_resource_class($resource); case 'option': return new $option_resource_class($resource); } } + + protected function applyIndexQueryForType($type, Query $query) { + $page_resource_class = config('novapage.default_page_resource', \Whitecube\NovaPage\Pages\PageResource::class); + $option_resource_class = config('novapage.default_option_resource', \Whitecube\NovaPage\Pages\OptionResource::class); + switch ($type) { + case 'route': return $page_resource_class::novaPageIndexQuery($query); + case 'option': return $option_resource_class::novaPageIndexQuery($query); + } + } } diff --git a/src/Pages/Query.php b/src/Pages/Query.php index 5e42388..78f3287 100644 --- a/src/Pages/Query.php +++ b/src/Pages/Query.php @@ -29,6 +29,16 @@ class Query */ protected $type; + /** + * The column to order by + */ + protected $orderColumn; + + /** + * The direction to order by + */ + protected $orderDirection; + /** * The locale filter used to retrieve the resource * @@ -70,6 +80,19 @@ public function whereType($type) return $this; } + /** + * Mimic eloquent's Builder and register a orderBy statment + * + * @param mixed $column + * @param string $direction + */ + public function orderBy($column, string $direction = 'ASC') + { + $this->orderColumn = $column; + $this->orderDirection = $direction; + return $this; + } + /** * Mimic eloquent's Builder and return corresponding Resource * @@ -97,7 +120,7 @@ public function get($throwOnMissing = false) { $resources = $this->repository->getFiltered(trim($this->type . '.*', '.')); - return Collection::make($resources) + $result = Collection::make($resources) ->map(function($template, $key) { return $this->repository->getResourceTemplate($key); }) @@ -107,6 +130,12 @@ public function get($throwOnMissing = false) list($type, $name) = explode('.', $key, 2); return $this->repository->load($type, $name, $this->locale, $throwOnMissing); }); + + if ($this->orderColumn && $this->orderDirection) { + $result = $result->sortBy($this->orderColumn, SORT_REGULAR, ($this->orderDirection === 'DESC') ? true : false); + } + + return $result; } /** diff --git a/src/Pages/StaticResource.php b/src/Pages/StaticResource.php index fc97d10..2eba9f7 100644 --- a/src/Pages/StaticResource.php +++ b/src/Pages/StaticResource.php @@ -104,6 +104,17 @@ public function fields(Request $request) ); } + /** + * A blank method which allows index queries to be manipulated by the Resource + * + * @param Query $query + * @return Query + */ + public static function novaPageIndexQuery(Query $query) + { + return $query; + } + /** * Get the base fields displayed at the top of the resource's form. * @@ -221,4 +232,4 @@ protected function serializeWithId(Collection $fields) ]; } -} \ No newline at end of file +}