From 04653f9839b7a885cb9852a7b1dc29d67bb963ed Mon Sep 17 00:00:00 2001 From: Dan Feder Date: Wed, 6 Jul 2022 16:34:05 -0400 Subject: [PATCH] Order search facets by count, name (#3802) --- .../modules/metastore_search/src/Search.php | 25 +++++++++++-- .../tests/src/Unit/SearchTest.php | 35 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/modules/metastore/modules/metastore_search/src/Search.php b/modules/metastore/modules/metastore_search/src/Search.php index f8850e3848..6df4535c18 100644 --- a/modules/metastore/modules/metastore_search/src/Search.php +++ b/modules/metastore/modules/metastore_search/src/Search.php @@ -138,16 +138,37 @@ public function facets(array $params = []) : array { $facets = $this->getFacetsFromIndex($params, $this->index, $query); } + static::orderFacets($facets); return $facets; } + /** + * Order the facet array by total (desc) then name (asc) + * + * @param array $facets + * Array of facet objects with properties "total", "name" and "type". + */ + public static function orderFacets(array &$facets): void { + usort($facets, function ($a, $b) { + if (!isset($a->name, $b->name, $a->total, $b->total)) { + throw new \InvalidArgumentException("Facets much name and total properties."); + } + if ($a->total == $b->total) { + return strcmp($a->name, $b->name); + } + else { + return $b->total - $a->total; + } + }); + } + /** * Private. * * @param \Drupal\search_api\Query\ResultSet $result * Result set. * - * @return array + * @return null|array * Filtered results. */ private function getData(ResultSet $result) { @@ -158,7 +179,7 @@ function ($item) use ($metastore) { $id = $item->getId(); $id = str_replace('dkan_dataset/', '', $id); try { - return json_decode($metastore->get('dataset', $id)); + return json_decode((string) $metastore->get('dataset', $id)); } catch (\Exception $e) { return NULL; diff --git a/modules/metastore/modules/metastore_search/tests/src/Unit/SearchTest.php b/modules/metastore/modules/metastore_search/tests/src/Unit/SearchTest.php index 095446187c..6fd6e73c1c 100644 --- a/modules/metastore/modules/metastore_search/tests/src/Unit/SearchTest.php +++ b/modules/metastore/modules/metastore_search/tests/src/Unit/SearchTest.php @@ -104,6 +104,41 @@ public function testSearchParameterWithComma() { ); } + /** + * Test the Service::orderFacets method. + */ + public function testOrderFacets() { + $in = [ + (object) ['name' => 'Ana', 'total' => 1], + (object) ['name' => 'Bob', 'total' => 2], + (object) ['name' => 'Chris', 'total' => 3], + (object) ['name' => 'Dana', 'total' => 3], + (object) ['name' => 'Ed', 'total' => 3], + ]; + + // orderFacets() should order descending by count, then ascending by name. + $out = [ + (object) ['name' => 'Chris', 'total' => 3], + (object) ['name' => 'Dana', 'total' => 3], + (object) ['name' => 'Ed', 'total' => 3], + (object) ['name' => 'Bob', 'total' => 2], + (object) ['name' => 'Ana', 'total' => 1], + ]; + + Search::orderFacets($in); + + $this->assertEquals($out, $in); + + $no_name = [ + (object) ['field1' => 'foo', 'field2' => 'bar'], + (object) ['field1' => 'x', 'field2' => 'y'], + ]; + + // Passing facets without name or total properties will throw exception. + $this->expectException(\InvalidArgumentException::class); + Search::orderFacets($no_name); + } + /** * Test for facets(). */