From e0cd518a2246a7a04c6e82124d7f4578f6be4abb Mon Sep 17 00:00:00 2001
From: Andreas Bouche <andreas.bouche@flagbit.de>
Date: Fri, 16 Oct 2015 19:04:14 +0200
Subject: [PATCH] [BUGFIX] Remove dependency to DocumentTemplate in FormEngine

Move wrapClickMenuOnIcon() from DocumentTemplate to BackendUtility
next to similar static helper methods of this kind. This reduces
the need to have an instance of DocumentTemplate available which
is not always the case for instance in inline ajax requests.

Resolves: #70494
Releases: master
Change-Id: I977d79d48ffce5db84c9a91b8fac233edbc238ec
Reviewed-on: https://review.typo3.org/44116
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Jan Helke <typo3@helke.de>
Reviewed-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
Tested-by: Stefan Neufeind <typo3.neufeind@speedpartner.de>
---
 .../Form/Container/AbstractContainer.php      | 12 +----
 .../Form/Container/OuterWrapContainer.php     |  8 +--
 .../Form/Element/AbstractFormElement.php      | 15 +-----
 .../Form/Utility/FormEngineUtility.php        |  1 +
 .../Template/Components/MetaInformation.php   |  7 ++-
 .../Classes/Template/DocumentTemplate.php     | 25 +++------
 .../Classes/Template/ModuleTemplate.php       | 52 -------------------
 .../Classes/Tree/View/BrowseTreeView.php      |  2 +-
 .../Classes/Tree/View/FolderTreeView.php      |  5 +-
 .../Classes/Utility/BackendUtility.php        | 50 ++++++++++++++++++
 .../backend/Classes/View/PageLayoutView.php   |  8 +--
 .../backend/Classes/View/PageTreeView.php     | 13 +----
 .../7.0/Breaking-33805-ClickMenuRewrite.rst   |  2 +-
 .../Deprecation-70494-WrapClickMenuOnIcon.rst | 20 +++++++
 typo3/sysext/filelist/Classes/FileList.php    |  6 +--
 .../Link/ClickMenuOnIconViewHelper.php        |  2 +-
 .../ViewHelpers/Be/PageInfoViewHelper.php     |  5 +-
 .../TranslationStatusController.php           |  2 +-
 .../Classes/RecordList/DatabaseRecordList.php |  2 +-
 19 files changed, 106 insertions(+), 131 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Deprecation-70494-WrapClickMenuOnIcon.rst

diff --git a/typo3/sysext/backend/Classes/Form/Container/AbstractContainer.php b/typo3/sysext/backend/Classes/Form/Container/AbstractContainer.php
index 80271b293459..77ef3a0359be 100644
--- a/typo3/sysext/backend/Classes/Form/Container/AbstractContainer.php
+++ b/typo3/sysext/backend/Classes/Form/Container/AbstractContainer.php
@@ -15,12 +15,12 @@ namespace TYPO3\CMS\Backend\Form\Container;
  */
 
 use TYPO3\CMS\Backend\Form\NodeFactory;
+use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Backend\Form\AbstractNode;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
 
 /**
  * Abstract container has various methods used by the container classes
@@ -114,7 +114,7 @@ abstract class AbstractContainer extends AbstractNode
                         'thumbs.php',
                         $config['config']['uploadfolder'], 0, ' align="middle"'
                     ) .
-                    ($absFilePath ? $this->getControllerDocumentTemplate()->wrapClickMenuOnIcon($fileIcon, $absFilePath, 0, 1, '', '+copy,info,edit,view') : $fileIcon) .
+                    ($absFilePath ? BackendUtility::wrapClickMenuOnIcon($fileIcon, $absFilePath, 0, 1, '', '+copy,info,edit,view') : $fileIcon) .
                     $imgPath .
                     '</span>';
             }
@@ -123,12 +123,4 @@ abstract class AbstractContainer extends AbstractNode
             return nl2br(htmlspecialchars($value));
         }
     }
-
-    /**
-     * @return DocumentTemplate
-     */
-    protected function getControllerDocumentTemplate()
-    {
-        return $GLOBALS['SOBE']->doc;
-    }
 }
