3232namespace VuFind \Controller ;
3333
3434use DateTime ;
35+ use Exception ;
3536use Laminas \ServiceManager \ServiceLocatorInterface ;
3637use Laminas \Session \Container ;
3738use Laminas \View \Model \ViewModel ;
3839use VuFind \Account \UserAccountService ;
3940use VuFind \Auth \ILSAuthenticator ;
4041use VuFind \Controller \Feature \ListItemSelectionTrait ;
42+ use VuFind \Crypt \SecretCalculator ;
43+ use VuFind \Db \Entity \SearchEntityInterface ;
4144use VuFind \Db \Entity \UserEntityInterface ;
45+ use VuFind \Db \Service \SearchServiceInterface ;
4246use VuFind \Db \Service \UserListServiceInterface ;
4347use VuFind \Db \Service \UserResourceServiceInterface ;
4448use 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 }
0 commit comments