diff --git a/config/vufind/reserves.ini b/config/vufind/reserves.ini index cddeb3a9238..d5540a6dffa 100644 --- a/config/vufind/reserves.ini +++ b/config/vufind/reserves.ini @@ -42,6 +42,11 @@ formatting_rule[*] = "phrase" [Autocomplete_Types] Reserves = "SolrReserves:AllFields:course,instructor,department" +[Advanced_Settings] +translated_facets[] = course_str:Reserves +translated_facets[] = department_str:Reserves +translated_facets[] = instructor_str:Reserves + [SearchCache] ;adapter = Memcached ;options[servers] = "localhost:11211,otherhost:11211" diff --git a/languages/Reserves/en.ini b/languages/Reserves/en.ini new file mode 100644 index 00000000000..453f273b194 --- /dev/null +++ b/languages/Reserves/en.ini @@ -0,0 +1,3 @@ +no_course_listed = "No Course Listed" +no_department_listed = "No Department Listed" +no_instructor_listed = "No Instructor Listed" diff --git a/languages/en.ini b/languages/en.ini index c58ac9c99b7..e82696e28f5 100644 --- a/languages/en.ini +++ b/languages/en.ini @@ -889,8 +889,11 @@ No Preference = "No Preference" No reviews were found for this record = "No reviews were found for this record" No saved logins = "No saved logins" No Tags = "No Tags" +no_course_listed = "No Course Listed" +no_department_listed = "No Department Listed" no_description = "Description not available." no_email_address = "Email address missing." +no_instructor_listed = "No Instructor Listed" no_items_selected = "No Items were Selected" no_proxied_user = "No proxied user (request for yourself)" nohit_active_filters = "One or more facet filters have been applied to this search. If you remove filters, you may retrieve more results." diff --git a/module/VuFind/src/VuFind/Autocomplete/SolrReserves.php b/module/VuFind/src/VuFind/Autocomplete/SolrReserves.php index 8a58f86c9b1..f8795cd5433 100644 --- a/module/VuFind/src/VuFind/Autocomplete/SolrReserves.php +++ b/module/VuFind/src/VuFind/Autocomplete/SolrReserves.php @@ -54,4 +54,37 @@ public function __construct(\VuFind\Search\Results\PluginManager $results) $this->defaultDisplayField = 'course'; $this->searchClassId = 'SolrReserves'; } + + /** + * Try to turn an array of record drivers into an array of suggestions. + * Excluding `no_*_listed` matches since those are the translation values + * when there is no data in that field. + * + * @param array $searchResults An array of record drivers + * @param string $query User search query + * @param bool $exact Ignore non-exact matches? + * + * @return array + */ + protected function getSuggestionsFromSearch($searchResults, $query, $exact) + { + $results = []; + foreach ($searchResults as $object) { + $current = $object->getRawData(); + foreach ($this->displayField as $field) { + if (isset($current[$field]) && !preg_match('/no_.*_listed/', $current[$field])) { + $bestMatch = $this->pickBestMatch( + $current[$field], + $query, + $exact + ); + if ($bestMatch) { + $results[] = $bestMatch; + break; + } + } + } + } + return $results; + } } diff --git a/module/VuFindConsole/src/VuFindConsole/Command/Util/IndexReservesCommand.php b/module/VuFindConsole/src/VuFindConsole/Command/Util/IndexReservesCommand.php index e542b0ce14b..c15e095e86d 100644 --- a/module/VuFindConsole/src/VuFindConsole/Command/Util/IndexReservesCommand.php +++ b/module/VuFindConsole/src/VuFindConsole/Command/Util/IndexReservesCommand.php @@ -40,6 +40,7 @@ use function count; use function in_array; use function ini_get; +use function sprintf; /** * Console command: index course reserves into Solr. @@ -56,6 +57,13 @@ )] class IndexReservesCommand extends AbstractSolrAndIlsCommand { + /** + * Output interface + * + * @var OutputInterface + */ + protected $output; + /** * Default delimiter for reading files * @@ -154,16 +162,57 @@ protected function buildReservesIndex( 'id' => $id, 'bib_id' => [], 'instructor_id' => $instructorId, - 'instructor' => $instructors[$instructorId] ?? '', + 'instructor' => $instructors[$instructorId] ?? 'no_instructor_listed', 'course_id' => $courseId, - 'course' => $courses[$courseId] ?? '', + 'course' => $courses[$courseId] ?? 'no_course_listed', 'department_id' => $departmentId, - 'department' => $departments[$departmentId] ?? '', + 'department' => $departments[$departmentId] ?? 'no_department_listed', ]; } if (!in_array($record['BIB_ID'], $index[$id]['bib_id'])) { $index[$id]['bib_id'][] = $record['BIB_ID']; } + + // Show a warning if the any of the IDs were set, but was not found in the resulting data + if (!empty($instructorId) && !isset($instructors[$instructorId])) { + $this->showTimestampedMessage( + sprintf( + 'WARNING! The instructor (ID: %s) for the course: %s (ID: %s) ' . + 'and department: %s (ID: %s) did not match any found instructors.', + $index[$id]['instructor_id'], + $index[$id]['course'], + $index[$id]['course_id'], + $index[$id]['department'], + $index[$id]['department_id'] + ) + ); + } + if (!empty($departmentId) && !isset($departments[$departmentId])) { + $this->showTimestampedMessage( + sprintf( + 'WARNING! The department (ID: %s) for the course: %s (ID: %s) ' . + 'and instructor: %s (ID: %s) did not match any found departments.', + $index[$id]['department_id'], + $index[$id]['course'], + $index[$id]['course_id'], + $index[$id]['instructor'], + $index[$id]['instructor_id'] + ) + ); + } + if (!empty($courseId) && !isset($courses[$courseId])) { + $this->showTimestampedMessage( + sprintf( + 'WARNING! The course (ID: %s) for the instructor: %s (ID: %s) ' . + 'and department: %s (ID: %s) did not match any found courses.', + $index[$id]['course_id'], + $index[$id]['instructor'], + $index[$id]['instructor_id'], + $index[$id]['department'], + $index[$id]['department_id'] + ) + ); + } } $updates = new UpdateDocument(); @@ -194,6 +243,18 @@ protected function getCsvReader( return new CsvReader($files, $delimiter, $template); } + /** + * Print the message to the provided output stream prefixed with a timestamp. + * + * @param string $message Message to display + * + * @return null + */ + protected function showTimestampedMessage(string $message) + { + $this->output->writeln(date('Y-m-d H:i:s') . ' ' . $message); + } + /** * Run the command. * @@ -204,6 +265,8 @@ protected function getCsvReader( */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->output = $output; + $startTime = date('Y-m-d H:i:s'); // Check time limit; increase if necessary: if (ini_get('max_execution_time') < 3600) { ini_set('max_execution_time', '3600'); @@ -214,30 +277,50 @@ protected function execute(InputInterface $input, OutputInterface $output) if ($file = $input->getOption('filename')) { try { + $this->showTimestampedMessage('Starting reserves processing from file'); + $reader = $this->getCsvReader($file, $delimiter, $template); + $this->showTimestampedMessage('Retrieving instructors'); $instructors = $reader->getInstructors(); + $this->showTimestampedMessage('Found instructor count: ' . count($instructors)); + $this->showTimestampedMessage('Retrieving courses'); $courses = $reader->getCourses(); + $this->showTimestampedMessage('Found course count: ' . count($courses)); + $this->showTimestampedMessage('Retrieving departments'); $departments = $reader->getDepartments(); + $this->showTimestampedMessage('Found department count: ' . count($departments)); + $this->showTimestampedMessage('Retrieving reserves'); $reserves = $reader->getReserves(); + $this->showTimestampedMessage('Found reserve count: ' . count($reserves)); } catch (\Exception $e) { - $output->writeln($e->getMessage()); + $this->showTimestampedMessage($e->getMessage()); return 1; } } elseif ($delimiter !== $this->defaultDelimiter) { - $output->writeln('-d (delimiter) is meaningless without -f (filename)'); + $this->output->writeln('-d (delimiter) is meaningless without -f (filename)'); return 1; } elseif ($template !== $this->defaultTemplate) { - $output->writeln('-t (template) is meaningless without -f (filename)'); + $this->output->writeln('-t (template) is meaningless without -f (filename)'); return 1; } else { try { + $this->showTimestampedMessage('Starting reserves processing from ILS'); + // Connect to ILS and load data: + $this->showTimestampedMessage('Retrieving instructors'); $instructors = $this->catalog->getInstructors(); + $this->showTimestampedMessage('Found instructor count: ' . count($instructors ?? [])); + $this->showTimestampedMessage('Retrieving courses'); $courses = $this->catalog->getCourses(); + $this->showTimestampedMessage('Found course count: ' . count($courses ?? [])); + $this->showTimestampedMessage('Retrieving departments'); $departments = $this->catalog->getDepartments(); + $this->showTimestampedMessage('Found department count: ' . count($departments ?? [])); + $this->showTimestampedMessage('Retrieving reserves'); $reserves = $this->catalog->findReserves('', '', ''); + $this->showTimestampedMessage('Found reserve count: ' . count($reserves ?? [])); } catch (\Exception $e) { - $output->writeln($e->getMessage()); + $this->showTimestampedMessage($e->getMessage()); return 1; } } @@ -249,22 +332,27 @@ protected function execute(InputInterface $input, OutputInterface $output) && !empty($reserves) ) { // Delete existing records + $this->showTimestampedMessage('Clearing existing reserves'); $this->solr->deleteAll('SolrReserves'); // Build and Save the index + $this->showTimestampedMessage('Building new reserves index'); $index = $this->buildReservesIndex( $instructors, $courses, $departments, $reserves ); + $this->showTimestampedMessage('Writing new reserves index'); $this->solr->save('SolrReserves', $index); // Commit and Optimize the Solr Index $this->solr->commit('SolrReserves'); $this->solr->optimize('SolrReserves'); - $output->writeln('Successfully loaded ' . count($reserves) . ' rows.'); + $this->showTimestampedMessage('Successfully loaded ' . count($reserves) . ' rows.'); + $endTime = date('Y-m-d H:i:s'); + $this->showTimestampedMessage('Started at: ' . $startTime . ' Completed at: ' . $endTime); return 0; } $missing = array_merge( @@ -273,9 +361,7 @@ protected function execute(InputInterface $input, OutputInterface $output) empty($departments) ? ['departments'] : [], empty($reserves) ? ['reserves'] : [] ); - $output->writeln( - 'Unable to load data. No data found for: ' . implode(', ', $missing) - ); + $this->showTimestampedMessage('Unable to load data. No data found for: ' . implode(', ', $missing)); return 1; } } diff --git a/module/VuFindConsole/tests/unit-tests/src/VuFindTest/Command/Util/IndexReservesCommandTest.php b/module/VuFindConsole/tests/unit-tests/src/VuFindTest/Command/Util/IndexReservesCommandTest.php index a5cb139e080..739d0dca83c 100644 --- a/module/VuFindConsole/tests/unit-tests/src/VuFindTest/Command/Util/IndexReservesCommandTest.php +++ b/module/VuFindConsole/tests/unit-tests/src/VuFindTest/Command/Util/IndexReservesCommandTest.php @@ -34,6 +34,8 @@ use VuFind\Solr\Writer; use VuFindConsole\Command\Util\IndexReservesCommand; +use function ini_get; + /** * IndexReservesCommand test. * @@ -60,6 +62,64 @@ protected function getMockIlsConnection() ->getMock(); } + /** + * Get command tester object given the course data provided. + * + * @param array $instructors Instructors returned from getInstructors + * @param array $courses Courses returned from getCourses + * @param array $departments Departments returned from getDepartments + * @param array $reserves Reserves returned from findReserves + * @param string $expectedXml Data to expect for the Solr document + * + * @return Symfony\Component\Console\Tester\CommandTester + */ + protected function getMockIlsCommandTesterWithCourseData( + $instructors = [], + $courses = [], + $departments = [], + $reserves = [], + $expectedXml = null + ) { + $ils = $this->getMockIlsConnection(); + $this->expectConsecutiveCalls( + $ils, + '__call', + [ + ['getInstructors'], + ['getCourses'], + ['getDepartments'], + ['findReserves'], + ], + [ + $instructors, + $courses, + $departments, + $reserves, + ] + ); + $writer = $this->getMockSolrWriter(); + if ($expectedXml) { + $updateValidator = function ($update) use ($expectedXml) { + $this->assertEquals($expectedXml, trim($update->getContent())); + return true; + }; + $writer->expects($this->once())->method('save') + ->with( + $this->equalTo('SolrReserves'), + $this->callback($updateValidator) + ); + $writer->expects($this->once())->method('deleteAll') + ->with($this->equalTo('SolrReserves')); + $writer->expects($this->once())->method('commit') + ->with($this->equalTo('SolrReserves')); + $writer->expects($this->once())->method('optimize') + ->with($this->equalTo('SolrReserves')); + } + $command = $this->getCommand($writer, $ils); + $commandTester = new CommandTester($command); + return $commandTester; + } + /** * Get mock Solr writer. * @@ -89,18 +149,35 @@ protected function getCommand(Writer $solr = null, Connection $ils = null) } /** - * Test bad parameter combination. + * Test bad parameter combination with template. + * + * @return void + */ + public function testBadParameterCombinationTemplate() + { + $command = $this->getCommand(); + $commandTester = new CommandTester($command); + $commandTester->execute(['--template' => '|']); + $this->assertEquals(1, $commandTester->getStatusCode()); + $this->assertStringContainsString( + '-t (template) is meaningless without -f (filename)', + $commandTester->getDisplay() + ); + } + + /** + * Test bad parameter combination with delimiter. * * @return void */ - public function testBadParameterCombination() + public function testBadParameterCombinationDelimiter() { $command = $this->getCommand(); $commandTester = new CommandTester($command); $commandTester->execute(['--delimiter' => '|']); $this->assertEquals(1, $commandTester->getStatusCode()); - $this->assertEquals( - "-d (delimiter) is meaningless without -f (filename)\n", + $this->assertStringContainsString( + '-d (delimiter) is meaningless without -f (filename)', $commandTester->getDisplay() ); } @@ -116,8 +193,8 @@ public function testBadFilename() $commandTester = new CommandTester($command); $commandTester->execute(['--filename' => '/does/not/exist']); $this->assertEquals(1, $commandTester->getStatusCode()); - $this->assertEquals( - "Could not open /does/not/exist!\n", + $this->assertStringContainsString( + 'Could not open /does/not/exist!', $commandTester->getDisplay() ); } @@ -191,8 +268,8 @@ public function testSuccessWithMultipleFiles() ] ); $this->assertEquals(0, $commandTester->getStatusCode()); - $this->assertEquals( - "Successfully loaded 3 rows.\n", + $this->assertStringContainsString( + 'Successfully loaded 3 rows.', $commandTester->getDisplay() ); } @@ -204,25 +281,12 @@ public function testSuccessWithMultipleFiles() */ public function testMissingData() { - $ils = $this->getMockIlsConnection(); - $this->expectConsecutiveCalls( - $ils, - '__call', - [ - ['getInstructors'], - ['getCourses'], - ['getDepartments'], - ['findReserves'], - ], - [] - ); - $command = $this->getCommand($this->getMockSolrWriter(), $ils); - $commandTester = new CommandTester($command); + $commandTester = $this->getMockIlsCommandTesterWithCourseData(); $commandTester->execute([]); $this->assertEquals(1, $commandTester->getStatusCode()); - $this->assertEquals( + $this->assertStringContainsString( 'Unable to load data. No data found for: ' - . "instructors, courses, departments, reserves\n", + . 'instructors, courses, departments, reserves', $commandTester->getDisplay() ); } @@ -234,7 +298,6 @@ public function testMissingData() */ public function testSuccessWithILS() { - $ils = $this->getMockIlsConnection(); $instructors = ['inst1' => 'inst1', 'inst2' => 'inst2', 'inst3' => 'inst3']; $courses = [ 'course1' => 'course1', 'course2' => 'course2', 'course3' => 'course3', @@ -260,79 +323,236 @@ public function testSuccessWithILS() 'INSTRUCTOR_ID' => 'inst3', ], ]; + $expectedXml = "\n" + . '' + . '' + . 'course1|inst1|dept1' + . '1' + . 'inst1' + . 'inst1' + . 'course1' + . 'course1' + . 'dept1' + . 'dept1' + . '' + . '' + . 'course2|inst2|dept2' + . '2' + . 'inst2' + . 'inst2' + . 'course2' + . 'course2' + . 'dept2' + . 'dept2' + . '' + . '' + . 'course3|inst3|dept3' + . '3' + . 'inst3' + . 'inst3' + . 'course3' + . 'course3' + . 'dept3' + . 'dept3' + . '' + . ''; + $commandTester = $this->getMockIlsCommandTesterWithCourseData( + $instructors, + $courses, + $departments, + $reserves, + $expectedXml + ); + $commandTester->execute([]); + + $this->assertEquals(0, $commandTester->getStatusCode()); + $this->assertStringContainsString( + 'Successfully loaded 3 rows.', + $commandTester->getDisplay() + ); + } + + /** + * Test successful ILS loading with some invalid data in reserves. + * + * @return void + */ + public function testSuccessWithILSWithInvalidData() + { + $instructors = ['inst1' => 'inst1']; + $courses = ['course1' => 'course1']; + $departments = ['dept1' => 'dept1']; + $reserves = [ + [ + 'BIB_ID' => 1, + 'COURSE_ID' => 'course2', + 'DEPARTMENT_ID' => 'dept2', + 'INSTRUCTOR_ID' => 'inst2', + ], + ]; + $expectedXml = "\n" + . '' + . '' + . 'course2|inst2|dept2' + . '1' + . 'inst2' + . 'no_instructor_listed' + . 'course2' + . 'no_course_listed' + . 'dept2' + . 'no_department_listed' + . '' + . ''; + $commandTester = $this->getMockIlsCommandTesterWithCourseData( + $instructors, + $courses, + $departments, + $reserves, + $expectedXml + ); + $commandTester->execute([]); + + $this->assertEquals(0, $commandTester->getStatusCode()); + $this->assertStringContainsString( + 'Successfully loaded 1 rows.', + $commandTester->getDisplay() + ); + $this->assertStringContainsString( + 'WARNING! The instructor (ID: inst2)', + $commandTester->getDisplay() + ); + $this->assertStringContainsString( + 'WARNING! The department (ID: dept2)', + $commandTester->getDisplay() + ); + $this->assertStringContainsString( + 'WARNING! The course (ID: course2)', + $commandTester->getDisplay() + ); + } + + /** + * Test successful ILS loading with some missing data in reserves. + * + * @return void + */ + public function testSuccessWithILSWithMissingData() + { + $instructors = ['inst1' => 'inst1']; + $courses = ['course1' => 'course1']; + $departments = ['dept1' => 'dept1']; + $reserves = [ + [ + 'BIB_ID' => 1, + 'COURSE_ID' => 'course1', + 'DEPARTMENT_ID' => '', + 'INSTRUCTOR_ID' => 'inst1', + ], + ]; + $expectedXml = "\n" + . '' + . '' + . 'course1|inst1|' + . '1' + . 'inst1' + . 'inst1' + . 'course1' + . 'course1' + . '' + . 'no_department_listed' + . '' + . ''; + $commandTester = $this->getMockIlsCommandTesterWithCourseData( + $instructors, + $courses, + $departments, + $reserves, + $expectedXml + ); + $commandTester->execute([]); + + $this->assertEquals(0, $commandTester->getStatusCode()); + $this->assertStringContainsString( + 'Successfully loaded 1 rows.', + $commandTester->getDisplay() + ); + $this->assertStringNotContainsString( + 'WARNING', + $commandTester->getDisplay() + ); + } + + /** + * Test successful ILS loading with some missing required fields + * + * @return void + */ + public function testSuccessWithILSWithMissingRequiredData() + { + $instructors = ['inst1' => 'inst1']; + $courses = ['course1' => 'course1']; + $departments = ['dept1' => 'dept1']; + $reserves = [ + [ + 'BIB_ID' => 1, + 'COURSE_ID' => 'course1', + 'INSTRUCTOR_ID' => 'inst1', + ], + ]; + $commandTester = $this->getMockIlsCommandTesterWithCourseData($instructors, $courses, $departments, $reserves); + $this->expectException( + \Exception::class + ); + $this->expectExceptionMessage( + 'fields not present in reserve records. Please update ILS driver.' + ); + $commandTester->execute([]); + } + + /** + * Test unsuccessful ILS call that raises exception + * + * @return void + */ + public function testILSException() + { + $exception = new \VuFind\Exception\ILS('Simulated exception'); + $ils = $this->getMockIlsConnection(); + $this->expectConsecutiveCalls( $ils, '__call', [ ['getInstructors'], - ['getCourses'], - ['getDepartments'], - ['findReserves'], ], - [ - $instructors, - $courses, - $departments, - $reserves, - ] + [] ); + $ils->method('__call')->willThrowException($exception); + $writer = $this->getMockSolrWriter(); - $writer->expects($this->once())->method('deleteAll') - ->with($this->equalTo('SolrReserves')); $that = $this; - $updateValidator = function ($update) use ($that) { - $expectedXml = "\n" - . '' - . '' - . 'course1|inst1|dept1' - . '1' - . 'inst1' - . 'inst1' - . 'course1' - . 'course1' - . 'dept1' - . 'dept1' - . '' - . '' - . 'course2|inst2|dept2' - . '2' - . 'inst2' - . 'inst2' - . 'course2' - . 'course2' - . 'dept2' - . 'dept2' - . '' - . '' - . 'course3|inst3|dept3' - . '3' - . 'inst3' - . 'inst3' - . 'course3' - . 'course3' - . 'dept3' - . 'dept3' - . '' - . ''; - $that->assertEquals($expectedXml, trim($update->getContent())); - return true; - }; - $writer->expects($this->once())->method('save') - ->with( - $this->equalTo('SolrReserves'), - $this->callback($updateValidator) - ); - $writer->expects($this->once())->method('commit') - ->with($this->equalTo('SolrReserves')); - $writer->expects($this->once())->method('optimize') - ->with($this->equalTo('SolrReserves')); $command = $this->getCommand($writer, $ils); $commandTester = new CommandTester($command); $commandTester->execute([]); - $this->assertEquals(0, $commandTester->getStatusCode()); - $this->assertEquals( - "Successfully loaded 3 rows.\n", + $this->assertEquals(1, $commandTester->getStatusCode()); + $this->assertStringContainsString( + $exception->getMessage(), $commandTester->getDisplay() ); } + + /** + * Test different ini setting. + * + * @return void + */ + public function testShortIniSetting() + { + $command = $this->getCommand(); + $commandTester = new CommandTester($command); + ini_set('max_execution_time', '60'); + // Run a command that will fail and exit right away, since the ini check happens first + $commandTester->execute(['--template' => '|']); + $this->assertEquals('3600', ini_get('max_execution_time')); + } } diff --git a/themes/bootstrap3/templates/search/reserves.phtml b/themes/bootstrap3/templates/search/reserves.phtml index 863c2ccddcc..94bd3e46e45 100644 --- a/themes/bootstrap3/templates/search/reserves.phtml +++ b/themes/bootstrap3/templates/search/reserves.phtml @@ -19,7 +19,7 @@ @@ -32,7 +32,7 @@ @@ -45,7 +45,7 @@ diff --git a/themes/bootstrap3/templates/search/reservesresults.phtml b/themes/bootstrap3/templates/search/reservesresults.phtml index 07eb384a635..f9d51491803 100644 --- a/themes/bootstrap3/templates/search/reservesresults.phtml +++ b/themes/bootstrap3/templates/search/reservesresults.phtml @@ -4,10 +4,10 @@ $this->slot('search-heading')->set($this->transEsc('Reserves')); $headingParts = []; if (isset($this->instructor)) { - $headingParts[] = $this->transEsc('Instructor') . ': ' . $this->escapeHtml($this->instructor) . ''; + $headingParts[] = $this->transEsc('Instructor') . ': ' . $this->transEsc('Reserves::' . $this->instructor) . ''; } if (isset($this->course)) { - $headingParts[] = $this->transEsc('Course') . ': ' . $this->escapeHtml($this->course) . ''; + $headingParts[] = $this->transEsc('Course') . ': ' . $this->transEsc('Reserves::' . $this->course) . ''; } if (!empty($headingParts)) { $this->slot('search-heading')->append(' (' . implode(', ', $headingParts) . ')'); diff --git a/themes/bootstrap3/templates/search/reservessearch.phtml b/themes/bootstrap3/templates/search/reservessearch.phtml index da243af98c2..52260148699 100644 --- a/themes/bootstrap3/templates/search/reservessearch.phtml +++ b/themes/bootstrap3/templates/search/reservessearch.phtml @@ -85,9 +85,9 @@ ); ?> - escapeHtml($record->getDepartment())?> - escapeHtml($record->getCourse())?> - escapeHtml($record->getInstructor())?> + transEsc('Reserves::' . $record->getDepartment())?> + transEsc('Reserves::' . $record->getCourse())?> + transEsc('Reserves::' . $record->getInstructor())?> escapeHtml($record->getItemCount())?> diff --git a/themes/bootstrap5/templates/search/reserves.phtml b/themes/bootstrap5/templates/search/reserves.phtml index 863c2ccddcc..94bd3e46e45 100644 --- a/themes/bootstrap5/templates/search/reserves.phtml +++ b/themes/bootstrap5/templates/search/reserves.phtml @@ -19,7 +19,7 @@ @@ -32,7 +32,7 @@ @@ -45,7 +45,7 @@ diff --git a/themes/bootstrap5/templates/search/reservesresults.phtml b/themes/bootstrap5/templates/search/reservesresults.phtml index 07eb384a635..f9d51491803 100644 --- a/themes/bootstrap5/templates/search/reservesresults.phtml +++ b/themes/bootstrap5/templates/search/reservesresults.phtml @@ -4,10 +4,10 @@ $this->slot('search-heading')->set($this->transEsc('Reserves')); $headingParts = []; if (isset($this->instructor)) { - $headingParts[] = $this->transEsc('Instructor') . ': ' . $this->escapeHtml($this->instructor) . ''; + $headingParts[] = $this->transEsc('Instructor') . ': ' . $this->transEsc('Reserves::' . $this->instructor) . ''; } if (isset($this->course)) { - $headingParts[] = $this->transEsc('Course') . ': ' . $this->escapeHtml($this->course) . ''; + $headingParts[] = $this->transEsc('Course') . ': ' . $this->transEsc('Reserves::' . $this->course) . ''; } if (!empty($headingParts)) { $this->slot('search-heading')->append(' (' . implode(', ', $headingParts) . ')'); diff --git a/themes/bootstrap5/templates/search/reservessearch.phtml b/themes/bootstrap5/templates/search/reservessearch.phtml index da243af98c2..52260148699 100644 --- a/themes/bootstrap5/templates/search/reservessearch.phtml +++ b/themes/bootstrap5/templates/search/reservessearch.phtml @@ -85,9 +85,9 @@ ); ?> - escapeHtml($record->getDepartment())?> - escapeHtml($record->getCourse())?> - escapeHtml($record->getInstructor())?> + transEsc('Reserves::' . $record->getDepartment())?> + transEsc('Reserves::' . $record->getCourse())?> + transEsc('Reserves::' . $record->getInstructor())?> escapeHtml($record->getItemCount())?>