Skip to content

Commit

Permalink
#9914 move cache management to userGroup repo, add a new locale key f…
Browse files Browse the repository at this point in the history
…or from - until
  • Loading branch information
bozana committed Jun 11, 2024
1 parent 3af8a95 commit ed96a30
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 101 deletions.
103 changes: 90 additions & 13 deletions classes/userGroup/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@

namespace PKP\userGroup;

use APP\core\Application;
use APP\core\Request;
use APP\core\Services;
use APP\facades\Repo;
use Carbon\Carbon;
use DateInterval;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\LazyCollection;
use PKP\core\Core;
use PKP\db\DAORegistry;
use PKP\pages\about\AboutContextHandler;
use PKP\facades\Locale;
use PKP\plugins\Hook;
use PKP\security\Role;
use PKP\services\PKPSchemaService;
Expand All @@ -32,6 +35,7 @@
use PKP\userGroup\relationships\UserUserGroup;
use PKP\validation\ValidatorFactory;
use PKP\xml\PKPXMLParser;
use stdClass;

class Repository
{
Expand All @@ -40,6 +44,9 @@ class Repository
*/
public const NOT_CHANGE_METADATA_EDIT_PERMISSION_ROLES = [Role::ROLE_ID_MANAGER];

/** @var string Max lifetime for the Editorial Masthead and Editorial History users cache. */
public const MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME = '1 year';

/** @var DAO */
public $dao;

Expand Down Expand Up @@ -152,7 +159,7 @@ public function add(UserGroup $userGroup): int
// Clear editorial masthead cache if the new role should be added to the masthead
// Because it is a new role, no need to clear editorial history chache
if ($userGroup->getMasthead()) {
AboutContextHandler::forgetEditorialMastheadCache($userGroup->getContextId());
self::forgetEditorialMastheadCache($userGroup->getContextId());
}
return $userGroup->getId();
}
Expand All @@ -167,8 +174,8 @@ public function edit(UserGroup $userGroup, array $params)

// Clear editorial masthead and history cache if the role is on the masthead
if ($userGroup->getMasthead()) {
AboutContextHandler::forgetEditorialMastheadCache($userGroup->getContextId());
AboutContextHandler::forgetEditorialHistoryCache($userGroup->getContextId());
self::forgetEditorialMastheadCache($userGroup->getContextId());
self::forgetEditorialHistoryCache($userGroup->getContextId());
}

Repo::userGroup()->get($newUserGroup->getId());
Expand Down Expand Up @@ -362,7 +369,7 @@ public function assignUserToGroup(int $userId, int $userGroupId, ?string $startD
}
// Clear editorial masthead cache if a new user is assigned to a masthead role
if ($userGroup->getMasthead()) {
AboutContextHandler::forgetEditorialMastheadCache($userGroup->getContextId());
self::forgetEditorialMastheadCache($userGroup->getContextId());
}
return UserUserGroup::create([
'userId' => $userId,
Expand All @@ -381,8 +388,8 @@ public function deleteAssignmentsByUserId(int $userId, ?int $userGroupId = null)
if (!$userGroupId) {
$contextIds = $this->getUserUserGroupsContextIds($userId);
foreach ($contextIds as $contextId) {
AboutContextHandler::forgetEditorialMastheadCache($contextId);
AboutContextHandler::forgetEditorialHistoryCache($contextId);
self::forgetEditorialMastheadCache($contextId);
self::forgetEditorialHistoryCache($contextId);
}
}

Expand All @@ -392,8 +399,8 @@ public function deleteAssignmentsByUserId(int $userId, ?int $userGroupId = null)
$query->withUserGroupId($userGroupId);
$userGroup = $this->get($userGroupId);
if ($userGroup->getMasthead()) {
AboutContextHandler::forgetEditorialMastheadCache($contextId);
AboutContextHandler::forgetEditorialHistoryCache($contextId);
self::forgetEditorialMastheadCache($contextId);
self::forgetEditorialHistoryCache($contextId);
}
}

Expand All @@ -404,8 +411,8 @@ public function endAssignments(int $contextId, int $userId, ?int $userGroupId =
{
// Clear editorial masthead and history cache if the user was displayed on the masthead for the given role
if ($this->userOnMasthead($userId, $userGroupId)) {
AboutContextHandler::forgetEditorialMastheadCache($contextId);
AboutContextHandler::forgetEditorialHistoryCache($contextId);
self::forgetEditorialMastheadCache($contextId);
self::forgetEditorialHistoryCache($contextId);
}

$dateEnd = Core::getCurrentDate();
Expand Down Expand Up @@ -570,8 +577,8 @@ public function installSettings($contextId, $filename)
}
}

AboutContextHandler::forgetEditorialMastheadCache($contextId);
AboutContextHandler::forgetEditorialHistoryCache($contextId);
self::forgetEditorialMastheadCache($contextId);
self::forgetEditorialHistoryCache($contextId);

return true;
}
Expand Down Expand Up @@ -601,4 +608,74 @@ public function installLocale($locale, ?int $contextId = null)
$this->edit($userGroup, []);
}
}

