[TASK] Switch UserStorageCapabilityService to a renderType 41/58141/4
authorChristian Kuhn <lolli@schwarzbu.ch>
Mon, 3 Sep 2018 14:16:34 +0000 (16:16 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Mon, 3 Sep 2018 18:52:15 +0000 (20:52 +0200)
Using a TCA type=user with a custom renderType is much more
elegant since the registered element can then fully access
$this->data and has control of node expansion and all the
other goodies that come with own renderType in comparison
to the shabby limited type=user with userFunc.
The patch switches the 'is_public' type=user userFunc to
a proper renderType and fixes the incomplete HTML of this
field along the way.
Note a type=check with own renderType is not possible in
this case since the config has no items array.

Resolves: #86109
Releases: master
Change-Id: I72507a4660fc64e5c2df60768564a788a4c38a05
Reviewed-on: https://review.typo3.org/58141
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/backend/Classes/Form/Element/CheckboxToggleElement.php
typo3/sysext/backend/Classes/Form/Element/UserSysFileStorageIsPublicElement.php [new file with mode: 0644]
typo3/sysext/backend/Classes/Form/NodeFactory.php
typo3/sysext/core/Classes/Resource/Service/UserStorageCapabilityService.php
typo3/sysext/core/Configuration/TCA/sys_file_storage.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-86109-ClassUserStorageCapabilityService.rst [new file with mode: 0644]
typo3/sysext/install/Configuration/ExtensionScanner/Php/ClassNameMatcher.php

index e94cf94..9b97ee4 100644 (file)
@@ -90,7 +90,7 @@ class CheckboxToggleElement extends AbstractFormElement
         // Traversing the array of items
         $items = $this->data['parameterArray']['fieldConf']['config']['items'];
 
         // Traversing the array of items
         $items = $this->data['parameterArray']['fieldConf']['config']['items'];
 
-        $numberOfItems = \count($items);
+        $numberOfItems = count($items);
         if ($numberOfItems === 0) {
             $items[] = ['', ''];
             $numberOfItems = 1;
         if ($numberOfItems === 0) {
             $items[] = ['', ''];
             $numberOfItems = 1;
diff --git a/typo3/sysext/backend/Classes/Form/Element/UserSysFileStorageIsPublicElement.php b/typo3/sysext/backend/Classes/Form/Element/UserSysFileStorageIsPublicElement.php
new file mode 100644 (file)
index 0000000..3c74fe8
--- /dev/null
@@ -0,0 +1,129 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Backend\Form\Element;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Localization\LanguageService;
+use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Messaging\FlashMessageService;
+use TYPO3\CMS\Core\Resource\Exception\InvalidPathException;
+use TYPO3\CMS\Core\Resource\ResourceFactory;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Special type="user" element used in sys_file_storage is_public field
+ *
+ * @internal
+ */
+class UserSysFileStorageIsPublicElement extends AbstractFormElement
+{
+    /**
+     * Default field information enabled for this element.
+     *
+     * @var array
+     */
+    protected $defaultFieldInformation = [
+        'tcaDescription' => [
+            'renderType' => 'tcaDescription',
+        ],
+    ];
+
+    /**
+     * There are some edge cases where "is_public" can never be marked as true in the BE,
+     * for instance for storage located outside the document root or
+     * for storages driven by special driver such as Flickr, ...
+     *
+     * @return array As defined in initializeResultArray() of AbstractNode
+     */
+    public function render(): array
+    {
+        $row = $this->data['databaseRow'];
+        $parameterArray = $this->data['parameterArray'];
+        $isPublic = (bool)$GLOBALS['TCA']['sys_file_storage']['columns']['is_public']['config']['default'];
+
+        if ($this->data['command'] === 'edit') {
+            // Make sure the storage object can be retrieved which is not the case when new storage.
+            $lang = $this->getLanguageService();
+            $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
+            $defaultFlashMessageQueue = $flashMessageService->getMessageQueueByIdentifier();
+            try {
+                $storage = ResourceFactory::getInstance()->getStorageObject((int)$row['uid']);
+                $storageRecord = $storage->getStorageRecord();
+                $isPublic = $storage->isPublic() && $storageRecord['is_public'];
+
+                // Display a warning to the BE User in case settings is not inline with storage capability.
+                if ($storageRecord['is_public'] && !$storage->isPublic()) {
+                    $message = GeneralUtility::makeInstance(
+                        FlashMessage::class,
+                        $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.message.storage_is_no_public'),
+                        $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:warning.header.storage_is_no_public'),
+                        FlashMessage::WARNING
+                    );
+                    $defaultFlashMessageQueue->enqueue($message);
+                }
+            } catch (InvalidPathException $e) {
+                $message = GeneralUtility::makeInstance(
+                    FlashMessage::class,
+                    $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:filestorage.invalidpathexception.message'),
+                    $lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:filestorage.invalidpathexception.title'),
+                    FlashMessage::ERROR
+                );
+                $defaultFlashMessageQueue->enqueue($message);
+            }
+        }
+
+        $fieldInformationResult = $this->renderFieldInformation();
+        $fieldInformationHtml = $fieldInformationResult['html'];
+        $resultArray = $this->mergeChildReturnIntoExistingResult($this->initializeResultArray(), $fieldInformationResult, false);
+
+        $checkboxParameters = $this->checkBoxParams($parameterArray['itemFormElName'], $isPublic, 0, 1, implode('', $parameterArray['fieldChangeFunc']));
+        $checkboxId = $parameterArray['itemFormElID'] . '_1';
+        $html = [];
+        $html[] = '<div class="formengine-field-item t3js-formengine-field-item">';
+        $html[] = $fieldInformationHtml;
+        $html[] =   '<div class="form-wizards-wrap">';
+        $html[] =       '<div class="form-wizards-element">';
+        $html[] =           '<div class="checkbox checkbox-type-toggle">';
+        $html[] =               '<input type="checkbox"';
+        $html[] =                   ' class="checkbox-input"';
+        $html[] =                   ' value="1"';
+        $html[] =                   ' data-formengine-input-name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
+        $html[] =                   ' id="' . htmlspecialchars($checkboxId) . '"';
+        $html[] =                   $checkboxParameters;
+        $html[] =                   $isPublic ? ' checked="checked"' : '';
+        $html[] =               '/>';
+        $html[] =               '<label class="checkbox-label" for="' . htmlspecialchars($checkboxId) . '">';
+        $html[] =                   '<span class="checkbox-label-text">' . $this->appendValueToLabelInDebugMode('&nbsp;', $isPublic ? '1' : '0') . '</span>';
+        $html[] =               '</label>';
+        $html[] =               '<input type="hidden"';
+        $html[] =                   ' name="' . htmlspecialchars($parameterArray['itemFormElName']) . '"';
+        $html[] =                   ' value="' . htmlspecialchars((string)$isPublic) . '"';
+        $html[] =               ' />';
+        $html[] =           '</div>';
+        $html[] =       '</div>';
+        $html[] =   '</div>';
+        $html[] = '</div>';
+        $resultArray['html'] = implode(LF, $html);
+        return $resultArray;
+    }
+
+    /**
+     * @return LanguageService
+     */
+    protected function getLanguageService(): LanguageService
+    {
+        return $GLOBALS['LANG'];
+    }
+}
index 63fb6c6..e98a5f5 100644 (file)
@@ -91,6 +91,8 @@ class NodeFactory
         'textTable' => Element\TextTableElement::class,
         'unknown' => Element\UnknownElement::class,
         'user' => Element\UserElement::class,
         'textTable' => Element\TextTableElement::class,
         'unknown' => Element\UnknownElement::class,
         'user' => Element\UserElement::class,
+        // special renderType for type="user" on sys_file_storage is_public column
+        'userSysFileStorageIsPublic' => Element\UserSysFileStorageIsPublicElement::class,
         'fileInfo' => Element\FileInfoElement::class,
         'slug' => Element\InputSlugElement::class,
         'passthrough' => Element\PassThroughElement::class,
         'fileInfo' => Element\FileInfoElement::class,
         'slug' => Element\InputSlugElement::class,
         'passthrough' => Element\PassThroughElement::class,
index 0a4d878..d0d2748 100644 (file)
@@ -24,10 +24,20 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Utility class to render capabilities of the storage.
 
 /**
  * Utility class to render capabilities of the storage.
+ *
+ * @deprecated since TYPO3 v9, will be removed in TYPO3 v10.
  */
 class UserStorageCapabilityService
 {
     /**
  */
 class UserStorageCapabilityService
 {
     /**
+     * Constructor logs deprecation
+     */
+    public function __construct()
+    {
+        trigger_error('This class will be removed in TYPO3 v10.', E_USER_DEPRECATED);
+    }
+
+    /**
      * UserFunc function for rendering field "is_public".
      * There are some edge cases where "is_public" can never be marked as true in the BE,
      * for instance for storage located outside the document root or
      * UserFunc function for rendering field "is_public".
      * There are some edge cases where "is_public" can never be marked as true in the BE,
      * for instance for storage located outside the document root or
index dabadc2..c5aa724 100644 (file)
@@ -74,7 +74,7 @@ return [
             'config' => [
                 'default' => true,
                 'type' => 'user',
             'config' => [
                 'default' => true,
                 'type' => 'user',
-                'userFunc' => \TYPO3\CMS\Core\Resource\Service\UserStorageCapabilityService::class . '->renderIsPublic',
+                'renderType' => 'userSysFileStorageIsPublic',
             ]
         ],
         'is_writable' => [
             ]
         ],
         'is_writable' => [
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86109-ClassUserStorageCapabilityService.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86109-ClassUserStorageCapabilityService.rst
new file mode 100644 (file)
index 0000000..036e4bd
--- /dev/null
@@ -0,0 +1,35 @@
+.. include:: ../../Includes.txt
+
+========================================================
+Deprecation: #86109 - Class UserStorageCapabilityService
+========================================================
+
+See :issue:`86109`
+
+Description
+===========
+
+Class :php:`TYPO3\CMS\Core\Resource\Service\UserStorageCapabilityService` has been
+marked as deprecated and should not be used any longer.
+
+
+Impact
+======
+
+This core internal class has been switched from a `TCA` :php:`userFunc` to a
+:php:`renderType`.
+
+
+Affected Installations
+======================
+
+Extensions probably never used this internal class, however, the extension
+scanner will still find any usages.
+
+
+Migration
+=========
+
+No migration possible.
+
+.. index:: Backend, PHP-API, TCA, FullyScanned
index 9ffba24..dae0ad6 100644 (file)
@@ -924,4 +924,9 @@ return [
             'Deprecation-85977-ExtbaseCommandControllersAndCliAnnotation.rst',
         ],
     ],
             'Deprecation-85977-ExtbaseCommandControllersAndCliAnnotation.rst',
         ],
     ],
+    'TYPO3\CMS\Core\Resource\Service\UserStorageCapabilityService' => [
+        'restFiles' => [
+            'Deprecation-86109-ClassUserStorageCapabilityService.rst',
+        ],
+    ],
 ];
 ];