Project

General

Profile

Actions

Task #82404

closed

Improve enumeration usage

Added by Romain Canon over 6 years ago. Updated about 4 years ago.

Status:
Closed
Priority:
Should have
Assignee:
Category:
-
Start date:
2017-09-09
Due date:
% Done:

100%

Estimated time:
(Total: 0.00 h)
TYPO3 Version:
8
PHP Version:
Tags:
Complexity:
Sprint Focus:

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.


Subtasks 3 (0 open3 closed)

Task #82411: Breaking: refactor enumeration classClosedRomain Canon2017-09-09

Actions
Feature #82412: Add magic static call to enumeration classClosedRomain Canon2017-09-09

Actions
Task #82413: Change enumeration usage in coreClosedRomain Canon2017-09-09

Actions
Actions #1

Updated by Romain Canon over 6 years ago

  • Tracker changed from Feature to Task
  • TYPO3 Version set to 9
Actions #2

Updated by Gerrit Code Review over 6 years ago

  • Status changed from New to Under Review

Patch set 1 for branch master of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/54064

Actions #3

Updated by Romain Canon over 6 years ago

  • Tracker changed from Task to Epic
Actions #4

Updated by Romain Canon over 6 years ago

  • Sprint Focus deleted (On Location Sprint)
Actions #5

Updated by Susanne Moog over 5 years ago

  • Target version changed from 9 LTS to Candidate for Major Version
Actions #6

Updated by Susanne Moog about 5 years ago

  • Tracker changed from Epic to Feature
  • Status changed from Under Review to New

Patch has been abandoned.

Actions #7

Updated by Susanne Moog about 5 years ago

  • Tracker changed from Feature to Epic
Actions #8

Updated by Susanne Moog about 5 years ago

  • Tracker changed from Epic to Task
  • Status changed from New to Closed
  • TYPO3 Version set to 8

As this is a technical task and nothing happened for a long time due to lack of time, I'm going to close the ticket for now. If you have time to work on it again, please reopen (with pushing a patch).

Actions

Also available in: Atom PDF