From de6af8b1c186b05fcb69fad653dc86904101d444 Mon Sep 17 00:00:00 2001
From: Benni Mack <benni@typo3.org>
Date: Tue, 18 Feb 2020 15:53:06 +0100
Subject: [PATCH] [TASK] Deprecate DocumentTemplate

Since TYPO3 v7, the new ModuleTemplate API is in place,
which contains a fluid-based and fluent interface possibility
to add DocHeader components and to render content.

Resolves: #90421
Releases: master
Change-Id: I5634ea0427486f37fbbfe3ee00695fc98e52d980
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/63290
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
---
 .../Classes/Controller/DummyController.php    |  9 ++--
 .../Classes/Template/DocumentTemplate.php     |  3 ++
 .../Classes/Template/ModuleTemplate.php       | 38 ++--------------
 .../Classes/Localization/LanguageService.php  |  7 ++-
 .../Deprecation-90421-DocumentTemplate.rst    | 45 +++++++++++++++++++
 .../ViewHelpers/Be/TriggerViewHelper.php      |  1 -
 .../Be/AbstractBackendViewHelper.php          | 19 ++++----
 .../Be/Buttons/ShortcutViewHelper.php         | 10 ++---
 .../ViewHelpers/Be/ContainerViewHelper.php    | 13 +++---
 .../ViewHelpers/Be/PageInfoViewHelper.php     |  1 -
 .../ViewHelpers/Be/PagePathViewHelper.php     |  1 -
 .../ExtensionScanner/Php/ClassNameMatcher.php |  7 ++-
 12 files changed, 84 insertions(+), 70 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-90421-DocumentTemplate.rst

diff --git a/typo3/sysext/backend/Classes/Controller/DummyController.php b/typo3/sysext/backend/Classes/Controller/DummyController.php
index 62b27a2c5555..897d2cacd532 100644
--- a/typo3/sysext/backend/Classes/Controller/DummyController.php
+++ b/typo3/sysext/backend/Classes/Controller/DummyController.php
@@ -15,7 +15,7 @@ namespace TYPO3\CMS\Backend\Controller;
  */
 
 use Psr\Http\Message\ResponseInterface;
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
 use TYPO3\CMS\Core\Http\HtmlResponse;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -32,8 +32,9 @@ class DummyController
      */
     public function mainAction(): ResponseInterface
     {
-        $documentTemplate = GeneralUtility::makeInstance(DocumentTemplate::class);
-        $content = $documentTemplate->startPage('Dummy document') . $documentTemplate->endPage();
-        return new HtmlResponse($content);
+        $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+        $moduleTemplate->setTitle('Blank');
+        $moduleTemplate->getDocHeaderComponent()->disable();
+        return new HtmlResponse($moduleTemplate->renderContent());
     }
 }
diff --git a/typo3/sysext/backend/Classes/Template/DocumentTemplate.php b/typo3/sysext/backend/Classes/Template/DocumentTemplate.php
index 6d530a1e77d2..96932c7a4ff9 100644
--- a/typo3/sysext/backend/Classes/Template/DocumentTemplate.php
+++ b/typo3/sysext/backend/Classes/Template/DocumentTemplate.php
@@ -44,6 +44,8 @@ use TYPO3\CMS\Core\Utility\PathUtility;
  * After this file $LANG and $TBE_TEMPLATE are global variables / instances of their respective classes.
  *
  * Please refer to Inside TYPO3 for a discussion of how to use this API.
