Git Product home page Git Product logo

typo3-rector's Introduction

Caution

Never run this tool on production, only on development environment where code is under version control (e.g. git). Always review and test automatic changes before releasing to production.

Rector for TYPO3

Apply automatic fixes on your TYPO3 code.

Coverage Status

Rector aims to provide instant upgrades and instant refactoring of any PHP 5.3+ code. This project adds rectors specific to TYPO3 to help you migrate between TYPO3 releases or keep your code deprecation free.

Let´s see some examples in action

Let´s say you have a Fluid ViewHelper looking like this:

class InArrayViewHelper extends \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper
{
    /**
     * Checks if given $uid is in a given $array
     *
     * @param int $uid the uid
     * @param array $arrayToCheckAgainst the array to check for the given $uid
     * @return bool
     */
    public function render($uid, array $arrayToCheckAgainst)
    {
        if (in_array($uid, $arrayToCheckAgainst)) {
           return true;
        } else {
           return false;
        }
    }
}

What´s "wrong" with this code? Well, it depends on the context. But, if we assume you would like to have this code ready for TYPO3 version 10 you should move the render method arguments to the method initializeArguments and you should rename the namespace \TYPO3\CMS\Fluid\Core\ViewHelper\AbstractViewHelper to \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper.

And we are not talking about the superfluous else statement, not having Type Declarations or in_array could be used. That´s a different story.

Do you like to do these changes manually on a codebase with let´s say 40-100 ViewHelpers? We don´t. So let Rector do the heavy work for us and apply the "rules" MoveRenderArgumentsToInitializeArgumentsMethodRector and RenameClassMapAliasRector for Version 9.5.

Rector transforms this code for us to the following one:

class InArrayViewHelper extends \TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper
{
    public function initializeArguments(): void
    {
        $this->registerArgument('uid', 'int', 'the uid', true);
        $this->registerArgument('arrayToCheckAgainst', 'array', 'the array to check for the given $uid', true);
    }

    /**
     * Checks if given $uid is in a given $array
     *
     * @return bool
     */
    public function render()
    {
        $uid = $this->arguments['uid'];
        $arrayToCheckAgainst = $this->arguments['arrayToCheckAgainst'];
        if (in_array($uid, $arrayToCheckAgainst)) {
           return true;
        } else {
           return false;
        }
    }
}

Isn´t this amazing? You don´t even have to know that these change has to be done. Your changelog resides in living code.

Let´s see another one:

final class SomeService
{
    /**
     * @var \Ssch\TYPO3Rector\Tests\Rector\Annotation\Source\InjectionClass
     * @inject
     */
    protected $injectMe;
}

So we guess, everyone knows that TYPO3 switched to Doctrine Annotations on the one hand and you should better use either constructor injection or setter injection. Again, if you have only one class, this change is not a problem. But most of the time you have hundreds of them and you have to remember what to do. This is cumbersome and error prone. So let´s run Rector for us with the InjectAnnotationRector and you get this:

use Ssch\TYPO3Rector\Tests\Rector\Annotation\Source\InjectionClass;

final class SomeInjectClass
{
    /**
     * @var \Ssch\TYPO3Rector\Tests\Rector\Annotation\Source\InjectionClass
     */
    protected $injectMe;

    public function injectInjectMe(InjectionClass $inject): void
    {
        $this->inject = $inject;
    }
}

Cool. Let me show you one more example.

Let´s say you want to upgrade vom version 9 to 10 and you have the following code:

use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Extbase\Configuration\Exception\NoSuchOptionException;

class MyActionController extends ActionController
{
    public function exceptionAction()
    {
        $foo = 'foo';
        $bar = 'bar';
        if($foo !== $bar) {
            throw new NoSuchOptionException();
        }
    }
}

Can you spot the error? Guess not. At least i couldn´t. The exception class NoSuchOptionException does not exist anymore in version 10. What. But it still worked in version 9. Why? Because TYPO3 offers a nice way to deprecate such changes for one major version with these handy ClassAliasMap.php files. But, postponed is not abandoned. You have to react to these changes at a certain time. Do you know all these changes by heart? Sure not.