diff --git a/typo3/sysext/backend/Classes/Form/Container/OuterWrapContainer.php b/typo3/sysext/backend/Classes/Form/Container/OuterWrapContainer.php
index 9851b5811c46..711b2d628c59 100644
--- a/typo3/sysext/backend/Classes/Form/Container/OuterWrapContainer.php
+++ b/typo3/sysext/backend/Classes/Form/Container/OuterWrapContainer.php
@@ -14,7 +14,7 @@ namespace TYPO3\CMS\Backend\Form\Container;
  * The TYPO3 project - inspiring people to share!
  */
 
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
+use TYPO3\CMS\Backend\Form\Utility\FormEngineUtility;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Imaging\Icon;
@@ -85,11 +85,7 @@ class OuterWrapContainer extends AbstractContainer
                 $pageTitle = sprintf($label, $tableTitle, $pageTitle);
             }
         } else {
-            // DocumentTemplate is needed for wrapClickMenuOnIcon(), the method has no state, simply use fresh instance
-            /** @var DocumentTemplate $documentTemplate */
-            $documentTemplate = GeneralUtility::makeInstance(DocumentTemplate::class);
-            $icon = $documentTemplate->wrapClickMenuOnIcon($icon, $table, $row['uid'], 1, '', '+copy,info,edit,view');
-
+            $icon = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid'], 1, '', '+copy,info,edit,view');
             $newOrUid = ' <span class="typo3-TCEforms-recUid">[' . htmlspecialchars($row['uid']) . ']</span>';
 
             // @todo: getRecordTitlePrep applies an htmlspecialchars here
diff --git a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
index 4f6d193c1e35..a0fdeca4c111 100644
--- a/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
+++ b/typo3/sysext/backend/Classes/Form/Element/AbstractFormElement.php
@@ -17,7 +17,6 @@ namespace TYPO3\CMS\Backend\Form\Element;
 use TYPO3\CMS\Backend\Form\FormDataCompiler;
 use TYPO3\CMS\Backend\Form\FormDataGroup\OnTheFly;
 use TYPO3\CMS\Backend\Form\FormDataProvider\TcaSelectItems;
-use TYPO3\CMS\Backend\Template\DocumentTemplate;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Lang\LanguageService;
@@ -694,12 +693,12 @@ abstract class AbstractFormElement extends AbstractNode
 						<tr>
 							<td class="col-icon">
 								' . ($config['internal_type'] === 'db'
-                            ? $this->getControllerDocumentTemplate()->wrapClickMenuOnIcon($thumbnail['image'], $thumbnail['table'], $thumbnail['uid'], 1, '', '+copy,info,edit,view')
+                            ? BackendUtility::wrapClickMenuOnIcon($thumbnail['image'], $thumbnail['table'], $thumbnail['uid'], 1, '', '+copy,info,edit,view')
                             : $thumbnail['image']) . '
 							</td>
 							<td class="col-title">
 								' . ($config['internal_type'] === 'db'
-                            ? $this->getControllerDocumentTemplate()->wrapClickMenuOnIcon($thumbnail['name'], $thumbnail['table'], $thumbnail['uid'], 1, '', '+copy,info,edit,view')
+                            ? BackendUtility::wrapClickMenuOnIcon($thumbnail['name'], $thumbnail['table'], $thumbnail['uid'], 1, '', '+copy,info,edit,view')
                             : $thumbnail['name']) . '
 								' . ($config['internal_type'] === 'db' ? ' <span class="text-muted">[' . $thumbnail['uid'] . ']</span>' : '') . '
 							</td>
@@ -861,14 +860,4 @@ abstract class AbstractFormElement extends AbstractNode
     {
         return $GLOBALS['LANG'];
     }
-
-    /**
-     * @return DocumentTemplate
-     */
-    protected function getControllerDocumentTemplate()
-    {
-        // $GLOBALS['SOBE'] might be any kind of PHP class (controller most of the times)
-        // These classes do not inherit from any common class, but they all seem to have a "doc" member
-        return $GLOBALS['SOBE']->doc;
-    }
 }
diff --git a/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php b/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php
index 67b4d8bf6eee..6f69ae894b18 100644
--- a/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php
+++ b/typo3/sysext/backend/Classes/Form/Utility/FormEngineUtility.php
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Backend\Form\Utility;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Backend\Template\ModuleTemplate;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
diff --git a/typo3/sysext/backend/Classes/Template/Components/MetaInformation.php b/typo3/sysext/backend/Classes/Template/Components/MetaInformation.php
index 3470ab697a73..836505064104 100644
--- a/typo3/sysext/backend/Classes/Template/Components/MetaInformation.php
+++ b/typo3/sysext/backend/Classes/Template/Components/MetaInformation.php
@@ -100,7 +100,6 @@ class MetaInformation
     public function getRecordInformation()
     {
         $iconFactory = GeneralUtility::makeInstance(IconFactory::class);
-        $moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
         $pageRecord = $this->recordArray;
         $uid = '';
         $title = '';
@@ -111,7 +110,7 @@ class MetaInformation
             $altText = BackendUtility::getRecordIconAltText($pageRecord, 'pages');
             $iconImg = '<span title="' . $altText . '">' . $iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
             // Make Icon:
-            $theIcon = $moduleTemplate->wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
+            $theIcon = BackendUtility::wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
             $uid = $pageRecord['uid'];
             $title = BackendUtility::getRecordTitle('pages', $pageRecord);
         // If the module is about a FAL resource
@@ -134,7 +133,7 @@ class MetaInformation
                         Icon::SIZE_SMALL
                     )->render() . '</span>';
                 }
