diff --git a/composer.json b/composer.json index 4f488fb..2a3c23e 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ } }, "require": { - "squizlabs/php_codesniffer": "2.8.*" + "squizlabs/php_codesniffer": "2.8.*", + "symfony/yaml": "3.2.*" }, "license": "GPL-2.0+", "authors": [ diff --git a/src/Standards/Typo3Update/Configuration/Deprecated/Functions/7.0.yaml b/src/Standards/Typo3Update/Configuration/Deprecated/Functions/7.0.yaml new file mode 100644 index 0000000..f01183a --- /dev/null +++ b/src/Standards/Typo3Update/Configuration/Deprecated/Functions/7.0.yaml @@ -0,0 +1,114 @@ +# Deprecated in 7.0: https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Index.html#breaking-changes +loadTCA: + oldFunctionCall: '\TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html' +getCompressedTCarray: + oldFunctionCall: '\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::getCompressedTCarray()' + newFunctionCall: 'Full TCA is always loaded during bootstrap in FE, the method is obsolete. If an eid script calls this method to load TCA, use \TYPO3\CMS\Frontend\Utility\EidUtility::initTCA() instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61785-FrontendTcaFunctionsRemoved.html' +includeTCA: + oldFunctionCall: '\TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::includeTCA()' + newFunctionCall: 'Full TCA is always loaded during bootstrap in FE, the method is obsolete. If an eid script calls this method to load TCA, use \TYPO3\CMS\Frontend\Utility\EidUtility::initTCA() instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61785-FrontendTcaFunctionsRemoved.html' +mail: + oldFunctionCall: 'MailUtility::mail()' + newFunctionCall: 'Use the \TYPO3\CMS\Core\Mail\Mailer API for sending email' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61783-RemoveDeprecatedMailFunctionality.html' +plainMailEncoded: + oldFunctionCall: 'GeneralUtility::plainMailEncoded()' + newFunctionCall: 'Use the \TYPO3\CMS\Core\Mail\Mailer API for sending email' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61783-RemoveDeprecatedMailFunctionality.html' +connectDB: + oldFunctionCall: '\TYPO3\CMS\Frontend\Utility\EidUtility::connectDB()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61863-ConnectDbFunctionRemoved.html' +int_from_ver: + oldFunctionCall: '\TYPO3\CMS\Core\Utility\GeneralUtility::int_from_ver' + newFunctionCall: 'Replace the usage of the removed function with \TYPO3\CMS\Core\Utility\VersionNumberUtility::convertVersionNumberToInteger()' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61860-RemoveIntFromVerFunction.html' +getUniqueFields: + oldFunctionCall: '\TYPO3\CMS\Core\DataHandling\DataHandler::getUniqueFields()' + newFunctionCall: 'Replace all calls to \TYPO3\CMS\Core\DataHandling\DataHandler::getUniqueFields() with calls to \TYPO3\CMS\Version\Hook\DataHandlerHook::getUniqueFields()' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61822-GetUniqueFieldsFunctionRemoved.html' +isSafeModeEnabled: + oldFunctionCall: '\TYPO3\CMS\Core\Utility\PhpOptionsUtility::isSafeModeEnabled()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61820-PhpOptionsUtilityDeprecatedFunctionsRemoved.html' +isMagicQuotesGpcEnabled: + oldFunctionCall: '\TYPO3\CMS\Core\Utility\PhpOptionsUtility::isMagicQuotesGpcEnabled()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61820-PhpOptionsUtilityDeprecatedFunctionsRemoved.html' +isLocalconfWritable: + oldFunctionCall: '\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::isLocalconfWritable' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61802-IsLocalconfWritableFunctionRemoved.html' +create: + oldFunctionCall: 'ObjectManager::create()' + newFunctionCall: 'Use ObjectManager::get() instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +# TODO: Find a way to make same method name in different classes work. +# create: +# oldFunctionCall: 'ObjectManagerInterface::create()' +# newFunctionCall: null +# docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +replaceObject: + oldFunctionCall: 'PersistenceGenericBackend::replaceObject()' + newFunctionCall: 'Removed without replacement' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +setReturnRawQueryResult: + oldFunctionCall: 'QuerySettingsInterface::setReturnRawQueryResult()' + newFunctionCall: 'Removed without replacement' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +getReturnRawQueryResult: + oldFunctionCall: 'QuerySettingsInterface::getReturnRawQueryResult()' + newFunctionCall: 'Use the parameter on $query->execute() directly' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +setSysLanguageUid: + oldFunctionCall: 'Typo3QuerySettings::setSysLanguageUid()' + newFunctionCall: 'Use setLanguageUid() instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +getSysLanguageUid: + oldFunctionCall: 'Typo3QuerySettings::getSysLanguageUid()' + newFunctionCall: 'Use getLanguageUid() instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62673-ExtbaseDeprecatedCodeRemoved.html' +JScharCode: + oldFunctionCall: 'LanguageService::JScharCode()' + newFunctionCall: 'Use GeneralUtility::quoteJSvalue instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +joinTSarrays: + oldFunctionCall: 'ContentObjectRenderer::joinTSarrays()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +tidyHTML: + oldFunctionCall: 'TypoScriptFrontendController::tidyHTML()' + newFunctionCall: 'You may use the tidy extension from TER' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +isWebFolder: + oldFunctionCall: 'ElementBrowser::isWebFolder()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +checkFolder: + oldFunctionCall: 'ElementBrowser::checkFolder()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +getTreeObject: + oldFunctionCall: 'AbstractDatabaseRecordList::getTreeObject()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +dirData: + oldFunctionCall: 'FileList::dirData()' + newFunctionCall: null + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +stdWrapValue: + oldFunctionCall: 'FilesContentObject::stdWrapValue()' + newFunctionCall: 'Use ContentObjectRenderer::stdWrapValue instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +userTempFolder: + oldFunctionCall: 'ImportExportController::userTempFolder()' + newFunctionCall: 'Use getDefaultImportExportFolder instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' +userSaveFolder: + oldFunctionCall: 'ImportExportController::userSaveFolder()' + newFunctionCall: 'Use getDefaultImportExportFolder instead' + docsUrl: 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-62670-DeprecatedCodeRemovalInMultipleSysexts.html' diff --git a/src/Standards/Typo3Update/Sniffs/Deprecated/GenericFunctionCallSniff.php b/src/Standards/Typo3Update/Sniffs/Deprecated/GenericFunctionCallSniff.php index 9dac445..ff02b8d 100644 --- a/src/Standards/Typo3Update/Sniffs/Deprecated/GenericFunctionCallSniff.php +++ b/src/Standards/Typo3Update/Sniffs/Deprecated/GenericFunctionCallSniff.php @@ -22,6 +22,7 @@ use PHP_CodeSniffer_File as PhpCsFile; use PHP_CodeSniffer_Sniff as PhpCsSniff; use PHP_CodeSniffer_Tokens as Tokens; +use Symfony\Component\Yaml\Yaml; /** * Sniff that handles all calls to deprecated functions. @@ -31,21 +32,31 @@ use PHP_CodeSniffer_Tokens as Tokens; class Typo3Update_Sniffs_Deprecated_GenericFunctionCallSniff implements PhpCsSniff { use \Typo3Update\Sniffs\ExtendedPhpCsSupportTrait; + use \Typo3Update\Sniffs\OptionsAccessTrait; /** * Configuration to define deprecated functions. * * Keys have to match the function name. * + * TODO: Multiple files allowed, using glob ... to allow splitting per ext (extbase, fluid, ...) and TYPO3 Version 7.1, 7.0, ... + * TODO: Build necessary structure from that files, to make it more independent ... ?! + * * @var array */ - protected $deprecatedFunctions = [ - 'loadTCA' => [ - 'oldFunctionCall' => '\TYPO3\CMS\Core\Utility\GeneralUtility::loadTCA()', - 'newFunctionCall' => null, - 'docsUrl' => 'https://docs.typo3.org/typo3cms/extensions/core/Changelog/7.0/Breaking-61785-LoadTcaFunctionRemoved.html', - ], - ]; + protected static $deprecatedFunctions = []; + + public function __construct() + { + if (static::$deprecatedFunctions === []) { + foreach ($this->getDeprecatedFunctionConfigFiles() as $file) { + static::$deprecatedFunctions = array_merge( + static::$deprecatedFunctions, + Yaml::parse(file_get_contents((string) $file)) + ); + } + } + } /** * Returns the token types that this sniff is interested in. @@ -83,6 +94,13 @@ class Typo3Update_Sniffs_Deprecated_GenericFunctionCallSniff implements PhpCsSni return; } + // TODO: Check if function is static and whether last class name part matches. + // TODO: Add new property to array "last class name part" and use for check if exists. + // TODO: How to handle methods? They are not static, are behind a variable or something else ... + + // E.g.: getUniqueFields + // E.g.: mail + $this->addWarning($phpcsFile, $stackPtr); } @@ -120,7 +138,7 @@ class Typo3Update_Sniffs_Deprecated_GenericFunctionCallSniff implements PhpCsSni */ protected function getFunctionNames() { - return array_keys($this->deprecatedFunctions); + return array_keys(static::$deprecatedFunctions); } /** @@ -134,7 +152,7 @@ class Typo3Update_Sniffs_Deprecated_GenericFunctionCallSniff implements PhpCsSni */ protected function getOldFunctionCall($functionName) { - return $this->deprecatedFunctions[$functionName]['oldFunctionCall']; + return static::$deprecatedFunctions[$functionName]['oldFunctionCall']; } /** @@ -146,7 +164,7 @@ class Typo3Update_Sniffs_Deprecated_GenericFunctionCallSniff implements PhpCsSni */ protected function getNewFunctionCall($functionName) { - $newCall = $this->deprecatedFunctions[$functionName]['newFunctionCall']; + $newCall = static::$deprecatedFunctions[$functionName]['newFunctionCall']; if ($newCall !== null) { return $newCall; } @@ -160,6 +178,6 @@ class Typo3Update_Sniffs_Deprecated_GenericFunctionCallSniff implements PhpCsSni */ protected function getDocsUrl($functionName) { - return $this->deprecatedFunctions[$functionName]['docsUrl']; + return static::$deprecatedFunctions[$functionName]['docsUrl']; } } diff --git a/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php b/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php index 7193e07..93c6745 100644 --- a/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php +++ b/src/Standards/Typo3Update/Sniffs/OptionsAccessTrait.php @@ -54,4 +54,21 @@ trait OptionsAccessTrait } return $mappingFile; } + + /** + * Returns an array of absolute file names containing deprecation function configurations. + * + * @return \Generator + */ + public function getDeprecatedFunctionConfigFiles() + { + $configFiles = PhpCs::getConfigData('deprecatedfunctionConfigFiles'); + if (!$configFiles) { + $configFiles = __DIR__ . '/../Configuration/Deprecated/Functions/*.yaml'; + } + + foreach ((new \GlobIterator($configFiles)) as $file) { + yield (string) $file; + } + } }