So, again, let rector do it for you with the RenameClassMapAliasRector. Have a look at an example config file shipped with typo3-rector

And there is more...

...look at the overview of all available TYPO3 Rectors with before/after diffs and configuration examples.

You can also watch the video from the T3CRR conference:

RectorPHP for TYPO3

Installation

Install the library.

$ composer require --dev ssch/typo3-rector

Composer conflicts

It is not uncommon to run into unresolvable composer conflicts when installing typo3-rector, especially with older TYPO3 Versions (< 9.5 LTS), for example TYPO3 8.7 LTS. In this case, you have multiple options:

Solution #1

The best solution is to install the package ssch/typo3-rector-shim

$ composer require --dev ssch/typo3-rector-shim

Solution #2

As an alternative to installing ssch/typo3-rector-shim, you may also want to use the package rector/rector-prefixed, which aims for maximum compatibility. Just install it via composer before installing ssch/typo3-rector, it works as a drop-in-replacement for rector/rector:

$ composer require --dev rector/rector-prefixed
$ composer require --dev ssch/typo3-rector

Non composer installations

If you have a non composer TYPO3 installation. Don´t worry. Install typo3-rector as a global dependency:

$ composer global require --dev ssch/typo3-rector

Add an extra autoload file. In the example case it is placed in the Document Root of your TYPO3 project. The autoload could look something like that:

use TYPO3\CMS\Core\Core\Bootstrap;
use TYPO3\CMS\Core\Core\ClassLoadingInformation;
use TYPO3\CMS\Core\Core\SystemEnvironmentBuilder;

define('PATH_site', __DIR__.'/public/');
$classLoader = require PATH_site.'/typo3_src/vendor/autoload.php';

SystemEnvironmentBuilder::run(0, SystemEnvironmentBuilder::REQUESTTYPE_CLI);

ClassLoadingInformation::setClassLoader($classLoader);
if (ClassLoadingInformation::isClassLoadingInformationAvailable()) {
    ClassLoadingInformation::registerClassLoadingInformation();
}

Bootstrap::initializeClassLoader($classLoader);

Afterwards run rector:

php ~/.composer/vendor/bin/typo3-rector process public/typo3conf/ext/your_extension/  -c .rector/config.php -n --autoload-file autoload.php

Configuration and Processing

This library ships already with a bunch of configuration files organized by TYPO3 version. To get you started quickly run the following command inside the root directory of your project:

./vendor/bin/typo3-rector typo3-init

The command generates a basic configuration skeleton which you can adapt to your needs. The file is fully of comments so you can follow along what is going on.

For more configuration options see Rector README.

After your adopt the configuration to your needs, run typo3-rector to simulate (hence the option -n) the future code fixes:

./vendor/bin/typo3-rector process packages/my_custom_extension --dry-run

Check if everything makes sense and run the process command without the --dry-run option to apply the changes.

Contributing

Want to help? Great! Joing TYPO3 slack channel #ext-typo3-rector

Fork the project

Fork this project into your own account.

Install typo3-rector

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 You can filter by tags

Assign the issue to yourself

Assign the issue to yourself so others can see that you are working on it.

Create Rector

Run command and answer all questions properly

./bin/typo3-rector typo3-create

Afterwards you have to write your Rector and your tests for it. If you need, you have to create so called stubs. Stubs contain basically the skeleton of the classes you would like to refactor. Have a look at the stubs folder.

Last but not least, register your file in the right config file under the config folder (Maybe not necessary anymore in the near future).

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.

./vendor/bin/phpunit

Submit your changes

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

typo3-rector's People

Contributors

abeutel avatar ayacoo avatar christophlehmann avatar mk-42 avatar moe2k avatar rintisch avatar robert-heinig avatar sabbelasichon avatar simonschaufi avatar tmotyl avatar tomasnorre avatar tomasvotruba avatar tuurlijk avatar utrotzek avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.