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..e517203a8ad 100644 --- a/themes/bootstrap3/js/account_ajax.js +++ b/themes/bootstrap3/js/account_ajax.js @@ -243,6 +243,20 @@ $(function registerAccountAjax() { } }); + VuFind.account.register("favorites", { + selector: ".favorites-status", + ajaxMethod: "getUserFavoritesStatus", + render: function render($element, status, ICON_LEVELS) { + var html = '' + parseInt(status.count || 0) + ''; + var level = ICON_LEVELS.NONE; + $element.html(html); + return level; + }, + updateNeeded: function updateNeeded(currentStatus, status) { + return currentStatus.count !== status.count; + } + }); + VuFind.account.register("holds", { selector: ".holds-status", ajaxMethod: "getUserHolds", diff --git a/themes/bootstrap3/templates/myresearch/mylist.phtml b/themes/bootstrap3/templates/myresearch/mylist.phtml index da21f93fb72..e4d3e2b6f77 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]]); ?> + 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]]); ?> +