diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1b4873f --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/LegacyClassnames.php + +/composer.lock +/vendor/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..432e039 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +BIN_PHPCS = ./vendor/bin/phpcs +BIN_PHPCBF = ./vendor/bin/phpcbf +DEFAULT_STANDARD = Typo3Update +CUSTOM_STANDARDS = $(abspath ./src/Standards/) + +install: + composer install + $(BIN_PHPCS) --config-set installed_paths $(CUSTOM_STANDARDS) + $(BIN_PHPCS) -i | grep Typo3Update + $(BIN_PHPCS) --config-set default_standard $(DEFAULT_STANDARD) + +# For development / testing purposes: +test-search: + $(BIN_PHPCS) -p --colors -s PROJECT_PATH +test-fix: + $(BIN_PHPCBF) -p --colors -s PROJECT_PATH diff --git a/Readme.rst b/Readme.rst new file mode 100644 index 0000000..50a98b1 --- /dev/null +++ b/Readme.rst @@ -0,0 +1,27 @@ +.. _highlight: bash + +About +===== + +Our goal is to provide an automated migration for TYPO3 updates. + +This should include source code modifications like adjusting old legacy class names to new ones. + +Requirements +============ + +- ``composer`` needs to be installed and inside your ``$PATH``. + +Installation +============ + +Run:: + + make install + +Copy the ``vendor/composer/autoload_classaliasmap.php`` generated by ``composer`` in your TYPO3 installation to ``LegacyClassnames.php`` in the root of this project. + +Usage +===== + +Will follow. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..896e5ec --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "siepmann/typo3_update", + "description": "Auto migrate PHP Source of extensions to be compatible.", + "type": "project", + "autoload": { + "psr-4": { + "Typo3Update\\": "src/Classes/" + } + }, + "require-dev": { + "psy/psysh": "~0.8" + }, + "require": { + "squizlabs/php_codesniffer_tests": "^2.0" + }, + "license": "GPL-2.0+", + "authors": [ + { + "name": "Daniel Siepmann", + "email": "coding@daniel-siepmann.de" + } + ] +} diff --git a/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php new file mode 100644 index 0000000..d9993ae --- /dev/null +++ b/src/Standards/Typo3Update/Sniffs/Legacy/ClassnamesSniff.php @@ -0,0 +1,124 @@ + + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/** + * This sniff detects old, legacy class names like t3lib_div. + * Also it will make them fixable and migrate them to new ones. + */ +class Typo3Update_Sniffs_Legacy_ClassnamesSniff implements PHP_CodeSniffer_Sniff +{ + /** + * Contains mapping from old -> new class names. + * @var array + */ + protected $legacyClassnames = []; + + /** + * @param string $mappingFile File containing php array for mapping. + */ + public function __construct($mappingFile = __DIR__ . '/../../../../../LegacyClassnames.php') + { + $legacyClassnames = require $mappingFile; + $this->legacyClassnames = $legacyClassnames['aliasToClassNameMapping']; + } + + /** + * Returns the token types that this sniff is interested in. + * + * @see http://php.net/manual/en/tokens.php + * + * @return array + */ + public function register() + { + return [ + T_EXTENDS, + T_IMPLEMENTS, + // T_INSTANCEOF, + // T_NEW, + // T_STRING, + // T_USE, + ]; + } + + /** + * Processes the tokens that this sniff is interested in. + * + * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. + * @param int $stackPtr The position in the stack where + * the token was found. + * + * @return void + */ + public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) + { + $tokens = $phpcsFile->getTokens(); + $classnamePosition = $phpcsFile->findNext(T_STRING, $stackPtr); + if ($classnamePosition === false) { + return; + } + $classname = $tokens[$classnamePosition]['content']; + + if ($this->isLegacyClassname($classname) === false) { + return; + } + + $fix = $phpcsFile->addFixableError( + 'Legacy classes are not allowed; found %s', + $classnamePosition, + 'legacyClassname', + [$classname] + ); + + if ($fix === false) { + return; + } + + switch ($tokens[$stackPtr]['code']) { + case T_EXTENDS: + case T_IMPLEMENTS: + $phpcsFile->fixer->replaceToken($classnamePosition, '\\' . $this->getNewClassname($classname)); + break; + + default: + throw new \RuntimeException('Could not fix type "' . $tokens[$stackPtr]['type'] . '"', 1488891438); + break; + } + } + + /** + * @param string $classname + * @return bool + */ + protected function isLegacyClassname($classname) + { + return isset($this->legacyClassnames[strtolower($classname)]); + } + + /** + * @param string $classname + * @return string + */ + protected function getNewClassname($classname) + { + return $this->legacyClassnames[strtolower($classname)]; + } +} diff --git a/src/Standards/Typo3Update/ruleset.xml b/src/Standards/Typo3Update/ruleset.xml new file mode 100644 index 0000000..b44e6e2 --- /dev/null +++ b/src/Standards/Typo3Update/ruleset.xml @@ -0,0 +1,4 @@ + + + Provides sniffs and fixes for TYPO3 Updates. +