-                $theIcon = $moduleTemplate->wrapClickMenuOnIcon($iconImg, $pageRecord['combined_identifier']);
+                $theIcon = BackendUtility::wrapClickMenuOnIcon($iconImg, $pageRecord['combined_identifier']);
             } catch (ResourceDoesNotExistException $e) {
                 $theIcon = '';
             }
@@ -146,7 +145,7 @@ class MetaInformation
                 '">' .
                 $iconFactory->getIcon('apps-pagetree-root', Icon::SIZE_SMALL)->render() . '</span>';
             if ($this->getBackendUser()->isAdmin()) {
-                $theIcon = $moduleTemplate->wrapClickMenuOnIcon($iconImg, 'pages', 0);
+                $theIcon = BackendUtility::wrapClickMenuOnIcon($iconImg, 'pages', 0);
             } else {
                 $theIcon = $iconImg;
             }
diff --git a/typo3/sysext/backend/Classes/Template/DocumentTemplate.php b/typo3/sysext/backend/Classes/Template/DocumentTemplate.php
index 20094aa7cfc4..2da2649e3627 100644
--- a/typo3/sysext/backend/Classes/Template/DocumentTemplate.php
+++ b/typo3/sysext/backend/Classes/Template/DocumentTemplate.php
@@ -518,23 +518,12 @@ function jumpToUrl(URL) {
      * @param string $enDisItems Enable / Disable click menu items. Example: "+new,view" will display ONLY these two items (and any spacers in between), "new,view" will display all BUT these two items.
      * @param bool $returnTagParameters If set, will return only the onclick JavaScript, not the whole link.
      * @return string The link-wrapped input string.
+     * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8, use BackendUtility::wrapClickMenuOnIcon() instead
      */
     public function wrapClickMenuOnIcon($content, $table, $uid = 0, $listFr = true, $addParams = '', $enDisItems = '', $returnTagParameters = false)
     {
-        $tagParameters = array(
-            'class'           => 't3-js-clickmenutrigger',
-            'data-table'      => $table,
-            'data-uid'        => (int)$uid !== 0 ? (int)$uid : '',
-            'data-listframe'  => $listFr,
-            'data-iteminfo'   => str_replace('+', '%2B', $enDisItems),
-            'data-parameters' => $addParams,
-        );
-
-        if ($returnTagParameters) {
-            return $tagParameters;
-        } else {
-            return '<a href="#" ' . GeneralUtility::implodeAttributes($tagParameters, true) . '>' . $content . '</a>';
-        }
+        GeneralUtility::logDeprecatedFunction();
+        return BackendUtility::wrapClickMenuOnIcon($content, $table, $uid, $listFr, $addParams, $enDisItems, $returnTagParameters);
     }
 
     /**
@@ -613,7 +602,7 @@ function jumpToUrl(URL) {
         }
 
         if ($enableClickMenu) {
-            $iconImgTag = $this->wrapClickMenuOnIcon($iconImgTag, $table, $row['uid']);
+            $iconImgTag = BackendUtility::wrapClickMenuOnIcon($iconImgTag, $table, $row['uid']);
         }
 
         return '<span class="typo3-moduleHeader">' . $iconImgTag . $viewPage . $tWrap[0] . htmlspecialchars(GeneralUtility::fixed_lgd_cs($title, 45)) . $tWrap[1] . '</span>';
@@ -639,7 +628,7 @@ function jumpToUrl(URL) {
 
         if ($enableClickMenu && ($resource instanceof \TYPO3\CMS\Core\Resource\File)) {
             $metaData = $resource->_getMetaData();
-            $iconImgTag = $this->wrapClickMenuOnIcon($iconImgTag, 'sys_file_metadata', $metaData['uid']);
+            $iconImgTag = BackendUtility::wrapClickMenuOnIcon($iconImgTag, 'sys_file_metadata', $metaData['uid']);
         }
 
         return '<span class="typo3-moduleHeader">' . $iconImgTag . $tWrap[0] . htmlspecialchars(GeneralUtility::fixed_lgd_cs($resource->getName(), 45)) . $tWrap[1] . '</span>';
@@ -1921,7 +1910,7 @@ function jumpToUrl(URL) {
             $alttext = BackendUtility::getRecordIconAltText($pageRecord, 'pages');
             $iconImg = '<span title="' . htmlspecialchars($alttext) . '">' . $this->iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
             // Make Icon:
-            $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
+            $theIcon = BackendUtility::wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
             $uid = $pageRecord['uid'];
             $title = BackendUtility::getRecordTitle('pages', $pageRecord);
         } else {
@@ -1929,7 +1918,7 @@ function jumpToUrl(URL) {
             // Make Icon
             $iconImg = '<span title="' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . '">' . $this->iconFactory->getIcon('apps-pagetree-root', Icon::SIZE_SMALL)->render() . '</span>';
             if ($GLOBALS['BE_USER']->user['admin']) {
-                $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', 0);
+                $theIcon = BackendUtility::wrapClickMenuOnIcon($iconImg, 'pages', 0);
             } else {
                 $theIcon = $iconImg;
             }
diff --git a/typo3/sysext/backend/Classes/Template/ModuleTemplate.php b/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
index dfad77486946..079257ab756c 100644
--- a/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
+++ b/typo3/sysext/backend/Classes/Template/ModuleTemplate.php
@@ -462,58 +462,6 @@ class ModuleTemplate
      * be prepared to change this later again.
      *******************************************/
 
-    /**
-     * Makes click menu link (context sensitive menu)
-     * Returns $str (possibly an <|img> tag/icon) wrapped in a link which will
-     * activate the context sensitive menu for the record ($table/$uid) or
-     * file ($table = file)
-     * The link will load the top frame with the parameter "&item" which is
-     * the table,uid and listFr arguments imploded
-     * by "|": rawurlencode($table.'|'.$uid.'|'.$listFr)
-     *
-     * @param string $content String to be wrapped in link, typ. image tag.
-     * @param string $table Table name/File path. If the icon is for a database
-     * record, enter the tablename from $GLOBALS['TCA']. If a file then enter
-     * the absolute filepath
-     * @param int $uid If icon is for database record this is the UID for the
-     * record from $table
-     * @param bool $listFr Tells the top frame script that the link is coming
-     * from a "list" frame which means a frame from within the backend content frame.
-     * @param string $addParams Additional GET parameters for the link to the
-     * ClickMenu AJAX request
-     * @param string $enDisItems Enable / Disable click menu items.
-     * Example: "+new,view" will display ONLY these two items (and any spacers
-     * in between), "new,view" will display all BUT these two items.
-     * @param bool $returnTagParameters If set, will return only the onclick
-     * JavaScript, not the whole link.
-     *
-     * @return string The link-wrapped input string.
-     * @internal
-     */
-    public function wrapClickMenuOnIcon(
-        $content,
-        $table,
-        $uid = 0,
-        $listFr = true,
-        $addParams = '',
-        $enDisItems = '',
-        $returnTagParameters = false
-    ) {
-        $tagParameters = array(
-            'class'           => 't3-js-clickmenutrigger',
-            'data-table'      => $table,
-            'data-uid'        => (int)$uid !== 0 ? (int)$uid : '',
-            'data-listframe'  => $listFr,
-            'data-iteminfo'   => str_replace('+', '%2B', $enDisItems),
-            'data-parameters' => $addParams,
-        );
-
-        if ($returnTagParameters) {
-            return $tagParameters;
-        }
-        return '<a href="#" ' . GeneralUtility::implodeAttributes($tagParameters, true) . '>' . $content . '</a>';
-    }
-
     /**
      * Includes a javascript library that exists in the core /typo3/ directory
      *
diff --git a/typo3/sysext/backend/Classes/Tree/View/BrowseTreeView.php b/typo3/sysext/backend/Classes/Tree/View/BrowseTreeView.php
index 54d78c7afa63..a23f6793b90b 100644
--- a/typo3/sysext/backend/Classes/Tree/View/BrowseTreeView.php
+++ b/typo3/sysext/backend/Classes/Tree/View/BrowseTreeView.php
@@ -117,7 +117,7 @@ class BrowseTreeView extends AbstractTreeView
         // Wrap icon in click-menu link.
         $theIcon = '';
         if (!$this->ext_IconMode) {
-            $theIcon = $GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon($icon, $this->treeName, $this->getId($row), 0);
+            $theIcon = BackendUtility::wrapClickMenuOnIcon($icon, $this->treeName, $this->getId($row), 0);
         } elseif ($this->ext_IconMode === 'titlelink') {
             $aOnClick = 'return jumpTo(' . \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($this->getJumpToParam($row)) . ',this,' . \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($this->domIdPrefix . $this->getId($row)) . ',' . $this->bank . ');';
             $theIcon = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $icon . '</a>';
diff --git a/typo3/sysext/backend/Classes/Tree/View/FolderTreeView.php b/typo3/sysext/backend/Classes/Tree/View/FolderTreeView.php
index c9932a44e7db..776c64c4efc6 100644
--- a/typo3/sysext/backend/Classes/Tree/View/FolderTreeView.php
+++ b/typo3/sysext/backend/Classes/Tree/View/FolderTreeView.php
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Backend\Tree\View;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Backend\Utility\BackendUtility;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
@@ -174,7 +175,7 @@ class FolderTreeView extends AbstractTreeView
         if (!$this->ext_IconMode) {
             // Check storage access to wrap with click menu
             if (!$folderObject instanceof InaccessibleFolder) {
-                $theFolderIcon = $GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon($icon, $folderObject->getCombinedIdentifier(), '', 0);
+                $theFolderIcon = BackendUtility::wrapClickMenuOnIcon($icon, $folderObject->getCombinedIdentifier(), '', 0);
             }
         } elseif ($this->ext_IconMode === 'titlelink') {
             $aOnClick = 'return jumpTo(' . GeneralUtility::quoteJSvalue($this->getJumpToParam($folderObject)) . ',this,' . GeneralUtility::quoteJSvalue($this->domIdPrefix . $this->getId($folderObject)) . ',' . $this->bank . ');';
@@ -199,7 +200,7 @@ class FolderTreeView extends AbstractTreeView
             return $title;
         }
         $aOnClick = 'return jumpTo(' . GeneralUtility::quoteJSvalue($this->getJumpToParam($folderObject)) . ', this, ' . GeneralUtility::quoteJSvalue($this->domIdPrefix . $this->getId($folderObject)) . ', ' . $bank . ');';
-        $clickMenuParts = $GLOBALS['TBE_TEMPLATE']->wrapClickMenuOnIcon('', $folderObject->getCombinedIdentifier(), '', 0, ('&bank=' . $this->bank), '', true);
+        $clickMenuParts = BackendUtility::wrapClickMenuOnIcon('', $folderObject->getCombinedIdentifier(), '', 0, ('&bank=' . $this->bank), '', true);
 
         return '<a href="#" title="' . htmlspecialchars(strip_tags($title)) . '" onclick="' . htmlspecialchars($aOnClick) . '" ' . GeneralUtility::implodeAttributes($clickMenuParts) . '>' . $title . '</a>';
     }
diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
index 9d1829aea60e..35a713c5318c 100755
--- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php
+++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php
@@ -2959,6 +2959,56 @@ class BackendUtility
         return $onclickCode;
     }
 
+    /**
+     * Makes click menu link (context sensitive menu)
+     *
+     * Returns $str wrapped in a link which will activate the context sensitive
+     * menu for the record ($table/$uid) or file ($table = file)
+     * The link will load the top frame with the parameter "&item" which is the table, uid
+     * and listFrame arguments imploded by "|": rawurlencode($table.'|'.$uid.'|'.$listFr)
+     *
+     * @param string $content String to be wrapped in link, typ. image tag.
+     * @param string $table Table name/File path. If the icon is for a database
+     * record, enter the tablename from $GLOBALS['TCA']. If a file then enter
+     * the absolute filepath
+     * @param int $uid If icon is for database record this is the UID for the
+     * record from $table
+     * @param bool $listFrame Tells the top frame script that the link is coming
+     * from a "list" frame which means a frame from within the backend content frame.
+     * @param string $addParams Additional GET parameters for the link to the
+     * ClickMenu AJAX request
+     * @param string $enDisItems Enable / Disable click menu items.
+     * Example: "+new,view" will display ONLY these two items (and any spacers
+     * in between), "new,view" will display all BUT these two items.
+     * @param bool $returnTagParameters If set, will return only the onclick
+     * JavaScript, not the whole link.
+     *
+     * @return string The link wrapped input string.
+     */
+    public static function wrapClickMenuOnIcon(
+        $content,
+        $table,
+        $uid = 0,
+        $listFrame = true,
+        $addParams = '',
+        $enDisItems = '',
+        $returnTagParameters = false
+    ) {
+        $tagParameters = array(
+            'class' => 't3-js-clickmenutrigger',
+            'data-table' => $table,
+            'data-uid' => (int)$uid !== 0 ? (int)$uid : '',
+            'data-listframe' => $listFrame,
+            'data-iteminfo' => str_replace('+', '%2B', $enDisItems),
+            'data-parameters' => $addParams,
+        );
+
+        if ($returnTagParameters) {
+            return $tagParameters;
+        }
+        return '<a href="#" ' . GeneralUtility::implodeAttributes($tagParameters, true) . '>' . $content . '</a>';
+    }
+
     /**
      * Creates the view-on-click preview URL without any alternative URL.
      *
diff --git a/typo3/sysext/backend/Classes/View/PageLayoutView.php b/typo3/sysext/backend/Classes/View/PageLayoutView.php
index 2885f314a947..cafce2bc576f 100644
--- a/typo3/sysext/backend/Classes/View/PageLayoutView.php
+++ b/typo3/sysext/backend/Classes/View/PageLayoutView.php
@@ -727,7 +727,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                     list($lpRecord) = BackendUtility::getRecordsByField('pages_language_overlay', 'pid', $id, 'AND sys_language_uid=' . $lP);
                     BackendUtility::workspaceOL('pages_language_overlay', $lpRecord);
                     $params = '&edit[pages_language_overlay][' . $lpRecord['uid'] . ']=edit&overrideVals[pages_language_overlay][sys_language_uid]=' . $lP;
-                    $lPLabel = $this->getPageLayoutController()->getModuleTemplate()->wrapClickMenuOnIcon(
+                    $lPLabel = BackendUtility::wrapClickMenuOnIcon(
                         $this->iconFactory->getIconForRecord('pages_language_overlay', $lpRecord, Icon::SIZE_SMALL)->render(),
                         'pages_language_overlay',
                         $lpRecord['uid']
@@ -739,7 +739,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                         ) . htmlspecialchars(GeneralUtility::fixed_lgd_cs($lpRecord['title'], 20));
                 } else {
                     $params = '&edit[pages][' . $this->id . ']=edit';
-                    $lPLabel = $this->getPageLayoutController()->getModuleTemplate()->wrapClickMenuOnIcon(
+                    $lPLabel = BackendUtility::wrapClickMenuOnIcon(
                         $this->iconFactory->getIconForRecord('pages', $this->pageRecord, Icon::SIZE_SMALL)->render(),
                         'pages',
                         $this->id
@@ -1468,7 +1468,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
                             $shortcutRecord = BackendUtility::getRecord($tableName, $split[1]);
                             if (is_array($shortcutRecord)) {
                                 $icon = $this->iconFactory->getIconForRecord($tableName, $shortcutRecord, Icon::SIZE_SMALL)->render();
-                                $icon = $this->getPageLayoutController()->getModuleTemplate()->wrapClickMenuOnIcon(
+                                $icon = BackendUtility::wrapClickMenuOnIcon(
                                     $icon,
                                     $tableName,
                                     $shortcutRecord['uid'],
@@ -2111,7 +2111,7 @@ class PageLayoutView extends \TYPO3\CMS\Recordlist\RecordList\AbstractDatabaseRe
         $this->counter++;
         // The icon with link
         if ($this->getBackendUser()->recordEditAccessInternals($table, $row)) {
-            $icon = $this->getPageLayoutController()->getModuleTemplate()->wrapClickMenuOnIcon($icon, $table, $row['uid']);
+            $icon = BackendUtility::wrapClickMenuOnIcon($icon, $table, $row['uid']);
         }
         return $icon;
     }
diff --git a/typo3/sysext/backend/Classes/View/PageTreeView.php b/typo3/sysext/backend/Classes/View/PageTreeView.php
index cd707d7740fe..26e15b4ad688 100644
--- a/typo3/sysext/backend/Classes/View/PageTreeView.php
+++ b/typo3/sysext/backend/Classes/View/PageTreeView.php
@@ -87,7 +87,7 @@ class PageTreeView extends BrowseTreeView
         }
         // Wrap icon in click-menu link.
         if (!$this->ext_IconMode) {
-            $thePageIcon = $this->getDocumentTemplate()->wrapClickMenuOnIcon($thePageIcon, 'pages', $row['uid'], 0, '&bank=' . $this->bank);
+            $thePageIcon = BackendUtility::wrapClickMenuOnIcon($thePageIcon, 'pages', $row['uid'], 0, '&bank=' . $this->bank);
         } elseif ($this->ext_IconMode === 'titlelink') {
             $aOnClick = 'return jumpTo(' . GeneralUtility::quoteJSvalue($this->getJumpToParam($row)) . ',this,' . GeneralUtility::quoteJSvalue($this->treeName) . ');';
             $thePageIcon = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '">' . $thePageIcon . '</a>';
@@ -130,7 +130,7 @@ class PageTreeView extends BrowseTreeView
             unset($_params);
         }
         $aOnClick = 'return jumpTo(' . GeneralUtility::quoteJSvalue($this->getJumpToParam($row)) . ',this,' . GeneralUtility::quoteJSvalue($this->domIdPrefix . $this->getId($row)) . ',' . $bank . ');';
-        $clickMenuParts = $this->getDocumentTemplate()->wrapClickMenuOnIcon('', 'pages', $row['uid'], 0, ('&bank=' . $this->bank), '', true);
+        $clickMenuParts = BackendUtility::wrapClickMenuOnIcon('', 'pages', $row['uid'], 0, ('&bank=' . $this->bank), '', true);
 
         $thePageTitle = '<a href="#" onclick="' . htmlspecialchars($aOnClick) . '"' . GeneralUtility::implodeAttributes($clickMenuParts) . '>' . $title . '</a>';
         // Wrap title in a drag/drop span.
@@ -339,13 +339,4 @@ class PageTreeView extends BrowseTreeView
         return $this->printTree($treeArr);
     }
 
-    /**
-     * Returns an instance of DocumentTemplate
-     *
-     * @return \TYPO3\CMS\Backend\Template\DocumentTemplate
-     */
-    protected function getDocumentTemplate()
-    {
-        return $GLOBALS['TBE_TEMPLATE'];
-    }
 }
