Skip to content

Commit

Permalink
[!!!][FEATURE] Flash message view helper add deferred rendering
Browse files Browse the repository at this point in the history
Deprecate renderMode in favor of a flexible deferred
rendering of flash messages in the Fluid template.

This means that flash messages should no longer contain HTML tags
but only plain text, if rendered by the default rendering.

The rendered output will by default now be a <ul> list.
The usage of renderMode in the Core is removed and styles are
adapted to match the previous output.

The core is adapted to now use htmlspecialchars in a controller context
for user input. Encoding is now taken care of during rendering of
the Fluid template.

Resolves: #63453
Releases: master
Change-Id: Ie02d2e1441ca2b3c7c159ffa917f7040f50327b5
Reviewed-on: http://review.typo3.org/34818
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
  • Loading branch information
helhum authored and maddy2101 committed Jun 3, 2015
1 parent d06dc87 commit 70a7ed3
Show file tree
Hide file tree
Showing 35 changed files with 301 additions and 127 deletions.
Expand Up @@ -120,8 +120,8 @@ public function indexAction() {
if ($this->getBackendUser()->workspace != 0) {
// Adding section with the permission setting matrix:
$this->addFlashMessage(
LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText', 'beuser'),
LocalizationUtility::translate('LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning', 'beuser'),
'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarningText',
'LLL:EXT:beuser/Resources/Private/Language/locallang_mod_permission.xlf:WorkspaceWarning',
FlashMessage::WARNING
);
}
Expand Down
2 changes: 1 addition & 1 deletion typo3/sysext/beuser/Resources/Private/Layouts/Default.html
Expand Up @@ -26,7 +26,7 @@
<div id="typo3-inner-docbody">
<f:render section="headline" />

<f:flashMessages renderMode="div" />
<f:flashMessages />

<f:render section="content" />
</div>
Expand Down
11 changes: 10 additions & 1 deletion typo3/sysext/beuser/Resources/Private/Layouts/Permission.html
Expand Up @@ -23,7 +23,16 @@
<div id="typo3-inner-docbody">
<f:render section="headline" />

<f:flashMessages renderMode="div" />
<f:flashMessages as="flashMessages">
<ul class="typo3-flashMessages">
<f:for each="{flashMessages}" as="flashMessage">
<li class="alert {flashMessage.class}">
<h4><f:translate id="{flashMessage.title}" extensionName="beuser" /></h4>
<f:translate id="{flashMessage.message}" extensionName="beuser" />
</li>
</f:for>
</ul>
</f:flashMessages>

<f:render section="content" />
</div>
Expand Down
@@ -0,0 +1,40 @@
===============================================================
Breaking: #63453 - Changed rendering of FlashMessagesViewHelper
===============================================================

Description
===========

The default (``renderMode="ul"``) rendering output of the ``FlashMessagesViewHelper`` has been changed.

By default the view helper rendered an unordered list, each list item containing one message.
This output has been adjusted and more markup is added.


Impact
======

You may see unexpected formatting of flash messages.


Affected Installations
======================

Any template using the ``FlashMessagesViewHelper`` unless the attribute ``renderMode`` is set to "div".
Be aware, though, that the ``renderMode`` attribute is deprecated.


Migration
=========

Add a custom rendering template for the flash messages, like outlined in the example, to obtain the same output as before.

.. code-block:: html

<f:flashMessages as="flashMessages">
<ul class="myFlashMessages">
<f:for each="{flashMessages}" as="flashMessage">
<li>{flashMessage.message}</li>
</f:for>
</ul>
</f:flashMessages>
@@ -0,0 +1,40 @@
===============================================================================
Deprecation: #63453 - Deprecate renderMode attribute of FlashMessagesViewHelper
===============================================================================

Description
===========

Deprecated renderMode in favor of a flexible deferred rendering of flash messages in the Fluid template.
This means that flash messages should no longer contain HTML, but the HTML output can and should be adjusted in the Fluid template.


Impact
======

Using renderMode on FlashMessage output will throw a deprecation warning.


Affected Installations
======================

All instances using the renderMode attribute in FlashMessage output.


Migration
=========

Adjust flash messages to contain only plain text and remove the renderMode attribute in the output Templates.

.. code-block:: html

<f:flashMessages as="flashMessages">
<ul class="typo3-flashMessages">
<f:for each="{flashMessages}" as="flashMessage">
<li class="alert {flashMessage.class}">
<h4>{flashMessage.title}</h4>
{flashMessage.message}
</li>
</f:for>
</ul>
</f:flashMessages>
@@ -0,0 +1,27 @@
==============================================================
Feature: #63453 - Template support for FlashMessagesViewHelper
==============================================================

Description
===========

Template support for ``FlashMessagesViewHelper`` has been added.
This allows to define a custom rendering for flash messages.

The new attribute ``as`` for the ``FlashMessagesViewHelper`` allows to specify a variable name,
which can be used within the view helper's child elements to access the flash messages.

Example usage:

.. code-block:: html

<f:flashMessages as="flashMessages">
<ul class="myFlashMessages">
<f:for each="{flashMessages}" as="flashMessage">
<li class="alert {flashMessage.class}">
<h4>{flashMessage.title}</h4>
<span class="fancy-icon">{flashMessage.message}</span>
</li>
</f:for>
</ul>
</f:flashMessages>
Expand Up @@ -15,7 +15,7 @@
<f:section name="main">
<h1>Edit Content</h1>

<f:flashMessages renderMode="div" />
<f:flashMessages />

<f:render partial="FormErrors" arguments="{object:Content}" />

Expand Down
Expand Up @@ -15,7 +15,7 @@
<f:section name="main">
<h1>Listing for Content</h1>

<f:flashMessages renderMode="div" />
<f:flashMessages />

<table class="tx_irretutorial" >
<tr>
Expand Down
Expand Up @@ -15,7 +15,7 @@
<f:section name="main">
<h1>New Content</h1>

<f:flashMessages renderMode="div" />
<f:flashMessages />

<f:render partial="FormErrors" arguments="{object:Content}" />

Expand Down
Expand Up @@ -16,7 +16,7 @@
<h1>Single View for Content</h1>
<f:debug>{content}</f:debug>

<f:flashMessages renderMode="div" />
<f:flashMessages />
<f:render partial="Content/Properties" arguments="{content:content}" />
<f:link.action action="list">Back to list</f:link.action><br />
<f:link.action action="new">New Content</f:link.action>
Expand Down
Expand Up @@ -149,23 +149,17 @@ public function fetchAction($url, $key, $version = NULL) {
$language = $this->languageUtility->getDocumentationLanguage();
try {
$result = $this->documentationService->fetchNearestDocument($url, $key, $version ?: 'latest', $language);

if ($result) {
/** @var FlashMessage $message */
$message = GeneralUtility::makeInstance(
FlashMessage::class,
$this->addFlashMessage(
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
'downloadSucceeded',
'documentation'
),
'',
\TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
TRUE
FlashMessage::OK
);
} else {
/** @var FlashMessage $message */
$message = GeneralUtility::makeInstance(
FlashMessage::class,
$this->addFlashMessage(
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
'downloadFailedNoArchive',
'documentation'
Expand All @@ -174,16 +168,11 @@ public function fetchAction($url, $key, $version = NULL) {
'downloadFailed',
'documentation'
),
FlashMessage::ERROR,
TRUE
FlashMessage::ERROR
);

}
$this->controllerContext->getFlashMessageQueue()->enqueue($message);
} catch (\Exception $e) {
/** @var FlashMessage $message */
$message = GeneralUtility::makeInstance(
FlashMessage::class,
$this->addFlashMessage(
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate(
'downloadFailedDetails',
'documentation',
Expand All @@ -197,10 +186,8 @@ public function fetchAction($url, $key, $version = NULL) {
'downloadFailed',
'documentation'
),
FlashMessage::ERROR,
TRUE
FlashMessage::ERROR
);
$this->controllerContext->getFlashMessageQueue()->enqueue($message);
}
$this->redirect('download');
}
Expand Down
Expand Up @@ -19,7 +19,7 @@
<div id="typo3-docbody">
<div id="typo3-inner-docbody" class="typo3-documentation">
<f:render section="module-headline" />
<f:flashMessages renderMode="div" />
<f:flashMessages />
<f:render section="Content" />
</div>
</div>
Expand Down
Expand Up @@ -67,9 +67,9 @@ protected function toggleExtensionInstallationStateAction($extensionKey) {
}
}
} catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
$this->addFlashMessage(htmlspecialchars($e->getMessage()), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
$this->addFlashMessage($e->getMessage(), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
} catch (\TYPO3\CMS\Core\Package\Exception\PackageStatesFileNotWritableException $e) {
$this->addFlashMessage(htmlspecialchars($e->getMessage()), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
$this->addFlashMessage($e->getMessage(), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
}
$this->redirect('index', 'List', NULL, array(self::TRIGGER_RefreshModuleMenu => TRUE));
}
Expand Down Expand Up @@ -104,7 +104,7 @@ protected function removeExtensionAction($extension) {
)
);
} catch (\TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException $e) {
$this->addFlashMessage(htmlspecialchars($e->getMessage()), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
$this->addFlashMessage($e->getMessage(), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR);
}

return '';
Expand Down
Expand Up @@ -168,7 +168,7 @@ public function installDistributionAction(\TYPO3\CMS\Extensionmanager\Domain\Mod
// FlashMessage that extension is installed
$this->addFlashMessage(
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('distribution.welcome.message', 'extensionmanager')
. ' <strong>' . $extension->getExtensionKey() . '</strong>',
. $extension->getExtensionKey(),
\TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate('distribution.welcome.headline', 'extensionmanager')
);

Expand Down Expand Up @@ -206,11 +206,11 @@ protected function updateExtensionAction() {
$this->managementService->downloadMainExtension($extension);
}
$this->addFlashMessage(
htmlspecialchars($this->translate('extensionList.updateFlashMessage.body', array($extensionKey))),
$this->translate('extensionList.updateFlashMessage.body', array($extensionKey)),
$this->translate('extensionList.updateFlashMessage.title')
);
} catch (\Exception $e) {
$this->addFlashMessage(htmlspecialchars($e->getMessage()), '', FlashMessage::ERROR);
$this->addFlashMessage($e->getMessage(), '', FlashMessage::ERROR);
}

return '';
Expand Down
Expand Up @@ -132,7 +132,7 @@ public function distributionsAction() {
$repositoryHelper->updateExtList();
}
} catch (ExtensionManagerException $e) {
$this->addFlashMessage(htmlspecialchars($e->getMessage()), $e->getCode(), FlashMessage::ERROR);
$this->addFlashMessage($e->getMessage(), $e->getCode(), FlashMessage::ERROR);
}

$officialDistributions = $this->extensionRepository->findAllOfficialDistributions();
Expand Down
Expand Up @@ -100,14 +100,14 @@ public function extractAction($overwrite = FALSE) {
$emConfiguration = $this->configurationUtility->getCurrentConfiguration('extensionmanager');
if (!$emConfiguration['automaticInstallation']['value']) {
$this->addFlashMessage(
htmlspecialchars($this->translate('extensionList.uploadFlashMessage.message', array($extensionData['extKey']))),
htmlspecialchars($this->translate('extensionList.uploadFlashMessage.title')),
$this->translate('extensionList.uploadFlashMessage.message', array($extensionData['extKey'])),
$this->translate('extensionList.uploadFlashMessage.title'),
FlashMessage::OK
);
} else {
if ($this->activateExtension($extensionData['extKey'])) {
$this->addFlashMessage(
htmlspecialchars($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey']))),
$this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey'])),
'',
FlashMessage::OK
);
Expand All @@ -119,7 +119,7 @@ public function extractAction($overwrite = FALSE) {
throw $exception;
} catch (\Exception $exception) {
$this->removeExtensionAndRestoreFromBackup($fileName);
$this->addFlashMessage(htmlspecialchars($exception->getMessage()), '', FlashMessage::ERROR);
$this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR);
}
$this->redirect('index', 'List', NULL, array(self::TRIGGER_RefreshModuleMenu => TRUE));
}
Expand Down
Expand Up @@ -67,7 +67,7 @@ public function download(\TYPO3\CMS\Extensionmanager\Domain\Model\Extension $ext
*/
public function setDownloadPath($downloadPath) {
if (!in_array($downloadPath, \TYPO3\CMS\Extensionmanager\Domain\Model\Extension::returnAllowedInstallTypes())) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(htmlspecialchars($downloadPath) . ' not in allowed download paths', 1344766387);
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException($downloadPath . ' not in allowed download paths', 1344766387);
}
$this->downloadPath = $downloadPath;
}
Expand Down
Expand Up @@ -58,7 +58,7 @@ public function parseXml($file) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to create XML parser.', 1342640540);
}
if ($this->objXml->open($file, 'utf-8') === FALSE) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', htmlspecialchars($file)));
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', $file));
}
while ($this->objXml->read()) {
if ($this->objXml->nodeType == \XMLReader::ELEMENT) {
Expand Down
Expand Up @@ -76,11 +76,11 @@ public function parseXml($file) {
xml_set_element_handler($this->objXml, 'startElement', 'endElement');
xml_set_character_data_handler($this->objXml, 'characterData');
if (!($fp = fopen($file, 'r'))) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', htmlspecialchars($file)), 1342640689);
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', $file), 1342640689);
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($this->objXml, $data, feof($fp))) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), htmlspecialchars($file)), 1342640703);
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), $file), 1342640703);
}
}
xml_parser_free($this->objXml);
Expand Down
Expand Up @@ -57,7 +57,7 @@ public function parseXml($file) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException('Unable to create XML parser.', 1342640820);
}
if ($this->objXml->open($file, 'utf-8') === FALSE) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', htmlspecialchars($file)), 1342640893);
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', $file), 1342640893);
}
while ($this->objXml->read()) {
if ($this->objXml->nodeType == \XMLReader::ELEMENT) {
Expand Down
Expand Up @@ -71,11 +71,11 @@ public function parseXml($file) {
xml_set_element_handler($this->objXml, 'startElement', 'endElement');
xml_set_character_data_handler($this->objXml, 'characterData');
if (!($fp = fopen($file, 'r'))) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', htmlspecialchars($file)), 1342641010);
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('Unable to open file resource %s.', $file), 1342641010);
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($this->objXml, $data, feof($fp))) {
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), htmlspecialchars($file)), 1342641011);
throw new \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException(sprintf('XML error %s in line %u of file resource %s.', xml_error_string(xml_get_error_code($this->objXml)), xml_get_current_line_number($this->objXml), $file), 1342641011);
}
}
xml_parser_free($this->objXml);
Expand Down
Expand Up @@ -139,10 +139,10 @@ protected function fetchFile($remoteResource, $localResource) {
$fileContent = \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($remoteResource, 0, array(TYPO3_user_agent));
if ($fileContent !== FALSE) {
if (\TYPO3\CMS\Core\Utility\GeneralUtility::writeFile($localResource, $fileContent) === FALSE) {
throw new ExtensionManagerException(sprintf('Could not write to file %s.', htmlspecialchars($localResource)), 1342635378);
throw new ExtensionManagerException(sprintf('Could not write to file %s.', $localResource), 1342635378);
}
} else {
throw new ExtensionManagerException(sprintf('Could not access remote resource %s.', htmlspecialchars($remoteResource)), 1342635425);
throw new ExtensionManagerException(sprintf('Could not access remote resource %s.', $remoteResource), 1342635425);
}
}
}
Expand Down

0 comments on commit 70a7ed3

Please sign in to comment.