‪TYPO3CMS  10.4
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;
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);
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 "' . $recipientData['email'] . '" due to mailer settings error', [
122  'recipientList' => array_column($recipients, 'email'),
123  'exception' => $e
124  ]);
125  // At this point we break since the next attempts will also fail due to the invalid mailer settings
126  break;
127  } catch (RfcComplianceException $e) {
128  $this->logger->warning('Could not send notification email to "' . $recipientData['email'] . '" due to invalid email address', [
129  'recipientList' => [$recipientData['email']],
130  'exception' => $e
131  ]);
132  }
133  }
134  }
135 
144  protected function ‪findFirstPageId(string $elementTable, int $elementUid, array $elementRecord): int
145  {
146  if ($elementTable === 'pages') {
147  return $elementUid;
148  }
149  ‪BackendUtility::fixVersioningPid($elementTable, $elementRecord);
150  return (int)$elementRecord['pid'];
151  }
152 
160  protected function ‪sendEmail(array $recipientData, array $emailConfig, array $variablesForView): void
161  {
162  $templatePaths = new ‪TemplatePaths(array_replace_recursive(‪$GLOBALS['TYPO3_CONF_VARS']['MAIL'], $emailConfig));
163  $emailObject = GeneralUtility::makeInstance(FluidEmail::class, $templatePaths);
164  $emailObject
165  ->to(new Address($recipientData['email'], $recipientData['realName'] ?? ''))
166  // Will be overridden by the template
167  ->subject('TYPO3 Workspaces: Stage Change')
168  ->setTemplate('StageChangeNotification')
169  ->assignMultiple($variablesForView)
170  ->assign('language', $recipientData['lang'] ?? 'default');
171 
172  // Injecting normalized params
173  if (‪$GLOBALS['TYPO3_REQUEST'] instanceof ServerRequestInterface) {
174  $emailObject->setRequest(‪$GLOBALS['TYPO3_REQUEST']);
175  }
176  if ($emailConfig['format']) {
177  $emailObject->format($emailConfig['format']);
178  }
179  if (!empty($emailConfig['senderEmail']) && GeneralUtility::validEmail($emailConfig['senderEmail'])) {
180  $emailObject->from(new Address($emailConfig['senderEmail'], $emailConfig['senderName'] ?? ''));
181  }
182  $this->mailer->send($emailObject);
183  }
184 }
‪TYPO3\CMS\Workspaces\Notification
Definition: StageChangeNotification.php:18
‪TYPO3\CMS\Fluid\View\TemplatePaths
Definition: TemplatePaths.php:35
‪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:141
‪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:157
‪TYPO3\CMS\Workspaces\Notification\StageChangeNotification
Definition: StageChangeNotification.php:44
‪TYPO3\CMS\Backend\Utility\BackendUtility\fixVersioningPid
‪static fixVersioningPid($table, &$rr, $ignoreWorkspaceMatch=false)
Definition: BackendUtility.php:3511
‪TYPO3\CMS\Core\Mail\FluidEmail
Definition: FluidEmail.php:35
‪TYPO3\CMS\Workspaces\Preview\PreviewUriBuilder
Definition: PreviewUriBuilder.php:43
‪TYPO3\CMS\Backend\Utility\BackendUtility\getPagesTSconfig
‪static array getPagesTSconfig($id)
Definition: BackendUtility.php:698
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordTitle
‪static string getRecordTitle($table, $row, $prep=false, $forceResult=true)
Definition: BackendUtility.php:1541
‪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\Backend\Utility\BackendUtility
Definition: BackendUtility.php:75
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecord
‪static array null getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
Definition: BackendUtility.php:95
‪TYPO3\CMS\Workspaces\Service\StagesService
Definition: StagesService.php:33
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Backend\Utility\BackendUtility\getRecordPath
‪static mixed getRecordPath($uid, $clause, $titleLimit, $fullTitleLimit=0)
Definition: BackendUtility.php:546