/**
* Cache/get cached array of masthead user IDs grouped by masthead role IDs [user_group_id => [user_ids]]
*
* @param array $mastheadRoles Masthead roles, filtered by the given context ID, and sorted as they should appear on the Editorial Masthead and Editorial History page
*
*/
public function getMastheadUserIdsByRoleIds(array $mastheadRoles, int $contextId, UserUserGroupStatus $userUserGroupStatus = UserUserGroupStatus::STATUS_ACTIVE): array
{
$key = __METHOD__;
switch ($userUserGroupStatus) {
case UserUserGroupStatus::STATUS_ACTIVE:
$key .= 'EditorialMasthead';
break;
case UserUserGroupStatus::STATUS_ENDED:
$key .= 'EditorialHistory';
break;
}
$key .= $contextId . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME;
$expiration = DateInterval::createFromDateString(static::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
$allUsersIdsGroupedByUserGroupId = Cache::remember($key, $expiration, function () use ($mastheadRoles, $contextId, $userUserGroupStatus) {
$mastheadRolesIds = array_map(
function (UserGroup $item) use ($contextId) {
if ($item->getContextId() == $contextId) {
return $item->getId();
}
},
$mastheadRoles
);
// Query that gets all users that are or were active in the given masthead roles
// and that have accepted to be displayed on the masthead for the roles.
// Sort the results by role ID and user family name.
$usersCollector = Repo::user()->getCollector();
$usersQuery = $usersCollector
->filterByContextIds([$contextId])
->filterByUserGroupIds($mastheadRolesIds)
->filterByUserUserGroupStatus($userUserGroupStatus)
->filterByUserUserGroupMastheadStatus(UserUserGroupMastheadStatus::STATUS_ON)
->orderBy($usersCollector::ORDERBY_FAMILYNAME, $usersCollector::ORDER_DIR_ASC, [Locale::getLocale(), Application::get()->getRequest()->getSite()->getPrimaryLocale()])
->orderByUserGroupIds($mastheadRolesIds)
->getQueryBuilder()
->get();

// Get unique user IDs grouped by user group ID
$userIdsByUserGroupId = $usersQuery->mapToGroups(function (stdClass $item, int $key) {
return [$item->user_group_id => $item->user_id];
})->map(function ($item) {
return collect($item)->unique();
});
return $userIdsByUserGroupId->toArray();
});
return $allUsersIdsGroupedByUserGroupId;
}

/**
* Clear editorial masthead cache
*/
public static function forgetEditorialMastheadCache(int $contextId)
{
Cache::forget('PKP\userGroup\Repository::getMastheadUserIdsByRoleIdsEditorialMasthead' . $contextId . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
}

/**
* Clear editorial history cache
*/
public static function forgetEditorialHistoryCache(int $contextId)
{
Cache::forget('PKP\userGroup\Repository::getMastheadUserIdsByRoleIdsEditorialHistory' . $contextId . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
}

}
3 changes: 3 additions & 0 deletions locale/en/common.po
Original file line number Diff line number Diff line change
Expand Up @@ -2322,3 +2322,6 @@ msgstr "Author edited."

msgid "common.sandbox"
msgstr "Application running in sandbox mode."

msgid "common.fromUntil"
msgstr "{$from} - {$until}"
89 changes: 2 additions & 87 deletions pages/about/AboutContextHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,16 @@
use APP\facades\Repo;
use APP\handler\Handler;
use APP\template\TemplateManager;
use DateInterval;
use DateTime;
use Illuminate\Support\Facades\Cache;
use PKP\facades\Locale;
use PKP\plugins\Hook;
use PKP\security\authorization\ContextRequiredPolicy;
use PKP\security\Role;
use PKP\userGroup\relationships\enums\UserUserGroupMastheadStatus;
use PKP\userGroup\relationships\enums\UserUserGroupStatus;
use PKP\userGroup\relationships\UserUserGroup;
use PKP\userGroup\UserGroup;
use stdClass;

class AboutContextHandler extends Handler
{
/** @var string Max lifetime for the Editorial History users cache. */
public const MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME = '1 year';

/**
* @see PKPHandler::authorize()
*/
Expand Down Expand Up @@ -66,22 +58,6 @@ public function index($args, $request)
$templateMgr->display('frontend/pages/about.tpl');
}

/**
* Clear editorial masthead cache
*/
public static function forgetEditorialMastheadCache(int $contextId)
{
Cache::forget('PKP\pages\about\AboutContextHandler::editorialMasthead' . $contextId . AboutContextHandler::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
}

/**
* Clear editorial history cache
*/
public static function forgetEditorialHistoryCache(int $contextId)
{
Cache::forget('PKP\pages\about\AboutContextHandler::editorialMasthead' . $contextId . AboutContextHandler::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
}

/**
* Display editorial masthead page.
*
Expand All @@ -107,37 +83,7 @@ public function editorialMasthead($args, $request)
// sort the masthead roles in their saved order for display
$mastheadRoles = array_replace(array_flip($savedMastheadUserGroupIdsOrder), $allMastheadUserGroups);

// Cache/get cached array of user IDs groped by role IDs [user_group_id => [user_ids]]
$key = __METHOD__ . $context->getId() . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME;
$expiration = DateInterval::createFromDateString(static::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
$allUsersIdsGroupedByUserGroupId = Cache::remember($key, $expiration, function () use ($mastheadRoles) {
$mastheadRolesIds = array_map(
function (UserGroup $item) {
return $item->getId();
},
$mastheadRoles
);
// Query that gets all users that are active in the given masthead roles
// and that have accepted to be displayed on the masthead for the roles.
// No need to filter by context ID, because the user groups are already filtered so.
// Sort the results by role IDs and family name.
$usersCollector = Repo::user()->getCollector();
$usersQuery = $usersCollector
->filterByUserGroupIds($mastheadRolesIds)
->filterByUserUserGroupMastheadStatus(UserUserGroupMastheadStatus::STATUS_ON)
->orderBy($usersCollector::ORDERBY_FAMILYNAME, $usersCollector::ORDER_DIR_ASC, [Locale::getLocale(), Application::get()->getRequest()->getSite()->getPrimaryLocale()])
->orderByUserGroupIds($mastheadRolesIds)
->getQueryBuilder()
->get();

// Get unique user IDs grouped by user group ID
$userIdsByUserGroupId = $usersQuery->mapToGroups(function (stdClass $item, int $key) {
return [$item->user_group_id => $item->user_id];
})->map(function ($item) {
return collect($item)->unique();
});
return $userIdsByUserGroupId->toArray();
});
$allUsersIdsGroupedByUserGroupId = Repo::userGroup()->getMastheadUserIdsByRoleIds($mastheadRoles, $context->getId());

$mastheadUsers = [];
foreach ($mastheadRoles as $mastheadUserGroup) {
Expand Down Expand Up @@ -212,38 +158,7 @@ public function editorialHistory($args, $request)
// sort the masthead roles in their saved order for display
$mastheadRoles = array_replace(array_flip($savedMastheadUserGroupIdsOrder), $allMastheadUserGroups);

// Cache/get cached array of user IDs groped by role IDs [user_group_id => [user_ids]]
$key = __METHOD__ . $context->getId() . self::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME;
$expiration = DateInterval::createFromDateString(static::MAX_EDITORIAL_MASTHEAD_CACHE_LIFETIME);
$allUsersIdsGroupedByUserGroupId = Cache::remember($key, $expiration, function () use ($mastheadRoles) {
$mastheadRolesIds = array_map(
function (UserGroup $item) {
return $item->getId();
},
$mastheadRoles
);
// Query that gets all users that were active and are not active any more in the masthead roles
// and that have accepted to be displayed on the masthead for the roles.
// No need to filter by context ID, because the user groups are already filtered so.
// Sort the results by role IDs and family name.
$usersCollector = Repo::user()->getCollector();
$usersQuery = $usersCollector
->filterByUserGroupIds($mastheadRolesIds)
->filterByUserUserGroupStatus(UserUserGroupStatus::STATUS_ENDED)
->filterByUserUserGroupMastheadStatus(UserUserGroupMastheadStatus::STATUS_ON)
->orderBy($usersCollector::ORDERBY_FAMILYNAME, $usersCollector::ORDER_DIR_ASC, [Locale::getLocale(), Application::get()->getRequest()->getSite()->getPrimaryLocale()])
->orderByUserGroupIds($mastheadRolesIds)
->getQueryBuilder()
->get();

// Group all user IDs grouped by user group ID
$userIdsByUserGroupId = $usersQuery->mapToGroups(function (stdClass $item, int $key) {
return [$item->user_group_id => $item->user_id];
})->map(function ($item) {
return collect($item)->unique();
});
return $userIdsByUserGroupId->toArray();
});
$allUsersIdsGroupedByUserGroupId = Repo::userGroup()->getMastheadUserIdsByRoleIds($mastheadRoles, $context->getId(), UserUserGroupStatus::STATUS_ENDED);

$mastheadUsers = [];
foreach ($mastheadRoles as $mastheadUserGroup) {
Expand Down
2 changes: 1 addition & 1 deletion templates/frontend/pages/editorialHistory.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
{if !empty($mastheadUser['user']->getLocalizedData('affiliation'))}
<li>{$mastheadUser['user']->getLocalizedData('affiliation')|escape}</li>
{/if}
<li>{$service['dateStart']} - {$service['dateEnd']}</li>
<li>{translate key="common.fromUntil" from=$service['dateStart'] until=$service['dateEnd']}</li>
</ul>
{if $mastheadUser['user']->getData('orcid')}
<span class="orcid">
Expand Down

0 comments on commit ed96a30

Please sign in to comment.