Skip to content

Commit

Permalink
Code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
taslangraham committed Nov 20, 2024
1 parent 03a39d4 commit 405e376
Show file tree
Hide file tree
Showing 21 changed files with 118 additions and 102 deletions.
5 changes: 3 additions & 2 deletions classes/components/forms/FieldEmailTemplateUnrestricted.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*
* @ingroup classes_controllers_form
*
* @brief A component to indicate if an email template is unrestricted, i.e accessible to all user groups within the associated mailable
* @brief A component to indicate if an email template is unrestricted, i.e accessible to all user groups.
*/

namespace PKP\components\forms;
Expand All @@ -20,13 +20,14 @@ class FieldEmailTemplateUnrestricted extends Field
{
/** @copydoc Field::$component */
public $component = 'field-email-template-unrestricted';

public string $subNote = '';
/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['subNote'] = $this->subNote;
return $config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
*
* @ingroup classes_controllers_form
*
* @brief A component managing user groups assignable to an email template
* @brief A component managing user groups assigned to an email template
*/

namespace PKP\components\forms;
Expand Down
12 changes: 5 additions & 7 deletions classes/components/forms/emailTemplate/EmailTemplateForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,14 @@ public function __construct(string $action, array $locales)
'isMultilingual' => true,
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))->addField(
new FieldEmailTemplateUnrestricted('isUnrestricted'),
[
'type' => 'checkbox'
]
)
]))->addField(new FieldEmailTemplateUnrestricted('isUnrestricted', [
'type' => 'checkbox',
'label' => __('admin.workflow.email.userGroup.assign.unrestricted'),
'subNote' => __('admin.workflow.email.userGroup.unrestricted.template.note')
]))
->addField(new FieldEmailTemplateUserGroupSettings('userGroupIds', [
'type' => 'checkbox',
'label' => __('admin.workflow.email.userGroup.allowed'),

]));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1048,7 +1048,7 @@ public function fetchTemplateBody(array $args, PKPRequest $request): ?JSONMessag
};
$template = Repo::emailTemplate()->getByKey($context->getId(), $request->getUserVar('template'));

if (!$template) {
if (!$template || ! Repo::emailTemplate()->isTemplateAccessibleToUser($request->getUser(), $template, $context->getId())) {
return null;
}

Expand Down
3 changes: 1 addition & 2 deletions classes/decision/steps/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ protected function getEmailTemplates(): array
$emailTemplates = collect();
if ($this->mailable::getEmailTemplateKey()) {
$emailTemplate = Repo::emailTemplate()->getByKey($context->getId(), $this->mailable::getEmailTemplateKey());
if (Repo::emailTemplate()->isTemplateAccessibleToUser($request->getUser(), $emailTemplate, $context->getId())) {
if ($emailTemplate && Repo::emailTemplate()->isTemplateAccessibleToUser($request->getUser(), $emailTemplate, $context->getId())) {
$emailTemplates->add($emailTemplate);
}
Repo::emailTemplate()
Expand All @@ -142,7 +142,6 @@ protected function getEmailTemplates(): array
});
}


return Repo::emailTemplate()->getSchemaMap()->mapMany($emailTemplates)->toArray();
}

Expand Down
19 changes: 13 additions & 6 deletions classes/emailTemplate/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,17 @@ public function getMainEmailTemplatesFilename()
* skipping others
* @param bool $skipExisting If true, do not install email templates
* that already exist in the database
* @param bool $recordTemplateGroupAccess - If true, records the templates as unrestricted.
* By default, it is set to false to ensure compatibility with older processes (e.g., migrations)
* where the `email_template_user_group_access` table may not exist at the time of execution.
*
*/
public function installEmailTemplates(
string $templatesFile,
array $locales = [],
?string $emailKey = null,
bool $skipExisting = false
bool $skipExisting = false,
$recordTemplateGroupAccess = false
): bool {
$xmlDao = new XMLDAO();
$data = $xmlDao->parseStruct($templatesFile, ['email']);
Expand Down Expand Up @@ -282,14 +286,17 @@ public function installEmailTemplates(
}
}

if (isset($attrs['isUnrestricted'])) {
if ($attrs['isUnrestricted'] !== '1' && $attrs['isUnrestricted'] !== '0') {
throw new Exception('Invalid value given for the `isUnrestricted` attribute on the ' . $attrs['key'] . ' template');
if ($recordTemplateGroupAccess) {
// Default to true if `isUnrestricted` is not set.
$isUnrestricted = $attrs['isUnrestricted'] ?? '1';

if ($isUnrestricted !== '1' && $isUnrestricted !== '0') {
throw new Exception('Invalid value given for the `isUnrestricted` attribute on the ' . $attrs['key'] . ' template.');
}

$contextIds = app()->get('context')->getIds();
foreach ($contextIds as $contextId) {
Repo::emailTemplate()->markTemplateAsUnrestricted($attrs['key'], (bool)$attrs['isUnrestricted'], $contextId);
Repo::emailTemplate()->markTemplateAsUnrestricted($attrs['key'], (bool)$isUnrestricted, $contextId);
}
}
}
Expand Down Expand Up @@ -420,7 +427,7 @@ public function installAlternateEmailTemplates(int $contextId, ?string $emailKey
'Tried to install email template as an alternate to `' . $alternateTo . '`, but no default template exists with this key. Installing ' . $alternateTo . ' email template first',
E_USER_WARNING
);
$this->installEmailTemplates(Repo::emailTemplate()->dao->getMainEmailTemplatesFilename(), [], $alternateTo);
$this->installEmailTemplates(Repo::emailTemplate()->dao->getMainEmailTemplatesFilename(), [], $alternateTo, false, true);
}

