Skip to content

Commit

Permalink
pkp#10571 WIP: Allow admins and managers to assign user groups to ema…
Browse files Browse the repository at this point in the history
…il templates within a mailable
  • Loading branch information
taslangraham committed Dec 19, 2024
1 parent 9d9a703 commit 8cc0645
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 20 deletions.
2 changes: 1 addition & 1 deletion api/v1/emailTemplates/PKPEmailTemplateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public function edit(Request $illuminateRequest): JsonResponse
return response()->json($errors, Response::HTTP_BAD_REQUEST);
}

Repo::emailTemplate()->edit($emailTemplate, $params);
Repo::emailTemplate()->edit($emailTemplate, $params, $requestContext->getId());

$emailTemplate = Repo::emailTemplate()->getByKey(
// context ID is null if edited for the first time
Expand Down
33 changes: 33 additions & 0 deletions classes/components/forms/FieldEmailTemplateUserGroupSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/**
* @file classes/components/form/FieldEmailTemplateUserGroupSettings.php
*
* Copyright (c) 2014-2024 Simon Fraser University
* Copyright (c) 2000-2024 John Willinsky
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
*
* @class FieldEmailTemplateUserGroupSettings
*
* @ingroup classes_controllers_form
*
* @brief A component managing user groups assignable to an email template
*/

namespace PKP\components\forms;

class FieldEmailTemplateUserGroupSettings extends Field
{
/** @copydoc Field::$component */
public $component = 'field-email-template-user-group-settings';

/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();

return $config;
}
}
4 changes: 4 additions & 0 deletions classes/components/forms/emailTemplate/EmailTemplateForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

namespace PKP\components\forms\emailTemplate;

use PKP\components\forms\FieldEmailTemplateUserGroupSettings;
use PKP\components\forms\FieldPreparedContent;
use PKP\components\forms\FieldText;
use PKP\components\forms\FormComponent;
Expand Down Expand Up @@ -46,6 +47,9 @@ public function __construct(string $action, array $locales)
'isMultilingual' => true,
'toolbar' => 'bold italic superscript subscript | link | blockquote bullist numlist',
'plugins' => 'paste,link,lists',
]))->addField(new FieldEmailTemplateUserGroupSettings('userGroupIds', [
'label' => __('workflow.userGroup.allowed'),
'type' => 'checkbox'
]));
}
}
29 changes: 29 additions & 0 deletions classes/emailTemplate/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -449,4 +449,33 @@ protected function getUniqueKey(EmailTemplate $emailTemplate): string

return $key;
}


public function updateTemplateAccessGroups(EmailTemplate $emailTemplate, array $newUserGroupIds, $contextId)
{

// Delete old entries for user groups IDs not found in new list of user group IDs
DB::table('email_template_role_access')
->where('email_key', $emailTemplate->getData('key'))
->where('context_id', $contextId)
->whereNotIn('user_group_id', $newUserGroupIds)
->delete();

foreach ($newUserGroupIds as $id) {
DB::table('email_template_role_access')
->updateOrInsert(
[ // The where conditions (keys that should match)
'email_key' => $emailTemplate->getData('key'),
'user_group_id' => $id,
'context_id' => $contextId
],
[ // The data to insert or update (values to set)
'email_key' => $emailTemplate->getData('key'),
'user_group_id' => $id,
'context_id' => $contextId,
]
);
}

}
}
23 changes: 22 additions & 1 deletion classes/emailTemplate/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,20 @@ 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 (isset($props['userGroupIds'])) {
$validator->after(function () use ($validator, $props, $context) {
$existingGroupIds = Repo::userGroup()->getCollector()
->filterByContextIds([$context->getId()])
->filterByUserGroupIds($props['userGroupIds'])->getIds()->toArray();

if (!empty(array_diff($existingGroupIds, $props['userGroupIds']))) {
$validator->errors()->add('userGroupIds', __('api.emailTemplates.404.userGroupIds'));
}
});

}

// Check for input from disallowed locales
ValidatorFactory::allowedLocales($validator, $this->schemaService->getMultilingualProps($this->dao->schema), $allowedLocales);

Expand Down Expand Up @@ -156,18 +170,25 @@ public function add(EmailTemplate $emailTemplate): string
}

