[!!!][TASK] Remove CSS/JS inclusion via PHP in TSFE 60/64660/6
authorBenni Mack <benni@typo3.org>
Wed, 3 Jun 2020 10:19:08 +0000 (12:19 +0200)
committerBenni Mack <benni@typo3.org>
Fri, 5 Jun 2020 16:03:52 +0000 (18:03 +0200)
TypoScriptFrontendController has had functionality to dynamically
load JavaScript and CSS code, also in non-cacheable (USER_INT) content.

This has been largely superseded via the AssetCollector API and
PageRenderer API which is built in a way to deal with non-cacheable
and cacheable content with proper method calls.

For this reason, the legacy functionality is removed:
* TSFE->setJS (used via TSFE->setJS('openpic') in core)
* TSFE->additionalJavaScript
* TSFE->additionalCSS
* TSFE->JSCode
* TSFE->inlineJS

Although all methods and properties have been marked as internal
in TYPO3 v10, a Breaking RST is still added.

Resolves: #91563
Releases: master
Change-Id: I167dae29e3daa5e1d5ad4c6848dcc49fbfec3183
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64660
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Benni Mack <benni@typo3.org>
typo3/sysext/core/Documentation/Changelog/master/Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst [new file with mode: 0644]
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Classes/ContentObject/Menu/AbstractMenuContentObject.php
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php
typo3/sysext/frontend/Classes/Http/RequestHandler.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/MethodCallMatcher.php
typo3/sysext/install/Configuration/ExtensionScanner/Php/PropertyPublicMatcher.php

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst
new file mode 100644 (file)
index 0000000..e838f5b
--- /dev/null
@@ -0,0 +1,40 @@
+.. include:: ../../Includes.txt
+
+=====================================================================
+Breaking: #91563 - PHP-based JS + CSS inclusions for Frontend removed
+=====================================================================
+
+See :issue:`91563`
+
+Description
+===========
+
+In the past, TYPO3's "TSFE" object allowed to manually add CSS or JavaScript snippets via PHP code via the following method and properties:
+
+* :php:`TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->setJS()`
+* :php:`TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->additionalJavaScript`
+* :php:`TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->additionalCSS`
+* :php:`TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->JSCode`
+* :php:`TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->inlineJS`
+
+These have been removed due to better APIs like PageRenderer (available since TYPO3 v4.5) and AssetCollector (TYPO3 v10).
+
+
+Impact
+======
+
+Accessing the method and properties will have no effect and trigger a PHP notice.
+
+
+Affected Installations
+======================
+
+TYPO3 installations with custom extensions using this functionality directly to inject custom CSS or JavaScript.
+
+
+Migration
+=========
+
+Use the AssetCollector API in PHP to add JavaScript and CSS code or use files directly.
+
+.. index:: PHP-API, FullyScanned, ext:frontend
index ea41cd1..42b44fb 100644 (file)
@@ -39,6 +39,7 @@ use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
 use TYPO3\CMS\Core\LinkHandling\Exception\UnknownLinkHandlerException;
 use TYPO3\CMS\Core\LinkHandling\LinkService;
 use TYPO3\CMS\Core\Log\LogManager;
+use TYPO3\CMS\Core\Page\AssetCollector;
 use TYPO3\CMS\Core\Resource\Exception;
 use TYPO3\CMS\Core\Resource\Exception\InvalidPathException;
 use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException;
@@ -1107,7 +1108,7 @@ class ContentObjectRenderer implements LoggerAwareInterface
                     . ($target !== '' ? ' target="' . htmlspecialchars($target) . '"' : '')
                     . $this->getTypoScriptFrontendController()->ATagParams . '>';
                 $a2 = '</a>';
-                $this->getTypoScriptFrontendController()->setJS('openPic');
+                GeneralUtility::makeInstance(AssetCollector::class)->addInlineJavaScript('openPic', 'function openPic(url, winName, winParams) { var theWindow = window.open(url, winName, winParams); if (theWindow) { theWindow.focus(); } }');
             } else {
                 $conf['linkParams.']['directImageLink'] = (bool)$conf['directImageLink'];
                 $conf['linkParams.']['parameter'] = $url;
index dbc3c89..56d0ef5 100644 (file)
@@ -22,6 +22,7 @@ use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\RelationHandler;
 use TYPO3\CMS\Core\Domain\Repository\PageRepository;
 use TYPO3\CMS\Core\Exception\SiteNotFoundException;
+use TYPO3\CMS\Core\Page\AssetCollector;
 use TYPO3\CMS\Core\Site\Entity\NullSite;
 use TYPO3\CMS\Core\Site\Entity\SiteInterface;
 use TYPO3\CMS\Core\Site\SiteFinder;
@@ -1414,7 +1415,7 @@ abstract class AbstractMenuContentObject
                 . GeneralUtility::quoteJSvalue($tsfe->baseUrlWrap($url)) . ','
                 . '\'' . ($conf['newWindow'] ? md5($url) : 'theNewPage') . '\','
                 . GeneralUtility::quoteJSvalue($conf['params']) . '); return false;';
-            $tsfe->setJS('openPic');
+            GeneralUtility::makeInstance(AssetCollector::class)->addInlineJavaScript('openPic', 'function openPic(url, winName, winParams) { var theWindow = window.open(url, winName, winParams); if (theWindow) { theWindow.focus(); } }');
         }
         // look for type and popup
         // following settings are valid in field target:
