Task #82404
closedImprove enumeration usage
100%
Description
TL;DR - Improve the enumeration feature to have something more similar to this implementation: https://github.com/myclabs/php-enum
Current usage
The current core enumeration implementations mainly work with string values and do not force types in any way. This can lead to incorrect values being used by functions and lead to more runtime errors.
See below some basic usage taken in current core master, and comments about what is wrong with them:
// Doubling type casting + duplicated class name
(int)(string)new VersionState(VersionState::DEFAULT_STATE)
// Duplicated class name + useless instance (could be only string comparison)
switch (VersionState::cast($row['t3ver_state'])) {
case new VersionState(VersionState::NEW_PLACEHOLDER):
$parts[] = 'PLH WSID#' . $row['t3ver_wsid'];
break;
}
// A string is passed in `$conflictMode`.
//
// This should not be the responsability of the method `rename()`
// to validate and cast the value that is passed, but to the
// method that actually calls `rename()`.
//
// This can lead to more errors if not handled correctly.
public function rename($newName, $conflictMode = DuplicationBehavior::RENAME)
Goal
The main goal of the patch would be to use enumerations as value objects, which allows a much more stronger and bug-free application, as well as more flexibility in how data can be used. This also helps with onboarding new contributors who can understand the logic behind a function much more easily.
The current enumeration class (\TYPO3\CMS\Core\Type\Enumeration
) would be improved.
Magic method calls
One of the new introduced features would be magic static methods calls, to dramatically ease readability:
// Old way:
$myEnum = MyEnum::cast(MyEnum::MY_VALUE);
// New way:
$myEnum = MyEnum::MY_VALUE();
Data mapping
The data mapper automatically fills enum values, which means a frontend form being submitted can then create a PHP object containing enum values, which is awesome when you actually have to work with the object.
Utility methods
Enumeration classes should use more utility functions to ease the usage when working with implementation.
TYPO3 core already uses this kind of methods (see TYPO3\CMS\Backend\Toolbar\Enumeration\InformationStatus::isGreaterThan()
), but there could be much more.
Example
See below an implementation example of how TYPO3 page types could be handled:
// The actual enumeration class.
class PageType extends Enumeration
{
// Pages
const STANDARD = 1;
const BACKEND_USER_SECTION = 6;
// Links
const SHORTCUT = 4;
const MOUNT_POINT = 7;
const EXTERNAL_URL = 3;
// Special
const FOLDER = 254;
const RECYCLER = 255;
const MENU_SEPARATOR = 199;
/**
* Will be true if the type is one of the links types.
*
* @return bool
*/
public function isLink(): bool
{
return $this->equal(static::SHORTCUT())
|| $this->equal(static::MOUNT_POINT())
|| $this->equal(static::EXTERNAL_URL());
}
/**
* Will be true only if the type is folder, false in any other case.
*
* @return bool
*/
public function isFolder(): bool
{
return $this->equals(static::FOLDER());
}
}
// A class using the enumeration.
class Page
{
/**
* @var PageType
*/
protected $type;
/**
* @param PageType $type
*/
public function setType(PageType $type)
{
$this->type = $type;
}
/**
* @return PageType
*/
public function getType()
{
return $this->type;
}
}
// Basic usage.
class MyClass
{
public function process()
{
$page = new Page;
$page->setType(PageType::STANDARD());
// ...
$this->doSomething($page);
}
/**
* @param Page $page
*/
protected function doSomething(Page $page)
{
if ($page->getType()->isFolder()) {
// Do folder related things...
} elseif ($page->getType()->isLink()) {
// Create some link...
} elseif ($page->getType()->equals(PageType::STANDARD())) {
// ...
} else {
// ...
}
}
}
Please note that this whole implementation has already been done and used in my company for a whole year now, using this tiny library: https://github.com/myclabs/php-enum
Every developer uses it almost every day and everyone did say this improved productivity, code understanding and application reliability by a lot, compared to an old string-comparison way.