diff --git a/typo3/sysext/backend/Classes/Form/Element/UserElement.php b/typo3/sysext/backend/Classes/Form/Element/UserElement.php index 09a73f78bd8fa674f0646df6c242859446f8f227..dfb9368be93b1bc581b7733db4c5854451a6e535 100644 --- a/typo3/sysext/backend/Classes/Form/Element/UserElement.php +++ b/typo3/sysext/backend/Classes/Form/Element/UserElement.php @@ -1,4 +1,5 @@ <?php +declare(strict_types = 1); namespace TYPO3\CMS\Backend\Form\Element; /* @@ -17,7 +18,11 @@ namespace TYPO3\CMS\Backend\Form\Element; use TYPO3\CMS\Core\Utility\GeneralUtility; /** - * Generation of elements of the type "user" + * Generation of elements of the type "user". This is a dummy implementation. + * + * type="user" elements should be combined with a custom renderType to create custom output. + * This implementation registered for type="user" kicks in if no renderType is given and is just + * a fallback implementation to hint developers that the TCA registration is incomplete. */ class UserElement extends AbstractFormElement { @@ -28,9 +33,27 @@ class UserElement extends AbstractFormElement */ public function render() { + $parameterArray = $this->data['parameterArray']; $resultArray = $this->initializeResultArray(); - $parameterArray = $this->data['parameterArray']; + if (empty($parameterArray['fieldConf']['config']['userFunc'])) { + // If there is no (deprecated) userFunc, render some dummy output to explain this element + // should usually not be called at all. + // @deprecated The if can be removed in v10, keeping the body only. + $resultArray['html'] = '<div class="alert alert-warning">'; + $resultArray['html'] .= 'This is dummy output: Field <code>' . htmlspecialchars($this->data['fieldName']) . '</code>'; + $resultArray['html'] .= 'of table <code>' . htmlspecialchars($this->data['tableName']) . '</code>'; + $resultArray['html'] .= ' is registered as type="user" element without a specific renderType.'; + $resultArray['html'] .= ' Please look up details in TCA reference documentation for type="user".'; + $resultArray['html'] .= '</div>'; + return $resultArray; + } + + // @deprecated since TYPO3 v9, everything below will be removed in v10. + trigger_error( + 'Properties "userFunc", "noTableWrapping" and "parameters" have been deprecated in v9, will be removed in v10. Use a renderType instead.', + E_USER_DEPRECATED + ); $parameterArray['table'] = $this->data['tableName']; $parameterArray['field'] = $this->data['fieldName']; $parameterArray['row'] = $this->data['databaseRow']; diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86163-TCATypeuserWithoutRenderType.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86163-TCATypeuserWithoutRenderType.rst new file mode 100644 index 0000000000000000000000000000000000000000..191d2b1b1ca5eca5f48f714404fa7b906fd7e0b4 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-86163-TCATypeuserWithoutRenderType.rst @@ -0,0 +1,111 @@ +.. include:: ../../Includes.txt + +======================================================== +Deprecation: #86163 - TCA type="user" without renderType +======================================================== + +See :issue:`86163` + +Description +=========== + +The following `TCA` properties on :php:`type="user"` config types have been deprecated and +should not be used any longer: + +* :php:`userFunc` +* :php:`parameters` +* :php:`noTableWrapping` + + +Impact +====== + +This especially means that :php:`userFunc` should not be used any longer on `TCA` fields +registered as config type :php:`user`. Those can be substituted with a custom :php:`renderType` +since TYPO3 v7. See example below for more details on this. + + +Affected Installations +====================== + +Instances are affected if an extension registers a :php:`type=user` `TCA` config type with a +custom :php:`userFunc`. If a field uses the :php:`userFunc` property, a PHP :php:`E_USER_DEPRECATED` +error is triggered during rendering. + + +Migration +========= + +:php:`userFunc` implementations can switched to use a custom :php:`renderType` as outlined +in the :ref:`FormEngine documentation <t3coreapi:FormEngine-Rendering-NodeFactory>`. The TYPO3 core +did that for example with the `is_public` field of table `sys_file_storge` in patch 58141_. + +To switch from a :php:`userFunc` implementation to a :php:`renderType`, an extension typically has +to register an own element node in :file:`ext_localconf.php`. Then change the user function to a class +that extends :php:`AbstractFormElement` where method :php:`render()` returns an array as defined +my helper method :php:`initializeResultArray`. The `HTML` created by the former user function should be +returned in :php:`$resultArray['html']`, parameters like the `tableName` can be found in :php:`$this->data`. + +Note the `renderType` variant can additionally load custom `JavaScript` and `CSS` using further parts of the +result array, typically :php:`requireJsModules` and :php:`stylesheetFiles`. Additional arguments to the element +can be defined by using any property within the `config` section, it is up to the specific `renderType` to +do this, using `parameters` as property key is probably a good idea, though. + +As example, imagine a `TCA` user element has been defined like this in the `columns` section:: + + 'myMapElement' = [ + 'label' => 'My map element' + 'config' => [ + 'type' => 'user', + 'userFunc' => 'Vendor\Extension\Tca\UserFunc\MyMap->render', + 'parameters' => [ + 'useOpenStreetMap' => true, + ], + ], + ], + +This should be adapted to a registered node element class:: + + // Register a node in ext_localconf.php + $GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][<unix timestamp of "now">] = [ + 'nodeName' => 'lollisCustomMapElement', + 'priority' => 40, + 'class' => \Vendor\Extension\Form\Element\LollisCustomMapElement::class, + ]; + +With a `TCA` registration like this to delegate the element rendering to the registered class:: + + 'myMapElement' = [ + 'label' => 'My map element' + 'config' => [ + 'type' => 'user', + 'renderType' => 'lollisCustomMapElement', + 'parameters' => [ + 'useOpenStreetMap' => true, + ], + ], + ], + +And a class implementation that extends :php:`AbstractFormElement`:: + + <?php + declare(strict_types = 1); + namespace Vendor\Extension\Form\Element; + + use TYPO3\CMS\Backend\Form\Element\AbstractFormElement; + + class LollisCustomMapElement extends AbstractFormElement + { + public function render() + { + // Custom TCA properties and other data can be found in $this->data, for example the above + // parameters are available in $this->data['parameterArray']['fieldConf']['config']['parameters'] + $result = $this->initializeResultArray(); + $result['html'] = 'my map content'; + return $result; + } + } + +.. _58141: https://review.typo3.org/#/c/58141/ + +.. index:: Backend, TCA, NotScanned \ No newline at end of file