From 4a41997d5b2770c4fc90e548f76ae5c713a9cf5e Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 25 Jul 2024 13:08:46 -0400 Subject: [PATCH 1/6] [VUFIND-1674] Show count of saved items in account menu --- config/vufind/AccountMenu.yaml | 1 + .../AjaxHandler/GetUserFavoritesStatus.php | 78 +++++++++++++++++++ .../GetUserFavoritesStatusFactory.php | 77 ++++++++++++++++++ .../src/VuFind/AjaxHandler/PluginManager.php | 2 + themes/bootstrap3/js/account_ajax.js | 13 ++++ 5 files changed, 171 insertions(+) create mode 100644 module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatus.php create mode 100644 module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatusFactory.php diff --git a/config/vufind/AccountMenu.yaml b/config/vufind/AccountMenu.yaml index 48acdc09dbf..0a614343410 100644 --- a/config/vufind/AccountMenu.yaml +++ b/config/vufind/AccountMenu.yaml @@ -16,6 +16,7 @@ MenuItems: label: saved_items route: myresearch-favorites icon: user-favorites + status: true checkMethod: checkFavorites - name: checkedout diff --git a/module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatus.php b/module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatus.php new file mode 100644 index 00000000000..0a02543f8de --- /dev/null +++ b/module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatus.php @@ -0,0 +1,78 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace VuFind\AjaxHandler; + +use Laminas\Mvc\Controller\Plugin\Params; +use VuFind\Db\Entity\UserEntityInterface; +use VuFind\Db\Service\ResourceServiceInterface; +use VuFind\Session\Settings as SessionSettings; + +use function count; + +/** + * "Get User Favorites Status" AJAX handler + * + * @category VuFind + * @package AJAX + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class GetUserFavoritesStatus extends AbstractBase +{ + /** + * Constructor + * + * @param SessionSettings $ss Session settings + * @param ?UserEntityInterface $user Logged in user (or null) + * @param ResourceServiceInterface $resourceService Resoruce database service + */ + public function __construct( + SessionSettings $ss, + protected ?UserEntityInterface $user, + protected ResourceServiceInterface $resourceService + ) { + $this->sessionSettings = $ss; + } + + /** + * Handle a request. + * + * @param Params $params Parameter helper from controller + * + * @return array [response data, internal status code, HTTP status code] + */ + public function handleRequest(Params $params) + { + $this->disableSessionWrites(); // avoid session write timing bug + $count = $this->user ? count($this->resourceService->getFavorites($this->user)) : 0; + return $this->formatResponse(compact('count')); + } +} diff --git a/module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatusFactory.php b/module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatusFactory.php new file mode 100644 index 00000000000..409cf577d44 --- /dev/null +++ b/module/VuFind/src/VuFind/AjaxHandler/GetUserFavoritesStatusFactory.php @@ -0,0 +1,77 @@ + + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ + +namespace VuFind\AjaxHandler; + +use Laminas\ServiceManager\Exception\ServiceNotCreatedException; +use Laminas\ServiceManager\Exception\ServiceNotFoundException; +use Psr\Container\ContainerExceptionInterface as ContainerException; +use Psr\Container\ContainerInterface; +use VuFind\Db\Service\ResourceServiceInterface; + +/** + * Factory for GetUserFavoritesStatus AJAX handler. + * + * @category VuFind + * @package AJAX + * @author Demian Katz + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link https://vufind.org/wiki/development Wiki + */ +class GetUserFavoritesStatusFactory implements \Laminas\ServiceManager\Factory\FactoryInterface +{ + /** + * Create an object + * + * @param ContainerInterface $container Service manager + * @param string $requestedName Service being created + * @param null|array $options Extra options (optional) + * + * @return object + * + * @throws ServiceNotFoundException if unable to resolve the service. + * @throws ServiceNotCreatedException if an exception is raised when + * creating a service. + * @throws ContainerException&\Throwable if any other error occurs + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function __invoke( + ContainerInterface $container, + $requestedName, + array $options = null + ) { + return new $requestedName( + $container->get(\VuFind\Session\Settings::class), + $container->get(\VuFind\Auth\Manager::class)->getUserObject(), + $container->get(\VuFind\Db\Service\PluginManager::class)->get(ResourceServiceInterface::class), + ...($options ?: []) + ); + } +} diff --git a/module/VuFind/src/VuFind/AjaxHandler/PluginManager.php b/module/VuFind/src/VuFind/AjaxHandler/PluginManager.php index 170f62d9b07..1ff1dbd71f0 100644 --- a/module/VuFind/src/VuFind/AjaxHandler/PluginManager.php +++ b/module/VuFind/src/VuFind/AjaxHandler/PluginManager.php @@ -66,6 +66,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager 'getSaveStatuses' => GetSaveStatuses::class, 'getSearchResults' => GetSearchResults::class, 'getSideFacets' => GetSideFacets::class, + 'getUserFavoritesStatus' => GetUserFavoritesStatus::class, 'getUserFines' => GetUserFines::class, 'getUserHolds' => GetUserHolds::class, 'getUserILLRequests' => GetUserILLRequests::class, @@ -108,6 +109,7 @@ class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager GetSaveStatuses::class => GetSaveStatusesFactory::class, GetSearchResults::class => GetSearchResultsFactory::class, GetSideFacets::class => GetSideFacetsFactory::class, + GetUserFavoritesStatus::class => GetUserFavoritesStatusFactory::class, GetUserFines::class => GetUserFinesFactory::class, GetUserHolds::class => AbstractIlsAndUserActionFactory::class, GetUserILLRequests::class => AbstractIlsAndUserActionFactory::class, diff --git a/themes/bootstrap3/js/account_ajax.js b/themes/bootstrap3/js/account_ajax.js index 80f64c53612..ad512b654b4 100644 --- a/themes/bootstrap3/js/account_ajax.js +++ b/themes/bootstrap3/js/account_ajax.js @@ -243,6 +243,19 @@ $(function registerAccountAjax() { } }); + VuFind.account.register("favorites", { + selector: ".favorites-status", + ajaxMethod: "getUserFavoritesStatus", + render: function render($element, status, ICON_LEVELS) { + var html = '' + status.count + ''; + var level = ICON_LEVELS.NONE; + $element.html(html); + return level; + } + } + + ); + VuFind.account.register("holds", { selector: ".holds-status", ajaxMethod: "getUserHolds", From 97c69813fe00816e4648feda084ac15a7ed9de0b Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 25 Jul 2024 13:11:10 -0400 Subject: [PATCH 2/6] Style. --- themes/bootstrap3/js/account_ajax.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/themes/bootstrap3/js/account_ajax.js b/themes/bootstrap3/js/account_ajax.js index ad512b654b4..698afc01547 100644 --- a/themes/bootstrap3/js/account_ajax.js +++ b/themes/bootstrap3/js/account_ajax.js @@ -252,9 +252,7 @@ $(function registerAccountAjax() { $element.html(html); return level; } - } - - ); + }); VuFind.account.register("holds", { selector: ".holds-status", From 26de56a7fc962f643c6e04abc5534edd02b27371 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 25 Jul 2024 13:12:35 -0400 Subject: [PATCH 3/6] Better validation. --- themes/bootstrap3/js/account_ajax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/bootstrap3/js/account_ajax.js b/themes/bootstrap3/js/account_ajax.js index 698afc01547..84ac978fa99 100644 --- a/themes/bootstrap3/js/account_ajax.js +++ b/themes/bootstrap3/js/account_ajax.js @@ -247,7 +247,7 @@ $(function registerAccountAjax() { selector: ".favorites-status", ajaxMethod: "getUserFavoritesStatus", render: function render($element, status, ICON_LEVELS) { - var html = '' + status.count + ''; + var html = '' + parseInt(status.count || 0) + ''; var level = ICON_LEVELS.NONE; $element.html(html); return level; From 7b747673535b1266bc24b67779cf95fe23ae3991 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 25 Jul 2024 13:21:17 -0400 Subject: [PATCH 4/6] Invalidate cache based on saved items count. --- themes/bootstrap3/js/account_ajax.js | 3 +++ themes/bootstrap3/templates/myresearch/mylist.phtml | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/themes/bootstrap3/js/account_ajax.js b/themes/bootstrap3/js/account_ajax.js index 84ac978fa99..e517203a8ad 100644 --- a/themes/bootstrap3/js/account_ajax.js +++ b/themes/bootstrap3/js/account_ajax.js @@ -251,6 +251,9 @@ $(function registerAccountAjax() { var level = ICON_LEVELS.NONE; $element.html(html); return level; + }, + updateNeeded: function updateNeeded(currentStatus, status) { + return currentStatus.count !== status.count; } }); diff --git a/themes/bootstrap3/templates/myresearch/mylist.phtml b/themes/bootstrap3/templates/myresearch/mylist.phtml index da21f93fb72..9bf0bfea38a 100644 --- a/themes/bootstrap3/templates/myresearch/mylist.phtml +++ b/themes/bootstrap3/templates/myresearch/mylist.phtml @@ -107,3 +107,7 @@ recommend($current)?> + + + render('myresearch/notify-account-status.phtml', ['method' => 'favorites', 'accountStatus' => ['count' => $recordTotal]]); ?> + \ No newline at end of file From de7aac7eb31b5472a91495d2e5618b4685d00f51 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 25 Jul 2024 13:22:20 -0400 Subject: [PATCH 5/6] Style. --- themes/bootstrap3/templates/myresearch/mylist.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/themes/bootstrap3/templates/myresearch/mylist.phtml b/themes/bootstrap3/templates/myresearch/mylist.phtml index 9bf0bfea38a..e4d3e2b6f77 100644 --- a/themes/bootstrap3/templates/myresearch/mylist.phtml +++ b/themes/bootstrap3/templates/myresearch/mylist.phtml @@ -110,4 +110,4 @@ render('myresearch/notify-account-status.phtml', ['method' => 'favorites', 'accountStatus' => ['count' => $recordTotal]]); ?> - \ No newline at end of file + From a621607e3a5d7b27041a60f2c43dcd55650a7ba5 Mon Sep 17 00:00:00 2001 From: Demian Katz Date: Thu, 25 Jul 2024 13:26:09 -0400 Subject: [PATCH 6/6] Get bootstrap5 in sync. --- themes/bootstrap5/templates/myresearch/mylist.phtml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/themes/bootstrap5/templates/myresearch/mylist.phtml b/themes/bootstrap5/templates/myresearch/mylist.phtml index da21f93fb72..e4d3e2b6f77 100644 --- a/themes/bootstrap5/templates/myresearch/mylist.phtml +++ b/themes/bootstrap5/templates/myresearch/mylist.phtml @@ -107,3 +107,7 @@ recommend($current)?> + + + render('myresearch/notify-account-status.phtml', ['method' => 'favorites', 'accountStatus' => ['count' => $recordTotal]]); ?> +