Skip to content

Commit

Permalink
pkp#10571 WIP: add support for unrestricted templates
Browse files Browse the repository at this point in the history
  • Loading branch information
taslangraham committed Nov 8, 2024
1 parent bf7381b commit 5dbb308
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 40 deletions.
9 changes: 9 additions & 0 deletions api/v1/emailTemplates/PKPEmailTemplateController.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ public function add(Request $illuminateRequest): JsonResponse

$emailTemplate = Repo::emailTemplate()->newDataObject($params);
Repo::emailTemplate()->add($emailTemplate);

if($params['userGroupIds']) {
Repo::emailTemplate()->updateTemplateAccessGroups($emailTemplate, $params['userGroupIds'], $requestContext->getId());
}
$emailTemplate = Repo::emailTemplate()->getByKey($emailTemplate->getData('contextId'), $emailTemplate->getData('key'));

return response()->json(Repo::emailTemplate()->getSchemaMap()->map($emailTemplate), Response::HTTP_OK);
Expand Down Expand Up @@ -238,6 +242,11 @@ public function edit(Request $illuminateRequest): JsonResponse
$params['contextId'] = $requestContext->getId();
}


// If the user submitted an empty list (meaning all user groups were unchecked), the empty array is converted to null in the request's data.
// Convert back to an empty array.
$params['userGroupIds'] = $params['userGroupIds'] ?: [];

$errors = Repo::emailTemplate()->validate(
$emailTemplate,
$params,
Expand Down
33 changes: 33 additions & 0 deletions classes/components/forms/FieldEmailTemplateUnrestricted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/**
* @file classes/components/form/FieldEmailTemplateUnrestricted.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 FieldEmailTemplateUnrestricted
*
* @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
*/

namespace PKP\components\forms;

class FieldEmailTemplateUnrestricted extends Field
{
/** @copydoc Field::$component */
public $component = 'field-email-template-unrestricted';

/**
* @copydoc Field::getConfig()
*/
public function getConfig()
{
$config = parent::getConfig();
$config['label'] = $this->label;
return $config;
}
}
12 changes: 10 additions & 2 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\FieldEmailTemplateUnrestricted;
use PKP\components\forms\FieldEmailTemplateUserGroupSettings;
use PKP\components\forms\FieldPreparedContent;
use PKP\components\forms\FieldText;
Expand Down Expand Up @@ -47,9 +48,16 @@ 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', [
]))->addField(
new FieldEmailTemplateUnrestricted('isUnrestricted'),
[
'type' => 'checkbox'
]
)
->addField(new FieldEmailTemplateUserGroupSettings('userGroupIds', [
'type' => 'checkbox',
'label' => __('workflow.userGroup.allowed'),
'type' => 'checkbox'

]));
}
}
7 changes: 7 additions & 0 deletions classes/decision/steps/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use PKP\facades\Locale;
use PKP\mail\Mailable;
use PKP\user\User;
use Role;
use stdClass;

class Email extends Step
Expand Down Expand Up @@ -124,6 +125,12 @@ protected function getEmailTemplates(): array
{
$request = Application::get()->getRequest();
$context = $request->getContext();
$userRoles = array_map(fn (Role $role) => $role->getId(), $request->getUser()->getRoles($context->getId()));

// Ensure user has access to mailable before proceeding
if(empty(array_intersect($this->mailable::getFromRoleIds(), $userRoles))) {
return [];
}

$emailTemplates = collect();
if ($this->mailable::getEmailTemplateKey()) {
Expand Down
26 changes: 0 additions & 26 deletions classes/emailTemplate/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -450,31 +450,5 @@ protected function getUniqueKey(EmailTemplate $emailTemplate): string
}


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,
]
);
}

}
}
41 changes: 36 additions & 5 deletions classes/emailTemplate/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,12 @@ public function add(EmailTemplate $emailTemplate): string
/** @copydoc DAO::update() */
public function edit(EmailTemplate $emailTemplate, array $params, $contextId)
{
$userGroupIds = $params['userGroupIds'];
unset($params['userGroupIds']);
$newEmailTemplate = clone $emailTemplate;
$newEmailTemplate->setAllData(array_merge($newEmailTemplate->_data, $params));

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


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

Expand All @@ -186,9 +187,7 @@ public function edit(EmailTemplate $emailTemplate, array $params, $contextId)
$this->dao->insert($newEmailTemplate);
}

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

/** @copydoc DAO::delete() */
Expand Down Expand Up @@ -278,4 +277,36 @@ public function filterTemplatesByUserAccess(array $templates, User $user, int $c
return collect(array_filter($templates, fn (EmailTemplate $template) => $this->isTemplateAccessibleToUser($user, $template, $contextId)));
}

/**
* Pass empty array to delete all existing user groups for a template
*/
public function updateTemplateAccessGroups(EmailTemplate $emailTemplate, array $newUserGroupIds, int $contextId): void
{
$isUnrestricted = in_array(null, $newUserGroupIds);
// remove any null values
// 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,
]
);
}

}

}
2 changes: 1 addition & 1 deletion classes/emailTemplate/maps/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function summarizeMany(Enumerable $collection, string $mailableClass = nu
}

/**
* Map schema properties of an Announcement to an assoc array
* Map schema properties of an Email Template to an assoc array
*/
protected function mapByProperties(array $props, EmailTemplate $item, string $mailableClass = null): array
{
Expand Down
7 changes: 1 addition & 6 deletions classes/mail/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,7 @@ protected function isMailableConfigurable(string $class, Context $context): bool
*/
public function isGroupsAssignableToTemplates(Mailable|string $mailable): bool
{
return !empty(array_intersect($mailable::getGroupIds(), [
Mailable::GROUP_SUBMISSION,
Mailable::GROUP_REVIEW,
Mailable::GROUP_COPYEDITING,
Mailable::GROUP_PRODUCTION,
]));
return !in_array(Mailable::FROM_SYSTEM, $mailable::getFromRoleIds());
}

/**
Expand Down
5 changes: 5 additions & 0 deletions schemas/emailTemplate.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@
"validation": [
"nullable"
]
},
"isUnrestricted": {
"type": "boolean",
"description": "Boolean indicating if an email template is available to all user groups within the roles associated with the template's mailable",
"apiSummary": true
}
}
}

0 comments on commit 5dbb308

Please sign in to comment.