+ *
+ * @deprecated will be removed in TYPO3 v11.0. Use ModuleTemplate and PageRenderer instead.
  */
 class DocumentTemplate implements LoggerAwareInterface
 {
@@ -226,6 +228,7 @@ function jumpToUrl(URL) {
     public function __construct()
     {
         $this->initPageRenderer();
+        trigerr_error(__CLASS__ . ' will be removed in TYPO3 v11. Use ModuleTemplate API instead.', E_USER_DEPRECATED);
 
         $this->iconFactory = GeneralUtility::makeInstance(IconFactory::class);
 
diff --git a/typo3/sysext/backend/Classes/Template/ModuleTemplate.php b/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
index 23e04d7e1ac4..90242c955080 100644
--- a/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
+++ b/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
@@ -23,6 +23,7 @@ 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\FlashMessageQueue;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Page\PageRenderer;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
@@ -35,39 +36,9 @@ use TYPO3Fluid\Fluid\View\Exception\InvalidTemplateResourceException;
 /**
  * A class taking care of the "outer" HTML of a module, especially
  * the doc header and other related parts.
- *
- * @internal This API is not yet carved in stone and may be adapted later.
  */
 class ModuleTemplate
 {
-    /**
-     * Error Icon Constant
-     *
-     * @internal
-     */
-    const STATUS_ICON_ERROR = 3;
-
-    /**
-     * Warning Icon Constant
-     *
-     * @internal
-     */
-    const STATUS_ICON_WARNING = 2;
-
-    /**
-     * Notification Icon Constant
-     *
-     * @internal
-     */
-    const STATUS_ICON_NOTIFICATION = 1;
-
-    /**
-     * OK Icon Constant
-     *
-     * @internal
-     */
-    const STATUS_ICON_OK = -1;
-
     /**
      * DocHeaderComponent
      *
@@ -180,7 +151,7 @@ class ModuleTemplate
     /**
      * Flash message queue
      *
-     * @var \TYPO3\CMS\Core\Messaging\FlashMessageQueue
+     * @var FlashMessageQueue
      */
     protected $flashMessageQueue;
 
@@ -296,7 +267,6 @@ class ModuleTemplate
         if (!empty($GLOBALS['TBE_STYLES']['stylesheet2'])) {
             $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheet2']);
         }
-        // @see DocumentTemplate::addStyleSheetDirectory
         // Add all *.css files of the directory $path to the stylesheets
         foreach ($this->getRegisteredStylesheetFolders() as $folder) {
             // Read all files in directory and sort them alphabetically
@@ -748,7 +718,7 @@ class ModuleTemplate
     }
 
     /**
-     * @param \TYPO3\CMS\Core\Messaging\FlashMessageQueue $flashMessageQueue
+     * @param FlashMessageQueue $flashMessageQueue
      * @return self
      */
     public function setFlashMessageQueue($flashMessageQueue): self
@@ -758,7 +728,7 @@ class ModuleTemplate
     }
 
     /**
-     * @return \TYPO3\CMS\Core\Messaging\FlashMessageQueue
+     * @return FlashMessageQueue
      */
     protected function getFlashMessageQueue()
     {
diff --git a/typo3/sysext/core/Classes/Localization/LanguageService.php b/typo3/sysext/core/Classes/Localization/LanguageService.php
index 1c61f54acc5b..62ed7f136b7f 100644
--- a/typo3/sysext/core/Classes/Localization/LanguageService.php
+++ b/typo3/sysext/core/Classes/Localization/LanguageService.php
@@ -97,10 +97,9 @@ class LanguageService
     }
 
     /**
-     * Initializes the backend language.
-     * This is for example done in \TYPO3\CMS\Backend\Template\DocumentTemplate with lines like these:
-     * $LANG = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Localization\LanguageService::class);
-     * $LANG->init($GLOBALS['BE_USER']->uc['lang']);
+     * Initializes the language to fetch XLF labels for.
+     * $languageService = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Localization\LanguageService::class);
+     * $languageService->init($GLOBALS['BE_USER']->uc['lang']);
      *
      * @throws \RuntimeException
      * @param string $languageKey The language key (two character string from backend users profile)
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-90421-DocumentTemplate.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-90421-DocumentTemplate.rst
new file mode 100644
index 000000000000..a7f5115e5358
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-90421-DocumentTemplate.rst
@@ -0,0 +1,45 @@
+.. include:: ../../Includes.txt
+
+======================================
+Deprecation: #90421 - DocumentTemplate
+======================================
+
+See :issue:`90421`
+
+Description
+===========
+
+The PHP class :php:`TYPO3\CMS\Backend\Template\DocumentTemplate`,
+also available as :php:`$GLOBALS['TBE_TEMPLATE']` until TYPO3 v10.0
+served as a basis to render backend modules or HTML-based output
+in TYPO3 Backend.
+
+Since TYPO3 v7, the new API via `ModuleTemplate` can be used instead. The DocumentTemplate class has been marked as deprecated.
+
+
+Impact
+======
+
+Instantiating the DocumentTemplate class will trigger a PHP deprecation warning.
+
+
+Affected Installations
+======================
+
+TYPO3 installations with third-party extensions adding backend modules using the DocumentTemplate API. These can typically be identified by extensions that "worked" but somehow looked ugly since TYPO3 v7 due to CSS and HTML changes.
+
+
+Migration
+=========
+
+Use ModuleTemplate API instead, which can be built like this in a typical non-Extbase Backend controller (e.g. in an action such as "overviewAction"):
+
+.. code-block:: php
+
+   $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+   $content = $this->getHtmlContentFromMyModule();
+   $moduleTemplate->setTitle('My module');
+   $moduleTemplate->setContent($content);
+   return new HtmlResponse($moduleTemplate->renderContent());
+
+.. index:: Backend, PHP-API, FullyScanned, ext:backend
\ No newline at end of file
diff --git a/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php b/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php
index e43cbda78118..806da16ebceb 100644
--- a/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php
+++ b/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php
@@ -47,7 +47,6 @@ class TriggerViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendV
      * menu when modules are loaded/unloaded.
      *
      * @return string This ViewHelper does not return any content
-     * @see \TYPO3\CMS\Backend\Template\DocumentTemplate
      * @see \TYPO3\CMS\Core\Page\PageRenderer
      */
     public function render()
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/AbstractBackendViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/AbstractBackendViewHelper.php
index 1ceb5dadceaa..0ed121496fa8 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/AbstractBackendViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/AbstractBackendViewHelper.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
 use TYPO3\CMS\Core\Page\PageRenderer;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;
@@ -29,20 +29,18 @@ abstract class AbstractBackendViewHelper extends AbstractViewHelper
      * Gets instance of template if exists or create a new one.
      * Saves instance in viewHelperVariableContainer
      *
-     * @return DocumentTemplate $doc
+     * @return ModuleTemplate
      */
-    public function getDocInstance()
+    public function getModuleTemplate()
     {
         $viewHelperVariableContainer = $this->renderingContext->getViewHelperVariableContainer();
-        if ($viewHelperVariableContainer->exists(self::class, 'DocumentTemplate')) {
-            $doc = $viewHelperVariableContainer->get(self::class, 'DocumentTemplate');
+        if ($viewHelperVariableContainer->exists(self::class, 'ModuleTemplate')) {
+            $moduleTemplate = $viewHelperVariableContainer->get(self::class, 'ModuleTemplate');
         } else {
-            /** @var DocumentTemplate $doc */
-            $doc = GeneralUtility::makeInstance(DocumentTemplate::class);
-            $viewHelperVariableContainer->add(self::class, 'DocumentTemplate', $doc);
+            $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
+            $viewHelperVariableContainer->add(self::class, 'ModuleTemplate', $moduleTemplate);
         }
-
-        return $doc;
+        return $moduleTemplate;
     }
 
     /**
@@ -57,7 +55,6 @@ abstract class AbstractBackendViewHelper extends AbstractViewHelper
         if ($viewHelperVariableContainer->exists(self::class, 'PageRenderer')) {
             $pageRenderer = $viewHelperVariableContainer->get(self::class, 'PageRenderer');
         } else {
-            /** @var DocumentTemplate $doc */
             $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
             $viewHelperVariableContainer->add(self::class, 'PageRenderer', $pageRenderer);
         }
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/ShortcutViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/ShortcutViewHelper.php
index 28cddc091f04..4cfb2ecdd250 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/ShortcutViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/Buttons/ShortcutViewHelper.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Be\Buttons;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendViewHelper;
 use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
@@ -64,14 +64,14 @@ class ShortcutViewHelper extends AbstractBackendViewHelper
     {
         parent::initializeArguments();
         $this->registerArgument('getVars', 'array', 'List of GET variables to store. By default the current id, module and all module arguments will be stored', false, []);
-        $this->registerArgument('setVars', 'array', 'List of SET[] variables to store. See DocumentTemplate::makeShortcutIcon(). Normally won\'t be used by Extbase modules', false, []);
+        $this->registerArgument('setVars', 'array', 'List of SET[] variables to store. See ModuleTemplate::makeShortcutIcon(). Normally won\'t be used by Extbase modules', false, []);
     }
 
     /**
      * Renders a shortcut button as known from the TYPO3 backend
      *
      * @return string the rendered shortcut button
-     * @see \TYPO3\CMS\Backend\Template\DocumentTemplate::makeShortcutIcon()
+     * @see ModuleTemplate::makeShortcutIcon()
      */
     public function render()
     {
@@ -96,7 +96,7 @@ class ShortcutViewHelper extends AbstractBackendViewHelper
         $mayMakeShortcut = $GLOBALS['BE_USER']->mayMakeShortcut();
 
         if ($mayMakeShortcut) {
-            $doc = GeneralUtility::makeInstance(DocumentTemplate::class);
+            $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
             $currentRequest = $renderingContext->getControllerContext()->getRequest();
             $extensionName = $currentRequest->getControllerExtensionName();
             $moduleName = $currentRequest->getPluginName();
@@ -106,7 +106,7 @@ class ShortcutViewHelper extends AbstractBackendViewHelper
             }
             $getList = implode(',', $getVars);
             $setList = implode(',', $setVars);
-            return $doc->makeShortcutIcon($getList, $setList, $moduleName);
+            return $moduleTemplate->makeShortcutIcon($getList, $setList, $moduleName);
         }
         return '';
     }
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/ContainerViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/ContainerViewHelper.php
index 19f5d5f0942d..7ad2eed136a9 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/ContainerViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/ContainerViewHelper.php
@@ -14,7 +14,6 @@ namespace TYPO3\CMS\Fluid\ViewHelpers\Be;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
 
 /**
@@ -69,10 +68,9 @@ class ContainerViewHelper extends AbstractBackendViewHelper
     }
 
     /**
-     * Render start page with \TYPO3\CMS\Backend\Template\DocumentTemplate and pageTitle
+     * Render start page with \TYPO3\CMS\Backend\Template\ModuleTemplate and pageTitle
      *
      * @return string
-     * @see \TYPO3\CMS\Backend\Template\DocumentTemplate
      * @see \TYPO3\CMS\Core\Page\PageRenderer
      */
     public function render()
@@ -84,8 +82,6 @@ class ContainerViewHelper extends AbstractBackendViewHelper
         $includeRequireJsModules = $this->arguments['includeRequireJsModules'];
 
         $pageRenderer = $this->getPageRenderer();
-        $doc = $this->getDocInstance();
-        $doc->JScode .= GeneralUtility::wrapJS($doc->redirectUrls());
 
         // Include custom CSS and JS files
         if (is_array($includeCssFiles) && count($includeCssFiles) > 0) {
@@ -113,8 +109,9 @@ class ContainerViewHelper extends AbstractBackendViewHelper
         }
         // Render the content and return it
         $output = $this->renderChildren();
-        $output = $doc->startPage($pageTitle) . $output;
-        $output .= $doc->endPage();
-        return $output;
+        $moduleTemplate = $this->getModuleTemplate();
+        $moduleTemplate->setTitle($pageTitle);
+        $moduleTemplate->setContent($output);
+        return $moduleTemplate->renderContent();
     }
 }
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php
index cc535cf76ac0..c0bab72d6d84 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php
@@ -50,7 +50,6 @@ class PageInfoViewHelper extends AbstractBackendViewHelper
      * Render javascript in header
      *
      * @return string the rendered page info icon
-     * @see \TYPO3\CMS\Backend\Template\DocumentTemplate::getPageInfo() Note: can't call this method as it's protected!
      */
     public function render()
     {
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/PagePathViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/PagePathViewHelper.php
index 4b61844348b3..a0b8b494e2d5 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/PagePathViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/PagePathViewHelper.php
@@ -49,7 +49,6 @@ class PagePathViewHelper extends AbstractBackendViewHelper
      * Renders the current page path
      *
      * @return string the rendered page path
-     * @see \TYPO3\CMS\Backend\Template\DocumentTemplate::getPagePath() Note: can't call this method as it's protected!
      */
     public function render()
     {
diff --git a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
index b58dafe4bc78..95308e787c5a 100644
--- a/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
+++ b/typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php
@@ -1346,5 +1346,10 @@ return [
         'restFiles' => [
             'Deprecation-89718-LegacyPageTSconfigParsingLowlevelAPI.rst',
         ],
-    ]
+    ],
+    'TYPO3\CMS\Backend\Template\DocumentTemplate' => [
+        'restFiles' => [
+            'Deprecation-90421-DocumentTemplate.rst',
+        ],
+    ],
 ];
-- 
GitLab