‪TYPO3CMS  11.5
StageChangeNotification.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
21 use Psr\Log\LoggerAwareInterface;
22 use Psr\Log\LoggerAwareTrait;
23 use Symfony\Component\Mailer\Exception\TransportException;
24 use Symfony\Component\Mime\Address;
25 use Symfony\Component\Mime\Exception\RfcComplianceException;
26 use TYPO3\CMS\Backend\Utility\BackendUtility;
35 
43 class ‪StageChangeNotification implements LoggerAwareInterface
44 {
45  use LoggerAwareTrait;
46 
50  protected ‪$stagesService;
51 
55  protected ‪$previewUriBuilder;
56 
60  protected ‪$mailer;
61 
62  public function ‪__construct()
63  {
64  $this->stagesService = GeneralUtility::makeInstance(StagesService::class);
65  $this->previewUriBuilder = GeneralUtility::makeInstance(PreviewUriBuilder::class);
66  $this->mailer = GeneralUtility::makeInstance(Mailer::class);
67  }
68 
80  public function ‪notifyStageChange(array $workspaceRecord, int $stageId, array $affectedElements, string $comment, array $recipients, ‪BackendUserAuthentication $currentUser): void
81  {
82  [$elementTable, $elementUid] = reset($affectedElements);
83  $elementUid = (int)$elementUid;
84  $elementRecord = (array)BackendUtility::getRecord($elementTable, $elementUid, '*', '', false);
85  $recordTitle = BackendUtility::getRecordTitle($elementTable, $elementRecord);
86  $pageUid = $this->‪findFirstPageId($elementTable, $elementUid, $elementRecord);
87  $emailConfig = BackendUtility::getPagesTSconfig($pageUid)['tx_workspaces.']['emails.'] ?? [];
88  $emailConfig = GeneralUtility::removeDotsFromTS($emailConfig);
89 
90  $previewLink = '';
91  try {
92  $languageId = $elementRecord[‪$GLOBALS['TCA'][$elementTable]['ctrl']['languageField'] ?? ''] ?? 0;
93  $previewLink = $this->previewUriBuilder->buildUriForPage($pageUid, $languageId);
94  } catch (‪UnableToLinkToPageException $e) {
95  // Generating a preview for a page that is is a delete placeholder
96  // in workspaces fails. No preview link in this case.
97  }
98 
99  $viewPlaceholders = [
100  'pageId' => $pageUid,
101  'workspace' => $workspaceRecord,
102  'rootLine' => BackendUtility::getRecordPath($pageUid, '', 20),
103  'currentUser' => $currentUser->user,
104  'additionalMessage' => $comment,
105  'recordTitle' => $recordTitle,
106  'affectedElements' => $affectedElements,
107  'nextStage' => $this->stagesService->getStageTitle($stageId),
108  'previewLink' => $previewLink,
109  ];
110 
111  $sentEmails = [];
112  foreach ($recipients as $recipientData) {
113  // don't send an email twice
114  if (in_array($recipientData['email'], $sentEmails, true)) {
115  continue;
116  }
117  $sentEmails[] = $recipientData['email'];
118  try {
119  $this->‪sendEmail($recipientData, $emailConfig, $viewPlaceholders);
120  } catch (TransportException $e) {
121  $this->logger->warning('Could not send notification email to "{recipient}" due to mailer settings error', [
122  'recipient' => $recipientData['email'],
123  'recipientList' => array_column($recipients, 'email'),
124  'exception' => $e,
125  ]);
126  // At this point we break since the next attempts will also fail due to the invalid mailer settings
127  break;
128  } catch (RfcComplianceException $e) {
129  $this->logger->warning('Could not send notification email to "{recipient}" due to invalid email address', [
130  'recipient' => $recipientData['email'],
131  'exception' => $e,
132  ]);
133  }
134  }
135  }
136 
145  protected function ‪findFirstPageId(string $elementTable, int $elementUid, array $elementRecord): int
146  {
147  if ($elementTable === 'pages') {
148  return $elementUid;
149  }
150  $pageId = $elementRecord['pid'];
151  BackendUtility::workspaceOL($elementTable, $elementRecord);
152  return (int)($elementRecord['pid'] ?? $pageId);
153  }
154 
162  protected function ‪sendEmail(array $recipientData, array $emailConfig, array $variablesForView): void
163  {
164  $templatePaths = new ‪TemplatePaths(array_replace_recursive(‪$GLOBALS['TYPO3_CONF_VARS']['MAIL'], $emailConfig));
165  $emailObject = GeneralUtility::makeInstance(FluidEmail::class, $templatePaths);
166  $emailObject
167  ->to(new Address($recipientData['email'], $recipientData['realName'] ?? ''))
168  // Will be overridden by the template
169  ->subject('TYPO3 Workspaces: Stage Change')
170  ->setTemplate('StageChangeNotification')
171  ->assignMultiple($variablesForView)
172  ->assign('language', $recipientData['lang'] ?? 'default');
173 
174  // Injecting normalized params
175  if (‪$GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) {
176  $emailObject->setRequest(‪$GLOBALS['TYPO3_REQUEST']);
177  }
178  if ($emailConfig['format']) {
179  $emailObject->format($emailConfig['format']);
180  }
181  if (!empty($emailConfig['senderEmail']) && GeneralUtility::validEmail($emailConfig['senderEmail'])) {
182  $emailObject->from(new Address($emailConfig['senderEmail'], $emailConfig['senderName'] ?? ''));
183  }
184  $this->mailer->send($emailObject);
185  }
186 }
‪TYPO3\CMS\Workspaces\Notification
Definition: StageChangeNotification.php:18
‪TYPO3\CMS\Fluid\View\TemplatePaths
Definition: TemplatePaths.php:37
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\$mailer
‪Mailer $mailer
Definition: StageChangeNotification.php:57
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\findFirstPageId
‪int findFirstPageId(string $elementTable, int $elementUid, array $elementRecord)
Definition: StageChangeNotification.php:142
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\$previewUriBuilder
‪PreviewUriBuilder $previewUriBuilder
Definition: StageChangeNotification.php:53
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\$stagesService
‪StagesService $stagesService
Definition: StageChangeNotification.php:49
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\notifyStageChange
‪notifyStageChange(array $workspaceRecord, int $stageId, array $affectedElements, string $comment, array $recipients, BackendUserAuthentication $currentUser)
Definition: StageChangeNotification.php:77
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\sendEmail
‪sendEmail(array $recipientData, array $emailConfig, array $variablesForView)
Definition: StageChangeNotification.php:159
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification
Definition: StageChangeNotification.php:44
‪TYPO3\CMS\Core\Mail\FluidEmail
Definition: FluidEmail.php:35
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder
Definition: PreviewUriBuilder.php:46
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification\__construct
‪__construct()
Definition: StageChangeNotification.php:59
‪TYPO3\CMS\Core\Mail\Mailer
Definition: Mailer.php:38
‪TYPO3\CMS\Workspaces\Service\StagesService
Definition: StagesService.php:32
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50