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 Nov 6, 2024
1 parent 0d674ee commit bf7381b
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 @@ -248,7 +248,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 @@ -448,4 +448,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 @@ -343,3 +343,6 @@ msgstr "The provided section does not exist."

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 bf7381b

Please sign in to comment.