diff --git a/README.md b/README.md index ab0b681..a5e1cbd 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,8 @@ Reference (module for Omeka S) alphabetized index) of links to records or to searches for all resources classes (item types) and properties (metadata fields) of all resources of an Omeka S instance, or an expandable hierarchical tree of statically specified references. -These lists can be displayed in any page via a helper or a block. +These lists can be displayed in any page via a helper or a block. References can +be limited by site or any other pool, and ordered alphabetically or by count. This [Omeka S] module is a rewrite of the [Reference plugin] for [Omeka] and intends to provide the same features as the original plugin. @@ -77,6 +78,8 @@ echo $this->reference()->displayListForTerm($term, [ 'type' => 'properties', 'resource_name' => 'items', + 'order' => ['alphabetic' => 'ASC'], + 'query' => ['site_id' => 1], 'per_page' => null, 'page' => null, ], @@ -99,6 +102,7 @@ echo $this->reference()->displayTree($references, 'term' => $term, 'type' => 'properties', 'resource_name' => 'items', + 'query' => ['site_id' => 1], ], [ 'query_type' => 'eq', @@ -115,6 +119,12 @@ echo $this->reference()->displayTree($references, All arguments are optional and the default ones are set in the config page or in the block, but they can be overridden in the theme. +For `order`, the sort can be `['count' => 'DESC']` too. + +For `query`, it is the standard query used in the api of Omeka, or the arguments +taken from the url of an advanced search, converted into an array with `parse_str`. +The conversion is automatically done inside the user interface (page blocks). + Warning ------- diff --git a/src/Controller/Site/ReferenceController.php b/src/Controller/Site/ReferenceController.php index 594d40d..c02564a 100644 --- a/src/Controller/Site/ReferenceController.php +++ b/src/Controller/Site/ReferenceController.php @@ -58,11 +58,12 @@ public function listAction() $term = $slugData['term']; $type = $slugData['type']; $resourceName = $settings->get('reference_resource_name', 'resources'); + $order = ['value.value' => 'ASC']; $query = ['site_id' => $this->currentSite()->id()]; $output = $this->params()->fromQuery('output'); if ($output === 'json') { - $references = $this->reference()->getList($term, $type, $resourceName, $query); + $references = $this->reference()->getList($term, $type, $resourceName, $order, $query); $view = new JsonModel($references); return $view; } @@ -76,6 +77,7 @@ public function listAction() $view->setVariable('args', [ 'type' => $type, 'resource_name' => $resourceName, + 'order' => $order, 'query' => $query, ]); $view->setVariable('options', [ diff --git a/src/Form/ReferenceBlockForm.php b/src/Form/ReferenceBlockForm.php index 693e2d6..b8e0d1c 100644 --- a/src/Form/ReferenceBlockForm.php +++ b/src/Form/ReferenceBlockForm.php @@ -92,6 +92,19 @@ public function init() ], ], ]); + $referenceFieldset->add([ + 'name' => 'order', + 'type' => Element\Select::class, + 'options' => [ + 'label' => 'Select order', // @translate + 'value_options' => [ + 'alphabetic ASC' => 'Alphabetic ascendant', // @translate + 'alphabetic DESC' => 'Alphabetic descendant', // @translate + 'count ASC' => 'Count ascendant', // @translate + 'count DESC' => 'Count descendant', // @translate + ], + ], + ]); $referenceFieldset->add([ 'name' => 'query', 'type' => Element\Text::class, diff --git a/src/Mvc/Controller/Plugin/Reference.php b/src/Mvc/Controller/Plugin/Reference.php index 48d30e1..e7d812b 100644 --- a/src/Mvc/Controller/Plugin/Reference.php +++ b/src/Mvc/Controller/Plugin/Reference.php @@ -45,18 +45,20 @@ public function __construct(EntityManager $entityManager, Api $api) * @param int|string|PropertyRepresentation|ResourceClassRepresentation $term * @param string $type "properties" (default) or "resource_classes". * @param string $resourceName All resources types if empty. + * @param array $order Sort and direction: ['alphabetic' => 'ASC'] (default), + * ['count' => 'DESC'], or any available column as sort. * @param array $query An api search formatted query to limit results. * @param int $perPage * @param int $page One-based page number. * @return Reference|array|null The result or null if called directly, else * this view plugin. */ - public function __invoke($term = null, $type = null, $resourceName = null, $query = null, $perPage = null, $page = null) + public function __invoke($term = null, $type = null, $resourceName = null, $order = null,$query = null, $perPage = null, $page = null) { if (empty($term)) { return $this; } - return $this->getList($term, $type, $resourceName, $query, $perPage, $page); + return $this->getList($term, $type, $resourceName, $order, $query, $perPage, $page); } /** @@ -65,12 +67,14 @@ public function __invoke($term = null, $type = null, $resourceName = null, $quer * @param int|string|PropertyRepresentation|ResourceClassRepresentation $term * @param string $type "properties" (default) or "resource_classes". * @param string $resourceName + * @param array $order Sort and direction: ['alphabetic' => 'ASC'] (default), + * ['count' => 'DESC'], or any available column as sort. * @param array $query An api search formatted query to limit results. * @param int $perPage * @param int $page One-based page number. * @return array Associative array with total and first record ids. */ - public function getList($term, $type = null, $resourceName = null, $query = null, $perPage = null, $page = null) + public function getList($term, $type = null, $resourceName = null, $order = null, $query = null, $perPage = null, $page = null) { $type = $type === 'resource_classes' ? 'resource_classes' : 'properties'; @@ -84,7 +88,7 @@ public function getList($term, $type = null, $resourceName = null, $query = null return; } - $references = $this->getReferencesList($termId, $type, $entityClass, $query, [], $perPage, $page, null); + $references = $this->getReferencesList($termId, $type, $entityClass, $order, $query, [], $perPage, $page, null); return $references; } @@ -273,7 +277,7 @@ public function count($term, $type = null, $resourceName = null, $query = null) * * @param int|string|PropertyRepresentation|ResourceClassRepresentation $term * @param array $args Specify the references with "type", "resource_name", - * "query", "per_page" and "page". + * "order", "query", "per_page" and "page". * @param array $options Options to display references. Values are booleans: * - raw: Show references as raw text, not links (default to false) * - skiplinks: Add the list of letters at top and bottom of the page @@ -302,12 +306,13 @@ public function displayListForTerm($term, array $args = [], array $options = []) $options = $this->cleanOptions($options); + $order = empty($args['order']) ? null : $args['order']; $query = empty($args['query']) ? null : $args['query']; $perPage = empty($args['per_page']) ? null : (int) $args['per_page']; $page = empty($args['page']) ? null : (int) $args['page']; $output = $options['link_to_single'] ? 'withFirst' : 'list'; - $references = $this->getReferencesList($termId, $type, $entityClass, $query, [], $perPage, $page, $output); + $references = $this->getReferencesList($termId, $type, $entityClass, $order, $query, [], $perPage, $page, $output); $controller = $this->getController(); $partial = $controller->viewHelpers()->get('partial'); @@ -317,6 +322,7 @@ public function displayListForTerm($term, array $args = [], array $options = []) 'type' => $type, 'resourceName' => $resourceName, 'options' => $options, + 'order' => $order, 'query' => $query, 'perPage' => $perPage, 'page' => $page, @@ -432,7 +438,7 @@ public function displayTree($references, array $args, array $options = []) $branches[] = $branch; $lowerBranches[] = $hasMb ? mb_strtolower($branch) : strtolower($branch); } - $totals = $this->getReferencesList($termId, $type, $entityClass, $query, $lowerBranches, null, null, $output); + $totals = $this->getReferencesList($termId, $type, $entityClass, null, $query, $lowerBranches, null, null, $output); } // Simple tree. else { @@ -443,7 +449,7 @@ public function displayTree($references, array $args, array $options = []) : array_map(function($v) { return strtolower(key($v)); }, $references); - $totals = $this->getReferencesList($termId, $type, $entityClass, $query, $lowerReferences, null, null, $output); + $totals = $this->getReferencesList($termId, $type, $entityClass, null, $query, $lowerReferences, null, null, $output); } $lowerTotals = []; @@ -557,6 +563,8 @@ protected function cleanOptions($options) * @param int $termId May be the resource class id. * @param string $type "properties" (default) or "resource_classes". * @param string $entityClass + * @param array $order Sort and direction: ['alphabetic' => 'ASC'] (default), + * ['count' => 'DESC'], or any available column as sort. * @param array $query An api search formatted query to limit results. * @param array $values Allow to limit the answer to the specified values. * @param int $perPage @@ -569,6 +577,7 @@ protected function getReferencesList( $termId, $type, $entityClass, + $order = null, $query = null, $values = [], $perPage = null, @@ -602,8 +611,7 @@ protected function getReferencesList( ->where($qb->expr()->eq('resource.resourceClass', ':resource_class')) ->setParameter('resource_class', (int) $resourceClassId) ->groupBy('value.value') - ->orderBy('value.value', 'ASC') - ->addOrderBy('resource.id', 'ASC'); + ; if ($entityClass !== \Omeka\Entity\Resource::class) { $qb @@ -628,11 +636,35 @@ protected function getReferencesList( // Only literal values. ->andWhere($qb->expr()->isNotNull('value.value')) ->groupBy('value.value') - ->orderBy('value.value', 'ASC') - ->addOrderBy('resource.id', 'ASC'); + ; break; } + if ($order) { + $direction = reset($order); + $order = strtolower(key($order)); + switch ($order) { + case 'count': + $qb + ->orderBy('total', $direction) + // Add alphabetic order for ergonomy. + ->addOrderBy('value.value', 'ASC'); + break; + case 'alphabetic': + $order = 'value.value'; + // No break; + default: + $qb + ->orderBy($order, $direction); + } + } else { + $qb + ->orderBy('value.value', 'ASC'); + } + // Always add an order by id for consistency. + $qb + ->addOrderBy('resource.id', 'ASC'); + if ($output === 'withFirst') { $qb ->addSelect([ diff --git a/src/Site/BlockLayout/Reference.php b/src/Site/BlockLayout/Reference.php index 92c0a73..730e82c 100644 --- a/src/Site/BlockLayout/Reference.php +++ b/src/Site/BlockLayout/Reference.php @@ -92,7 +92,13 @@ public function form(PhpRenderer $view, SiteRepresentation $site, ? $this->referencePlugin->convertLevelsToTree($data['reference']['tree']) : ''; - $data['reference']['query'] = urldecode(http_build_query($data['reference']['query'], "\n", '&', PHP_QUERY_RFC3986)); + $data['reference']['order'] = empty($data['reference']['order']) + ? 'alphabetic ASC' + : key($data['reference']['order']) . ' ' . reset($data['reference']['order']); + + $data['reference']['query'] = is_array($data['reference']['query']) + ? urldecode(http_build_query($data['reference']['query'], "\n", '&', PHP_QUERY_RFC3986)) + : $data['reference']['query']; // TODO Fix set data for radio buttons. $form->setData([ @@ -192,6 +198,10 @@ public function onHydrate(SitePageBlock $block, ErrorStore $errorStore) $data['reference']['resource_name'] = 'items'; } + $data['reference']['order'] = empty($data['reference']['order']) + ? ['alphabetic' => 'ASC'] + : [strtok($data['reference']['order'], ' ') => strtok(' ')]; + parse_str($data['reference']['query'], $query); $data['reference']['query'] = $query; diff --git a/src/View/Helper/Reference.php b/src/View/Helper/Reference.php index 9b4e769..4a6e859 100644 --- a/src/View/Helper/Reference.php +++ b/src/View/Helper/Reference.php @@ -27,18 +27,20 @@ public function __construct(ReferencePlugin $reference) * @param int|string|PropertyRepresentation|ResourceClassRepresentation $term * @param string $type "properties" (default) or "resource_classes". * @param string $resourceName All resources types if empty. + * @param array $order Sort and direction: ['alphabetic' => 'ASC'] (default), + * ['count' => 'DESC'], or any available column as sort. * @param array $query An api search formatted query to limit results. * @param int $perPage * @param int $page One-based page number. * @return Reference|array|null The result or null if called directly, else * this view helper. */ - public function __invoke($term = null, $type = null, $resourceName = null, $query = null, $perPage = null, $page = null) + public function __invoke($term = null, $type = null, $resourceName = null, $order = null, $query = null, $perPage = null, $page = null) { if (empty($term)) { return $this; } - return $this->reference->getList($term, $type, $resourceName, $query, $perPage, $page); + return $this->reference->getList($term, $type, $resourceName, $order, $query, $perPage, $page); } /** @@ -47,14 +49,16 @@ public function __invoke($term = null, $type = null, $resourceName = null, $quer * @param int|string|PropertyRepresentation|ResourceClassRepresentation $term * @param string $type "properties" (default) or "resource_classes". * @param string $resourceName + * @param array $order Sort and direction: ['alphabetic' => 'ASC'] (default), + * ['count' => 'DESC'], or any available column as sort. * @param array $query An api search formatted query to limit results. * @param int $perPage * @param int $page One-based page number. * @return array Associative array with total and first record ids. */ - public function getList($term, $type = null, $resourceName = null, $query = null, $perPage = null, $page = null) + public function getList($term, $type = null, $resourceName = null, $order = null, $query = null, $perPage = null, $page = null) { - return $this->reference->getList($term, $type, $resourceName, $query, $perPage, $page); + return $this->reference->getList($term, $type, $resourceName, $order, $query, $perPage, $page); } /** @@ -91,7 +95,7 @@ public function count($term, $type = null, $resourceName = null, $query = null) * * @param int|string|PropertyRepresentation|ResourceClassRepresentation $term * @param array $args Specify the references with "type", "resource_name", - * "query", "per_page" and "page". + * "order", "query", "per_page" and "page". * @param array $options Options to display references. Values are booleans: * - raw: Show references as raw text, not links (default to false) * - skiplinks: Add the list of letters at top and bottom of the page