Skip to content

Latest commit

 

History

History
163 lines (121 loc) · 5.26 KB

contribution.md

File metadata and controls

163 lines (121 loc) · 5.26 KB

Table of Contents

  1. Examples in action
  2. Overview of all rules
  3. Installation
  4. Configuration and Processing
  5. Best practice guide
  6. Limitations
  7. Contribution

Contributing

Want to help? Great! Join the TYPO3 Slack channel #ext-typo3-rector

Fork the project

Fork this project into your own account.

Install TYPO3 Rector

You can use TYPO3 Rector with at least PHP 7.4. Your contributed code MUST also be compatible with PHP 7.4!

Install the project using composer:

git clone [email protected]:your-account/typo3-rector.git
cd typo3-rector
composer install

Pick an issue from the list

https://github.com/sabbelasichon/typo3-rector/issues

INFO You can filter by tags where you can select, for example, only the easy ones by selecting "easy pick" or "good first issue".

Assign the issue to yourself

Assign the issue to yourself if you are a member of the project, so others can see that you are working on it. If you are not a member of the project, make a comment to let everyone know that you are working on it.

Create an own Rector Rule

Run the following command and answer all questions:

bin/typo3-rector

This command will ask you some questions to provide a proper rector setup. Following this will lead to the creation of the overall rector structure necessary. It will create the skeleton for the rector rule with the class, test class, fixtures and directories to start coding — basically everything you need to start!

Useful infos:

  • the refactor must return a node, an array of nodes or null.
  • keep it flat! Use early returns (with null) in case your conditions for migration are not met.
  • the getNodeTypes method is used to define the use case of the function to migrate. It helps as well acting like an early return (see example below).
  • helper functions and classes are provided via rector to make it easy for you to control further processing.
  • here is a list of all php node types: https://github.com/rectorphp/php-parser-nodes-docs/blob/master/README.md
  • search for similar rules and copy the code that is helpful for you. Frequent times you only need to make a few adjustments to existing rules.

Example

In this example the methods GeneralUtility::strtoupper(...) and GeneralUtility::strtolower(...) are migrated.

  • getNodeTypes checks for the StaticCall, preventing further rector execution if not met
  • refactor first checks for the ObjectType to do an early return in case the class scanned is not TYPO3\CMS\Core\Utility\GeneralUtility
  • after that, the actual function call is checked for being one of the functions to migrate
final class GeneralUtilityToUpperAndLowerRector extends AbstractRector implements DocumentedRuleInterface
{
    /**
     * @return array<class-string<Node>>
     */
    public function getNodeTypes(): array
    {
        return [StaticCall::class];
    }

    /**
     * @param StaticCall $node
     */
    public function refactor(Node $node): ?Node
    {
        if (! $this->nodeTypeResolver->isMethodStaticCallOrClassMethodObjectType(
            $node,
            new ObjectType('TYPO3\CMS\Core\Utility\GeneralUtility')
        )) {
            return null;
        }

        if (! $this->isNames($node->name, ['strtoupper', 'strtolower'])) {
            return null;
        }

        // ...
    }
}

Return multiple Nodes

Sometimes you need to return more than a single node. A typical use case is if you want to create another method, for example. In this case you need to listen to an Expression. Do a full text search for [Expression::class] to find existing rules which can help you.

final class MyRector extends AbstractRector implements DocumentedRuleInterface
{
    public function getNodeTypes(): array
    {
        return [Expression::class];
    }

    /**
     * @param Expression $node
     * @return Node[]|null
     */
    public function refactor(Node $node): ?array
    {
        $methodCall = $node->expr;

        if (! $methodCall instanceof Node\Expr\MethodCall) {
            return null;
        }

        // More checks

        // Do your magic

        $methodCall = $this->nodeFactory->createMethodCall(...);

        return [new Expression($methodCall), $node];
    }
}

All Tests must be green

Make sure you have a test in place for your Rector

All unit tests must pass before submitting a pull request. Additionally, the code style must be valid. Run the following commands:

composer run-script contribute
vendor/bin/phpunit

Overall hints for testing:

  • testing happens via fixture files (*.php.inc)
  • those files display the code before and after execution, separated by -----
  • rector keeps spaces etc. as its job is migration and not code cleaning, so keep that in mind. TCA fixture files don't need to look pretty!
  • provide custom test classes via "Source" folder, that will be tested, but will not be affected by your rector to test and prevent side effects of your rule.
  • Add stubs that reflect the original code

Submit your changes

Great, now you can submit your changes in a pull request