From a6a0d11cd9d2aa1a24c06114922619a0404aa71b Mon Sep 17 00:00:00 2001
From: Mario Lubenka <mario.lubenka@googlemail.com>
Date: Tue, 31 Dec 2019 21:31:51 +0100
Subject: [PATCH] [FEATURE] Customize special page icons by doktype

Resolves: #90042
Releases: master
Change-Id: I9ca7dbc59495372033659d7d4c82142c92ed5e1b
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/62813
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: Benni Mack <benni@typo3.org>
---
 .../core/Classes/Imaging/IconFactory.php      | 41 ++++++++++++++++---
 ...-SpecialPageIconsCustomizableByDoktype.rst | 41 +++++++++++++++++++
 2 files changed, 77 insertions(+), 5 deletions(-)
 create mode 100644 typo3/sysext/core/Documentation/Changelog/master/Feature-90042-SpecialPageIconsCustomizableByDoktype.rst

diff --git a/typo3/sysext/core/Classes/Imaging/IconFactory.php b/typo3/sysext/core/Classes/Imaging/IconFactory.php
index a65e088f8ede..197781eea214 100644
--- a/typo3/sysext/core/Classes/Imaging/IconFactory.php
+++ b/typo3/sysext/core/Classes/Imaging/IconFactory.php
@@ -165,20 +165,32 @@ class IconFactory
             // and to give root-pages an own icon
             if ($table === 'pages') {
                 if ((int)$row['nav_hide'] > 0) {
-                    $recordType[2] = $recordType[1] . '-hideinmenu';
+                    $recordType[2] = $this->getRecordTypeForPageType(
+                        $recordType[1],
+                        'hideinmenu',
+                        $table
+                    );
                 }
                 if ((int)$row['is_siteroot'] > 0) {
-                    $recordType[3] = $recordType[1] . '-root';
+                    $recordType[3] = $this->getRecordTypeForPageType(
+                        $recordType[1],
+                        'root',
+                        $table
+                    );
                 }
                 if (!empty($row['module'])) {
                     $recordType[4] = 'contains-' . $row['module'];
                 }
                 if ((int)$row['content_from_pid'] > 0) {
                     if ($row['is_siteroot']) {
-                        $recordType[4] = 'page-contentFromPid-root';
+                        $recordType[4] = $this->getRecordTypeForPageType(
+                            $recordType[1],
+                            'contentFromPid-root',
+                            $table
+                        );
                     } else {
-                        $recordType[4] = (int)$row['nav_hide'] === 0
-                            ? 'page-contentFromPid' : 'page-contentFromPid-hideinmenu';
+                        $suffix = (int)$row['nav_hide'] === 0 ? 'contentFromPid' : 'contentFromPid-hideinmenu';
+                        $recordType[4] = $this->getRecordTypeForPageType($recordType[1], $suffix, $table);
                     }
                 }
             }
@@ -233,6 +245,25 @@ class IconFactory
         return $this->iconRegistry->getDefaultIconIdentifier();
     }
 
+    /**
+     * Returns recordType for icon based on a typeName and a suffix.
+     * Fallback to page as typeName if resulting type is not configured.
+     * @param  string  $typeName
+     * @param  string  $suffix
+     * @param  string  $table
+     * @return string
+     */
+    protected function getRecordTypeForPageType(string $typeName, string $suffix, string $table): string
+    {
+        $recordType = $typeName . '-' . $suffix;
+
+        // Check if typeicon class exists. If not fallback to page as typeName
+        if (!isset($GLOBALS['TCA'][$table]['ctrl']['typeicon_classes'][$recordType])) {
+            $recordType = 'page-' . $suffix;
+        }
+        return $recordType;
+    }
+
     /**
      * This helper function checks if the DB record ($row) has any special status based on the TCA settings
      * like hidden, starttime etc, and then returns a specific icon overlay identifier for the overlay of this DB record
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-90042-SpecialPageIconsCustomizableByDoktype.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-90042-SpecialPageIconsCustomizableByDoktype.rst
new file mode 100644
index 000000000000..30f0ad996a79
--- /dev/null
+++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-90042-SpecialPageIconsCustomizableByDoktype.rst
@@ -0,0 +1,41 @@
+.. include:: ../../Includes.txt
+
+=========================================================
+Feature: #90042 - Customize special page icons by doktype
+=========================================================
+
+See :issue:`90042`
+
+Description
+===========
+
+The page icon in the pagetree can now be fully customized for own doktypes.
+Before this it was possible to provide one icon. This icon however was not used when the page was in one of the following states:
+
+* Page is hidden in navigation
+* Page is site-root
+* Page contains content from another page
+* Page contains content from another page AND is hidden in navigation
+
+Provide custom icons in TCA like so:
+
+:file:`EXT:my_extension/Configuration/TCA/Overrides/pages.php`
+
+.. code-block:: php
+
+   'ctrl' => [
+      'typeicon_classes' => [
+          '123' => "your-icon",
+          '123-contentFromPid' => "your-icon-contentFromPid",
+          '123-root' => "your-icon-root",
+          '123-hideinmenu' => "your-icon-hideinmenu",
+      ],
+   ]
+
+Icons you don't provide here will automatically fallback to the variant for regular page doktype.
+
+.. note::
+
+   Make sure to add the additional icons using the IconRegistry!
+
+.. index:: TCA, ext:core
-- 
GitLab