index 51f9ffa..fa710bf 100644 (file)
@@ -336,35 +336,6 @@ class TypoScriptFrontendController implements LoggerAwareInterface
     public $additionalFooterData = [];
 
     /**
-     * Used to accumulate additional JavaScript-code. Works like
-     * additionalHeaderData. Reserved keys at 'openPic' and 'mouseOver'
-     *
-     * @var array
-     * @internal only used by TYPO3 Core, use AssetCollector or PageRenderer to add JavaScript
-     */
-    public $additionalJavaScript = [];
-
-    /**
-     * Used to accumulate additional Style code. Works like additionalHeaderData.
-     *
-     * @var array
-     * @internal only used by TYPO3 Core, use AssetCollector or PageRenderer to add CSS
-     */
-    public $additionalCSS = [];
-
-    /**
-     * @var string
-     * @internal only used by TYPO3 Core, use AssetCollector or PageRenderer to add inline JavaScript
-     */
-    public $JSCode;
-
-    /**
-     * @var string
-     * @internal only used by TYPO3 Core, use AssetCollector or PageRenderer to add inline JavaScript
-     */
-    public $inlineJS;
-
-    /**
      * Default internal target
      * @var string
      */
@@ -2705,14 +2676,8 @@ class TypoScriptFrontendController implements LoggerAwareInterface
      */
     public function INTincScript()
     {
-        $this->additionalHeaderData = is_array($this->config['INTincScript_ext']['additionalHeaderData'] ?? false)
-            ? $this->config['INTincScript_ext']['additionalHeaderData']
-            : [];
-        $this->additionalFooterData = is_array($this->config['INTincScript_ext']['additionalFooterData'] ?? false)
-            ? $this->config['INTincScript_ext']['additionalFooterData']
-            : [];
-        $this->additionalJavaScript = $this->config['INTincScript_ext']['additionalJavaScript'] ?? null;
-        $this->additionalCSS = $this->config['INTincScript_ext']['additionalCSS'] ?? null;
+        $this->additionalHeaderData = $this->config['INTincScript_ext']['additionalHeaderData'] ?? [];
+        $this->additionalFooterData = $this->config['INTincScript_ext']['additionalFooterData'] ?? [];
         if (empty($this->config['INTincScript_ext']['pageRenderer'])) {
             $this->initPageRenderer();
         } else {
@@ -2830,51 +2795,16 @@ class TypoScriptFrontendController implements LoggerAwareInterface
     {
         // Prepare code and placeholders for additional header and footer files (and make sure that this isn't called twice)
         if ($this->isINTincScript() && !isset($this->config['INTincScript_ext'])) {
-            // Storing the JSCode vars...
-            $this->additionalHeaderData['JSCode'] = $this->JSCode;
-            $this->config['INTincScript_ext']['divKey'] = $this->uniqueHash();
+            $substituteHash = $this->uniqueHash();
+            $this->config['INTincScript_ext']['divKey'] = $substituteHash;
             // Storing the header-data array
             $this->config['INTincScript_ext']['additionalHeaderData'] = $this->additionalHeaderData;
             // Storing the footer-data array
             $this->config['INTincScript_ext']['additionalFooterData'] = $this->additionalFooterData;
-            // Storing the JS-data array
-            $this->config['INTincScript_ext']['additionalJavaScript'] = $this->additionalJavaScript;
-            // Storing the Style-data array
-            $this->config['INTincScript_ext']['additionalCSS'] = $this->additionalCSS;
             // Clearing the array
-            $this->additionalHeaderData = ['<!--HD_' . $this->config['INTincScript_ext']['divKey'] . '-->'];
+            $this->additionalHeaderData = ['<!--HD_' . $substituteHash . '-->'];
             // Clearing the array
-            $this->additionalFooterData = ['<!--FD_' . $this->config['INTincScript_ext']['divKey'] . '-->'];
-        } else {
-            // Add javascript in a "regular" fashion
-            $jsCode = trim($this->JSCode);
-            $additionalJavaScript = is_array($this->additionalJavaScript)
-                ? implode(LF, $this->additionalJavaScript)
-                : $this->additionalJavaScript;
-            $additionalJavaScript = trim($additionalJavaScript);
-            if ($jsCode !== '' || $additionalJavaScript !== '') {
-                $doctype = $this->config['config']['doctype'] ?? 'html5';
-                $scriptAttribute = $doctype === 'html5' ? '' : ' type="text/javascript"';
-
-                $this->additionalHeaderData['JSCode'] = '
-<script' . $scriptAttribute . '>
-       /*<![CDATA[*/
-<!--
-' . $additionalJavaScript . '
-' . $jsCode . '
-// -->
-       /*]]>*/
-</script>';
-            }
-            // Add CSS
-            $additionalCss = is_array($this->additionalCSS) ? implode(LF, $this->additionalCSS) : $this->additionalCSS;
-            $additionalCss = trim($additionalCss);
-            if ($additionalCss !== '') {
-                $this->additionalHeaderData['_CSS'] = '
-<style type="text/css">
-' . $additionalCss . '
-</style>';
-            }
+            $this->additionalFooterData = ['<!--FD_' . $substituteHash . '-->'];
         }
     }
 
@@ -3144,26 +3074,6 @@ class TypoScriptFrontendController implements LoggerAwareInterface
     }
 
     /**
-     * Sets JavaScript code in the additionalJavaScript array
-     *
-     * @param string $key is the key in the array, for num-key let the value be empty. Note reserved key: 'openPic'
-     * @param string $content is the content if you want any
-     * @see ContentObjectRenderer::imageLinkWrap()
-     * @internal only used by TYPO3 Core, use PageRenderer or AssetCollector API instead.
-     */
-    public function setJS($key, $content = '')
-    {
-        if ($key === 'openPic') {
-            $this->additionalJavaScript[$key] = '      function openPic(url, winName, winParams) {
-                var theWindow = window.open(url, winName, winParams);
-                if (theWindow) {theWindow.focus();}
-            }';
-        } elseif ($key) {
-            $this->additionalJavaScript[$key] = $content;
-        }
-    }
-
-    /**
      * Returns a unique md5 hash.
      * There is no special magic in this, the only point is that you don't have to call md5(uniqid()) which is slow and by this you are sure to get a unique string each time in a little faster way.
      *
index 0eaae95..6e89283 100644 (file)
@@ -736,22 +736,8 @@ class RequestHandler implements RequestHandlerInterface
                }
                ';
         }
-        // Add inline JS
-        $inlineJS = '';
-        // defined in php
-        if (is_array($controller->inlineJS)) {
-            foreach ($controller->inlineJS as $key => $val) {
-                if (!is_array($val)) {
-                    $inlineJS .= LF . $val . LF;
-                }
-            }
-        }
-        // defined in TS with page.inlineJS
         // Javascript inline code
-        $inline = $controller->cObj->cObjGet($controller->pSetup['jsInline.'] ?? null, 'jsInline.');
-        if ($inline) {
-            $inlineJS .= LF . $inline . LF;
-        }
+        $inlineJS = $controller->cObj->cObjGet($controller->pSetup['jsInline.'] ?? null, 'jsInline.');
         // Javascript inline code for Footer
         $inlineFooterJs = $controller->cObj->cObjGet($controller->pSetup['jsFooterInline.'] ?? null, 'jsFooterInline.');
         // Should minify?
index 0cbe271..a635a8c 100644 (file)
@@ -4539,4 +4539,11 @@ return [
             'Breaking-91473-DeprecatedFunctionalityRemoved.rst'
         ],
     ],
+    'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->setJS' => [
+        'numberOfMandatoryArguments' => 0,
+        'maximumNumberOfArguments' => 1,
+        'restFiles' => [
+            'Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst'
+        ],
+    ],
 ];
index 8a853ea..377ee4d 100644 (file)
@@ -669,4 +669,24 @@ return [
             'Breaking-91473-DeprecatedFunctionalityRemoved.rst'
         ],
     ],
+    'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->additionalJavaScript' => [
+        'restFiles' => [
+            'Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst'
+        ],
+    ],
+    'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->additionalCSS' => [
+        'restFiles' => [
+            'Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst'
+        ],
+    ],
+    'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->JSCode' => [
+        'restFiles' => [
+            'Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst'
+        ],
+    ],
+    'TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController->inlineJS' => [
+        'restFiles' => [
+            'Breaking-91563-PHP-basedJSCSSInclusionsForFrontendRemoved.rst'
+        ],
+    ],
 ];