From 7a8040869656a39b16a4038be051d6306d079980 Mon Sep 17 00:00:00 2001 From: Raphael Date: Wed, 3 Dec 2014 23:10:05 +0200 Subject: [PATCH] Add defaultSortInfo() method to define default sorts. --- README.md | 23 ++++++++- plugins/restful/RestfulBase.php | 2 +- .../restful/RestfulDataProviderDbQuery.php | 21 +++++++-- plugins/restful/RestfulDataProviderEFQ.php | 22 +++++---- tests/RestfulListTestCase.test | 47 +++++++++++++++++++ tests/RestfulRenderCacheTestCase.test | 3 +- ...RestfulTestArticlesResource__1_1.class.php | 12 ++++- 7 files changed, 113 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index a2730b13..6d1c739d 100644 --- a/README.md +++ b/README.md @@ -202,6 +202,27 @@ array( ); ``` +You can also define default sort fields in your plugin, by overriding +`defaultSortInfo()` in your class definition. + +This method should return an associative array, with each element having a key +that matches a field from `publicFieldsInfo()`, and a value of either 'ASC' or 'DESC'. + +This default sort will be ignored if the request URL contains a sort query. + +```php +class MyPlugin extends \RestfulEntityBaseTaxonomyTerm { + /** + * Overrides \RestfulEntityBase::defaultSortInfo(). + */ + public function defaultSortInfo() { + // Sort by 'id' in descending order. + return array('id' => 'DESC'); + } +} + +``` + ### Filter RESTful allows filtering of a list. @@ -580,7 +601,7 @@ Since the global event is not tied to any resource the limit and period is speci all roles. - `restful_global_rate_period`: The period string compatible with \DateInterval. - + ## Documenting your API It is of most importance to document your API, this is why the RESTful module provides a way to comprehensively document your resources and endpoints. This diff --git a/plugins/restful/RestfulBase.php b/plugins/restful/RestfulBase.php index f1eb40f3..bbcb8a23 100644 --- a/plugins/restful/RestfulBase.php +++ b/plugins/restful/RestfulBase.php @@ -286,7 +286,7 @@ public function setRateLimitManager($rateLimitManager) { /** * Getter for rateLimitManager. - + * * @return \RestfulRateLimitManager */ public function getRateLimitManager() { diff --git a/plugins/restful/RestfulDataProviderDbQuery.php b/plugins/restful/RestfulDataProviderDbQuery.php index 4f3fc730..d7281692 100644 --- a/plugins/restful/RestfulDataProviderDbQuery.php +++ b/plugins/restful/RestfulDataProviderDbQuery.php @@ -93,6 +93,20 @@ public function __construct(array $plugin, \RestfulAuthenticationManager $auth_m $this->primary = empty($plugin['primary']) ? NULL : $this->primary = $plugin['primary']; } + /** + * Defines default sort columns if none are provided via the request URL. + * + * @return array + * Array keyed by the database column name, and the order ('ASC' or 'DESC') as value. + */ + public function defaultSortInfo() { + $sorts = array(); + if (!empty($this->getPublicFields[$this->getIdColumn()])) { + $sorts[$this->getIdColumn()] = 'ASC'; + } + return $sorts; + } + /** * {@inheritdoc} */ @@ -121,12 +135,11 @@ public function getQueryForList() { */ protected function queryForListSort(\SelectQuery $query) { $public_fields = $this->getPublicFields(); + // Get the sorting options from the request object. $sorts = $this->parseRequestForListSort(); - if (empty($sorts)) { - $query->orderBy($this->getIdColumn(), 'ASC'); - return; - } + + $sorts = $sorts ? $sorts : $this->defaultSortInfo(); foreach ($sorts as $sort => $direction) { $query->orderBy($public_fields[$sort]['property'], $direction); diff --git a/plugins/restful/RestfulDataProviderEFQ.php b/plugins/restful/RestfulDataProviderEFQ.php index 0e2db883..52b19a2e 100644 --- a/plugins/restful/RestfulDataProviderEFQ.php +++ b/plugins/restful/RestfulDataProviderEFQ.php @@ -55,6 +55,16 @@ public function __construct(array $plugin, \RestfulAuthenticationManager $auth_m $this->bundle = $plugin['bundle']; } + /** + * Defines default sort fields if none are provided via the request URL. + * + * @return array + * Array keyed by the public field name, and the order ('ASC' or 'DESC') as value. + */ + public function defaultSortInfo() { + return array('id' => 'ASC'); + } + /** * {@inheritdoc} */ @@ -94,15 +104,11 @@ public function getQueryForList() { */ protected function queryForListSort(\EntityFieldQuery $query) { $public_fields = $this->getPublicFields(); + + // Get the sorting options from the request object. $sorts = $this->parseRequestForListSort(); - if (empty($sorts)) { - // Some endpoints like 'token_auth' don't have an id public field. In that - // case, skip the default sorting. - if (!empty($public_fields['id'])) { - // Sort by default using the entity ID. - $sorts['id'] = 'ASC'; - } - } + + $sorts = $sorts ? $sorts : $this->defaultSortInfo(); foreach ($sorts as $sort => $direction) { // Determine if sorting is by field or property. diff --git a/tests/RestfulListTestCase.test b/tests/RestfulListTestCase.test index 9fe35c31..f4676c9f 100644 --- a/tests/RestfulListTestCase.test +++ b/tests/RestfulListTestCase.test @@ -128,6 +128,53 @@ class RestfulListTestCase extends RestfulCurlBaseTestCase { ); $this->assertEqual($result, $expected_result, 'Sort by ID and by label.'); + // Test default sorting from plugin definition; by label, then by reverse id. + $handler = restful_get_restful_handler('test_articles', 1, 1); + unset($request['sort']); + $result = $handler->get('', $request); + $expected_result = array( + array( + 'id' => $node->nid, + 'label' => 'abc', + ), + array( + 'id' => $nodes['abc'], + 'label' => 'abc', + ), + array( + 'id' => $nodes['efg'], + 'label' => 'efg', + ), + array( + 'id' => $nodes['xyz'], + 'label' => 'xyz', + ), + ); + $this->assertEqual($result, $expected_result, 'Default sort by ID and by label.'); + + // Test that the default sort can be overridden. + $request['sort'] = 'id'; + $result = $handler->get('', $request); + $expected_result = array( + array( + 'id' => $nodes['abc'], + 'label' => 'abc', + ), + array( + 'id' => $nodes['xyz'], + 'label' => 'xyz', + ), + array( + 'id' => $nodes['efg'], + 'label' => 'efg', + ), + array( + 'id' => $node->nid, + 'label' => 'abc', + ), + ); + $this->assertEqual($result, $expected_result, 'Sort by ID, overriding default sort.'); + // Illegal sort property. $request['sort'] = 'wrong_key'; try { diff --git a/tests/RestfulRenderCacheTestCase.test b/tests/RestfulRenderCacheTestCase.test index f0a979ac..aaff663a 100644 --- a/tests/RestfulRenderCacheTestCase.test +++ b/tests/RestfulRenderCacheTestCase.test @@ -26,10 +26,9 @@ class RestfulRenderCacheTestCase extends DrupalWebTestCase { $settings = array('type' => 'article'); $account = $this->drupalCreateUser(); - $num_articles = 3; for ($index = 0; $index < $num_articles; $index++) { - $settings['title'] = $this->randomName(); + $settings['title'] = 'Node title ' . $index; $node = $this->drupalCreateNode($settings); $nodes[$node->nid] = $node; } diff --git a/tests/modules/restful_test/plugins/restful/node/test_articles/1.1/RestfulTestArticlesResource__1_1.class.php b/tests/modules/restful_test/plugins/restful/node/test_articles/1.1/RestfulTestArticlesResource__1_1.class.php index 7d6d615e..14aae5cc 100644 --- a/tests/modules/restful_test/plugins/restful/node/test_articles/1.1/RestfulTestArticlesResource__1_1.class.php +++ b/tests/modules/restful_test/plugins/restful/node/test_articles/1.1/RestfulTestArticlesResource__1_1.class.php @@ -5,4 +5,14 @@ * Contains RestfulTestArticlesResource__1_1. */ -class RestfulTestArticlesResource__1_1 extends RestfulExampleArticlesResource {} +class RestfulTestArticlesResource__1_1 extends RestfulExampleArticlesResource { + /** + * Overrides RestfulDataProviderEFQ::defaultSortInfo(). + */ + public function defaultSortInfo() { + return array( + 'label' => 'ASC', + 'id' => 'DESC' + ); + } +}