Skip to content

Commit 692b8bd

Browse files
authored
Refactor more methods to the SearchService (#3775)
1 parent 059735e commit 692b8bd

File tree

28 files changed

+877
-628
lines changed

28 files changed

+877
-628
lines changed

module/VuFind/config/module.config.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@
423423
'VuFind\Cover\Loader' => 'VuFind\Cover\LoaderFactory',
424424
'VuFind\Cover\Router' => 'VuFind\Cover\RouterFactory',
425425
'VuFind\Crypt\HMAC' => 'VuFind\Crypt\HMACFactory',
426+
'VuFind\Crypt\SecretCalculator' => 'VuFind\Crypt\SecretCalculatorFactory',
426427
'VuFind\Date\Converter' => 'VuFind\Service\DateConverterFactory',
427428
'VuFind\Db\AdapterFactory' => 'VuFind\Service\ServiceWithConfigIniFactory',
428429
'VuFind\Db\Row\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',

module/VuFind/src/VuFind/AjaxHandler/GetSearchResults.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ class GetSearchResults extends \VuFind\AjaxHandler\AbstractBase implements
116116
* @param ?UserEntityInterface $user Logged-in user
117117
* @param string $sessionId Session ID
118118
* @param SearchNormalizer $searchNormalizer Search normalizer
119-
* @param Search $searchTable Search table
120119
* @param array $config Main configuration
121120
* @param Memory $searchMemory Search memory
122121
*/
@@ -128,7 +127,6 @@ public function __construct(
128127
protected ?UserEntityInterface $user,
129128
protected string $sessionId,
130129
protected SearchNormalizer $searchNormalizer,
131-
protected Search $searchTable,
132130
protected array $config,
133131
protected Memory $searchMemory
134132
) {
@@ -361,8 +359,7 @@ protected function renderAnalytics(ParamsHelper $requestParams, Results $results
361359
*/
362360
protected function saveSearchToHistory(Results $results): void
363361
{
364-
$this->searchTable->saveSearch(
365-
$this->searchNormalizer,
362+
$this->searchNormalizer->saveNormalizedSearch(
366363
$results,
367364
$this->sessionId,
368365
$this->user?->getId()

module/VuFind/src/VuFind/AjaxHandler/GetSearchResultsFactory.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ public function __invoke(
7777
$container->get(\VuFind\Auth\Manager::class)->getUserObject(),
7878
$container->get(\Laminas\Session\SessionManager::class)->getId(),
7979
$container->get(\VuFind\Search\SearchNormalizer::class),
80-
$container->get(\VuFind\Db\Table\PluginManager::class)->get(\VuFind\Db\Table\Search::class),
8180
$container->get(\VuFind\Config\PluginManager::class)->get('config')->toArray(),
8281
$container->get(\VuFind\Search\Memory::class)
8382
);

module/VuFind/src/VuFind/Controller/AbstractSearch.php

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,13 @@
3030

3131
namespace VuFind\Controller;
3232

33+
use Exception;
3334
use Laminas\Http\Response as HttpResponse;
3435
use Laminas\Session\SessionManager;
3536
use Laminas\Stdlib\ResponseInterface as Response;
3637
use Laminas\View\Model\ViewModel;
38+
use VuFind\Db\Entity\SearchEntityInterface;
39+
use VuFind\Db\Service\SearchServiceInterface;
3740
use VuFind\Search\RecommendListener;
3841
use VuFind\Solr\Utils as SolrUtils;
3942

@@ -141,8 +144,10 @@ protected function redirectToSavedSearch($id)
141144

142145
// If we got this far, the user is allowed to view the search, so we can
143146
// deminify it to a new object.
144-
$minSO = $search->getSearchObjectOrThrowException();
145-
$savedSearch = $minSO->deminify($this->getResultsManager());
147+
$savedSearch = $search->getSearchObject()?->deminify($this->getResultsManager());
148+
if (!$savedSearch) {
149+
throw new Exception("Problem getting search object from search {$search->getId()}.");
150+
}
146151

147152
// Now redirect to the URL associated with the saved search; this
148153
// simplifies problems caused by mixing different classes of search
@@ -513,15 +518,13 @@ protected function getRedirectForRecord(
513518
*
514519
* @param int $searchId Primary key value
515520
*
516-
* @return ?\VuFind\Db\Row\Search
521+
* @return ?SearchEntityInterface
517522
*/
518523
protected function retrieveSearchSecurely($searchId)
519524
{
520-
$searchTable = $this->getTable('Search');
521525
$sessId = $this->serviceLocator->get(SessionManager::class)->getId();
522-
$user = $this->getUser();
523-
$userId = $user ? $user->id : null;
524-
return $searchTable->getOwnedRowById($searchId, $sessId, $userId);
526+
$user = $this->getUser() ?: null;
527+
return $this->getDbService(SearchServiceInterface::class)->getSearchByIdAndOwner($searchId, $sessId, $user);
525528
}
526529

527530
/**
@@ -533,14 +536,12 @@ protected function retrieveSearchSecurely($searchId)
533536
*/
534537
protected function saveSearchToHistory($results)
535538
{
536-
$user = $this->getUser();
539+
$user = $this->getUser() ?: null;
537540
$sessId = $this->serviceLocator->get(SessionManager::class)->getId();
538-
$history = $this->getTable('Search');
539-
$history->saveSearch(
540-
$this->serviceLocator->get(\VuFind\Search\SearchNormalizer::class),
541+
$this->serviceLocator->get(\VuFind\Search\SearchNormalizer::class)->saveNormalizedSearch(
541542
$results,
542543
$sessId,
543-
$user->id ?? null
544+
$user?->getId()
544545
);
545546
}
546547

@@ -562,8 +563,10 @@ protected function restoreAdvancedSearch($searchId)
562563
}
563564

564565
// Restore the full search object:
565-
$minSO = $search->getSearchObjectOrThrowException();
566-
$savedSearch = $minSO->deminify($this->getResultsManager());
566+
$savedSearch = $search->getSearchObject()?->deminify($this->getResultsManager());
567+
if (!$savedSearch) {
568+
throw new Exception("Problem getting search object from search {$search->getId()}.");
569+
}
567570

568571
// Fail if this is not the right type of search:
569572
if ($savedSearch->getParams()->getSearchType() != 'advanced') {

module/VuFind/src/VuFind/Controller/MyResearchController.php

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232
namespace VuFind\Controller;
3333

3434
use DateTime;
35+
use Exception;
3536
use Laminas\ServiceManager\ServiceLocatorInterface;
3637
use Laminas\Session\Container;
3738
use Laminas\View\Model\ViewModel;
3839
use VuFind\Account\UserAccountService;
3940
use VuFind\Auth\ILSAuthenticator;
4041
use VuFind\Controller\Feature\ListItemSelectionTrait;
42+
use VuFind\Crypt\SecretCalculator;
43+
use VuFind\Db\Entity\SearchEntityInterface;
4144
use VuFind\Db\Entity\UserEntityInterface;
45+
use VuFind\Db\Service\SearchServiceInterface;
4246
use VuFind\Db\Service\UserListServiceInterface;
4347
use VuFind\Db\Service\UserResourceServiceInterface;
4448
use VuFind\Db\Service\UserServiceInterface;
@@ -440,14 +444,14 @@ public function logoutAction()
440444
* @param int $userId ID of active user
441445
*
442446
* @throws ForbiddenException
443-
* @return \VuFind\Db\Row\Search
447+
* @return SearchEntityInterface
444448
*/
445449
protected function getSearchRowSecurely($searchId, $userId)
446450
{
447-
$searchTable = $this->getTable('Search');
448451
$sessId = $this->serviceLocator
449452
->get(\Laminas\Session\SessionManager::class)->getId();
450-
$search = $searchTable->getOwnedRowById($searchId, $sessId, $userId);
453+
$search = $this->getDbService(SearchServiceInterface::class)
454+
->getSearchByIdAndOwner($searchId, $sessId, $userId);
451455
if (empty($search)) {
452456
throw new ForbiddenException('Access denied.');
453457
}
@@ -507,7 +511,6 @@ protected function scheduleSearch(UserEntityInterface $user, $schedule, $sid)
507511
if (!isset($scheduleOptions[$schedule])) {
508512
throw new ForbiddenException('Illegal schedule option: ' . $schedule);
509513
}
510-
$search = $this->getTable('Search');
511514
$baseurl = rtrim($this->getServerUrl('home'), '/');
512515
$userId = $user->getId();
513516
$savedRow = $this->getSearchRowSecurely($sid, $userId);
@@ -516,7 +519,6 @@ protected function scheduleSearch(UserEntityInterface $user, $schedule, $sid)
516519
$sessId = $this->serviceLocator
517520
->get(\Laminas\Session\SessionManager::class)->getId();
518521
$duplicateId = $this->isDuplicateOfSavedSearch(
519-
$search,
520522
$savedRow,
521523
$sessId,
522524
$userId
@@ -536,9 +538,11 @@ protected function scheduleSearch(UserEntityInterface $user, $schedule, $sid)
536538
// By default, a first scheduled email will be sent because the database
537539
// last notification date will be initialized to a past date. If we don't
538540
// want that to happen, we need to set it to a more appropriate date:
539-
$savedRow->last_notification_sent = date('Y-m-d H:i:s');
541+
$savedRow->setLastNotificationSent(new DateTime());
540542
}
541-
$savedRow->setSchedule($schedule, $baseurl);
543+
$savedRow->setNotificationFrequency($schedule);
544+
$savedRow->setNotificationBaseUrl($baseurl);
545+
$this->getDbService(SearchServiceInterface::class)->persistEntity($savedRow);
542546
return $this->redirect()->toRoute('search-history');
543547
}
544548

@@ -575,11 +579,8 @@ public function schedulesearchAction()
575579

576580
// If the user has just logged in, the search might be a duplicate; if
577581
// so, let's switch to the pre-existing version instead.
578-
$searchTable = $this->getTable('search');
579-
$sessId = $this->serviceLocator
580-
->get(\Laminas\Session\SessionManager::class)->getId();
582+
$sessId = $this->serviceLocator->get(\Laminas\Session\SessionManager::class)->getId();
581583
$duplicateId = $this->isDuplicateOfSavedSearch(
582-
$searchTable,
583584
$search,
584585
$sessId,
585586
$user->getId()
@@ -594,9 +595,11 @@ public function schedulesearchAction()
594595
}
595596

596597
// Now fetch all the results:
597-
$resultsManager = $this->serviceLocator
598-
->get(\VuFind\Search\Results\PluginManager::class);
599-
$results = $search->getSearchObjectOrThrowException()->deminify($resultsManager);
598+
$resultsManager = $this->serviceLocator->get(\VuFind\Search\Results\PluginManager::class);
599+
$results = $search->getSearchObject()?->deminify($resultsManager);
600+
if (!$results) {
601+
throw new Exception("Problem getting search object from search {$search->getId()}.");
602+
}
600603

601604
// Build the form.
602605
return $this->createViewModel(
@@ -607,36 +610,34 @@ public function schedulesearchAction()
607610
/**
608611
* Is the provided search row a duplicate of a search that is already saved?
609612
*
610-
* @param \VuFind\Db\Table\Search $searchTable Search table
611-
* @param ?\VuFind\Db\Row\Search $rowToCheck Search row to check (if any)
612-
* @param string $sessId Current session ID
613-
* @param int $userId Current user ID
613+
* @param ?SearchEntityInterface $rowToCheck Search row to check (if any)
614+
* @param string $sessId Current session ID
615+
* @param int $userId Current user ID
614616
*
615617
* @return ?int
616618
*/
617619
protected function isDuplicateOfSavedSearch(
618-
\VuFind\Db\Table\Search $searchTable,
619-
?\VuFind\Db\Row\Search $rowToCheck,
620+
?SearchEntityInterface $rowToCheck,
620621
string $sessId,
621622
int $userId
622623
): ?int {
623624
if (!$rowToCheck) {
624625
return null;
625626
}
626-
$normalizer = $this->serviceLocator
627-
->get(\VuFind\Search\SearchNormalizer::class);
628-
$normalized = $normalizer
629-
->normalizeMinifiedSearch($rowToCheck->getSearchObjectOrThrowException());
630-
$matches = $searchTable->getSearchRowsMatchingNormalizedSearch(
627+
$normalizer = $this->serviceLocator->get(\VuFind\Search\SearchNormalizer::class);
628+
$searchObject = $rowToCheck->getSearchObject();
629+
if (!$searchObject) {
630+
throw new Exception("Problem getting search object from search {$rowToCheck->getId()}.");
631+
}
632+
$normalized = $normalizer->normalizeMinifiedSearch($searchObject);
633+
$matches = $normalizer->getSearchesMatchingNormalizedSearch(
631634
$normalized,
632635
$sessId,
633636
$userId
634637
);
635638
foreach ($matches as $current) {
636-
// $current->saved may be 1 (MySQL) or true (PostgreSQL), so we should
637-
// avoid a strict === comparison here:
638-
if ($current->saved == 1 && $current->id !== $rowToCheck->id) {
639-
return $current->id;
639+
if ($current->getSaved() && $current->getId() !== $rowToCheck->getId()) {
640+
return $current->getId();
640641
}
641642
}
642643
return null;
@@ -673,12 +674,11 @@ public function savesearchAction()
673674
// saved row, we should just delete the duplicate. (This can happen if
674675
// the user clicks "save" before logging in, then logs in during the
675676
// save process, but has the same search already saved in their account).
676-
$searchTable = $this->getTable('search');
677+
$searchService = $this->getDbService(SearchServiceInterface::class);
677678
$sessId = $this->serviceLocator
678679
->get(\Laminas\Session\SessionManager::class)->getId();
679-
$rowToCheck = $searchTable->getOwnedRowById($id, $sessId, $user->getId());
680+
$rowToCheck = $searchService->getSearchByIdAndOwner($id, $sessId, $user);
680681
$duplicateId = $this->isDuplicateOfSavedSearch(
681-
$searchTable,
682682
$rowToCheck,
683683
$sessId,
684684
$user->getId()
@@ -2318,25 +2318,21 @@ public function unsubscribeAction()
23182318
$view = $this->createViewModel();
23192319
if ($this->params()->fromQuery('confirm', false) == 1) {
23202320
if ($type == 'alert') {
2321-
$search
2322-
= $this->getTable('Search')->select(['id' => $id])->current();
2321+
$searchService = $this->getDbService(SearchServiceInterface::class);
2322+
$search = $searchService->getSearchById($id);
23232323
if (!$search) {
23242324
throw new \Exception('Invalid parameters.');
23252325
}
2326-
$user = $this->getTable('User')->getById($search->user_id);
2327-
$secret = $search->getUnsubscribeSecret(
2328-
$this->serviceLocator->get(\VuFind\Crypt\HMAC::class),
2329-
$user
2330-
);
2326+
$secret = $this->serviceLocator->get(SecretCalculator::class)->getSearchUnsubscribeSecret($search);
23312327
if ($key !== $secret) {
23322328
throw new \Exception('Invalid parameters.');
23332329
}
2334-
$search->setSchedule(0);
2330+
$search->setNotificationFrequency(0);
2331+
$searchService->persistEntity($search);
23352332
$view->success = true;
23362333
}
23372334
} else {
2338-
$view->unsubscribeUrl
2339-
= $this->getRequest()->getRequestUri() . '&confirm=1';
2335+
$view->unsubscribeUrl = $this->getRequest()->getRequestUri() . '&confirm=1';
23402336
}
23412337
return $view;
23422338
}

module/VuFind/src/VuFind/Controller/Plugin/ResultScroller.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131

3232
namespace VuFind\Controller\Plugin;
3333

34+
use Exception;
3435
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
3536
use Laminas\Session\Container as SessionContainer;
37+
use VuFind\Db\Service\SearchServiceInterface;
3638
use VuFind\RecordDriver\AbstractBase as BaseRecord;
3739
use VuFind\Search\Base\Results;
3840
use VuFind\Search\Memory as SearchMemory;
@@ -659,15 +661,17 @@ protected function fetchPage($searchObject, $page = null)
659661
*/
660662
protected function restoreSearch(int $searchId): ?Results
661663
{
662-
$searchTable = $this->getController()->getTable('Search');
663-
$row = $searchTable->getOwnedRowById(
664+
$searchService = $this->getController()->getDbService(SearchServiceInterface::class);
665+
$row = $searchService->getSearchByIdAndOwner(
664666
$searchId,
665667
$this->session->getManager()->getId(),
666668
null
667669
);
668670
if (!empty($row)) {
669-
$minSO = $row->getSearchObjectOrThrowException();
670-
$search = $minSO->deminify($this->resultsManager);
671+
$search = $row->getSearchObject()?->deminify($this->resultsManager);
672+
if (!$search) {
673+
throw new Exception("Problem getting search object from search {$row->getId()}.");
674+
}
671675
// The saved search does not remember its original limit or sort;
672676
// we should reapply them from the session data:
673677
$search->getParams()->setLimit(

module/VuFind/src/VuFind/Controller/UpgradeController.php

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -346,16 +346,18 @@ protected function fixInvalidUserIdsInSearchTable(): void
346346
protected function fixSearchChecksumsInDatabase()
347347
{
348348
$manager = $this->serviceLocator->get(ResultsManager::class);
349-
$search = $this->getTable('search');
350-
$searchWhere = ['checksum' => null, 'saved' => 1];
351-
$searchRows = $search->select($searchWhere);
349+
$searchService = $this->getDbService(SearchServiceInterface::class);
350+
$searchRows = $searchService->getSavedSearchesWithMissingChecksums();
352351
if (count($searchRows) > 0) {
353352
foreach ($searchRows as $searchRow) {
354-
$searchObj = $searchRow->getSearchObjectOrThrowException()->deminify($manager);
353+
$searchObj = $searchRow->getSearchObject()?->deminify($manager);
354+
if (!$searchObj) {
355+
throw new Exception("Missing search data for row {$searchRow->getId()}.");
356+
}
355357
$url = $searchObj->getUrlQuery()->getParams();
356358
$checksum = crc32($url) & 0xFFFFFFF;
357-
$searchRow->checksum = $checksum;
358-
$searchRow->save();
359+
$searchRow->setChecksum($checksum);
360+
$searchService->persistEntity($searchRow);
359361
}
360362
$this->session->warnings->append(
361363
'Added checksum to ' . count($searchRows) . ' rows in search table'

0 commit comments

Comments
 (0)