How to deprecate classes, methods, arguments and hooks in the TYPO3 core
TYPO3 Core development policy states that public API will not be changed without a grace period where extension authors can adapt to the changes. In that grace period a deprecation warning will be thrown. If you want to remove or change functionality in the TYPO3 Core, it has to be deprecated first.
Note
Upon deprecating or removing functionality the change must be added to the Extension scanner whenever possible.
Note
It's not always possible to "deprecate" everything. In some cases,
hard breaking changes must be introduced. These need to be addressed
and discussed with much care beyond the scope of this chapter, and can
only occur in new major versions of TYPO3 in the X.
focus release.
Here is how:
Deprecate a class
- Add a
@deprecated
annotation to the class doc comment - Deprecate the constructor - see next section about deprecating a method
Deprecate method
- Add a
@deprecated
annotation to the method doc comment - Add a
trigger_
call to the method, describing the migration path and triggering an error of typeerror E_
USER_ DEPRECATED
trigger_error(
'Content with <link> syntax was found, update your content to use the t3:// syntax, and migrate your content via the upgrade wizard in the install tool',
E_USER_DEPRECATED
);
Deprecate method arguments
If you want to deprecate method arguments, check for argument existence and
trigger an error the same way you would for a method. If you want to deprecate
and remove an unused argument, use func_
or func_
(see example below):
public function TS_AtagToAbs($value)
{
if (func_num_args() > 1) {
trigger_error('Second argument of TS_AtagToAbs() is not in use and is removed, however the argument in the callers code can be removed without side-effects.', E_USER_DEPRECATED);
}
// ...
}
Make class properties protected
To reach full encapsulation of classes, the public access to properties should be removed. The property access should be done by public methods only.
Public properties that should be protected can be migrated to protected or private and wrapped with getters/setters as needed.
During a phase of deprecation, entries into the deprecation log are triggered, if an extension accesses a previously public property. The code still keeps working until the next major release, when the deprecation and public access fallback are removed from the code.
To deprecate usage of a (still) public property that should be changed to protected in the future:
- Add the
\TYPO3\
trait to the class.CMS\ Core\ Compatibility\ Public Property Deprecation Trait - Add the property
$deprecated
to the class and list all properties that should no longer be accessed from outside of the class.Public Properties - Make the property private/protected.
+use TYPO3\CMS\Core\Compatibility\PublicPropertyDeprecationTrait;
+
class RecordHistory
{
+ use PublicPropertyDeprecationTrait;
+
+ /**
+ * @var string[]
+ */
+ private $deprecatedPublicProperties = [
+ 'changeLog' => 'Using changeLog is deprecated and will not be possible anymore in TYPO3 v11.0. Use getChangeLog() instead.',
+ ];
+
/**
* @var array
*/
- public $changeLog = [];
+ protected $changeLog = [];
Make class methods protected
This works in a similar way as Make class properties protected: The trait
\TYPO3\
allows to make
public methods protected or private without breaking extensions.
This can be used in case the public methods may still be called by extensions. This will then trigger a deprecation.
In order to make a method private or protected:
- Add the
\TYPO3\
trait to the class.CMS\ Core\ Compatibility\ Public Method Deprecation Trait - Add the property
$deprecated
to the class and list all methods that should no longer be accessed from outside of the class.Public Methods - Make the method private/protected.
+use TYPO3\CMS\Core\Compatibility\PublicMethodDeprecationTrait;
+
class PageRepository
{
+ use PublicMethodDeprecationTrait;
+
+ /**
+ * @var string[]
+ */
+ private $deprecatedPublicMethods = [
+ 'init' => 'init() is now called implicitly on object creation, and is not necessary anymore to be called explicitly. Calling init() will throw an error in TYPO3 v10.0.',
+ ];
+
- public function init($show_hidden)
+ protected function init($show_hidden)
Deprecate a hook
As hooks provide extension points throughout the core, deprecating and removing
them should be carefully considered, but sometimes the placement of a hook doesn't
make sense anymore as the functionality around it changed or other hooks / mechanisms
replaced it's purpose. If you have to deprecate a hook, call trigger_
before the hook call:
if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['modifyParams_LinksDb_PostProc'])
&& is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['modifyParams_LinksDb_PostProc'])) {
trigger_error(
'The hook "t3lib/class.t3lib_parsehtml_proc.php->modifyParams_LinksDb_PostProc" will be removed in TYPO3 v10, use LinkService syntax to modify links to be stored in the database.',
E_USER_DEPRECATED
);
$parameters = [
'currentBlock' => $v,
'linkInformation' => $linkInformation,
'url' => $linkInformation['href'],
'attributes' => $tagAttributes
];
foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_parsehtml_proc.php']['modifyParams_LinksDb_PostProc'] as $className) {
$processor = GeneralUtility::makeInstance($className);
$blockSplit[$k] = $processor->modifyParamsLinksDb($parameters, $this);
}
}
Deprecate methods still called by the TYPO3 Core
If you want to deprecate a method that still has to be used by the core itself to provide the functionality for the time being, you can achieve that by adding a new method parameter that will prevent the deprecation warning message being triggered and add that parameter to the callees in the core.
Example:
/**
* Transformation handler: 'ts_links' / direction: "rte"
* Converting TYPO3-specific <link> tags to <a> tags
*
* This functionality is only used to convert legacy <link> tags to the new linking syntax using <a> tags, and will
* not be converted back to <link> tags anymore.
*
* @param string $value Content input
* @param bool $internallyCalledFromCore internal option for calls where the Core is still using this function, to suppress method deprecations
* @return string Content output
* @deprecated will be removed in TYPO3 v10, only ->TS_AtagToAbs() should be called directly, <link> syntax is deprecated
*/
public function TS_links_rte($value, $internallyCalledFromCore = null)
{
if ($internallyCalledFromCore === null) {
trigger_error('This method will be removed in TYPO3 v10, use TS_AtagToAbs() directly and do not use <link> syntax anymore', E_USER_DEPRECATED);
}
$hasLinkTags = false;
$value = $this->TS_AtagToAbs($value);
// ...
}
More information
Changelogs