Skip to content
Snippets Groups Projects
Commit 1f4fed9a authored by Eli's avatar Eli Committed by Björn Brala
Browse files

Issue #3169654 by Eli.Stone: Default sorting

parent 4cd2be00
No related branches found
No related tags found
No related merge requests found
......@@ -14,6 +14,12 @@ jsonapi_extras.jsonapi_resource_config.*.third_party.jsonapi_defaults:
sequence:
type: string
label: 'Key and value'
default_sorting:
type: sequence
label: 'Default sorting list'
sequence:
type: string
label: 'Key and value'
page_limit:
type: integer
label: 'Limit of records fetched per page'
......@@ -41,11 +41,14 @@ function _jsonapi_defaults_form_alter(array &$form, FormStateInterface $form_sta
'jsonapi_defaults',
'default_include'
);
$sorting = _jsonapi_defaults_convert_value(
$config_resource->getThirdPartySetting('jsonapi_defaults', 'default_sorting')
);
$form['bundle_wrapper']['fields_wrapper']['defaults'] = [
'#type' => 'details',
'#title' => t('Collection'),
'#open' => $includes || $filters,
'#open' => $includes || $filters || $sorting,
'#description' => t('Sets resource default parameters.'),
'#states' => [
'visible' => [
......@@ -71,6 +74,16 @@ function _jsonapi_defaults_form_alter(array &$form, FormStateInterface $form_sta
If a request contains an "filter" query string parameter those filters will be added to the defaults.'),
];
$form['bundle_wrapper']['fields_wrapper']['defaults']['default_sorting'] = [
'#type' => 'textarea',
'#title' => 'Default sorting list',
'#default_value' => $sorting,
'#description' => t('Enter one sort per line, in the format key=value. For example:<br />
sort[titleSort][path]=created<br />
sort[titleSort][direction]=DESC<br />
If a request contains an "sort" query string parameter those sorting will be added to the defaults.'),
];
$form['bundle_wrapper']['fields_wrapper']['defaults']['page_limit'] = [
'#type' => 'number',
'#title' => 'Page limit',
......@@ -98,6 +111,14 @@ function jsonapi_defaults_form_jsonapi_resource_config_form_builder($entity_type
$config_resource->unsetThirdPartySetting('jsonapi_defaults', 'default_filter');
}
if ($raw_value = $form_state->getValue('default_sorting')) {
$value = _jsonapi_defaults_convert_rawvalue($raw_value);
$config_resource->setThirdPartySetting('jsonapi_defaults', 'default_sorting', $value);
}
else {
$config_resource->unsetThirdPartySetting('jsonapi_defaults', 'default_sorting');
}
if ($raw_value = $form_state->getValue('default_include')) {
$include = array_map('trim', preg_split('/\r\n?|\n/', $raw_value));
$include = array_filter($include);
......@@ -140,6 +161,11 @@ function _jsonapi_defaults_convert_rawvalue($raw_value) {
$key = explode('][', $key);
$value['filter:' . trim(implode('#', $key), '[]')] = $val;
}
elseif (preg_match('/^sort.+/', $key)){
$key = str_replace('sort[', '', $key);
$key = explode('][', $key);
$value['sort:' . trim(implode('#', $key), '[]')] = $val;
}
}
}
......@@ -166,6 +192,10 @@ function _jsonapi_defaults_convert_value($value) {
$key = implode('][', explode('#', preg_replace('/^filter:/', '', $key)));
$raw_value .= "filter[$key]=$val\n";
}
elseif (preg_match('/^sort.+/', $key)) {
$key = implode('][', explode('#', preg_replace('/^sort:/', '', $key)));
$raw_value .= "sort[$key]=$val\n";
}
}
}
return $raw_value;
......
......
......@@ -46,7 +46,15 @@ class EntityResource extends JsonApiEntityResourse {
[]
);
$default_sorting_input = $resource_config->getThirdPartySetting(
'jsonapi_defaults',
'default_sorting',
[]
);
$default_filter = [];
$default_sorting = [];
foreach ($default_filter_input as $key => $value) {
if (substr($key, 0, 6) === 'filter') {
$key = str_replace('filter:', '', $key);
......@@ -54,15 +62,33 @@ class EntityResource extends JsonApiEntityResourse {
$this->setFilterValue($default_filter, $key, $value);
}
}
foreach ($default_sorting_input as $key => $value) {
if (substr($key, 0, 4) === 'sort') {
$key = str_replace('sort:', '', $key);
// TODO: Replace this with use of the NestedArray utility.
$this->setFilterValue($default_sorting, $key, $value);
}
}
$filters = array_merge(
$default_filter,
$request->query->get('filter', [])
);
$sorting = array_merge(
$default_sorting,
$request->query->get('sort', [])
);
if (!empty($filters)) {
$request->query->set('filter', $filters);
}
if (!empty($sorting)) {
$request->query->set('sort', $sorting);
}
// Implements overridden page limits.
$params = parent::getJsonApiParams($request, $resource_type);
$this->setPageLimit($request, $resource_config, $params);
......
......
......@@ -71,6 +71,49 @@ class JsonApiDefaultsFunctionalTest extends JsonApiExtrasFunctionalTestBase {
]);
$parsed_response = Json::decode($response);
$this->assertArrayNotHasKey('included', $parsed_response);
// 4. Using the default sorting check the order.
// Unset filters of resource config in this test as those limit the results.
$this->setResouceConfigValue(['default_filter' => []]);
$this->nodes[0]->setTitle('a');
$this->nodes[0]->save();
$this->nodes[1]->setTitle('b');
$this->nodes[1]->save();
$this->nodes[2]->setTitle('c');
$this->nodes[2]->save();
$this->nodes[3]->setTitle('d');
$this->nodes[3]->save();
$response = $this->drupalGet('/api/articles');
$parsed_response = Json::decode($response);
// Check if order is as expected.
$this->assertEquals('d', $parsed_response['data'][0]['attributes']['title']);
$this->assertEquals('c', $parsed_response['data'][1]['attributes']['title']);
$this->assertEquals('b', $parsed_response['data'][2]['attributes']['title']);
$this->assertEquals('a', $parsed_response['data'][3]['attributes']['title']);
// 5. Override default sorting with explicit sorting.
$response = $this->drupalGet('/api/articles', [
'query' => [
'sort' => [
'title' => [
'path' => 'title',
'direction' => 'ASC',
],
],
],
]);
$parsed_response = Json::decode($response);
// Check if order changed as expected.
$this->assertEquals('a', $parsed_response['data'][0]['attributes']['title']);
$this->assertEquals('b', $parsed_response['data'][1]['attributes']['title']);
$this->assertEquals('c', $parsed_response['data'][2]['attributes']['title']);
$this->assertEquals('d', $parsed_response['data'][3]['attributes']['title']);
}
/**
......@@ -194,6 +237,10 @@ class JsonApiDefaultsFunctionalTest extends JsonApiExtrasFunctionalTestBase {
'filter:nidFilter#condition#path' => 'internalId',
'filter:nidFilter#condition#value' => 3,
],
'default_sorting' => [
'sort:title#path' => 'title',
'sort:title#direction' => 'DESC',
],
// TODO: Change this to 'tags.vid'.
'default_include' => ['tags'],
],
......
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment