From bd130526932b49135a2b8985fcf2a2c385137602 Mon Sep 17 00:00:00 2001 From: Robert Lange Date: Wed, 16 Oct 2024 20:28:13 +0200 Subject: [PATCH] refs vufind-org#2999 Add support for result set identifier in Record and Backend classes * Updated `VuFind\View\Helper\Root\Record` to include `ResultSetIdentifier` in the HTML element IDs, ensuring unique and context-aware IDs across templates. * Modified `VuFindTest\View\Helper\Root\RecordTest` to account for the new `ResultSetIdentifier` in tests, ensuring the unique identifier is reflected correctly in different scenarios. * Enhanced `VuFindSearch\Backend\AbstractBackend` by generating and assigning a unique, shorter UUID-like identifier to each record collection using `Laminas\Math\Rand`. * Implemented `setResultSetIdentifier` and `getResultSetIdentifier` methods in `RecordCollectionInterface`, `AbstractRecordCollection`, `RecordInterface`, and `RecordTrait` to manage and retrieve the result set identifiers. * Adjusted `RecordTrait` to include a new `resultSetIdentifier` property with appropriate PHPDoc for easier management and retrieval of unique identifiers per record. --- .../src/VuFind/View/Helper/Root/Record.php | 4 ++- .../View/Helper/Root/RecordTest.php | 12 ++++--- .../VuFindSearch/Backend/AbstractBackend.php | 32 +++++++++++++++++ .../Response/AbstractRecordCollection.php | 16 +++++++++ .../Response/RecordCollectionInterface.php | 7 ++++ .../VuFindSearch/Response/RecordInterface.php | 4 +++ .../src/VuFindSearch/Response/RecordTrait.php | 35 +++++++++++++++++++ 7 files changed, 105 insertions(+), 5 deletions(-) diff --git a/module/VuFind/src/VuFind/View/Helper/Root/Record.php b/module/VuFind/src/VuFind/View/Helper/Root/Record.php index 23c690f17e2..a557545b41b 100644 --- a/module/VuFind/src/VuFind/View/Helper/Root/Record.php +++ b/module/VuFind/src/VuFind/View/Helper/Root/Record.php @@ -871,7 +871,9 @@ public function getUniqueHtmlElementId($idPrefix = '') return preg_replace( "/\s+/", '_', - ($idPrefix ? $idPrefix . '-' : '') . $this->getUniqueIdWithSourcePrefix() + ($idPrefix ? $idPrefix . '-' : '') + . $this->driver->getResultSetIdentifier() . '-' + . $this->driver->getUniqueId() ); } diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php index 2951b010a25..190c0908f01 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/View/Helper/Root/RecordTest.php @@ -392,6 +392,8 @@ public function testGetCheckbox(): void $driver = $this->loadRecordFixture('testbug1.json'); $tpl = 'record/checkbox.phtml'; $context = $this->getMockContext(); + $randomIdentifier = 'baz'; + $driver->setResultSetIdentifier($randomIdentifier); $expectedCalls = [ [ @@ -399,7 +401,7 @@ public function testGetCheckbox(): void [ 'number' => 1, 'id' => 'Solr|000105196', - 'checkboxElementId' => 'bar-Solr|000105196', + 'checkboxElementId' => "bar-{$randomIdentifier}-000105196", 'prefix' => 'bar', 'formAttr' => 'foo', ], @@ -409,7 +411,7 @@ public function testGetCheckbox(): void [ 'number' => 2, 'id' => 'Solr|000105196', - 'checkboxElementId' => 'bar-Solr|000105196', + 'checkboxElementId' => "bar-{$randomIdentifier}-000105196", 'prefix' => 'bar', 'formAttr' => 'foo', ], @@ -439,16 +441,18 @@ public function testGetUniqueHtmlElementId() { $driver = $this->loadRecordFixture('testbug1.json'); $record = $this->getRecord($driver); + $randomIdentifier = 'bar'; + $driver->setResultSetIdentifier($randomIdentifier); // with prefix $this->assertEquals( - 'testPrefix-Solr|000105196', + "testPrefix-{$randomIdentifier}-000105196", $record->getUniqueHtmlElementId('testPrefix') ); // without prefix $this->assertEquals( - 'Solr|000105196', + "{$randomIdentifier}-000105196", $record->getUniqueHtmlElementId() ); } diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/AbstractBackend.php b/module/VuFindSearch/src/VuFindSearch/Backend/AbstractBackend.php index c039edb99a6..767770d086d 100644 --- a/module/VuFindSearch/src/VuFindSearch/Backend/AbstractBackend.php +++ b/module/VuFindSearch/src/VuFindSearch/Backend/AbstractBackend.php @@ -30,6 +30,7 @@ namespace VuFindSearch\Backend; use Laminas\Log\LoggerAwareInterface; +use Laminas\Math\Rand; use VuFindSearch\Response\RecordCollectionFactoryInterface; use VuFindSearch\Response\RecordCollectionInterface; @@ -116,6 +117,37 @@ abstract public function getRecordCollectionFactory(); protected function injectSourceIdentifier(RecordCollectionInterface $response) { $response->setSourceIdentifiers($this->identifier); + $response->setResultSetIdentifier($this->generateUuid()); + return $response; } + + /** + * Sets the result set identifier for the record collection. + * + * @param string $uuid A valid UUID associated with the data set. + * + * @return void + */ + public function setResultSetIdentifier(string $uuid): void { + $this->recordCollection->setResultSetIdentifier($uuid); + } + + /** + * Generates a shorter UUID-like identifier. + * + * This method uses Laminas\Math\Rand to generate cryptographically secure random bytes + * and formats them into a shorter identifier. + * + * @return string A randomly generated shorter UUID-like identifier. + */ + function generateUuid(): string { + $data = bin2hex(Rand::getBytes(8)); + return sprintf( + '%08s-%04s-%04s', + substr($data, 0, 8), + substr($data, 8, 4), + substr($data, 12, 4) + ); + } } diff --git a/module/VuFindSearch/src/VuFindSearch/Response/AbstractRecordCollection.php b/module/VuFindSearch/src/VuFindSearch/Response/AbstractRecordCollection.php index 0c7541bcc98..b36fefe17b8 100644 --- a/module/VuFindSearch/src/VuFindSearch/Response/AbstractRecordCollection.php +++ b/module/VuFindSearch/src/VuFindSearch/Response/AbstractRecordCollection.php @@ -297,4 +297,20 @@ public function count(): int { return count($this->records); } + + /** + * Sets the result set identifier for all records in the collection. + * + * This method assigns a given UUID to each record in the collection by calling + * the `setResultSetIdentifier` method on each record. + * + * @param string $uuid A valid UUID to be assigned to each record in the collection. + * + * @return void + */ + public function setResultSetIdentifier($uuid) { + foreach ($this->records as $record) { + $record->setResultSetIdentifier($uuid); + } + } } diff --git a/module/VuFindSearch/src/VuFindSearch/Response/RecordCollectionInterface.php b/module/VuFindSearch/src/VuFindSearch/Response/RecordCollectionInterface.php index 9866db7becd..95352f7d61d 100644 --- a/module/VuFindSearch/src/VuFindSearch/Response/RecordCollectionInterface.php +++ b/module/VuFindSearch/src/VuFindSearch/Response/RecordCollectionInterface.php @@ -117,6 +117,13 @@ public function setSourceIdentifiers($identifier, $searchBackendId = ''); */ public function getSourceIdentifier(); + /** + * Return the result set identifier. + * + * @return void + */ + public function setResultSetIdentifier($uuid); + /** * Add a record to the collection. * diff --git a/module/VuFindSearch/src/VuFindSearch/Response/RecordInterface.php b/module/VuFindSearch/src/VuFindSearch/Response/RecordInterface.php index e909f57f936..327ca11da38 100644 --- a/module/VuFindSearch/src/VuFindSearch/Response/RecordInterface.php +++ b/module/VuFindSearch/src/VuFindSearch/Response/RecordInterface.php @@ -78,6 +78,10 @@ public function getSourceIdentifier(); */ public function getSearchBackendIdentifier(); + public function setResultSetIdentifier($uuid); + + public function getResultSetIdentifier(); + /** * Add a label for the record * diff --git a/module/VuFindSearch/src/VuFindSearch/Response/RecordTrait.php b/module/VuFindSearch/src/VuFindSearch/Response/RecordTrait.php index 5b6b52c25ac..d8683c4200e 100644 --- a/module/VuFindSearch/src/VuFindSearch/Response/RecordTrait.php +++ b/module/VuFindSearch/src/VuFindSearch/Response/RecordTrait.php @@ -46,6 +46,16 @@ trait RecordTrait * @var string */ protected $sourceIdentifier = ''; + + /** + * The unique identifier for the result set. + * + * This property stores a UUID or similar identifier that uniquely identifies + * the result set. It is typically set by calling the `setResultSetIdentifier` method. + * + * @var string|null + */ + protected $resultSetIdentifier; /** * Used for identifying the search backend used to find the record @@ -109,6 +119,31 @@ public function getSearchBackendIdentifier() { return $this->searchBackendIdentifier; } + + /** + * Sets the unique result set identifier. + * + * This method assigns a UUID or similar identifier to the result set. + * + * @param string $uuid A valid UUID or identifier to assign to the result set. + * + * @return void + */ + public function setResultSetIdentifier(string $uuid): void { + $this->resultSetIdentifier = $uuid; + } + + /** + * Retrieves the unique result set identifier. + * + * This method returns the UUID or similar identifier associated with the result set. + * If no identifier has been set, it will return null. + * + * @return string|null The UUID of the result set, or null if not set. + */ + public function getResultSetIdentifier(): ?string { + return $this->resultSetIdentifier; + } /** * Add a label for the record