diff --git a/typo3/sysext/core/Documentation/Changelog/7.0/Breaking-33805-ClickMenuRewrite.rst b/typo3/sysext/core/Documentation/Changelog/7.0/Breaking-33805-ClickMenuRewrite.rst
index 6e42eecc1a2f..1f5015392168 100644
--- a/typo3/sysext/core/Documentation/Changelog/7.0/Breaking-33805-ClickMenuRewrite.rst
+++ b/typo3/sysext/core/Documentation/Changelog/7.0/Breaking-33805-ClickMenuRewrite.rst
@@ -34,7 +34,7 @@ Migration
 
 Any use of "Clickmenu.show()" etc should be avoided and channelled through the according DocumentTemplate methods.
 
-- DocumentTemplate->wrapClickMenuOnIcon()
+- BackendUtility::wrapClickMenuOnIcon()
 - DocumentTemplate->getContextMenuCode()
 
 If a backend module without a DocumentTemplate (with e.g. Extbase/Fluid) is used, this is done with a separate class
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-70494-WrapClickMenuOnIcon.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-70494-WrapClickMenuOnIcon.rst
new file mode 100644
index 000000000000..9f3d0358527c
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-70494-WrapClickMenuOnIcon.rst
@@ -0,0 +1,20 @@
+=============================================================
+Deprecation: #70494 - DocumentTemplate->wrapClickMenuOnIcon()
+=============================================================
+
+Description
+===========
+
+Method ``TYPO3\CMS\Backend\Template\DocumentTemplate::wrapClickMenuOnIcon()`` has been deprecated.
+
+
+Affected Installations
+======================
+
+Instances with custom backend modules that use this method.
+
+
+Migration
+=========
+
+Use ``TYPO3\CMS\Backend\Utility\BackendUtility::wrapClickMenuOnIcon()`` instead.
diff --git a/typo3/sysext/filelist/Classes/FileList.php b/typo3/sysext/filelist/Classes/FileList.php
index 9f842f6896b1..44e6b77927ef 100644
--- a/typo3/sysext/filelist/Classes/FileList.php
+++ b/typo3/sysext/filelist/Classes/FileList.php
@@ -271,7 +271,7 @@ class FileList extends AbstractRecordList
             $otherMarkers['TITLE'] .= htmlspecialchars(GeneralUtility::fixed_lgd_cs($title, -($this->fixedL + 20)));
 
             if ($this->clickMenus) {
-                $otherMarkers['PAGE_ICON'] = $this->fileListController->doc->wrapClickMenuOnIcon($otherMarkers['PAGE_ICON'], $folderObject->getCombinedIdentifier());
+                $otherMarkers['PAGE_ICON'] = BackendUtility::wrapClickMenuOnIcon($otherMarkers['PAGE_ICON'], $folderObject->getCombinedIdentifier());
             }
             // Add paste button if clipboard is initialized
             if ($this->clipObj instanceof Clipboard && $folderObject->checkActionPermission('write')) {
@@ -536,7 +536,7 @@ class FileList extends AbstractRecordList
             // The icon with link
             $theIcon = '<span title="' . htmlspecialchars($folderName) . '">' . $this->iconFactory->getIconForResource($folderObject, Icon::SIZE_SMALL)->render() . '</span>';
             if (!$isLocked && $this->clickMenus) {
-                $theIcon = $this->fileListController->doc->wrapClickMenuOnIcon($theIcon, $folderObject->getCombinedIdentifier());
+                $theIcon = BackendUtility::wrapClickMenuOnIcon($theIcon, $folderObject->getCombinedIdentifier());
             }
 
             // Preparing and getting the data-array
@@ -684,7 +684,7 @@ class FileList extends AbstractRecordList
             $theIcon = '<span title="' . htmlspecialchars($fileName . ' [' . (int)$fileObject->getUid() . ']') . '">'
                 . $this->iconFactory->getIconForResource($fileObject, Icon::SIZE_SMALL)->render() . '</span>';
             if ($this->clickMenus) {
-                $theIcon = $this->fileListController->doc->wrapClickMenuOnIcon($theIcon, $fileObject->getCombinedIdentifier());
+                $theIcon = BackendUtility::wrapClickMenuOnIcon($theIcon, $fileObject->getCombinedIdentifier());
             }
             // Preparing and getting the data-array
             $theData = array();
diff --git a/typo3/sysext/filelist/Classes/ViewHelpers/Link/ClickMenuOnIconViewHelper.php b/typo3/sysext/filelist/Classes/ViewHelpers/Link/ClickMenuOnIconViewHelper.php
index dd6ee7594c7d..b65b0834d3b5 100644
--- a/typo3/sysext/filelist/Classes/ViewHelpers/Link/ClickMenuOnIconViewHelper.php
+++ b/typo3/sysext/filelist/Classes/ViewHelpers/Link/ClickMenuOnIconViewHelper.php
@@ -38,7 +38,7 @@ class ClickMenuOnIconViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\Abstrac
      * @param string $table
      *
      * @return string
-     * @see \TYPO3\CMS\Backend\Template\DocumentTemplate->wrapClickMenuOnIcon()
+     * @see \TYPO3\CMS\Backend\Utility\BackendUtility::wrapClickMenuOnIcon()
      */
     public function render($table)
     {
diff --git a/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php b/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php
index 65445de623f9..7f7992e4396d 100644
--- a/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php
+++ b/typo3/sysext/fluid/Classes/ViewHelpers/Be/PageInfoViewHelper.php
@@ -68,7 +68,6 @@ class PageInfoViewHelper extends AbstractBackendViewHelper implements Compilable
      */
     public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext)
     {
-        $doc = GeneralUtility::makeInstance(DocumentTemplate::class);
         $id = GeneralUtility::_GP('id');
         $pageRecord = BackendUtility::readPageAccess($id, $GLOBALS['BE_USER']->getPagePermsClause(1));
         // Add icon with clickmenu, etc:
@@ -79,7 +78,7 @@ class PageInfoViewHelper extends AbstractBackendViewHelper implements Compilable
             $altText = BackendUtility::getRecordIconAltText($pageRecord, 'pages');
             $theIcon = '<span title="' . $altText . '">' . $iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() . '</span>';
             // Make Icon:
-            $theIcon = $doc->wrapClickMenuOnIcon($theIcon, 'pages', $pageRecord['uid']);
+            $theIcon = BackendUtility::wrapClickMenuOnIcon($theIcon, 'pages', $pageRecord['uid']);
 
             // Setting icon with clickmenu + uid
             $theIcon .= ' <em>[PID: ' . $pageRecord['uid'] . ']</em>';
@@ -88,7 +87,7 @@ class PageInfoViewHelper extends AbstractBackendViewHelper implements Compilable
             // Make Icon
             $theIcon = '<span title="' . htmlspecialchars($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']) . '">' . $iconFactory->getIcon('apps-pagetree-page-domain', Icon::SIZE_SMALL)->render() . '</span>';
             if ($GLOBALS['BE_USER']->user['admin']) {
-                $theIcon = $doc->wrapClickMenuOnIcon($theIcon, 'pages', 0);
+                $theIcon = BackendUtility::wrapClickMenuOnIcon($theIcon, 'pages', 0);
             }
         }
         return $theIcon;
diff --git a/typo3/sysext/frontend/Classes/Controller/TranslationStatusController.php b/typo3/sysext/frontend/Classes/Controller/TranslationStatusController.php
index 107d8dc0643f..32517fdaff11 100644
--- a/typo3/sysext/frontend/Classes/Controller/TranslationStatusController.php
+++ b/typo3/sysext/frontend/Classes/Controller/TranslationStatusController.php
@@ -133,7 +133,7 @@ class TranslationStatusController extends \TYPO3\CMS\Backend\Module\AbstractFunc
             // Page icons / titles etc.
             $tCells[] = '<td' . ($data['row']['_CSSCLASS'] ? ' class="' . $data['row']['_CSSCLASS'] . '"' : '') . '>' .
                 ($data['depthData'] ?: '') .
-                $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($data['HTML'], 'pages', $data['row']['uid']) .
+                BackendUtility::wrapClickMenuOnIcon($data['HTML'], 'pages', $data['row']['uid']) .
                 '<a href="#" onclick="' . htmlspecialchars(
                     'top.loadEditId(' . (int)$data['row']['uid'] . ',"&SET[language]=0"); return false;'
                 ) . '" title="' . $lang->sL('LLL:EXT:frontend/Resources/Private/Language/locallang_webinfo.xlf:lang_renderl10n_editPage') . '">' .
diff --git a/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php b/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
index 0ecff6995176..a4d48bc0e1d1 100644
--- a/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
+++ b/typo3/sysext/recordlist/Classes/RecordList/DatabaseRecordList.php
@@ -892,7 +892,7 @@ class DatabaseRecordList extends AbstractDatabaseRecordList
         $iconImg = '<span title="' . $altText . '" ' . $additionalStyle . '>'
             . $this->iconFactory->getIconForRecord($table, $row, Icon::SIZE_SMALL)->render()
             . '</span>';
-        $theIcon = $this->clickMenuEnabled ? $this->getModule()->getModuleTemplate()->wrapClickMenuOnIcon($iconImg, $table, $row['uid']) : $iconImg;
+        $theIcon = $this->clickMenuEnabled ? BackendUtility::wrapClickMenuOnIcon($iconImg, $table, $row['uid']) : $iconImg;
         // Preparing and getting the data-array
         $theData = array();
         $localizationMarkerClass = '';
-- 
GitLab