153 lines
4.8 KiB
PHP
153 lines
4.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/mail/traits/Unsubscribe.php
|
|
*
|
|
* Copyright (c) 2014-2022 Simon Fraser University
|
|
* Copyright (c) 2000-2022 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class Unsubscribe
|
|
*
|
|
* @ingroup mail_traits
|
|
*
|
|
* @brief trait to embed footer with unsubscribe link to notification emails
|
|
*/
|
|
|
|
namespace PKP\mail\traits;
|
|
|
|
use APP\core\Application;
|
|
use APP\mail\variables\ContextEmailVariable;
|
|
use APP\notification\Notification;
|
|
use APP\notification\NotificationManager;
|
|
use Exception;
|
|
use Illuminate\Mail\Mailables\Headers;
|
|
use PKP\mail\Mailable;
|
|
use PKP\mail\variables\ContextEmailVariable as PKPContextEmailVariable;
|
|
|
|
trait Unsubscribe
|
|
{
|
|
protected static string $unsubscribeUrl = 'unsubscribeUrl';
|
|
|
|
// Notification to generate unsubscribe link
|
|
protected Notification $notification;
|
|
|
|
// Locale key used by default in the footer if none is specified by Mailable::setupUnsubscribeFooter()
|
|
protected string $defaultUnsubscribeLocaleKey = 'emails.footer.unsubscribe';
|
|
|
|
/**
|
|
* @var string[] template variables required for the unsubscribe footer
|
|
*/
|
|
protected static array $requiredVariables = [PKPContextEmailVariable::class];
|
|
|
|
abstract public function addData(array $data): Mailable;
|
|
abstract public function getVariables(): array;
|
|
|
|
/**
|
|
* Use this public method to set footer for this email
|
|
*/
|
|
public function allowUnsubscribe(Notification $notification): self
|
|
{
|
|
$this->notification = $notification;
|
|
|
|
if (!$this->hasRequiredVariables()) {
|
|
throw new Exception(
|
|
'Mailable should include the following template variables: ' .
|
|
implode(',', static::getRequiredVariables())
|
|
);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Setup footer with unsubscribe link if notification is deliberately set with self::allowUnsubscribe()
|
|
*
|
|
* @param null|mixed $localeKey
|
|
*/
|
|
protected function setupUnsubscribeFooter(string $locale, $context, $localeKey = null): void
|
|
{
|
|
if (!isset($this->notification)) {
|
|
return;
|
|
}
|
|
|
|
$this->footer = $this->renameContextVariables($this->setFooterText($locale, $localeKey));
|
|
|
|
$notificationManager = new NotificationManager(); /** @var NotificationManager $notificationManager */
|
|
$request = Application::get()->getRequest();
|
|
$this->addData([
|
|
self::$unsubscribeUrl => $notificationManager->getUnsubscribeNotificationUrl(
|
|
$request,
|
|
$this->notification,
|
|
$context
|
|
),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Adds unsubscribe headers, see pkp/pkp-lib#6627
|
|
*/
|
|
public function headers(): Headers
|
|
{
|
|
$unsubscribeUrl = $this->viewData[self::$unsubscribeUrl] ?? null;
|
|
return new Headers(
|
|
null,
|
|
[],
|
|
$unsubscribeUrl ? [
|
|
'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
|
|
'List-Unsubscribe' => '<' . $unsubscribeUrl . '>',
|
|
] : []
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return bool whether mailable contains variables requires for the footer
|
|
*/
|
|
protected function hasRequiredVariables(): bool
|
|
{
|
|
$included = [];
|
|
$requiredVariables = static::getRequiredVariables();
|
|
foreach ($requiredVariables as $requiredVariable) {
|
|
foreach ($this->getVariables() as $variable) {
|
|
if (is_a($variable, $requiredVariable, true)) {
|
|
$included[] = $requiredVariable;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return count($included) === count($requiredVariables);
|
|
}
|
|
|
|
/**
|
|
* Replace email template variables in the locale string, so they correspond to the application,
|
|
* e.g., contextName => journalName/pressName/serverName
|
|
*/
|
|
protected function renameContextVariables(string $footer): string
|
|
{
|
|
$map = [
|
|
'{$' . PKPContextEmailVariable::CONTEXT_NAME . '}' => '{$' . ContextEmailVariable::CONTEXT_NAME . '}',
|
|
'{$' . PKPContextEmailVariable::CONTEXT_URL . '}' => '{$' . ContextEmailVariable::CONTEXT_URL . '}',
|
|
'{$' . PKPContextEmailVariable::CONTEXT_SIGNATURE . '}' => '{$' . ContextEmailVariable::CONTEXT_SIGNATURE . '}',
|
|
];
|
|
|
|
return str_replace(array_keys($map), array_values($map), $footer);
|
|
}
|
|
|
|
/**
|
|
* Set the message to be displayed in the footer
|
|
*/
|
|
protected function setFooterText(string $locale, string $localeKey = null): string
|
|
{
|
|
if (is_null($localeKey)) {
|
|
$localeKey = $this->defaultUnsubscribeLocaleKey;
|
|
}
|
|
|
|
return __($localeKey, [], $locale);
|
|
}
|
|
|
|
protected static function getRequiredVariables(): array
|
|
{
|
|
return static::$requiredVariables;
|
|
}
|
|
}
|