From a4d3d53036d4a953197034b4da46ce9e7bf772b5 Mon Sep 17 00:00:00 2001 From: Andreas Fernandez <a.fernandez@scripting-base.de> Date: Wed, 6 Apr 2022 11:30:23 +0200 Subject: [PATCH] [TASK] Render notification when saving a record succeeded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To improve both, UX and acceptance tests (incl. automated screenshots for docs), a notification is now dispatched when records were saved via EditDocumentController. Resolves: #95271 Releases: main Change-Id: I98b43bb9ecf643d634740ffc4241943a49a5a87f Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/74196 Tested-by: core-ci <typo3@b13.com> Tested-by: Björn Jacob <bjoern.jacob@tritum.de> Tested-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Björn Jacob <bjoern.jacob@tritum.de> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- .../Controller/EditDocumentController.php | 40 ++++++++++++++++++- .../Private/Language/locallang_alt_doc.xlf | 9 +++++ .../core/Classes/DataHandling/DataHandler.php | 12 +++++- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/typo3/sysext/backend/Classes/Controller/EditDocumentController.php b/typo3/sysext/backend/Classes/Controller/EditDocumentController.php index 876085349d0d..c9fb98c5012e 100644 --- a/typo3/sysext/backend/Classes/Controller/EditDocumentController.php +++ b/typo3/sysext/backend/Classes/Controller/EditDocumentController.php @@ -50,6 +50,9 @@ use TYPO3\CMS\Core\Imaging\Icon; use TYPO3\CMS\Core\Imaging\IconFactory; use TYPO3\CMS\Core\Localization\LanguageService; use TYPO3\CMS\Core\Messaging\AbstractMessage; +use TYPO3\CMS\Core\Messaging\FlashMessage; +use TYPO3\CMS\Core\Messaging\FlashMessageQueue; +use TYPO3\CMS\Core\Messaging\FlashMessageService; use TYPO3\CMS\Core\Page\PageRenderer; use TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException; use TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException; @@ -636,6 +639,42 @@ class EditDocumentController // Recompile the store* values since editconf changed... $this->compileStoreData($request); } + + // Explicitly require a save operation + if ($this->doSave) { + $erroneousRecords = $tce->printLogErrorMessages(); + $messages = []; + $table = (string)key($this->editconf); + $uidList = GeneralUtility::intExplode(',', (string)key($this->editconf[$table])); + + foreach ($uidList as $uid) { + $uid = (int)abs($uid); + if (!in_array($table . '.' . $uid, $erroneousRecords, true)) { + $realUidInPayload = ($tceSubstId = array_search($uid, $tce->substNEWwithIDs, true)) !== false ? $tceSubstId : $uid; + $row = $this->data[$table][$uid] ?? $this->data[$table][$realUidInPayload] ?? null; + if ($row !== null) { + $recordTitle = GeneralUtility::fixed_lgd_cs(BackendUtility::getRecordTitle($table, $row), $this->getBackendUser()->uc['titleLen']); + $messages[] = sprintf($this->getLanguageService()->getLL('notification.record_saved.message'), $recordTitle); + } + } + } + + // Add messages to the flash message container only if the request is a save action (excludes "duplicate") + if ($messages !== []) { + $title = count($messages) === 1 ? 'notification.record_saved.title.singular' : 'notification.record_saved.title.plural'; + $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class); + $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier(FlashMessageQueue::NOTIFICATION_QUEUE); + $flashMessage = GeneralUtility::makeInstance( + FlashMessage::class, + implode(LF, $messages), + $this->getLanguageService()->getLL($title), + AbstractMessage::OK, + true + ); + $defaultFlashMessageQueue->enqueue($flashMessage); + } + } + // If a document should be duplicated. if (isset($parsedBody['_duplicatedoc']) && is_array($this->editconf)) { $this->closeDocument(self::DOCUMENT_CLOSE_MODE_NO_REDIRECT, $request); @@ -693,7 +732,6 @@ class EditDocumentController // Inform the user of the duplication $view->addFlashMessage($this->getLanguageService()->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.recordDuplicated')); } - $tce->printLogErrorMessages(); if ($this->closeDoc < self::DOCUMENT_CLOSE_MODE_DEFAULT || isset($parsedBody['_saveandclosedok']) diff --git a/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf b/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf index 39115e454701..767025a2cfe6 100644 --- a/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf +++ b/typo3/sysext/backend/Resources/Private/Language/locallang_alt_doc.xlf @@ -144,6 +144,15 @@ <trans-unit id="buttons.pageTsConfig" resname="buttons.pageTsConfig"> <source>PageTS Config</source> </trans-unit> + <trans-unit id="notification.record_saved.title.singular" resname="notification.record_saved.title.singular"> + <source>Record saved</source> + </trans-unit> + <trans-unit id="notification.record_saved.title.plural" resname="notification.record_saved.title.plural"> + <source>Records saved</source> + </trans-unit> + <trans-unit id="notification.record_saved.message" resname="notification.record_saved.message"> + <source>Record "%s" has been successfully saved.</source> + </trans-unit> </body> </file> </xliff> diff --git a/typo3/sysext/core/Classes/DataHandling/DataHandler.php b/typo3/sysext/core/Classes/DataHandling/DataHandler.php index 4ec85c1ede9f..fa05d4eb079b 100644 --- a/typo3/sysext/core/Classes/DataHandling/DataHandler.php +++ b/typo3/sysext/core/Classes/DataHandling/DataHandler.php @@ -9181,10 +9181,13 @@ class DataHandler implements LoggerAwareInterface } /** - * Print log error messages from the operations of this script instance + * Print log error messages from the operations of this script instance and return a list of the erroneous records + * * @internal should only be used from within TYPO3 Core + * + * @return non-empty-string[] */ - public function printLogErrorMessages() + public function printLogErrorMessages(): array { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_log'); $queryBuilder->getRestrictions()->removeAll(); @@ -9205,7 +9208,10 @@ class DataHandler implements LoggerAwareInterface ) ->executeQuery(); + $affectedRecords = []; while ($row = $result->fetchAssociative()) { + $affectedRecords[] = $row['tablename'] . '.' . $row['recuid']; + $msg = $this->formatLogDetails($row['details'], $row['log_data'] ?? ''); $msg = $row['error'] . ': ' . $msg; $flashMessage = GeneralUtility::makeInstance(FlashMessage::class, $msg, '', $row['error'] === SystemLogErrorClassification::WARNING ? FlashMessage::WARNING : FlashMessage::ERROR, true); @@ -9213,6 +9219,8 @@ class DataHandler implements LoggerAwareInterface $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier(); $defaultFlashMessageQueue->enqueue($flashMessage); } + + return $affectedRecords; } /***************************** -- GitLab