DB::table($this->table)->insert([
Expand Down
26 changes: 12 additions & 14 deletions classes/emailTemplate/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ public function validate(?EmailTemplate $object, array $props, Context $context)
});
}

// If groupIds were passed to limit email access, check that groups exists within the context
// If groupIds were passed to limit email access, check that the user groups exists within the context
if (isset($props['userGroupIds'])) {
$validator->after(function () use ($validator, $props, $context) {
$existingGroupIds = Repo::userGroup()->getCollector()
Expand All @@ -141,7 +141,6 @@ public function validate(?EmailTemplate $object, array $props, Context $context)
$validator->errors()->add('userGroupIds', __('api.emailTemplates.404.userGroupIds'));
}
});

}

// Check for input from disallowed locales
Expand Down Expand Up @@ -231,7 +230,7 @@ public function restoreDefaults($contextId): array
/***
* Gets the IDs of the user groups assigned to an email template
*/
public function getUserGroupsIdsAssignedToTemplate(string $templateKey, int $contextId): array
public function getAssignedGroupsIds(string $templateKey, int $contextId): array
{
return EmailTemplateAccessGroup::withEmailKey([$templateKey])
->withContextId($contextId)
Expand All @@ -248,7 +247,7 @@ public function isTemplateUnrestricted(string $templateKey, int $contextId): boo
{
return !!EmailTemplateAccessGroup::withEmailKey([$templateKey])
->withContextId($contextId)
->where('user_group_id', null)
->whereNull('user_group_id')
->first();
}

Expand All @@ -263,7 +262,7 @@ public function isTemplateAccessibleToUser(User $user, EmailTemplate $template,
}

$userUserGroups = Repo::userGroup()->userUserGroups($user->getId(), $contextId)->all();
$templateUserGroups = $this->getUserGroupsIdsAssignedToTemplate($template->getData('key'), $contextId);
$templateUserGroups = $this->getAssignedGroupsIds($template->getData('key'), $contextId);

foreach ($userUserGroups as $userGroup) {
if (in_array($userGroup->getId(), $templateUserGroups)) {
Expand All @@ -280,7 +279,7 @@ public function isTemplateAccessibleToUser(User $user, EmailTemplate $template,
* @param Enumerable $templates List of EmailTemplates to filter.
* @param User $user The user whose access level is used for filtering.
*
* @return Collection Filtered list of EmailTemplate objects accessible to the user.
* @return Collection Filtered list of EmailTemplates accessible to the user.
*/
public function filterTemplatesByUserAccess(Enumerable $templates, User $user, int $contextId): Collection
{
Expand All @@ -298,7 +297,7 @@ public function filterTemplatesByUserAccess(Enumerable $templates, User $user, i
/***
* Internal method used to assign user group IDs to an email template
*/
private function _updateTemplateAccessGroups(EmailTemplate $emailTemplate, array $newUserGroupIds, int $contextId): void
private function updateTemplateAccessGroups(EmailTemplate $emailTemplate, array $newUserGroupIds, int $contextId): void
{
EmailTemplateAccessGroup::withEmailKey([$emailTemplate->getData('key')])
->withContextId($contextId)
Expand All @@ -307,13 +306,13 @@ private function _updateTemplateAccessGroups(EmailTemplate $emailTemplate, array
foreach ($newUserGroupIds as $id) {
EmailTemplateAccessGroup::updateOrCreate(
[
// The where conditions (keys that should match)
// The where conditions
'email_key' => $emailTemplate->getData('key'),
'user_group_id' => $id,
'context_id' => $contextId,
],
[
// The data to insert or update (values to set)
// The data to insert or update
'emailKey' => $emailTemplate->getData('key'),
'userGroupId' => $id,
'contextId' => $contextId,
Expand All @@ -328,7 +327,7 @@ private function _updateTemplateAccessGroups(EmailTemplate $emailTemplate, array
public function setEmailTemplateAccess(EmailTemplate $emailTemplate, int $contextId, ?array $userGroupIds, ?bool $isUnrestricted): void
{
if($userGroupIds !== null) {
$this->_updateTemplateAccessGroups($emailTemplate, $userGroupIds, $contextId);
$this->updateTemplateAccessGroups($emailTemplate, $userGroupIds, $contextId);
}

if($isUnrestricted !== null) {
Expand All @@ -339,22 +338,21 @@ public function setEmailTemplateAccess(EmailTemplate $emailTemplate, int $contex

/**
* Mark an email template as unrestricted or not.
* An unrestricted email template is available to all user groups associated with the Roles linked to the mailable that the template belongs to.
* Mailable roles are stored in the $fromRoleIds property of a mailable
* An unrestricted email template is available to all user groups.
*/
public function markTemplateAsUnrestricted(string $emailKey, bool $isUnrestricted, int $contextId): void
{
// Unrestricted emails are represented by an entry with a `null` value for the user group ID
if ($isUnrestricted) {
EmailTemplateAccessGroup::updateOrCreate(
[
// The where conditions (keys that should match)
// The where conditions
'email_key' => $emailKey,
'user_group_id' => null,
'context_id' => $contextId,
],
[
// The data to insert or update (values to set)
// The data to insert or update
'emailKey' => $emailKey,
'userGroupId' => null,
'contextId' => $contextId,
Expand Down
21 changes: 19 additions & 2 deletions classes/emailTemplate/maps/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use PKP\core\PKPApplication;
use PKP\emailTemplate\EmailTemplate;
use PKP\services\PKPSchemaService;
use PKP\userGroup\UserGroup;

class Schema extends \PKP\core\maps\Schema
{
Expand Down Expand Up @@ -82,8 +83,8 @@ public function summarizeMany(Enumerable $collection, string $mailableClass = nu
protected function mapByProperties(array $props, EmailTemplate $item, string $mailableClass = null): array
{
$output = [];
$mailableClass = $mailableClass ?? Repo::mailable()->get($item->getData('key'), Application::get()->getRequest()->getContext());

$mailableClass = $mailableClass ?? Repo::mailable()->getMailableByEmailTemplate($item);
foreach ($props as $prop) {
switch ($prop) {
case '_href':
Expand All @@ -99,11 +100,27 @@ protected function mapByProperties(array $props, EmailTemplate $item, string $ma
break;
case 'assignedUserGroupIds':
if ($mailableClass && Repo::mailable()->isGroupsAssignableToTemplates($mailableClass)) {
$output['assignedUserGroupIds'] = Repo::emailTemplate()->getUserGroupsIdsAssignedToTemplate($item->getData('key'), Application::get()->getRequest()->getContext()->getId());
$output['assignedUserGroupIds'] = Repo::emailTemplate()->getAssignedGroupsIds($item->getData('key'), Application::get()->getRequest()->getContext()->getId());
} else {
$output['assignedUserGroupIds'] = [];
}
break;
case 'assignableTemplateUserGroups':
if($mailableClass && Repo::mailable()->isGroupsAssignableToTemplates($mailableClass)) {
$userGroups = collect();

Repo::userGroup()->getCollector()
->filterByContextIds([Application::get()->getRequest()->getContext()->getId()])
->getMany()->each(fn (UserGroup $group) => $userGroups->add([
'id' => $group->getId(),
'name' => $group->getLocalizedName()
]));

$output['assignableTemplateUserGroups'] = $userGroups;
} else {
$output['assignableTemplateUserGroups'] = [];
}
break;
default:
$output[$prop] = $item->getData($prop);
break;
Expand Down
12 changes: 8 additions & 4 deletions classes/invitation/sections/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public function getState(): stdClass

/**
* Get all email recipients for email composer
* @return array
*/
protected function getRecipientOptions(): array
{
Expand All @@ -84,7 +83,6 @@ protected function getRecipientOptions(): array

/**
* Get all email templates for email composer
* @return array
*/
protected function getEmailTemplates(): array
{
Expand All @@ -93,15 +91,21 @@ protected function getEmailTemplates(): array

$emailTemplates = collect();
if ($this->mailable::getEmailTemplateKey()) {
$user = $request->getUser();

$emailTemplate = Repo::emailTemplate()->getByKey($context->getId(), $this->mailable::getEmailTemplateKey());
if ($emailTemplate) {
if ($emailTemplate && Repo::emailTemplate()->isTemplateAccessibleToUser($user, $emailTemplate, $context->getId())) {
$emailTemplates->add($emailTemplate);
}
Repo::emailTemplate()
->getCollector($context->getId())
->alternateTo([$this->mailable::getEmailTemplateKey()])
->getMany()
->each(fn (EmailTemplate $e) => $emailTemplates->add($e));
->each(function (EmailTemplate $e) use ($context, $user, $emailTemplates) {
if(Repo::emailTemplate()->isTemplateAccessibleToUser($user, $e, $context->getId())) {
$emailTemplates->add($e);
}
});
}

return Repo::emailTemplate()->getSchemaMap()->mapMany($emailTemplates)->toArray();
Expand Down
Loading

0 comments on commit 405e376

Please sign in to comment.