/** @copydoc DAO::update() */
public function edit(EmailTemplate $emailTemplate, array $params)
public function edit(EmailTemplate $emailTemplate, array $params, $contextId)
{
$newEmailTemplate = clone $emailTemplate;
$newEmailTemplate->setAllData(array_merge($newEmailTemplate->_data, $params));

$userGroupIds = $params['userGroupIds'];
unset($params['userGroupIds']);

Hook::call('EmailTemplate::edit', [$newEmailTemplate, $emailTemplate, $params]);

if ($newEmailTemplate->getId()) {
$this->dao->update($newEmailTemplate);
} else {
$this->dao->insert($newEmailTemplate);
}

if($userGroupIds) {
$this->dao->updateTemplateAccessGroups($emailTemplate, $userGroupIds, $contextId);
}
}

/** @copydoc DAO::delete() */
Expand Down
19 changes: 1 addition & 18 deletions classes/emailTemplate/maps/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,11 @@ protected function mapByProperties(array $props, EmailTemplate $item, string $ma

$mailableClass = $mailableClass ?? Repo::mailable()->getMailableByEmailTemplate($item);

if(!$mailableClass) {
error_log('TEMPLATE NAME ' . $item->getData('key'));
error_log('TEMPLATE ALTERNATE TO ' . $item->getData('alternateTo') ?? '');
}


// some mailable are not found during some operations such as performing a search for templates. So ensure mailable exist before using
if($mailableClass) {
$isUserGroupsAssignable = Repo::mailable()->isGroupsAssignableToTemplates($mailableClass);

if ($isUserGroupsAssignable) {
$output['assignableUserGroups'] = [];
if (!$isUserGroupsAssignable) {
$output['assignedUserGroupIds'] = [];
} else {
// get roles for mailable
Expand All @@ -105,16 +98,6 @@ protected function mapByProperties(array $props, EmailTemplate $item, string $ma
$userGroups = [];
$roleNames = Application::get()->getRoleNames();

foreach (Repo::userGroup()->getByRoleIds($roles, $this->context->getId())->all() as $group) {
$roleId = $group->getRoleId();
$userGroups[] = [
'id' => $group->getId(),
'name' => $group->getLocalizedName(),
'roleId' => $roleId,
'roleName' => $roleNames[$roleId]];
}

$output['assignableUserGroups'] = $userGroups;
// Get the current user groups assigned to the template
$output['assignedUserGroupIds'] = Repo::emailTemplate()->getGroupsAssignedToTemplate($item->getData('key'), Application::get()->getRequest()->getContext()->getId());
}
Expand Down
16 changes: 16 additions & 0 deletions classes/mail/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,21 @@ public function summarizeMailable(string $class): array
$dataDescriptions = $class::getDataDescriptions();
ksort($dataDescriptions);

// get roles for mailable
$roles = $class::getFromRoleIds();
// Get the groups for each role
$userGroups = [];
$roleNames = Application::get()->getRoleNames();

foreach (Repo::userGroup()->getByRoleIds($roles, Application::get()->getRequest()->getContext()->getId())->all() as $group) {
$roleId = $group->getRoleId();
$userGroups[] = [
'id' => $group->getId(),
'name' => $group->getLocalizedName(),
'roleId' => $roleId,
'roleName' => $roleNames[$roleId]];
}

return [
'_href' => Application::get()->getRequest()->getDispatcher()->url(
Application::get()->getRequest(),
Expand All @@ -118,6 +133,7 @@ public function summarizeMailable(string $class): array
'supportsTemplates' => $class::getSupportsTemplates(),
'toRoleIds' => $class::getToRoleIds(),
'canAssignUserGroupToTemplates' => $this->isGroupsAssignableToTemplates($class),
'assignableTemplateUserGroups' => $userGroups
];
}

Expand Down
3 changes: 3 additions & 0 deletions locale/en/api.po
Original file line number Diff line number Diff line change
Expand Up @@ -355,3 +355,6 @@ msgstr "Invalid ID: \"{$id}\" provided."

msgid "api.publications.403.noEnabledIdentifiers"
msgstr "Publication identifiers form is unavailable as there are no enabled Identifiers."

msgid "api.emailTemplates.404.userGroupIds"
msgstr "One or more of the provided user groups does not exist."
3 changes: 3 additions & 0 deletions locale/en/common.po
Original file line number Diff line number Diff line change
Expand Up @@ -2343,3 +2343,6 @@ msgstr "Application running in sandbox mode."

msgid "common.fromUntil"
msgstr "{$from} &ndash; {$until}"

msgid "workflow.userGroup.allowed"
msgstr "Allowed User Groups"

0 comments on commit 8cc0645

Please sign in to comment.