Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get unique html element id from record view helper #2999

Merged
merged 32 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c69cbc0
get unique html element id from record view helper
RLangeUni Jul 21, 2023
4859ace
add prefix for unique html id - adapt test
RLangeUni Jul 21, 2023
3d33b82
refs #2999 unique element id
jpkanter Apr 3, 2024
3dd8446
refs #2999 unique element id
jpkanter Apr 3, 2024
22e7630
refs #2999 keep prefix in context and set checkboxElementId in checkb…
RLangeUni Apr 18, 2024
cbdedf7
refs #2999 adjust test fir getCheckbox: use separate property for new…
RLangeUni Apr 18, 2024
3e308f2
refs #2999 use escapeHtmlAttr to escape checkboxElementId attribute
RLangeUni Apr 19, 2024
e294a75
refs #2999 fix testGetCheckbox with expectConsecutiveCalls
RLangeUni Apr 19, 2024
c05492d
refs #2999 fix styles
RLangeUni Apr 19, 2024
0c34fbc
refs #2999 fix styles
RLangeUni Apr 19, 2024
07af7fa
refs #2999 fix styles
RLangeUni Apr 19, 2024
60de01a
refs #2999 fix styles
RLangeUni Apr 19, 2024
d8dfc5e
refs #2999 remove unnecessary tryMethod
RLangeUni Apr 22, 2024
d4a6492
refs #2999 restore comment for duplicate call of getCheckbox
RLangeUni Apr 22, 2024
6c57f53
refs #2999 add simple test for getUniqueHtmlElementId
RLangeUni Apr 22, 2024
3a9c45f
refs #2999 add simple test for getUniqueHtmlElementId - remove traili…
RLangeUni Apr 22, 2024
1848009
Merge remote-tracking branch 'vufind-org/dev' into pull-request-uniqu…
RLangeUni Oct 15, 2024
bd13052
refs vufind-org#2999 Add support for result set identifier in Record …
RLangeUni Oct 16, 2024
6ee8f92
refs vufind-org#2999 sync method signature
RLangeUni Oct 16, 2024
010756c
refs vufind-org#2999 fix styles with vufind rules
RLangeUni Oct 16, 2024
634dacb
refs vufind-org#2999 fix styles with vufind rules
RLangeUni Oct 16, 2024
898df17
refs vufind-org#2999 import sprintf - todo: generateUuid() should be …
RLangeUni Oct 16, 2024
48e5a10
refs vufind-org#2999 add recordCollection as property in AbstractBack…
RLangeUni Oct 16, 2024
939411f
refs vufind-org#2999 sync checkbox.phtml 3 and 5
RLangeUni Oct 16, 2024
87480db
refs vufind-org#2999 remove function setResultSetIdentifier in Abstra…
RLangeUni Oct 18, 2024
d31c992
refs vufind-org#2999 cleanup AbstractRecordCollection - order setResu…
RLangeUni Oct 18, 2024
d614377
refs vufind-org#2999 do not use inheritdoc
RLangeUni Oct 18, 2024
3a9b9d5
refs vufind-org#2999 sync checkbox examples with dev - should be chan…
RLangeUni Oct 18, 2024
8cba230
refs vufind-org#2999 handle nullable result set id: add test
RLangeUni Oct 18, 2024
46b2f01
refs vufind-org#2999 handle nullable result set id - initializing to …
RLangeUni Oct 18, 2024
83f543d
refs vufind-org#2999 add testGetCheckboxWithoutIdAndWithEmptyPrefix
RLangeUni Oct 18, 2024
0ee81bc
refs vufind-org#2999 handle nullable result set id - initializing to …
RLangeUni Oct 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions module/VuFind/src/VuFind/View/Helper/Root/Record.php
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,11 @@ public function getSearchResult($view)
*/
public function getCheckbox($idPrefix = '', $formAttr = false, $number = null)
{
$id = $this->driver->getSourceIdentifier() . '|'
. $this->driver->getUniqueId();
$context
= ['id' => $id, 'number' => $number, 'prefix' => $idPrefix];
$context = compact('number') + [
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
'id' => $this->getUniqueIdWithSourcePrefix(),
'checkboxElementId' => $this->getUniqueHtmlElementId($idPrefix),
'prefix' => $idPrefix,
];
if ($formAttr) {
$context['formAttr'] = $formAttr;
}
Expand Down Expand Up @@ -857,4 +858,38 @@ protected function deduplicateLinks($links)
{
return array_values(array_unique($links, SORT_REGULAR));
}

/**
* Get the source identifier + unique id of the record without spaces
*
* @param string $idPrefix Prefix for HTML ids
*
* @return string
*/
public function getUniqueHtmlElementId($idPrefix = '')
{
$resultSetId = $this->driver->getResultSetIdentifier() ?? '';

return preg_replace(
"/\s+/",
'_',
($idPrefix ? $idPrefix . '-' : '')
. ($resultSetId ? $resultSetId . '-' : '')
. $this->driver->getUniqueId()
);
}

/**
* Get the source identifier + unique id of the record
*
* @return string
*/
public function getUniqueIdWithSourcePrefix()
{
if ($this->driver) {
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
return "{$this->driver->getSourceIdentifier()}"
. "|{$this->driver->getUniqueId()}";
}
throw new \Exception('No record driver found.');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -389,30 +389,135 @@ public function testGetLink(
*/
public function testGetCheckbox(): void
{
$driver = $this->loadRecordFixture('testbug1.json');
$tpl = 'record/checkbox.phtml';
$context = $this->getMockContext();
$randomIdentifier = 'baz';
$driver->setResultSetIdentifier($randomIdentifier);

$expectedCalls = [
[
$tpl,
[
'number' => 1,
'id' => 'Solr|000105196',
'checkboxElementId' => "bar-{$randomIdentifier}-000105196",
'prefix' => 'bar',
'formAttr' => 'foo',
],
],
[
$tpl,
[
'number' => 2,
'id' => 'Solr|000105196',
'checkboxElementId' => "bar-{$randomIdentifier}-000105196",
'prefix' => 'bar',
'formAttr' => 'foo',
],
],
];

$this->expectConsecutiveCalls(
$context,
'renderInContext',
$expectedCalls,
['success', 'success']
);

$record = $this->getRecord($driver, [], $context);

// We run the test twice to ensure that checkbox incrementing works properly:
$this->assertEquals('success', $record->getCheckbox('bar', 'foo', 1));
$this->assertEquals('success', $record->getCheckbox('bar', 'foo', 2));
}

/**
* Test getCheckboxWithoutIdAndWithoutPrefix.
*
* @return void
*/
public function testGetCheckboxWithoutIdAndWithEmptyPrefix(): void
{
$driver = $this->loadRecordFixture('testbug1.json');
$tpl = 'record/checkbox.phtml';
$context = $this->getMockContext();

$expectedCalls = [
[
$tpl,
[
'record/checkbox.phtml',
['id' => 'Solr|000105196', 'number' => 1, 'prefix' => 'bar', 'formAttr' => 'foo'],
'number' => 1,
'id' => 'Solr|000105196',
'checkboxElementId' => '000105196',
'prefix' => '',
'formAttr' => 'foo',
],
],
[
$tpl,
[
'record/checkbox.phtml',
['id' => 'Solr|000105196', 'number' => 2, 'prefix' => 'bar', 'formAttr' => 'foo'],
'number' => 2,
'id' => 'Solr|000105196',
'checkboxElementId' => '000105196',
'prefix' => '',
'formAttr' => 'foo',
],
],
'success'
);
$record = $this->getRecord(
$this->loadRecordFixture('testbug1.json'),
[],
$context
];

$record = $this->getRecord($driver, [], $context);

$this->expectConsecutiveCalls(
$context,
'renderInContext',
$expectedCalls,
['success', 'success']
);

$record = $this->getRecord($driver, [], $context);

// We run the test twice to ensure that checkbox incrementing works properly:
demiankatz marked this conversation as resolved.
Show resolved Hide resolved
$this->assertEquals('success', $record->getCheckbox('bar', 'foo', 1));
$this->assertEquals('success', $record->getCheckbox('bar', 'foo', 2));
$this->assertEquals('success', $record->getCheckbox(formAttr: 'foo', number: 1));
$this->assertEquals('success', $record->getCheckbox('', 'foo', 2));
}

/**
* Test getUniqueHtmlElementId.
*
* @return void
*/
public function testGetUniqueHtmlElementId()
{
$driver = $this->loadRecordFixture('testbug1.json');
$record = $this->getRecord($driver);
$contextPrefix = 'foo';
$randomIdentifier = 'bar';

// no result set identifier and no prefix
$this->assertEquals(
'000105196',
$record->getUniqueHtmlElementId()
);

// no result set identifier but with prefix
$this->assertEquals(
"{$contextPrefix}-000105196",
$record->getUniqueHtmlElementId($contextPrefix)
);

// with result set identifier but no prefix
$driver->setResultSetIdentifier($randomIdentifier);
$this->assertEquals(
"{$randomIdentifier}-000105196",
$record->getUniqueHtmlElementId()
);

// with result set identifier and with prefix
$this->assertEquals(
"{$contextPrefix}-{$randomIdentifier}-000105196",
$record->getUniqueHtmlElementId($contextPrefix)
);
}

/**
Expand Down
30 changes: 30 additions & 0 deletions module/VuFindSearch/src/VuFindSearch/Backend/AbstractBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@
namespace VuFindSearch\Backend;

use Laminas\Log\LoggerAwareInterface;
use Laminas\Math\Rand;
use VuFindSearch\Response\RecordCollectionFactoryInterface;
use VuFindSearch\Response\RecordCollectionInterface;

use function count;
use function sprintf;

/**
* Abstract backend.
*
Expand Down Expand Up @@ -116,6 +120,32 @@ abstract public function getRecordCollectionFactory();
protected function injectSourceIdentifier(RecordCollectionInterface $response)
{
$response->setSourceIdentifiers($this->identifier);

if (count($response->getRecords()) > 0) {
// TODO: Replace custom UUID generation with Doctrine
// UUID generator once available (after the merge of #2233)
$response->setResultSetIdentifier($this->generateUuid());
}

return $response;
}

/**
* 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.
*/
public 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)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,23 @@ public function getSourceIdentifier()
return $this->source;
}

/**
* 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(string $uuid)
{
foreach ($this->records as $record) {
$record->setResultSetIdentifier($uuid);
}
}

/**
* Add a record to the collection.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,17 @@ public function setSourceIdentifiers($identifier, $searchBackendId = '');
*/
public function getSourceIdentifier();

/**
* Sets the result set identifier for the record.
*
* This method assigns a UUID or a unique string identifier to the result set.
*
* @param string $uuid A valid UUID or unique identifier to be assigned to the result set.
*
* @return void
*/
public function setResultSetIdentifier(string $uuid);

/**
* Add a record to the collection.
*
Expand Down
19 changes: 19 additions & 0 deletions module/VuFindSearch/src/VuFindSearch/Response/RecordInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,25 @@ public function getSourceIdentifier();
*/
public function getSearchBackendIdentifier();

/**
* 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);

/**
* 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();

/**
* Add a label for the record
*
Expand Down
37 changes: 37 additions & 0 deletions module/VuFindSearch/src/VuFindSearch/Response/RecordTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ trait RecordTrait
*/
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 = null;

/**
* Used for identifying the search backend used to find the record
*
Expand Down Expand Up @@ -110,6 +120,33 @@ 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)
{
$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
*
Expand Down
Loading