├── tests
├── test_apps
│ ├── original
│ │ ├── FileRenameCommand-testLocales
│ │ │ ├── src
│ │ │ │ ├── Template
│ │ │ │ │ └── empty
│ │ │ │ └── Locale
│ │ │ │ │ └── default.pot
│ │ │ └── plugins
│ │ │ │ ├── TestPlugin
│ │ │ │ └── src
│ │ │ │ │ ├── Template
│ │ │ │ │ └── empty
│ │ │ │ │ └── Locale
│ │ │ │ │ └── default.pot
│ │ │ │ └── WithoutLocalesPlugin
│ │ │ │ └── src
│ │ │ │ └── Template
│ │ │ │ └── empty
│ │ ├── FileRenameCommand-testTemplates
│ │ │ ├── src
│ │ │ │ ├── View
│ │ │ │ │ ├── Cell
│ │ │ │ │ │ └── empty
│ │ │ │ │ ├── Helper
│ │ │ │ │ │ └── empty
│ │ │ │ │ ├── AppView.php
│ │ │ │ │ └── AjaxView.php
│ │ │ │ ├── Locale
│ │ │ │ │ └── default.pot
│ │ │ │ └── Template
│ │ │ │ │ ├── Error
│ │ │ │ │ ├── error400.ctp
│ │ │ │ │ └── error500.ctp
│ │ │ │ │ ├── Layout
│ │ │ │ │ └── default.ctp
│ │ │ │ │ ├── Pages
│ │ │ │ │ └── home.ctp
│ │ │ │ │ ├── Email
│ │ │ │ │ ├── html
│ │ │ │ │ │ └── default.ctp
│ │ │ │ │ └── text
│ │ │ │ │ │ └── default.ctp
│ │ │ │ │ ├── Cell
│ │ │ │ │ └── TestCell
│ │ │ │ │ │ └── display.ctp
│ │ │ │ │ └── Element
│ │ │ │ │ └── Flash
│ │ │ │ │ └── default.ctp
│ │ │ └── plugins
│ │ │ │ ├── TestPlugin
│ │ │ │ └── src
│ │ │ │ │ ├── Locale
│ │ │ │ │ └── default.pot
│ │ │ │ │ └── Template
│ │ │ │ │ ├── Pages
│ │ │ │ │ └── home.ctp
│ │ │ │ │ ├── Error
│ │ │ │ │ ├── error400.ctp
│ │ │ │ │ └── error500.ctp
│ │ │ │ │ ├── Layout
│ │ │ │ │ └── default.ctp
│ │ │ │ │ ├── Email
│ │ │ │ │ ├── html
│ │ │ │ │ │ └── default.ctp
│ │ │ │ │ └── text
│ │ │ │ │ │ └── default.ctp
│ │ │ │ │ ├── Cell
│ │ │ │ │ └── TestPluginCell
│ │ │ │ │ │ └── bar.ctp
│ │ │ │ │ └── Element
│ │ │ │ │ └── Flash
│ │ │ │ │ └── default.ctp
│ │ │ │ └── WithoutTemplatesPlugin
│ │ │ │ └── src
│ │ │ │ ├── empty
│ │ │ │ └── Locale
│ │ │ │ └── default.pot
│ │ ├── RectorCommand-testApply50
│ │ │ └── src
│ │ │ │ ├── SomeView.php
│ │ │ │ ├── SomeMailer.php
│ │ │ │ ├── SomeWidget.php
│ │ │ │ ├── DateTimeRename.php
│ │ │ │ ├── SomeCell.php
│ │ │ │ ├── Model
│ │ │ │ └── Entity
│ │ │ │ │ └── Category.php
│ │ │ │ ├── SomeComponent.php
│ │ │ │ ├── CommandExecuteReturn.php
│ │ │ │ ├── SomeTest.php
│ │ │ │ ├── FixtureProperties.php
│ │ │ │ ├── QueryUpgrade.php
│ │ │ │ ├── HelperProperties.php
│ │ │ │ └── Plugin.php
│ │ ├── RectorCommand-testApplyMigrations45
│ │ │ └── src
│ │ │ │ └── Migrations45.php
│ │ ├── RectorCommand-testApplyAppDir
│ │ │ └── Command
│ │ │ │ └── HelloCommand.php
│ │ ├── RectorCommand-testApply52
│ │ │ └── src
│ │ │ │ └── SomeTest.php
│ │ ├── RectorCommand-testApplyChronos3DateTime
│ │ │ └── src
│ │ │ │ └── Chronos3.php
│ │ ├── RectorCommand-testApply53
│ │ │ └── src
│ │ │ │ └── SomeTest.php
│ │ ├── RectorCommand-testApplyChronos3Date
│ │ │ └── src
│ │ │ │ └── Chronos3.php
│ │ ├── RectorCommand-testApply45
│ │ │ └── src
│ │ │ │ └── View
│ │ │ │ └── AppView.php
│ │ └── RectorCommand-testApply51
│ │ │ └── src
│ │ │ └── SomeTest.php
│ └── upgraded
│ │ ├── FileRenameCommand-testLocales
│ │ ├── src
│ │ │ └── Template
│ │ │ │ └── empty
│ │ ├── resources
│ │ │ └── locales
│ │ │ │ └── default.pot
│ │ └── plugins
│ │ │ ├── TestPlugin
│ │ │ ├── src
│ │ │ │ └── Template
│ │ │ │ │ └── empty
│ │ │ └── resources
│ │ │ │ └── locales
│ │ │ │ └── default.pot
│ │ │ └── WithoutLocalesPlugin
│ │ │ └── src
│ │ │ └── Template
│ │ │ └── empty
│ │ ├── FileRenameCommand-testTemplates
│ │ ├── src
│ │ │ ├── View
│ │ │ │ ├── Cell
│ │ │ │ │ └── empty
│ │ │ │ ├── Helper
│ │ │ │ │ └── empty
│ │ │ │ ├── AppView.php
│ │ │ │ └── AjaxView.php
│ │ │ └── Locale
│ │ │ │ └── default.pot
│ │ ├── templates
│ │ │ ├── Pages
│ │ │ │ └── home.php
│ │ │ ├── Error
│ │ │ │ ├── error400.php
│ │ │ │ └── error500.php
│ │ │ ├── layout
│ │ │ │ └── default.php
│ │ │ ├── cell
│ │ │ │ └── TestCell
│ │ │ │ │ └── display.php
│ │ │ ├── element
│ │ │ │ └── flash
│ │ │ │ │ └── default.php
│ │ │ └── email
│ │ │ │ ├── html
│ │ │ │ └── default.php
│ │ │ │ └── text
│ │ │ │ └── default.php
│ │ └── plugins
│ │ │ ├── TestPlugin
│ │ │ ├── src
│ │ │ │ └── Locale
│ │ │ │ │ └── default.pot
│ │ │ └── templates
│ │ │ │ ├── Pages
│ │ │ │ └── home.php
│ │ │ │ ├── Error
│ │ │ │ ├── error400.php
│ │ │ │ └── error500.php
│ │ │ │ ├── email
│ │ │ │ ├── html
│ │ │ │ │ └── default.php
│ │ │ │ └── text
│ │ │ │ │ └── default.php
│ │ │ │ ├── layout
│ │ │ │ └── default.php
│ │ │ │ ├── cell
│ │ │ │ └── TestPluginCell
│ │ │ │ │ └── bar.php
│ │ │ │ └── element
│ │ │ │ └── flash
│ │ │ │ └── default.php
│ │ │ └── WithoutTemplatesPlugin
│ │ │ └── src
│ │ │ ├── empty
│ │ │ └── Locale
│ │ │ └── default.pot
│ │ ├── RectorCommand-testApply50
│ │ └── src
│ │ │ ├── SomeView.php
│ │ │ ├── SomeMailer.php
│ │ │ ├── SomeWidget.php
│ │ │ ├── DateTimeRename.php
│ │ │ ├── SomeCell.php
│ │ │ ├── Model
│ │ │ └── Entity
│ │ │ │ └── Category.php
│ │ │ ├── SomeTest.php
│ │ │ ├── SomeComponent.php
│ │ │ ├── CommandExecuteReturn.php
│ │ │ ├── FixtureProperties.php
│ │ │ ├── QueryUpgrade.php
│ │ │ ├── HelperProperties.php
│ │ │ └── Plugin.php
│ │ ├── RectorCommand-testApplyMigrations45
│ │ └── src
│ │ │ └── Migrations45.php
│ │ ├── RectorCommand-testApply52
│ │ └── src
│ │ │ └── SomeTest.php
│ │ ├── RectorCommand-testApplyChronos3DateTime
│ │ └── src
│ │ │ └── Chronos3.php
│ │ ├── RectorCommand-testApply53
│ │ └── src
│ │ │ └── SomeTest.php
│ │ ├── RectorCommand-testApply45
│ │ └── src
│ │ │ └── View
│ │ │ └── AppView.php
│ │ ├── RectorCommand-testApplyChronos3Date
│ │ └── src
│ │ │ └── Chronos3.php
│ │ └── RectorCommand-testApply51
│ │ └── src
│ │ └── SomeTest.php
├── TestCase
│ ├── Rector
│ │ ├── Namespace_
│ │ │ └── AppUsesStaticCallToUseStatementRector
│ │ │ │ ├── Source
│ │ │ │ ├── Xml.php
│ │ │ │ └── App.php
│ │ │ │ ├── config
│ │ │ │ └── configured_rule.php
│ │ │ │ ├── Fixture
│ │ │ │ ├── skip_different_static_call.php.inc
│ │ │ │ ├── without_namespace.php.inc
│ │ │ │ ├── cakephp_controller.php.inc
│ │ │ │ ├── without_namespace_with_strict_types.php.inc
│ │ │ │ ├── cakephp_controller_with_strict_types.php.inc
│ │ │ │ ├── fixture.php.inc
│ │ │ │ ├── cakephp_import_namespaces_up.php.inc
│ │ │ │ ├── inside_if.php.inc
│ │ │ │ └── cakephp_fixture.php.inc
│ │ │ │ └── AppUsesStaticCallToUseStatementRectorTest.php
│ │ ├── MethodCall
│ │ │ ├── ModalToGetSetRector
│ │ │ │ ├── Source
│ │ │ │ │ ├── Entity.php
│ │ │ │ │ └── SomeModelType.php
│ │ │ │ ├── Fixture
│ │ │ │ │ ├── fixture4.php.inc
│ │ │ │ │ ├── fixture3.php.inc
│ │ │ │ │ ├── fixture2.php.inc
│ │ │ │ │ └── fixture.php.inc
│ │ │ │ ├── ModalToGetSetRectorTest.php
│ │ │ │ └── config
│ │ │ │ │ └── configured_rule.php
│ │ │ ├── AddMethodCallArgsRector
│ │ │ │ ├── Source
│ │ │ │ │ └── SomeModelType.php
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── AddMethodCallArgsRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ └── fixture.php.inc
│ │ │ ├── RemoveMethodCallArgsRector
│ │ │ │ ├── Source
│ │ │ │ │ └── SomeModelType.php
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── Fixture
│ │ │ │ │ └── fixture.php.inc
│ │ │ │ └── RemoveMethodCallArgsRectorTest.php
│ │ │ ├── OptionsArrayToNamedParametersRector
│ │ │ │ ├── Source
│ │ │ │ │ └── ConfigurableClass.php
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── OptionsArrayToNamedParametersRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ └── options_to_named_parameters.php.inc
│ │ │ ├── RenameMethodCallBasedOnParameterRector
│ │ │ │ ├── Source
│ │ │ │ │ └── SomeModelType.php
│ │ │ │ ├── Fixture
│ │ │ │ │ ├── skip_fixture2.php.inc
│ │ │ │ │ └── fixture.php.inc
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ └── RenameMethodCallBasedOnParameterRectorTest.php
│ │ │ ├── EntityPatchRector
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── EntityPatchRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ ├── skip_non_entity.php.inc
│ │ │ │ │ └── fixture.php.inc
│ │ │ ├── NewExprToFuncRector
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── NewExprToFuncRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ ├── aggregate_functions.php.inc
│ │ │ │ │ ├── sql_functions.php.inc
│ │ │ │ │ └── skip_non_func_methods.php.inc
│ │ │ ├── ChangeEntityTraitSetArrayToPatch
│ │ │ │ ├── Source
│ │ │ │ │ └── OtherClassWithSetMethod.php
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── ChangeEntityTraitSetArrayToPatchTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ └── fixture.php.inc
│ │ │ ├── QueryParamAccessRector
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── QueryParamAccessRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ ├── fixture.php.inc
│ │ │ │ │ └── skip_other_params.php.inc
│ │ │ ├── PaginatorCounterFormatRector
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── PaginatorCounterFormatRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ └── fixture.php.inc
│ │ │ ├── NewEntityToNewEmptyEntityRector
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── NewEntityToNewEmptyEntityRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ └── fixture.php.inc
│ │ │ ├── ArrayToFluentCallRector
│ │ │ │ ├── Source
│ │ │ │ │ ├── FactoryClass.php
│ │ │ │ │ └── ConfigurableClass.php
│ │ │ │ ├── ArrayToFluentCallRectorTest.php
│ │ │ │ ├── Fixture
│ │ │ │ │ ├── fluent_factory.php.inc
│ │ │ │ │ └── array_to_fluent_call.php.inc
│ │ │ │ └── config
│ │ │ │ │ └── configured_rule.php
│ │ │ └── RemoveIntermediaryMethodRector
│ │ │ │ ├── config
│ │ │ │ └── configured_rule.php
│ │ │ │ ├── RemoveIntermediaryMethodRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ └── fixture.php.inc
│ │ ├── ClassMethod
│ │ │ ├── FormBuildValidatorRector
│ │ │ │ ├── config
│ │ │ │ │ └── configured_rule.php
│ │ │ │ ├── FormBuildValidatorRectorTest.php
│ │ │ │ └── Fixture
│ │ │ │ │ └── fixture.php.inc
│ │ │ └── FormExecuteToProcessRector
│ │ │ │ ├── config
│ │ │ │ └── configured_rule.php
│ │ │ │ ├── Fixture
│ │ │ │ ├── skip_when_process_exists.php.inc
│ │ │ │ └── fixture.php.inc
│ │ │ │ └── FormExecuteToProcessRectorTest.php
│ │ └── Property
│ │ │ └── ChangeSnakedFixtureNameToPascal
│ │ │ ├── config
│ │ │ └── configured_rule.php
│ │ │ ├── ChangeSnakedFixtureNameToPascalTest.php
│ │ │ └── Fixture
│ │ │ └── fixture.php.inc
│ ├── Command
│ │ └── FileRenameCommandTest.php
│ └── TestCase.php
└── bootstrap.php
├── .github
├── codecov.yml
├── dependabot.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── .gitattributes
├── config
├── rector
│ ├── chronos3.php
│ ├── phpunit80.php
│ ├── cakephp40.php
│ ├── cakephp41.php
│ ├── cakephp42.php
│ ├── cakephp43.php
│ ├── cakephp44.php
│ ├── cakephp45.php
│ ├── cakephp50.php
│ ├── cakephp51.php
│ ├── cakephp52.php
│ ├── cakephp53.php
│ ├── migrations45.php
│ ├── migrations50.php
│ └── sets
│ │ ├── migrations45.php
│ │ ├── cakephp38.php
│ │ ├── cakephp51.php
│ │ ├── cakephp52.php
│ │ ├── cakephp42.php
│ │ ├── cakephp45.php
│ │ ├── cakephp44.php
│ │ ├── cakephp30.php
│ │ ├── cakephp41.php
│ │ ├── cakephp53.php
│ │ ├── cakephp43.php
│ │ └── cakephp36.php
├── requirements.php
├── bootstrap.php
└── paths.php
├── .editorconfig
├── bin
├── cake.php
├── cake.bat
└── cake
├── src
├── Rector
│ ├── ValueObject
│ │ ├── SetSerializeToView.php
│ │ ├── RemoveMethodCall.php
│ │ ├── ArrayToFluentCall.php
│ │ ├── RemoveIntermediaryMethod.php
│ │ ├── FactoryMethod.php
│ │ ├── ArrayItemsAndFluentClass.php
│ │ ├── AddMethodCallArgs.php
│ │ ├── RenameMethodCallBasedOnParameter.php
│ │ ├── OptionsArrayToNamedParameters.php
│ │ └── ModalToGetSet.php
│ ├── NodeAnalyzer
│ │ └── FluentChainMethodCallNodeAnalyzer.php
│ ├── Set
│ │ ├── CakePHPLevelSetList.php
│ │ └── CakePHPSetList.php
│ └── Rector
│ │ ├── MethodCall
│ │ ├── EntityIsEmptyRector.php
│ │ ├── TableRegistryLocatorRector.php
│ │ ├── NewEntityToNewEmptyEntityRector.php
│ │ ├── EntityPatchRector.php
│ │ ├── ChangeEntityTraitSetArrayToPatchRector.php
│ │ ├── SetSerializeToViewBuilderRector.php
│ │ ├── StaticConnectionHelperRector.php
│ │ ├── RemoveMethodCallRector.php
│ │ ├── QueryParamAccessRector.php
│ │ └── PaginatorCounterFormatRector.php
│ │ └── ClassMethod
│ │ └── FormExecuteToProcessRector.php
└── Application.php
├── phpunit.xml.dist
├── Makefile
├── phpcs.xml
├── LICENSE.md
└── composer.json
/tests/test_apps/original/FileRenameCommand-testLocales/src/Template/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testLocales/src/Template/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testLocales/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/View/Cell/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/View/Helper/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/View/Cell/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/View/Helper/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Pages/home.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Error/error400.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Error/error500.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Layout/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Pages/home.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testLocales/resources/locales/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Error/error400.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Error/error500.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/layout/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testLocales/plugins/TestPlugin/src/Template/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Email/html/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Email/text/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testLocales/plugins/TestPlugin/src/Template/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/cell/TestCell/display.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/element/flash/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/email/html/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/email/text/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testLocales/plugins/TestPlugin/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/WithoutTemplatesPlugin/src/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Cell/TestCell/display.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/Template/Element/Flash/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/WithoutTemplatesPlugin/src/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testLocales/plugins/WithoutLocalesPlugin/src/Template/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Pages/home.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testLocales/plugins/TestPlugin/resources/locales/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testLocales/plugins/WithoutLocalesPlugin/src/Template/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/Pages/home.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Error/error400.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Error/error500.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Layout/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/Error/error400.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/Error/error500.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/email/html/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/email/text/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/layout/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Email/html/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Email/text/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/WithoutTemplatesPlugin/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/cell/TestPluginCell/bar.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/TestPlugin/templates/element/flash/default.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/plugins/WithoutTemplatesPlugin/src/Locale/default.pot:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Cell/TestPluginCell/bar.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/plugins/TestPlugin/src/Template/Element/Flash/default.ctp:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/codecov.yml:
--------------------------------------------------------------------------------
1 | codecov:
2 | require_ci_to_pass: yes
3 |
4 | coverage:
5 | range: "90...100"
6 |
7 | comment: false
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /tmp/
2 | /vendor/
3 | /logs/
4 | /composer.lock
5 | /plugins/DebugKit
6 | /phpunit.phar
7 | .phpunit*
8 | /.idea/
9 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/SomeView.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CHRONOS_3]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/phpunit80.php:
--------------------------------------------------------------------------------
1 | sets([PHPUnitSetList::PHPUNIT_80]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp40.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_40]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp41.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_41]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp42.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_42]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp43.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_43]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp44.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_44]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp45.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_45]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp50.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_50]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp51.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_51]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp52.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_52]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/cakephp53.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::CAKEPHP_53]);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/DateTimeRename.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::MIGRATIONS_45]);
9 | };
10 |
--------------------------------------------------------------------------------
/config/rector/migrations50.php:
--------------------------------------------------------------------------------
1 | sets([CakePHPSetList::MIGRATIONS_50]);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RenameMethodCallBasedOnParameterRector/Source/SomeModelType.php:
--------------------------------------------------------------------------------
1 | set('_serialize', 'result');
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/SomeCell.php:
--------------------------------------------------------------------------------
1 | viewBuilder()->setOption('serialize', 'result');
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/EntityPatchRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | rule(EntityPatchRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/Model/Entity/Category.php:
--------------------------------------------------------------------------------
1 | rule(NewExprToFuncRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ChangeEntityTraitSetArrayToPatch/Source/OtherClassWithSetMethod.php:
--------------------------------------------------------------------------------
1 | rule(QueryParamAccessRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApplyMigrations45/src/Migrations45.php:
--------------------------------------------------------------------------------
1 | rule(FormBuildValidatorRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/Model/Entity/Category.php:
--------------------------------------------------------------------------------
1 | rule(FormExecuteToProcessRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApplyMigrations45/src/Migrations45.php:
--------------------------------------------------------------------------------
1 | rule(PaginatorCounterFormatRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/NewEntityToNewEmptyEntityRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | rule(NewEntityToNewEmptyEntityRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/SomeComponent.php:
--------------------------------------------------------------------------------
1 | rule(ChangeSnakedFixtureNameToPascalRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | get('/');
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ChangeEntityTraitSetArrayToPatch/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | rule(ChangeEntityTraitSetArrayToPatchRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | rule(AppUsesStaticCallToUseStatementRector::class);
9 | };
10 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Source/App.php:
--------------------------------------------------------------------------------
1 | get('MyTable');
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/CommandExecuteReturn.php:
--------------------------------------------------------------------------------
1 | run($argv));
13 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApplyAppDir/Command/HelloCommand.php:
--------------------------------------------------------------------------------
1 | styles('green', ['background' => 'green']);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | useCommandRunner();
16 | $this->useHttpServer();
17 | $this->get('/');
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/FixtureProperties.php:
--------------------------------------------------------------------------------
1 | setName($options['name']);
13 |
14 | return $configurableClass;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ArrayToFluentCallRector/Source/ConfigurableClass.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameClassRector::class, [
12 | 'Migrations\AbstractMigration' => 'Migrations\BaseMigration',
13 | 'Migrations\AbstractSeed' => 'Migrations\BaseSeed',
14 | ]);
15 | };
16 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/SetSerializeToView.php:
--------------------------------------------------------------------------------
1 | class;
18 | }
19 |
20 | public function getObjectType(): ObjectType
21 | {
22 | return new ObjectType($this->class);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/without_namespace.php.inc:
--------------------------------------------------------------------------------
1 |
14 | -----
15 |
28 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 | tests/TestCase/
9 |
10 |
11 |
12 |
13 |
14 | src/
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_controller.php.inc:
--------------------------------------------------------------------------------
1 |
12 | -----
13 |
24 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp38.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(
12 | RenameMethodRector::class,
13 | [new MethodCallRename('Cake\ORM\Entity', 'visibleProperties', 'getVisible')]
14 | );
15 | };
16 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RemoveIntermediaryMethodRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(
10 | RemoveIntermediaryMethodRector::class,
11 | [new RemoveIntermediaryMethod('getTableLocator', 'get', 'fetchTable')]
12 | );
13 | };
14 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RenameMethodCallBasedOnParameterRector/Fixture/skip_fixture2.php.inc:
--------------------------------------------------------------------------------
1 | getParam($value);
12 | $config = $object->getParam('other');
13 | $object->withParam('other', 'value');
14 | }
15 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/ClassMethod/FormExecuteToProcessRector/Fixture/skip_when_process_exists.php.inc:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RemoveMethodCallRector::class, [
11 | new RemoveMethodCall(SomeModelType::class, 'getAttribute'),
12 | ]);
13 | };
14 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/AddMethodCallArgsRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(AddMethodCallArgsRector::class, [
11 | new AddMethodCallArgs(SomeModelType::class, 'getAttribute', '2ndArg', 1, true),
12 | ]);
13 | };
14 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply52/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | [1, 2]], []);
14 | $option = $args->getMultipleOption('a');
15 |
16 | $entity = new Entity();
17 | // This should be changed to patch
18 | $entity->set(['paging' => 'test']);
19 | // This should not be changed
20 | $entity->set('paging', 'test');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply52/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | [1, 2]], []);
14 | $option = $args->getArrayOption('a');
15 |
16 | $entity = new Entity();
17 | // This should be changed to patch
18 | $entity->patch(['paging' => 'test']);
19 | // This should not be changed
20 | $entity->set('paging', 'test');
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/without_namespace_with_strict_types.php.inc:
--------------------------------------------------------------------------------
1 |
16 | -----
17 |
32 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_controller_with_strict_types.php.inc:
--------------------------------------------------------------------------------
1 |
14 | -----
15 |
28 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp51.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameStringRector::class, [
12 | // Rename the cache configuration used by translations.
13 | '_cake_core_' => '_cake_translations_',
14 | ]);
15 |
16 | $rectorConfig->rule(StaticConnectionHelperRector::class);
17 | };
18 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/RemoveMethodCall.php:
--------------------------------------------------------------------------------
1 | class;
19 | }
20 |
21 | public function getMethodName(): string
22 | {
23 | return $this->methodName;
24 | }
25 |
26 | public function getObjectType(): ObjectType
27 | {
28 | return new ObjectType($this->class);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/ArrayToFluentCall.php:
--------------------------------------------------------------------------------
1 | $class
10 | */
11 | public function __construct(
12 | private string $class,
13 | private array $arrayKeysToFluentCalls,
14 | ) {
15 | }
16 |
17 | public function getClass(): string
18 | {
19 | return $this->class;
20 | }
21 |
22 | /**
23 | * @return array
24 | */
25 | public function getArrayKeysToFluentCalls(): array
26 | {
27 | return $this->arrayKeysToFluentCalls;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameMethodRector::class, [
12 | new MethodCallRename('Cake\Console\Arguments', 'getMultipleOption', 'getArrayOption'),
13 | ]);
14 | $rectorConfig->rule(ChangeEntityTraitSetArrayToPatchRector::class);
15 | };
16 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/RemoveIntermediaryMethod.php:
--------------------------------------------------------------------------------
1 | firstMethod;
18 | }
19 |
20 | public function getSecondMethod(): string
21 | {
22 | return $this->secondMethod;
23 | }
24 |
25 | public function getFinalMethod(): string
26 | {
27 | return $this->finalMethod;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ModalToGetSetRector/Fixture/fixture4.php.inc:
--------------------------------------------------------------------------------
1 | makeEntity();
12 | }
13 |
14 | ?>
15 | -----
16 | createEntity();
27 | }
28 |
29 | ?>
30 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 |
16 | -----
17 |
32 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/QueryUpgrade.php:
--------------------------------------------------------------------------------
1 | find('all', ['conditions' => ['Articles.slug' => 'test']]);
9 | $query->find('list', ['fields' => ['id', 'title']])
10 | ->order('id')
11 | ->orderAsc('id')
12 | ->orderDesc('id')
13 | ->group('id');
14 |
15 | $articles->query()
16 | ->order('id')
17 | ->orderAsc('id')
18 | ->orderDesc('id')
19 | ->group('id');
20 |
21 | $article = $articles->get(1, ['key' => 'cache-key', 'contain' => ['Users']]);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/QueryUpgrade.php:
--------------------------------------------------------------------------------
1 | find('all', conditions: ['Articles.slug' => 'test']);
9 | $query->find('list', fields: ['id', 'title'])
10 | ->orderBy('id')
11 | ->orderByAsc('id')
12 | ->orderByDesc('id')
13 | ->groupBy('id');
14 |
15 | $articles->query()
16 | ->orderBy('id')
17 | ->orderByAsc('id')
18 | ->orderByDesc('id')
19 | ->groupBy('id');
20 |
21 | $article = $articles->get(1, cacheKey: 'cache-key', contain: ['Users']);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/ClassMethod/FormExecuteToProcessRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 |
17 | -----
18 |
34 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/EntityPatchRector/EntityPatchRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ModalToGetSetRector/ModalToGetSetRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/NewExprToFuncRector/NewExprToFuncRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RenameMethodCallBasedOnParameterRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameMethodCallBasedOnParameterRector::class, [
11 | new RenameMethodCallBasedOnParameter(SomeModelType::class, 'getParam', 'paging', 'getAttribute'),
12 | new RenameMethodCallBasedOnParameter(SomeModelType::class, 'withParam', 'paging', 'withAttribute'),
13 | ]);
14 | };
15 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ModalToGetSetRector/Fixture/fixture3.php.inc:
--------------------------------------------------------------------------------
1 | method();
12 | $config = $object->method('key');
13 | }
14 |
15 | ?>
16 | -----
17 | getMethod();
28 | $config = $object->setMethod('key');
29 | }
30 |
31 | ?>
32 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/OptionsArrayToNamedParametersRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(OptionsArrayToNamedParametersRector::class, [
12 | new OptionsArrayToNamedParameters(ConfigurableClass::class, ['find']),
13 | new OptionsArrayToNamedParameters(ConfigurableClass::class, [
14 | 'get', 'rename' => ['key' => 'cacheKey'],
15 | ]),
16 | ]);
17 | };
18 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/QueryParamAccessRector/QueryParamAccessRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/AddMethodCallArgsRector/AddMethodCallArgsRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RemoveMethodCallArgsRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | getAttribute('paging');
11 | $object->setAttribute('paging', []);
12 | }
13 |
14 | ?>
15 | -----
16 | setAttribute('paging', []);
26 | }
27 |
28 | ?>
29 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp42.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameClassRector::class, [
12 | 'Cake\Core\Exception\Exception' => 'Cake\Core\Exception\CakeException',
13 | 'Cake\Database\Exception' => 'Cake\Database\Exception\DatabaseException',
14 | ]);
15 |
16 | $rectorConfig->ruleWithConfiguration(
17 | RenameMethodRector::class,
18 | [new MethodCallRename('Cake\ORM\Behavior', 'getTable', 'table')]
19 | );
20 | };
21 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/ClassMethod/FormBuildValidatorRector/FormBuildValidatorRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ArrayToFluentCallRector/ArrayToFluentCallRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
18 | }
19 |
20 | public static function provideData(): Iterator
21 | {
22 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
23 | }
24 |
25 | public function provideConfigFilePath(): string
26 | {
27 | return __DIR__ . '/config/configured_rule.php';
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/FactoryMethod.php:
--------------------------------------------------------------------------------
1 | type);
21 | }
22 |
23 | public function getMethod(): string
24 | {
25 | return $this->method;
26 | }
27 |
28 | public function getPosition(): int
29 | {
30 | return $this->position;
31 | }
32 |
33 | public function getNewClass(): string
34 | {
35 | return $this->newClass;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RemoveMethodCallArgsRector/RemoveMethodCallArgsRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/ArrayItemsAndFluentClass.php:
--------------------------------------------------------------------------------
1 | $arrayItems
10 | * @param array $fluentCalls
11 | */
12 | public function __construct(
13 | private array $arrayItems,
14 | private array $fluentCalls,
15 | ) {
16 | }
17 |
18 | /**
19 | * @return array<\PhpParser\Node\ArrayItem>
20 | */
21 | public function getArrayItems(): array
22 | {
23 | return $this->arrayItems;
24 | }
25 |
26 | /**
27 | * @return array
28 | */
29 | public function getFluentCalls(): array
30 | {
31 | return $this->fluentCalls;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/ClassMethod/FormExecuteToProcessRector/FormExecuteToProcessRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/PaginatorCounterFormatRector/PaginatorCounterFormatRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/NewEntityToNewEmptyEntityRector/NewEntityToNewEmptyEntityRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RemoveIntermediaryMethodRector/RemoveIntermediaryMethodRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Property/ChangeSnakedFixtureNameToPascal/ChangeSnakedFixtureNameToPascalTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ChangeEntityTraitSetArrayToPatch/ChangeEntityTraitSetArrayToPatchTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Property/ChangeSnakedFixtureNameToPascal/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 |
18 | -----
19 |
36 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/AddMethodCallArgsRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | getAttribute('paging');
11 | $object->getAttribute();
12 | }
13 |
14 | ?>
15 | -----
16 | getAttribute('paging', '2ndArg', 1, true);
26 | $object->getAttribute('2ndArg', 1, true);
27 | }
28 |
29 | ?>
30 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/AddMethodCallArgs.php:
--------------------------------------------------------------------------------
1 | values = $values;
18 | }
19 |
20 | public function getClass(): string
21 | {
22 | return $this->class;
23 | }
24 |
25 | public function getMethodName(): string
26 | {
27 | return $this->methodName;
28 | }
29 |
30 | public function getValues(): array
31 | {
32 | return $this->values;
33 | }
34 |
35 | public function getObjectType(): ObjectType
36 | {
37 | return new ObjectType($this->class);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/OptionsArrayToNamedParametersRector/OptionsArrayToNamedParametersRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
18 | }
19 |
20 | public static function provideData(): Iterator
21 | {
22 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
23 | }
24 |
25 | public function provideConfigFilePath(): string
26 | {
27 | return __DIR__ . '/config/configured_rule.php';
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/AppUsesStaticCallToUseStatementRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RenameMethodCallBasedOnParameterRector/RenameMethodCallBasedOnParameterRectorTest.php:
--------------------------------------------------------------------------------
1 | doTestFile($filePath);
17 | }
18 |
19 | public static function provideData(): Iterator
20 | {
21 | return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22 | }
23 |
24 | public function provideConfigFilePath(): string
25 | {
26 | return __DIR__ . '/config/configured_rule.php';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | src/
6 | tests/
7 |
8 | tests/test_apps/
9 | tests/TestCase/Rector/
10 |
11 |
12 | 0
13 |
14 |
15 | 0
16 |
17 |
18 | 0
19 |
20 |
21 | 0
22 |
23 |
24 | 0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_import_namespaces_up.php.inc:
--------------------------------------------------------------------------------
1 |
17 | -----
18 |
34 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/RenameMethodCallBasedOnParameter.php:
--------------------------------------------------------------------------------
1 | oldMethod;
21 | }
22 |
23 | public function getParameterName(): string
24 | {
25 | return $this->parameterName;
26 | }
27 |
28 | public function getNewMethod(): string
29 | {
30 | return $this->newMethod;
31 | }
32 |
33 | public function getOldObjectType(): ObjectType
34 | {
35 | return new ObjectType($this->oldClass);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/bin/cake.bat:
--------------------------------------------------------------------------------
1 | ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2 | ::
3 | :: Cake is a Windows batch script for invoking CakePHP shell commands
4 | ::
5 | :: CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
6 | :: Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
7 | ::
8 | :: Licensed under The MIT License
9 | :: Redistributions of files must retain the above copyright notice.
10 | ::
11 | :: @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
12 | :: @link https://cakephp.org CakePHP(tm) Project
13 | :: @since 2.0.0
14 | :: @license https://opensource.org/licenses/mit-license.php MIT License
15 | ::
16 | ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
17 |
18 | @echo off
19 |
20 | SET app=%0
21 | SET lib=%~dp0
22 |
23 | php "%lib%cake.php" %*
24 |
25 | echo.
26 |
27 | exit /B %ERRORLEVEL%
28 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ArrayToFluentCallRector/Fixture/fluent_factory.php.inc:
--------------------------------------------------------------------------------
1 | buildClass('foo');
12 |
13 | $factory->buildClass('foo', []);
14 |
15 | $factory->buildClass('foo', ['baz' => 1]);
16 | }
17 |
18 | ?>
19 | -----
20 | buildClass('foo');
31 |
32 | $factory->buildClass('foo');
33 |
34 | $factory->buildClass('foo', ['baz' => 1]);
35 | }
36 |
37 | ?>
38 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/inside_if.php.inc:
--------------------------------------------------------------------------------
1 |
19 | -----
20 |
38 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApplyChronos3DateTime/src/Chronos3.php:
--------------------------------------------------------------------------------
1 | addYear();
9 | $dateTime->subYear();
10 | $dateTime->addYearWithOverflow();
11 | $dateTime->subYearWithOverflow();
12 | $dateTime->addMonth();
13 | $dateTime->subMonth();
14 | $dateTime->addMonthWithOverflow();
15 | $dateTime->subMonthWithOverflow();
16 | $dateTime->addDay();
17 | $dateTime->subDay();
18 | $dateTime->addWeekday();
19 | $dateTime->subWeekday();
20 | $dateTime->addWeek();
21 | $dateTime->subWeek();
22 |
23 | $dateTime->addHour();
24 | $dateTime->subHour();
25 | $dateTime->addMinute();
26 | $dateTime->subMinute();
27 | $dateTime->addSecond();
28 | $dateTime->subSecond();
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RenameMethodCallBasedOnParameterRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | getParam('paging');
12 | $object->withParam('paging', 'value');
13 | }
14 |
15 | ?>
16 | -----
17 | getAttribute('paging');
28 | $object->withAttribute('paging', 'value');
29 | }
30 |
31 | ?>
32 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ModalToGetSetRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(ModalToGetSetRector::class, [
11 |
12 | new ModalToGetSet(SomeModelType::class, 'config', null, null, 2, 'array'),
13 | new ModalToGetSet(
14 | SomeModelType::class,
15 | 'customMethod',
16 | 'customMethodGetName',
17 | 'customMethodSetName',
18 | 2,
19 | 'array'
20 | ),
21 | new ModalToGetSet(SomeModelType::class, 'makeEntity', 'createEntity', 'generateEntity'),
22 | new ModalToGetSet(SomeModelType::class, 'method'),
23 |
24 | ]);
25 | };
26 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply53/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | isEmpty('test');
18 | $entity->set('test', 'value'); // This should stay as is
19 | $entity->set('test', 'value', ['asOriginal' => 'true']); // This should stay as is
20 | $entity->set(['test' => 'value']); // This should be changed to patch
21 | $entity->set(['test' => 'value'], ['asOriginal' => 'true']); // This should be changed to patch
22 |
23 | $table = $this->fetchTable('Articles');
24 | $expr = $table->find()->newExpr();
25 | }
26 |
27 | public function findSomething(Query $query, array $options): Query {
28 | return $query;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApplyChronos3DateTime/src/Chronos3.php:
--------------------------------------------------------------------------------
1 | addYears(1);
9 | $dateTime->subYears(1);
10 | $dateTime->addYearsWithOverflow(1);
11 | $dateTime->subYearsWithOverflow(1);
12 | $dateTime->addMonths(1);
13 | $dateTime->subMonths(1);
14 | $dateTime->addMonthsWithOverflow(1);
15 | $dateTime->subMonthsWithOverflow(1);
16 | $dateTime->addDays(1);
17 | $dateTime->subDays(1);
18 | $dateTime->addWeekdays(1);
19 | $dateTime->subWeekdays(1);
20 | $dateTime->addWeeks(1);
21 | $dateTime->subWeeks(1);
22 |
23 | $dateTime->addHours(1);
24 | $dateTime->subHours(1);
25 | $dateTime->addMinutes(1);
26 | $dateTime->subMinutes(1);
27 | $dateTime->addSeconds(1);
28 | $dateTime->subSeconds(1);
29 |
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply53/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | hasValue('test');
18 | $entity->set('test', 'value'); // This should stay as is
19 | $entity->set('test', 'value', ['asOriginal' => 'true']); // This should stay as is
20 | $entity->patch(['test' => 'value']); // This should be changed to patch
21 | $entity->patch(['test' => 'value'], ['asOriginal' => 'true']); // This should be changed to patch
22 |
23 | $table = $this->fetchTable('Articles');
24 | $expr = $table->find()->expr();
25 | }
26 |
27 | public function findSomething(\Cake\ORM\Query\SelectQuery $query, array $options): \Cake\ORM\Query\SelectQuery {
28 | return $query;
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/OptionsArrayToNamedParameters.php:
--------------------------------------------------------------------------------
1 | class;
19 | }
20 |
21 | public function getObjectType(): ObjectType
22 | {
23 | return new ObjectType($this->class);
24 | }
25 |
26 | /**
27 | * @return array
28 | */
29 | public function getMethod(): string
30 | {
31 | return $this->methods[0] ?? '';
32 | }
33 |
34 | /**
35 | * @return array
36 | */
37 | public function getRenames(): array
38 | {
39 | if (isset($this->methods['rename'])) {
40 | return $this->methods['rename'];
41 | }
42 |
43 | return [];
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/HelperProperties.php:
--------------------------------------------------------------------------------
1 | set('_serialize', 'result');
40 | }
41 | }
42 |
43 | class CustomBehavior extends Behavior
44 | {
45 | protected $_defaultConfig = [];
46 | }
47 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ModalToGetSetRector/Fixture/fixture2.php.inc:
--------------------------------------------------------------------------------
1 | customMethod();
12 | $config = $object->customMethod('key');
13 |
14 | $object->customMethod('key', 'value');
15 | $object->customMethod(['key' => 'value']);
16 | }
17 |
18 | ?>
19 | -----
20 | customMethodGetName();
31 | $config = $object->customMethodGetName('key');
32 |
33 | $object->customMethodSetName('key', 'value');
34 | $object->customMethodSetName(['key' => 'value']);
35 | }
36 |
37 | ?>
38 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/RemoveIntermediaryMethodRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | regularMethod('call');
10 | $this->getTableLocator()->otherMethod();
11 | $this->Users = $this->getTableLocator()->get('Users');
12 | $articles = $this->getTableLocator()->get('Articles', ['table' => 'alt_articles']);
13 | $comments = $this->getTableLocator()
14 | ->get('Comments');
15 | }
16 | }
17 |
18 | ?>
19 | -----
20 | regularMethod('call');
29 | $this->getTableLocator()->otherMethod();
30 | $this->Users = $this->fetchTable('Users');
31 | $articles = $this->fetchTable('Articles', ['table' => 'alt_articles']);
32 | $comments = $this->fetchTable('Comments');
33 | }
34 | }
35 |
36 | ?>
37 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ArrayToFluentCallRector/config/configured_rule.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(ArrayToFluentCallRector::class, [
14 | ArrayToFluentCallRector::ARRAYS_TO_FLUENT_CALLS => [
15 | new ArrayToFluentCall(ConfigurableClass::class, [
16 | 'name' => 'setName',
17 | 'size' => 'setSize',
18 | ]),
19 | ],
20 | ArrayToFluentCallRector::FACTORY_METHODS => [
21 | new FactoryMethod(FactoryClass::class, 'buildClass', ConfigurableClass::class, 2),
22 | ],
23 | ]);
24 | };
25 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/NewEntityToNewEmptyEntityRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | newEntity();
13 |
14 | // This should NOT be changed (has arguments)
15 | $entity2 = $this->newEntity(['title' => 'Test']);
16 |
17 | return $entity;
18 | }
19 | }
20 |
21 | ?>
22 | -----
23 | newEmptyEntity();
35 |
36 | // This should NOT be changed (has arguments)
37 | $entity2 = $this->newEntity(['title' => 'Test']);
38 |
39 | return $entity;
40 | }
41 | }
42 |
43 | ?>
44 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7 | of the Software, and to permit persons to whom the Software is furnished to do
8 | so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/HelperProperties.php:
--------------------------------------------------------------------------------
1 | viewBuilder()->setOption('serialize', 'result');
40 | }
41 | }
42 |
43 | class CustomBehavior extends Behavior
44 | {
45 | protected array $_defaultConfig = [];
46 | }
47 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp45.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameClassRector::class, [
12 | 'Cake\Datasource\Paging\Paginator' => 'Cake\Datasource\Paging\NumericPaginator',
13 | 'Cake\TestSuite\ContainerStubTrait' => 'Cake\Core\TestSuite\ContainerStubTrait',
14 | 'Cake\TestSuite\HttpClientTrait' => 'Cake\Http\TestSuite\HttpClientTrait',
15 | 'Cake\Cache\InvalidArgumentException' => 'Cake\Cache\Exception\InvalidArgumentException',
16 | ]);
17 |
18 | $rectorConfig->ruleWithConfiguration(
19 | RenameMethodRector::class,
20 | [
21 | new MethodCallRename('Cake\View\View', 'loadHelper', 'addHelper'),
22 | new MethodCallRename('Cake\Validation\Validator', 'isArray', 'array'),
23 | ]
24 | );
25 |
26 | };
27 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_fixture.php.inc:
--------------------------------------------------------------------------------
1 |
18 | -----
19 |
36 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ModalToGetSetRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | config();
14 | $config = $object->config('key');
15 | $object->config('key', 'value');
16 | $object->config(['key' => 'value']);
17 | $object->config('key');
18 | }
19 | }
20 |
21 | ?>
22 | -----
23 | getConfig();
36 | $config = $object->getConfig('key');
37 | $object->setConfig('key', 'value');
38 | $object->setConfig(['key' => 'value']);
39 | $object->getConfig('key');
40 | }
41 | }
42 |
43 | ?>
44 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/View/AppView.php:
--------------------------------------------------------------------------------
1 | loadHelper('Html');`
34 | *
35 | * @return void
36 | */
37 | public function initialize()
38 | {
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/View/AppView.php:
--------------------------------------------------------------------------------
1 | loadHelper('Html');`
34 | *
35 | * @return void
36 | */
37 | public function initialize()
38 | {
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApplyChronos3Date/src/Chronos3.php:
--------------------------------------------------------------------------------
1 | addYear();
9 | $date->subYear();
10 | $date->addYearWithOverflow();
11 | $date->subYearWithOverflow();
12 | $date->addMonth();
13 | $date->subMonth();
14 | $date->addMonthWithOverflow();
15 | $date->subMonthWithOverflow();
16 | $date->addDay();
17 | $date->subDay();
18 | $date->addWeekday();
19 | $date->subWeekday();
20 | $date->addWeek();
21 | $date->subWeek();
22 |
23 | $date = new \Cake\Chronos\MutableDate();
24 | $date->addYear();
25 | $date->subYear();
26 | $date->addYearWithOverflow();
27 | $date->subYearWithOverflow();
28 | $date->addMonth();
29 | $date->subMonth();
30 | $date->addMonthWithOverflow();
31 | $date->subMonthWithOverflow();
32 | $date->addDay();
33 | $date->subDay();
34 | $date->addWeekday();
35 | $date->subWeekday();
36 | $date->addWeek();
37 | $date->subWeek();
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply45/src/View/AppView.php:
--------------------------------------------------------------------------------
1 | loadHelper('Html');`
34 | *
35 | * @return void
36 | */
37 | public function initialize()
38 | {
39 | $this->loadHelper('Html', ['className' => 'MyHtml']);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply45/src/View/AppView.php:
--------------------------------------------------------------------------------
1 | loadHelper('Html');`
34 | *
35 | * @return void
36 | */
37 | public function initialize()
38 | {
39 | $this->addHelper('Html', ['className' => 'MyHtml']);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApplyChronos3Date/src/Chronos3.php:
--------------------------------------------------------------------------------
1 | addYears(1);
9 | $date->subYears(1);
10 | $date->addYearsWithOverflow(1);
11 | $date->subYearsWithOverflow(1);
12 | $date->addMonths(1);
13 | $date->subMonths(1);
14 | $date->addMonthsWithOverflow(1);
15 | $date->subMonthsWithOverflow(1);
16 | $date->addDays(1);
17 | $date->subDays(1);
18 | $date->addWeekdays(1);
19 | $date->subWeekdays(1);
20 | $date->addWeeks(1);
21 | $date->subWeeks(1);
22 |
23 | $date = new \Cake\Chronos\ChronosDate();
24 | $date->addYears(1);
25 | $date->subYears(1);
26 | $date->addYearsWithOverflow(1);
27 | $date->subYearsWithOverflow(1);
28 | $date->addMonths(1);
29 | $date->subMonths(1);
30 | $date->addMonthsWithOverflow(1);
31 | $date->subMonthsWithOverflow(1);
32 | $date->addDays(1);
33 | $date->subDays(1);
34 | $date->addWeekdays(1);
35 | $date->subWeekdays(1);
36 | $date->addWeeks(1);
37 | $date->subWeeks(1);
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ArrayToFluentCallRector/Fixture/array_to_fluent_call.php.inc:
--------------------------------------------------------------------------------
1 | buildClass('foo', [
12 | 'name' => 'bar',
13 | 'size' => 2,
14 | ]);
15 |
16 | $factory->buildClass('foo', ['name' => 'bar'])
17 | ->setSize(3)
18 | ->doSomething();
19 |
20 | $factory->buildClass('foo', [
21 | 'name' => 'bar',
22 | 'baz' => 4,
23 | ]);
24 | }
25 |
26 | ?>
27 | -----
28 | buildClass('foo')->setName('bar')->setSize(2);
39 |
40 | $factory->buildClass('foo')->setName('bar')
41 | ->setSize(3)
42 | ->doSomething();
43 |
44 | $factory->buildClass('foo', [
45 | 'baz' => 4,
46 | ])->setName('bar');
47 | }
48 |
49 | ?>
50 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply51/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | [
19 | 'className' => 'FileEngine',
20 | 'prefix' => 'myapp_cake_core_',
21 | 'path' => 'persistent',
22 | 'serialize' => true,
23 | 'duration' => '+1 years',
24 | ],
25 | ];
26 | }
27 |
28 | public function testConnectionHelper()
29 | {
30 | $connectionHelper = new ConnectionHelper();
31 | $connection = ConnectionManager::get('test');
32 | $connectionHelper->runWithoutConstraints($connection, function ($connection) {
33 | $connection->execute('SELECT * FROM table');
34 | });
35 | $connectionHelper->dropTables('test', ['table']);
36 | $connectionHelper->enableQueryLogging(['test']);
37 | $connectionHelper->truncateTables('test', ['table']);
38 | $connectionHelper->addTestAliases();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/EntityPatchRector/Fixture/skip_non_entity.php.inc:
--------------------------------------------------------------------------------
1 | set(['key' => 'value']);
21 |
22 | // Should NOT transform: unknown object type
23 | $someObject->set(['data' => 'test']);
24 |
25 | return $object;
26 | }
27 | }
28 |
29 | ?>
30 | -----
31 | set(['key' => 'value']);
51 |
52 | // Should NOT transform: unknown object type
53 | $someObject->set(['data' => 'test']);
54 |
55 | return $object;
56 | }
57 | }
58 |
59 | ?>
60 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cakephp/upgrade",
3 | "type": "rector-extension",
4 | "description": "Command line tool for updating CakePHP applications and plugins.",
5 | "homepage": "https://cakephp.org",
6 | "license": "MIT",
7 | "require": {
8 | "php": "^8.1",
9 | "cakephp/console": "^5.0",
10 | "nette/utils": "^4.0",
11 | "rector/rector": "~2.2.9",
12 | "symfony/string": "^6.0 || ^7.0"
13 | },
14 | "autoload": {
15 | "psr-4": {
16 | "Cake\\Upgrade\\": "src/"
17 | }
18 | },
19 | "autoload-dev": {
20 | "psr-4": {
21 | "Cake\\Upgrade\\Test\\TestCase\\": "tests/TestCase/"
22 | }
23 | },
24 | "prefer-stable": true,
25 | "minimum-stability": "dev",
26 | "scripts": {
27 | "setup": "cp composer.json composer.backup && make install-dev && mv composer.backup composer.json",
28 | "cs-check": "phpcs --colors --parallel=16 -p -s",
29 | "cs-fix": "phpcbf --colors --parallel=16 -p",
30 | "test": "phpunit"
31 | },
32 | "config": {
33 | "sort-packages": true,
34 | "allow-plugins": {
35 | "dealerdirect/phpcodesniffer-composer-installer": true,
36 | "rector/extension-installer": true
37 | }
38 | },
39 | "support": {
40 | "source": "https://github.com/cakephp/upgrade"
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp44.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameClassRector::class, [
13 | 'Cake\TestSuite\ConsoleIntegrationTestTrait' => 'Cake\Console\TestSuite\ConsoleIntegrationTestTrait',
14 | 'Cake\TestSuite\Stub\ConsoleInput' => 'Cake\Console\TestSuite\StubConsoleInput',
15 | 'Cake\TestSuite\Stub\ConsoleOutput' => 'Cake\Console\TestSuite\StubConsoleOutput',
16 | 'Cake\TestSuite\Stub\MissingConsoleInputException' => 'Cake\Console\TestSuite\MissingConsoleInputException',
17 | 'Cake\TestSuite\HttpClientTrait' => 'Cake\Http\TestSuite\HttpClientTrait',
18 | ]);
19 |
20 | // Apply newExpr()->count() -> func()->count('*') transformation before general newExpr rename
21 | $rectorConfig->rule(NewExprToFuncRector::class);
22 |
23 | $rectorConfig->ruleWithConfiguration(
24 | RenameMethodRector::class,
25 | [new MethodCallRename('Cake\Database\Query', 'newExpr', 'expr')],
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/ChangeEntityTraitSetArrayToPatch/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | set(['paging' => 'test']);
13 | // This should not be changed
14 | $object->set('paging', 'test');
15 |
16 | $otherObject = new OtherClassWithSetMethod();
17 | // This should not be changed as well
18 | $otherObject->set(['paging' => 'test']);
19 | }
20 |
21 | ?>
22 | -----
23 | patch(['paging' => 'test']);
35 | // This should not be changed
36 | $object->set('paging', 'test');
37 |
38 | $otherObject = new OtherClassWithSetMethod();
39 | // This should not be changed as well
40 | $otherObject->set(['paging' => 'test']);
41 | }
42 |
43 | ?>
44 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/PaginatorCounterFormatRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | counter(['format' => __('Page {{page}} of {{pages}}')]);
11 |
12 | // This should NOT be converted (already using direct format)
13 | echo $paginator->counter(__('Showing {{current}} of {{count}}'));
14 |
15 | // This should NOT be converted (has more than one array item)
16 | echo $paginator->counter(['format' => __('Page {{page}}'), 'model' => 'Articles']);
17 | }
18 |
19 | ?>
20 | -----
21 | counter(__('Page {{page}} of {{pages}}'));
31 |
32 | // This should NOT be converted (already using direct format)
33 | echo $paginator->counter(__('Showing {{current}} of {{count}}'));
34 |
35 | // This should NOT be converted (has more than one array item)
36 | echo $paginator->counter(['format' => __('Page {{page}}'), 'model' => 'Articles']);
37 | }
38 |
39 | ?>
40 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/QueryParamAccessRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | getParam('?');
15 |
16 | // Should also work with method chaining
17 | $params = $this->getRequest()->getParam('?');
18 |
19 | return $queryParams;
20 | }
21 |
22 | protected function getRequest(): ServerRequest
23 | {
24 | return new ServerRequest();
25 | }
26 | }
27 |
28 | ?>
29 | -----
30 | getQueryParams();
44 |
45 | // Should also work with method chaining
46 | $params = $this->getRequest()->getQueryParams();
47 |
48 | return $queryParams;
49 | }
50 |
51 | protected function getRequest(): ServerRequest
52 | {
53 | return new ServerRequest();
54 | }
55 | }
56 |
57 | ?>
58 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply51/src/SomeTest.php:
--------------------------------------------------------------------------------
1 | [
19 | 'className' => 'FileEngine',
20 | 'prefix' => 'myapp_cake_core_',
21 | 'path' => 'persistent',
22 | 'serialize' => true,
23 | 'duration' => '+1 years',
24 | ],
25 | ];
26 | }
27 |
28 | public function testConnectionHelper()
29 | {
30 | $connectionHelper = new ConnectionHelper();
31 | $connection = ConnectionManager::get('test');
32 | \Cake\TestSuite\ConnectionHelper::runWithoutConstraints($connection, function ($connection) {
33 | $connection->execute('SELECT * FROM table');
34 | });
35 | \Cake\TestSuite\ConnectionHelper::dropTables('test', ['table']);
36 | \Cake\TestSuite\ConnectionHelper::enableQueryLogging(['test']);
37 | \Cake\TestSuite\ConnectionHelper::truncateTables('test', ['table']);
38 | \Cake\TestSuite\ConnectionHelper::addTestAliases();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/QueryParamAccessRector/Fixture/skip_other_params.php.inc:
--------------------------------------------------------------------------------
1 | getParam('id');
15 | $action = $request->getParam('action');
16 | $paging = $request->getParam('paging');
17 |
18 | // Should NOT transform: non-Request object
19 | $someObject->getParam('?');
20 |
21 | return compact('id', 'action', 'paging');
22 | }
23 | }
24 |
25 | ?>
26 | -----
27 | getParam('id');
41 | $action = $request->getParam('action');
42 | $paging = $request->getParam('paging');
43 |
44 | // Should NOT transform: non-Request object
45 | $someObject->getParam('?');
46 |
47 | return compact('id', 'action', 'paging');
48 | }
49 | }
50 |
51 | ?>
52 |
--------------------------------------------------------------------------------
/config/requirements.php:
--------------------------------------------------------------------------------
1 | newExpr()->count();
14 | $countField = $query->newExpr()->count('id');
15 | $sum = $query->newExpr()->sum('total');
16 | $avg = $query->newExpr()->avg('score');
17 | $min = $query->newExpr()->min('price');
18 | $max = $query->newExpr()->max('price');
19 |
20 | return compact('count', 'sum', 'avg', 'min', 'max');
21 | }
22 | }
23 |
24 | ?>
25 | -----
26 | func()->count('*');
39 | $countField = $query->func()->count('id');
40 | $sum = $query->func()->sum('total');
41 | $avg = $query->func()->avg('score');
42 | $min = $query->func()->min('price');
43 | $max = $query->func()->max('price');
44 |
45 | return compact('count', 'sum', 'avg', 'min', 'max');
46 | }
47 | }
48 |
49 | ?>
50 |
--------------------------------------------------------------------------------
/tests/TestCase/Command/FileRenameCommandTest.php:
--------------------------------------------------------------------------------
1 | setupTestApp(__FUNCTION__);
30 | Configure::write('App.paths.plugins', TEST_APP . 'plugins');
31 |
32 | $this->exec('upgrade file_rename templates ' . TEST_APP);
33 | $this->assertTestAppUpgraded();
34 | }
35 |
36 | public function testLocales(): void
37 | {
38 | $this->setupTestApp(__FUNCTION__);
39 | Configure::write('App.paths.plugins', TEST_APP . 'plugins');
40 |
41 | $this->exec('upgrade file_rename locales ' . TEST_APP);
42 | $this->assertTestAppUpgraded();
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/NewExprToFuncRector/Fixture/sql_functions.php.inc:
--------------------------------------------------------------------------------
1 | newExpr()->now();
13 | $diff = $query->newExpr()->dateDiff('created', 'modified');
14 | $extract = $query->newExpr()->extract('year', 'created');
15 |
16 | // Other SQL functions
17 | $concat = $query->newExpr()->concat(['first_name', 'last_name']);
18 | $coalesce = $query->newExpr()->coalesce(['email', 'backup_email']);
19 | $rand = $query->newExpr()->rand();
20 |
21 | return $query;
22 | }
23 | }
24 |
25 | ?>
26 | -----
27 | func()->now();
39 | $diff = $query->func()->dateDiff('created', 'modified');
40 | $extract = $query->func()->extract('year', 'created');
41 |
42 | // Other SQL functions
43 | $concat = $query->func()->concat(['first_name', 'last_name']);
44 | $coalesce = $query->func()->coalesce(['email', 'backup_email']);
45 | $rand = $query->func()->rand();
46 |
47 | return $query;
48 | }
49 | }
50 |
51 | ?>
52 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/EntityPatchRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | set with array literal
18 | $entity->set(['name' => 'Test', 'email' => 'test@example.com']);
19 |
20 | // Should NOT transform: set with variable
21 | $data = ['name' => 'Test'];
22 | $entity->set($data);
23 |
24 | // Should NOT transform: set with non-array argument
25 | $entity->set('name', 'Test');
26 |
27 | return $entity;
28 | }
29 | }
30 |
31 | ?>
32 | -----
33 | set with array literal
50 | $entity->patch(['name' => 'Test', 'email' => 'test@example.com']);
51 |
52 | // Should NOT transform: set with variable
53 | $data = ['name' => 'Test'];
54 | $entity->set($data);
55 |
56 | // Should NOT transform: set with non-array argument
57 | $entity->set('name', 'Test');
58 |
59 | return $entity;
60 | }
61 | }
62 |
63 | ?>
64 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/ClassMethod/FormBuildValidatorRector/Fixture/fixture.php.inc:
--------------------------------------------------------------------------------
1 | add('name', 'length', [
15 | 'rule' => ['minLength', 10],
16 | 'message' => 'Name is required',
17 | ])
18 | ->add('email', 'format', [
19 | 'rule' => 'email',
20 | 'message' => 'A valid email address is required',
21 | ]);
22 |
23 | return $validator;
24 | }
25 | }
26 |
27 | ?>
28 | -----
29 | add('name', 'length', [
43 | 'rule' => ['minLength', 10],
44 | 'message' => 'Name is required',
45 | ])
46 | ->add('email', 'format', [
47 | 'rule' => 'email',
48 | 'message' => 'A valid email address is required',
49 | ]);
50 |
51 | return $validator;
52 | }
53 | }
54 |
55 | ?>
56 |
--------------------------------------------------------------------------------
/src/Rector/ValueObject/ModalToGetSet.php:
--------------------------------------------------------------------------------
1 | getMethod = $getMethod ?? 'get' . ucfirst($unprefixedMethod);
29 | $this->setMethod = $setMethod ?? 'set' . ucfirst($unprefixedMethod);
30 | }
31 |
32 | public function getObjectType(): ObjectType
33 | {
34 | return new ObjectType($this->type);
35 | }
36 |
37 | public function getUnprefixedMethod(): string
38 | {
39 | return $this->unprefixedMethod;
40 | }
41 |
42 | public function getGetMethod(): string
43 | {
44 | return $this->getMethod;
45 | }
46 |
47 | public function getSetMethod(): string
48 | {
49 | return $this->setMethod;
50 | }
51 |
52 | public function getMinimalSetterArgumentCount(): int
53 | {
54 | return $this->minimalSetterArgumentCount;
55 | }
56 |
57 | public function getFirstArgumentType(): ?string
58 | {
59 | return $this->firstArgumentType;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp30.php:
--------------------------------------------------------------------------------
1 | rule(AppUsesStaticCallToUseStatementRector::class);
11 |
12 | $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
13 | # see https://github.com/cakephp/upgrade/blob/756410c8b7d5aff9daec3fa1fe750a3858d422ac/src/Shell/Task/RenameClassesTask.php#L37
14 | 'Cake\Network\Http\HttpSocket' => 'Cake\Network\Http\Client',
15 | 'Cake\Model\ConnectionManager' => 'Cake\Database\ConnectionManager',
16 | 'Cake\TestSuite\CakeTestCase' => 'Cake\TestSuite\TestCase',
17 | 'Cake\TestSuite\Fixture\CakeTestFixture' => 'Cake\TestSuite\Fixture\TestFixture',
18 | 'Cake\Utility\String' => 'Cake\Utility\Text',
19 | 'CakePlugin' => 'Plugin',
20 | 'CakeException' => 'Exception',
21 | # see https://book.cakephp.org/3/en/appendices/3-0-migration-guide.html#configure
22 | 'Cake\Configure\PhpReader' => 'Cake\Core\Configure\EnginePhpConfig',
23 | 'Cake\Configure\IniReader' => 'Cake\Core\Configure\EngineIniConfig',
24 | 'Cake\Configure\ConfigReaderInterface' => 'Cake\Core\Configure\ConfigEngineInterface',
25 | # https://book.cakephp.org/3/en/appendices/3-0-migration-guide.html#request
26 | 'CakeRequest' => 'Cake\Network\Request',
27 | ]);
28 | };
29 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp41.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameClassRector::class, [
13 | 'Cake\Routing\Exception\RedirectException' => 'Cake\Http\Exception\RedirectException',
14 | 'Cake\Database\Expression\Comparison' => 'Cake\Database\Expression\ComparisonExpression',
15 | ]);
16 |
17 | $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [
18 | new MethodCallRename('Cake\Database\Schema\TableSchema', 'getPrimary', 'getPrimaryKey'),
19 | new MethodCallRename('Cake\Database\Type\DateTimeType', 'setTimezone', 'setDatabaseTimezone'),
20 | new MethodCallRename('Cake\Database\Expression\QueryExpression', 'or_', 'or'),
21 | new MethodCallRename('Cake\Database\Expression\QueryExpression', 'and_', 'and'),
22 | new MethodCallRename('Cake\View\Form\ContextInterface', 'primaryKey', 'getPrimaryKey'),
23 | new MethodCallRename(
24 | 'Cake\Http\Middleware\CsrfProtectionMiddleware',
25 | 'whitelistCallback',
26 | 'skipCheckCallback'
27 | ),
28 | ]);
29 |
30 | $rectorConfig->ruleWithConfiguration(ModalToGetSetRector::class, [new ModalToGetSet('Cake\Form\Form', 'schema')]);
31 | };
32 |
--------------------------------------------------------------------------------
/tests/test_apps/original/FileRenameCommand-testTemplates/src/View/AjaxView.php:
--------------------------------------------------------------------------------
1 | response = $this->response->withType('ajax');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/tests/test_apps/original/RectorCommand-testApply50/src/Plugin.php:
--------------------------------------------------------------------------------
1 | response = $this->response->withType('ajax');
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/Rector/NodeAnalyzer/FluentChainMethodCallNodeAnalyzer.php:
--------------------------------------------------------------------------------
1 | methodCall()->chainedMethodCall()"
14 | *
15 | * Taken from https://github.com/rectorphp/rector/blob/d8da002b107c9b64d464bb48101290d4d078df4b/packages/Defluent/NodeAnalyzer/FluentChainMethodCallNodeAnalyzer.php
16 | * https://github.com/rectorphp/rector/blob/main/LICENSE
17 | */
18 | final class FluentChainMethodCallNodeAnalyzer
19 | {
20 | /**
21 | * @api doctrine
22 | */
23 | public function resolveRootMethodCall(MethodCall $methodCall): ?MethodCall
24 | {
25 | $callerNode = $methodCall->var;
26 | while ($callerNode instanceof MethodCall && $callerNode->var instanceof MethodCall) {
27 | $callerNode = $callerNode->var;
28 | }
29 | if ($callerNode instanceof MethodCall) {
30 | return $callerNode;
31 | }
32 |
33 | return null;
34 | }
35 |
36 | /**
37 | * @return \PhpParser\Node\Expr|\PhpParser\Node\Name
38 | */
39 | public function resolveRootExpr(MethodCall $methodCall): Expr|Name
40 | {
41 | $callerNode = $methodCall->var;
42 | while ($callerNode instanceof MethodCall || $callerNode instanceof StaticCall) {
43 | $callerNode = $callerNode instanceof StaticCall ? $callerNode->class : $callerNode->var;
44 | }
45 |
46 | return $callerNode;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/NewExprToFuncRector/Fixture/skip_non_func_methods.php.inc:
--------------------------------------------------------------------------------
1 | newExpr()->eq('status', 1);
13 | $expr2 = $query->newExpr()->gt('price', 100);
14 | $expr3 = $query->newExpr()->and(['status' => 1, 'active' => true]);
15 |
16 | // Should NOT transform: standalone newExpr() call
17 | $expr4 = $query->newExpr();
18 |
19 | // Should NOT transform: non-Query object
20 | $someObject->newExpr()->count();
21 |
22 | return $query;
23 | }
24 | }
25 |
26 | ?>
27 | -----
28 | newExpr()->eq('status', 1);
40 | $expr2 = $query->newExpr()->gt('price', 100);
41 | $expr3 = $query->newExpr()->and(['status' => 1, 'active' => true]);
42 |
43 | // Should NOT transform: standalone newExpr() call
44 | $expr4 = $query->newExpr();
45 |
46 | // Should NOT transform: non-Query object
47 | $someObject->newExpr()->count();
48 |
49 | return $query;
50 | }
51 | }
52 |
53 | ?>
54 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp53.php:
--------------------------------------------------------------------------------
1 | count() -> func()->count('*') transformation before general newExpr rename
17 | $rectorConfig->rule(NewExprToFuncRector::class);
18 |
19 | $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [
20 | new MethodCallRename('Cake\Database\Query', 'newExpr', 'expr'),
21 | ]);
22 | $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
23 | 'Cake\ORM\Query' => 'Cake\ORM\Query\SelectQuery',
24 | 'Cake\TestSuite\Fixture\TransactionFixtureStrategy' => 'Cake\TestSuite\Fixture\TransactionStrategy',
25 | 'Cake\TestSuite\Fixture\TruncateFixtureStrategy' => 'Cake\TestSuite\Fixture\TruncateStrategy',
26 | ]);
27 | $rectorConfig->rule(EntityIsEmptyRector::class);
28 | $rectorConfig->rule(EntityPatchRector::class);
29 | $rectorConfig->rule(FormExecuteToProcessRector::class);
30 | $rectorConfig->rule(QueryParamAccessRector::class);
31 | };
32 |
--------------------------------------------------------------------------------
/tests/test_apps/upgraded/RectorCommand-testApply50/src/Plugin.php:
--------------------------------------------------------------------------------
1 | isEmpty() with !$entity->hasValue() for \Cake\ORM\Entity descendants',
22 | [
23 | new CodeSample(
24 | '$entity->isEmpty();',
25 | '!$entity->hasValue();',
26 | ),
27 | ],
28 | );
29 | }
30 |
31 | public function getNodeTypes(): array
32 | {
33 | return [MethodCall::class];
34 | }
35 |
36 | public function refactor(Node $node): ?Node
37 | {
38 | if (!$node instanceof MethodCall) {
39 | return null;
40 | }
41 |
42 | if (!$this->isName($node->name, 'isEmpty')) {
43 | return null;
44 | }
45 |
46 | $objectType = $this->getType($node->var);
47 | if (!$objectType instanceof ObjectType) {
48 | return null;
49 | }
50 |
51 | if (!$objectType->isInstanceOf(Entity::class)->yes()) {
52 | return null;
53 | }
54 |
55 | $newMethodCall = new MethodCall(
56 | $node->var,
57 | new Identifier('hasValue'),
58 | $node->args,
59 | );
60 |
61 | // Replace with !$entity->hasValue($args)
62 | return new BooleanNot($newMethodCall);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/Application.php:
--------------------------------------------------------------------------------
1 | add('upgrade', UpgradeCommand::class);
52 | $commands->add('upgrade file_rename', FileRenameCommand::class);
53 | $commands->add('upgrade rector', RectorCommand::class);
54 |
55 | return $commands;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/TableRegistryLocatorRector.php:
--------------------------------------------------------------------------------
1 | get()`', [
17 | new ConfiguredCodeSample(
18 | <<<'CODE_SAMPLE'
19 | TableRegistry::get('something');
20 | CODE_SAMPLE
21 | ,
22 | <<<'CODE_SAMPLE'
23 | TableRegistry::getTableLocator()->get('something');
24 | CODE_SAMPLE,
25 | ),
26 | ]);
27 | }
28 |
29 | public function getNodeTypes(): array
30 | {
31 | return [StaticCall::class];
32 | }
33 |
34 | public function refactor(Node $node): ?Node
35 | {
36 | if (! $node instanceof StaticCall) {
37 | return null;
38 | }
39 |
40 | // Ensure it's a static call we're looking for: TableRegistry::get(...)
41 | if (! $this->isStaticCallMatch($node, 'Cake\ORM\TableRegistry', 'get')) {
42 | return null;
43 | }
44 |
45 | // Create new static call TableRegistry::getTableLocator()->get(...)
46 | return $this->nodeFactory->createMethodCall(
47 | $this->nodeFactory->createStaticCall('Cake\ORM\TableRegistry', 'getTableLocator'),
48 | 'get',
49 | $node->args,
50 | );
51 | }
52 |
53 | private function isStaticCallMatch(StaticCall $staticCall, string $className, string $methodName): bool
54 | {
55 | // Check if the static call is `TableRegistry::get`
56 | return $this->isName($staticCall->class, $className) && $this->isName($staticCall->name, $methodName);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/NewEntityToNewEmptyEntityRector.php:
--------------------------------------------------------------------------------
1 | newEntity() to Table->newEmptyEntity() when called with no arguments.
16 | *
17 | * @see https://github.com/cakephp/upgrade/issues/143
18 | */
19 | final class NewEntityToNewEmptyEntityRector extends AbstractRector
20 | {
21 | public function getRuleDefinition(): RuleDefinition
22 | {
23 | return new RuleDefinition(
24 | 'Rename Table->newEntity() to Table->newEmptyEntity() when called with no arguments',
25 | [
26 | new CodeSample(
27 | <<<'CODE_SAMPLE'
28 | $entity = $this->Articles->newEntity();
29 | CODE_SAMPLE
30 | ,
31 | <<<'CODE_SAMPLE'
32 | $entity = $this->Articles->newEmptyEntity();
33 | CODE_SAMPLE,
34 | ),
35 | ],
36 | );
37 | }
38 |
39 | /**
40 | * @return array>
41 | */
42 | public function getNodeTypes(): array
43 | {
44 | return [MethodCall::class];
45 | }
46 |
47 | /**
48 | * @param \PhpParser\Node\Expr\MethodCall $node
49 | */
50 | public function refactor(Node $node): ?Node
51 | {
52 | if (!$this->isName($node->name, 'newEntity')) {
53 | return null;
54 | }
55 |
56 | if (!$this->isObjectType($node->var, new ObjectType('Cake\ORM\Table'))) {
57 | return null;
58 | }
59 |
60 | // Only rename if there are no arguments
61 | if (count($node->args) > 0) {
62 | return null;
63 | }
64 |
65 | $node->name = new Identifier('newEmptyEntity');
66 |
67 | return $node;
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp43.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(
17 | RenameMethodRector::class,
18 | [new MethodCallRename('Cake\Controller\Component', 'shutdown', 'afterFilter')]
19 | );
20 |
21 | $rectorConfig->ruleWithConfiguration(PropertyFetchToMethodCallRector::class, [
22 | new PropertyFetchToMethodCall('Cake\Network\Socket', 'connected', 'isConnected'),
23 | new PropertyFetchToMethodCall('Cake\Network\Socket', 'encrypted', 'isEncrypted'),
24 | new PropertyFetchToMethodCall('Cake\Network\Socket', 'lastError', 'lastError'),
25 | ]);
26 |
27 | $rectorConfig->ruleWithConfiguration(
28 | RemoveIntermediaryMethodRector::class,
29 | [new RemoveIntermediaryMethod('getTableLocator', 'get', 'fetchTable')]
30 | );
31 |
32 | // These rector rules were removed in rector 0.17 - see https://github.com/rectorphp/rector-src/pull/3777
33 | //$rectorConfig->ruleWithConfiguration(MethodCallToAnotherMethodCallWithArgumentsRector::class, [
34 | // new MethodCallToAnotherMethodCallWithArguments(
35 | // 'Cake\Database\DriverInterface',
36 | // 'supportsQuoting',
37 | // 'supports',
38 | // ['quote'],
39 | // ),
40 | // new MethodCallToAnotherMethodCallWithArguments(
41 | // 'Cake\Database\DriverInterface',
42 | // 'supportsSavepoints',
43 | // 'supports',
44 | // ['savepoint']
45 | // ),
46 | //]);
47 | };
48 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/EntityPatchRector.php:
--------------------------------------------------------------------------------
1 | set([...]) to $entity->patch([...]) only if first argument is an array literal',
22 | [
23 | new CodeSample(
24 | <<<'CODE_SAMPLE'
25 | $entity->set(['test' => 'value']);
26 | CODE_SAMPLE
27 | ,
28 | <<<'CODE_SAMPLE'
29 | $entity->patch(['test' => 'value']);
30 | CODE_SAMPLE,
31 | ),
32 | ],
33 | );
34 | }
35 |
36 | public function getNodeTypes(): array
37 | {
38 | return [MethodCall::class];
39 | }
40 |
41 | public function refactor(Node $node): ?Node
42 | {
43 | if (!$node instanceof MethodCall) {
44 | return null;
45 | }
46 |
47 | // must be $something->set(...)
48 | if (!$node->name instanceof Identifier || $node->name->toString() !== 'set') {
49 | return null;
50 | }
51 |
52 | // must have at least 1 argument
53 | if ($node->args === [] || !isset($node->args[0])) {
54 | return null;
55 | }
56 |
57 | $firstArg = $node->args[0]->value;
58 |
59 | // only change if first argument is an array literal
60 | if (!$firstArg instanceof Array_) {
61 | return null;
62 | }
63 |
64 | $callerType = $this->getType($node->var);
65 | if (!$callerType instanceof ObjectType) {
66 | return null;
67 | }
68 |
69 | if (!$callerType->isInstanceOf(Entity::class)->yes()) {
70 | return null;
71 | }
72 |
73 | // change the method name
74 | $node->name = new Identifier('patch');
75 |
76 | return $node;
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/tests/TestCase/Rector/MethodCall/OptionsArrayToNamedParametersRector/Fixture/options_to_named_parameters.php.inc:
--------------------------------------------------------------------------------
1 | find();
13 | $instance->find('all');
14 | $instance->find('list', ['fields' => ['name']]);
15 | $instance->find('all', [
16 | 'conditions' => ['Articles.id' => $value],
17 | 'order' => ['Articles.id' => 'asc'],
18 | ]);
19 |
20 | // Preserve named parameters should they exist.
21 | $instance->find('all',
22 | conditions: ['Articles.id' => $value],
23 | order: ['Articles.id' => 'asc'],
24 | );
25 | $instance->get(1, contain: ['Articles' => ['Categories']]);
26 |
27 | // Array values are not spread
28 | $options = ['conditions' => ['Articles.id' => $value]];
29 | $instance->find('all', $options);
30 |
31 | // Can modify get as well.
32 | $instance->get(1);
33 | $instance->get(1, ['key' => 'cache-this']);
34 | }
35 |
36 | ?>
37 | -----
38 | find();
50 | $instance->find('all');
51 | $instance->find('list', fields: ['name']);
52 | $instance->find('all',
53 | conditions: ['Articles.id' => $value],
54 | order: ['Articles.id' => 'asc']);
55 |
56 | // Preserve named parameters should they exist.
57 | $instance->find('all',
58 | conditions: ['Articles.id' => $value],
59 | order: ['Articles.id' => 'asc'],
60 | );
61 | $instance->get(1, contain: ['Articles' => ['Categories']]);
62 |
63 | // Array values are not spread
64 | $options = ['conditions' => ['Articles.id' => $value]];
65 | $instance->find('all', $options);
66 |
67 | // Can modify get as well.
68 | $instance->get(1);
69 | $instance->get(1, cacheKey: 'cache-this');
70 | }
71 |
72 | ?>
73 |
--------------------------------------------------------------------------------
/config/bootstrap.php:
--------------------------------------------------------------------------------
1 | getMessage() . "\n");
43 | }
44 |
45 | /*
46 | * Load an environment local configuration file.
47 | * You can use a file like app_local.php to provide local overrides to your
48 | * shared configuration.
49 | */
50 | //Configure::load('app_local', 'default');
51 |
52 | /*
53 | * Set the default server timezone. Using UTC makes time calculations / conversions easier.
54 | * Check https://php.net/manual/en/timezones.php for list of valid timezone strings.
55 | */
56 | date_default_timezone_set(Configure::read('App.defaultTimezone'));
57 |
58 | /*
59 | * Configure the mbstring extension to use the correct encoding.
60 | */
61 | mb_internal_encoding(Configure::read('App.encoding'));
62 |
63 | /*
64 | * Set the default locale. This controls how dates, number and currency is
65 | * formatted and sets the default language to use for translations.
66 | */
67 | ini_set('intl.default_locale', Configure::read('App.defaultLocale'));
68 |
69 | Log::setConfig(Configure::consume('Log'));
70 |
--------------------------------------------------------------------------------
/bin/cake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 | ################################################################################
3 | #
4 | # Cake is a shell script for invoking CakePHP shell commands
5 | #
6 | # CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
7 | # Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
8 | #
9 | # Licensed under The MIT License
10 | # For full copyright and license information, please see the LICENSE.txt
11 | # Redistributions of files must retain the above copyright notice.
12 | #
13 | # @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
14 | # @link https://cakephp.org CakePHP(tm) Project
15 | # @since 1.2.0
16 | # @license https://opensource.org/licenses/mit-license.php MIT License
17 | #
18 | ################################################################################
19 |
20 | # Canonicalize by following every symlink of the given name recursively
21 | canonicalize() {
22 | NAME="$1"
23 | if [ -f "$NAME" ]
24 | then
25 | DIR=$(dirname -- "$NAME")
26 | NAME=$(cd -P "$DIR" > /dev/null && pwd -P)/$(basename -- "$NAME")
27 | fi
28 | while [ -h "$NAME" ]; do
29 | DIR=$(dirname -- "$NAME")
30 | SYM=$(readlink "$NAME")
31 | NAME=$(cd "$DIR" > /dev/null && cd $(dirname -- "$SYM") > /dev/null && pwd)/$(basename -- "$SYM")
32 | done
33 | echo "$NAME"
34 | }
35 |
36 | # Find a CLI version of PHP
37 | findCliPhp() {
38 | for TESTEXEC in php php-cli /usr/local/bin/php
39 | do
40 | SAPI=`echo "= PHP_SAPI ?>" | $TESTEXEC 2>/dev/null`
41 | if [ "$SAPI" = "cli" ]
42 | then
43 | echo $TESTEXEC
44 | return
45 | fi
46 | done
47 | echo "Failed to find a CLI version of PHP; falling back to system standard php executable" >&2
48 | echo "php";
49 | }
50 |
51 | # If current path is a symlink, resolve to real path
52 | realname="$0"
53 | if [ -L "$realname" ]
54 | then
55 | realname=$(readlink -f "$0")
56 | fi
57 |
58 | CONSOLE=$(dirname -- "$(canonicalize "$realname")")
59 | APP=$(dirname "$CONSOLE")
60 |
61 | # If your CLI PHP is somewhere that this doesn't find, you can define a PHP environment
62 | # variable with the correct path in it.
63 | if [ -z "$PHP" ]
64 | then
65 | PHP=$(findCliPhp)
66 | fi
67 |
68 | if [ $(basename $realname) != 'cake' ]
69 | then
70 | exec $PHP "$CONSOLE"/cake.php $(basename $realname) "$@"
71 | else
72 | exec $PHP "$CONSOLE"/cake.php "$@"
73 | fi
74 |
75 | exit
76 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/ChangeEntityTraitSetArrayToPatchRector.php:
--------------------------------------------------------------------------------
1 | set(array) with $this->patch(array) when the first param is an array',
21 | [
22 | new ConfiguredCodeSample(
23 | <<<'CODE_SAMPLE'
24 | $this->set(['key' => 'value']);
25 | CODE_SAMPLE
26 | ,
27 | <<<'CODE_SAMPLE'
28 | $this->patch(['key' => 'value']);
29 | CODE_SAMPLE,
30 | ),
31 | ],
32 | );
33 | }
34 |
35 | public function getNodeTypes(): array
36 | {
37 | return [MethodCall::class];
38 | }
39 |
40 | public function refactor(Node $node): ?Node
41 | {
42 | if (! $node instanceof MethodCall) {
43 | return null;
44 | }
45 |
46 | // Check the method name is "set"
47 | if (! $this->isName($node->name, 'set')) {
48 | return null;
49 | }
50 |
51 | // Check that the first argument exists and is an array
52 | if (! isset($node->args[0])) {
53 | return null;
54 | }
55 |
56 | $firstArg = $node->args[0]->value;
57 | if (! $firstArg instanceof Array_) {
58 | return null;
59 | }
60 |
61 | // Make sure the method is called on an object that uses EntityTrait
62 | $callerType = $this->getType($node->var);
63 | if (! $callerType instanceof ObjectType) {
64 | return null;
65 | }
66 |
67 | $classReflection = $callerType->getClassReflection();
68 | if ($classReflection === null) {
69 | return null;
70 | }
71 | if (! $classReflection->hasTraitUse('Cake\Datasource\EntityTrait')) {
72 | return null;
73 | }
74 |
75 | // Rename the method to "patch"
76 | $node->name = new Identifier('patch');
77 |
78 | return $node;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/SetSerializeToViewBuilderRector.php:
--------------------------------------------------------------------------------
1 | set(\'_serialize\', \'result\')` to ' .
19 | '`$this->viewBuilder()->setOption(\'serialize\', \'result\')`.',
20 | [
21 | new ConfiguredCodeSample(
22 | <<<'CODE_SAMPLE'
23 | $this->set('_serialize', 'result');
24 | CODE_SAMPLE
25 | ,
26 | <<<'CODE_SAMPLE'
27 | $this->viewBuilder()->setOption('serialize', 'result');
28 | CODE_SAMPLE,
29 | ),
30 | ],
31 | );
32 | }
33 |
34 | public function getNodeTypes(): array
35 | {
36 | return [MethodCall::class];
37 | }
38 |
39 | public function refactor(Node $node): ?Node
40 | {
41 | if (! $node instanceof MethodCall) {
42 | return null;
43 | }
44 |
45 | // Ensure it's the method call we're looking for: $this->set('_serialize', ...)
46 | if (! $this->isMethodCallMatch($node, 'set', '_serialize')) {
47 | return null;
48 | }
49 |
50 | // Create the new method call
51 | return $this->nodeFactory->createMethodCall(
52 | $this->nodeFactory->createMethodCall($node->var, 'viewBuilder'),
53 | 'setOption',
54 | ['serialize', $node->args[1]->value],
55 | );
56 | }
57 |
58 | private function isMethodCallMatch(MethodCall $methodCall, string $methodName, string $firstArgumentValue): bool
59 | {
60 | // Check if the method is 'set'
61 | if (! $this->isName($methodCall->name, $methodName)) {
62 | return false;
63 | }
64 |
65 | // Check if the first argument is '_serialize'w
66 | return isset($methodCall->args[0]) && $methodCall->args[0]->value->value === $firstArgumentValue;
67 | }
68 |
69 | public function configure(array $configuration): void
70 | {
71 | // No configuration options
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/StaticConnectionHelperRector.php:
--------------------------------------------------------------------------------
1 | runWithoutConstraints($connection, function ($connection) {
28 | $connection->execute('SELECT * FROM table');
29 | });
30 | CODE_SAMPLE
31 | ,
32 | <<<'CODE_SAMPLE'
33 | ConnectionHelper::runWithoutConstraints($connection, function ($connection) {
34 | $connection->execute('SELECT * FROM table');
35 | });
36 | CODE_SAMPLE,
37 | ),
38 | ]);
39 | }
40 |
41 | public function getNodeTypes(): array
42 | {
43 | return [MethodCall::class, Assign::class];
44 | }
45 |
46 | public function refactor(Node $node): ?Node
47 | {
48 | if ($node instanceof Assign) {
49 | if ($node->expr instanceof New_ && $this->isName($node->expr->class, 'ConnectionHelper')) {
50 | // Remove the instantiation statement
51 | $parent = $node->getAttribute(AttributeKey::PARENT_NODE);
52 | if ($parent instanceof Expression) {
53 | $this->removeNode($parent);
54 | }
55 | }
56 |
57 | return null;
58 | }
59 |
60 | // Ensure the node is a method call on the ConnectionHelper instance
61 | if (! $this->isObjectType($node->var, new ObjectType(ConnectionHelper::class))) {
62 | return null;
63 | }
64 |
65 | // Replace with a static method call
66 | return new StaticCall(
67 | new Node\Name\FullyQualified(ConnectionHelper::class),
68 | $node->name,
69 | $node->args,
70 | );
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/config/paths.php:
--------------------------------------------------------------------------------
1 |
27 | */
28 | private array $callsWithRemoveMethodCallArgs = [];
29 |
30 | public function getRuleDefinition(): RuleDefinition
31 | {
32 | return new RuleDefinition('Remove method call', [
33 | new ConfiguredCodeSample(
34 | <<<'CODE_SAMPLE'
35 | $obj = new SomeClass();
36 | $obj->methodCall1();
37 | $obj->methodCall2();
38 | CODE_SAMPLE,
39 | <<<'CODE_SAMPLE'
40 | $obj = new SomeClass();
41 | $obj->methodCall2();
42 | CODE_SAMPLE,
43 | ['SomeClass', 'methodCall1'],
44 | ),
45 | ]);
46 | }
47 |
48 | /**
49 | * @return array>
50 | */
51 | public function getNodeTypes(): array
52 | {
53 | return [Expression::class];
54 | }
55 |
56 | /**
57 | * @param \PhpParser\Node\Stmt\Expression $node
58 | */
59 | public function refactor(Node $node): ?int
60 | {
61 | if (! $node->expr instanceof MethodCall) {
62 | return null;
63 | }
64 |
65 | foreach ($this->callsWithRemoveMethodCallArgs as $removedFunction) {
66 | if (! $this->isObjectType($node->expr->var, $removedFunction->getObjectType())) {
67 | continue;
68 | }
69 |
70 | if (! $this->isName($node->expr->name, $removedFunction->getMethodName())) {
71 | continue;
72 | }
73 |
74 | return NodeVisitor::REMOVE_NODE;
75 | }
76 |
77 | return null;
78 | }
79 |
80 | /**
81 | * @param array $configuration
82 | */
83 | public function configure(array $configuration): void
84 | {
85 | $this->callsWithRemoveMethodCallArgs = $configuration[self::REMOVE_METHOD_CALL_ARGS] ?? $configuration;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/QueryParamAccessRector.php:
--------------------------------------------------------------------------------
1 | getParam('?') to $request->getQueryParams()
17 | *
18 | * In CakePHP 6.0, the getParam('?') shortcut for accessing query parameters
19 | * is removed. Instead, use getQueryParams() directly.
20 | *
21 | * @see https://book.cakephp.org/6/en/appendices/6-0-migration-guide.html
22 | */
23 | final class QueryParamAccessRector extends AbstractRector
24 | {
25 | public function __construct(
26 | private ValueResolver $valueResolver,
27 | ) {
28 | }
29 |
30 | public function getRuleDefinition(): RuleDefinition
31 | {
32 | return new RuleDefinition(
33 | 'Change $request->getParam(\'?\') to $request->getQueryParams()',
34 | [
35 | new CodeSample(
36 | <<<'CODE_SAMPLE'
37 | $queryParams = $request->getParam('?');
38 | CODE_SAMPLE
39 | ,
40 | <<<'CODE_SAMPLE'
41 | $queryParams = $request->getQueryParams();
42 | CODE_SAMPLE,
43 | ),
44 | ],
45 | );
46 | }
47 |
48 | public function getNodeTypes(): array
49 | {
50 | return [MethodCall::class];
51 | }
52 |
53 | public function refactor(Node $node): ?Node
54 | {
55 | if (!$node instanceof MethodCall) {
56 | return null;
57 | }
58 |
59 | // Must be ->getParam() call
60 | if (!$node->name instanceof Identifier || $node->name->toString() !== 'getParam') {
61 | return null;
62 | }
63 |
64 | // Must have at least one argument
65 | if (count($node->args) < 1) {
66 | return null;
67 | }
68 |
69 | // First argument must be the string '?'
70 | $firstArg = $node->args[0]->value;
71 | if (!$this->valueResolver->isValue($firstArg, '?')) {
72 | return null;
73 | }
74 |
75 | // Check if this is called on a Request object
76 | $callerType = $this->getType($node->var);
77 | if (!$callerType instanceof ObjectType) {
78 | return null;
79 | }
80 |
81 | if (
82 | !$callerType->isInstanceOf('Cake\Http\ServerRequest')->yes() &&
83 | !$callerType->isInstanceOf('Psr\Http\Message\ServerRequestInterface')->yes()
84 | ) {
85 | return null;
86 | }
87 |
88 | // Transform to getQueryParams() with no arguments
89 | $node->name = new Identifier('getQueryParams');
90 | $node->args = [];
91 |
92 | return $node;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/Rector/Rector/MethodCall/PaginatorCounterFormatRector.php:
--------------------------------------------------------------------------------
1 | counter(['format' => ...]) to Paginator->counter(...).
18 | *
19 | * @see https://github.com/cakephp/upgrade/issues/143
20 | */
21 | final class PaginatorCounterFormatRector extends AbstractRector
22 | {
23 | public function getRuleDefinition(): RuleDefinition
24 | {
25 | return new RuleDefinition(
26 | 'Convert Paginator->counter([\'format\' => ...]) to Paginator->counter(...)',
27 | [
28 | new CodeSample(
29 | <<<'CODE_SAMPLE'
30 | $this->Paginator->counter(['format' => __('Page {{page}} of {{pages}}')]);
31 | CODE_SAMPLE
32 | ,
33 | <<<'CODE_SAMPLE'
34 | $this->Paginator->counter(__('Page {{page}} of {{pages}}'));
35 | CODE_SAMPLE,
36 | ),
37 | ],
38 | );
39 | }
40 |
41 | /**
42 | * @return array>
43 | */
44 | public function getNodeTypes(): array
45 | {
46 | return [MethodCall::class];
47 | }
48 |
49 | /**
50 | * @param \PhpParser\Node\Expr\MethodCall $node
51 | */
52 | public function refactor(Node $node): ?Node
53 | {
54 | if (!$this->isName($node->name, 'counter')) {
55 | return null;
56 | }
57 |
58 | if (!$this->isObjectType($node->var, new ObjectType('Cake\View\Helper\PaginatorHelper'))) {
59 | return null;
60 | }
61 |
62 | // Must have exactly one argument
63 | if (count($node->args) !== 1) {
64 | return null;
65 | }
66 |
67 | $firstArgNode = $node->args[0];
68 | if (!$firstArgNode instanceof Arg) {
69 | return null;
70 | }
71 |
72 | $firstArg = $firstArgNode->value;
73 |
74 | // Check if the argument is an array
75 | if (!$firstArg instanceof Array_) {
76 | return null;
77 | }
78 |
79 | // Check if the array has exactly one item with key 'format'
80 | if (count($firstArg->items) !== 1) {
81 | return null;
82 | }
83 |
84 | $arrayItem = $firstArg->items[0];
85 |
86 | if (!$arrayItem->key instanceof String_) {
87 | return null;
88 | }
89 |
90 | if ($arrayItem->key->value !== 'format') {
91 | return null;
92 | }
93 |
94 | // Replace the array argument with just the format value
95 | $node->args = [new Arg($arrayItem->value)];
96 |
97 | return $node;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/Rector/Set/CakePHPSetList.php:
--------------------------------------------------------------------------------
1 | > $GITHUB_OUTPUT
39 |
40 | - name: Get date part for cache key
41 | id: key-date
42 | run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT
43 |
44 | - name: Cache composer dependencies
45 | uses: actions/cache@v5
46 | with:
47 | path: ${{ steps.composer-cache.outputs.dir }}
48 | key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }}
49 |
50 | - name: Composer Install
51 | run: |
52 | if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then
53 | make install-dev-lowest
54 | elif ${{ matrix.php-version == '8.1' }}; then
55 | make install-dev-ignore-reqs
56 | else
57 | make install-dev
58 | fi
59 |
60 | - name: Setup problem matchers for PHPUnit
61 | if: matrix.php-version == '8.1'
62 | run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
63 |
64 | - name: Run PHPUnit
65 | run: vendor/bin/phpunit --display-incomplete --display-skipped
66 |
67 | cs-stan:
68 | name: Coding Standard & Static Analysis
69 | runs-on: ubuntu-22.04
70 |
71 | steps:
72 | - uses: actions/checkout@v6
73 |
74 | - name: Setup PHP
75 | uses: shivammathur/setup-php@v2
76 | with:
77 | php-version: '8.1'
78 | extensions: mbstring, intl
79 | tools: cs2pr
80 | coverage: none
81 |
82 | - name: Get composer cache directory
83 | id: composer-cache
84 | run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
85 |
86 | - name: Get date part for cache key
87 | id: key-date
88 | run: echo "date=$(date +'%Y-%m')" >> $GITHUB_OUTPUT
89 |
90 | - name: Cache composer dependencies
91 | uses: actions/cache@v5
92 | with:
93 | path: ${{ steps.composer-cache.outputs.dir }}
94 | key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }}
95 |
96 | - name: Composer install
97 | run: make install-dev
98 |
99 | - name: Run PHP CodeSniffer
100 | run: vendor/bin/phpcs --report=checkstyle | cs2pr
101 |
--------------------------------------------------------------------------------
/src/Rector/Rector/ClassMethod/FormExecuteToProcessRector.php:
--------------------------------------------------------------------------------
1 | >
61 | */
62 | public function getNodeTypes(): array
63 | {
64 | return [Class_::class];
65 | }
66 |
67 | /**
68 | * @param \PhpParser\Node\Stmt\Class_ $node
69 | */
70 | public function refactor(Node $node): ?Node
71 | {
72 | if (!$this->isObjectType($node, new ObjectType('Cake\Form\Form'))) {
73 | return null;
74 | }
75 |
76 | // Check if process() already exists
77 | $hasProcess = false;
78 | foreach ($node->stmts as $stmt) {
79 | if ($stmt instanceof ClassMethod && $this->isName($stmt->name, 'process')) {
80 | $hasProcess = true;
81 | break;
82 | }
83 | }
84 |
85 | // If process() exists, don't rename _execute()
86 | if ($hasProcess) {
87 | return null;
88 | }
89 |
90 | // Find and rename _execute() method
91 | $hasChanges = false;
92 | foreach ($node->stmts as $stmt) {
93 | if (!$stmt instanceof ClassMethod) {
94 | continue;
95 | }
96 |
97 | if (!$this->isName($stmt->name, '_execute')) {
98 | continue;
99 | }
100 |
101 | // Rename the method to process()
102 | $stmt->name = new Identifier('process');
103 |
104 | $hasChanges = true;
105 | break;
106 | }
107 |
108 | return $hasChanges ? $node : null;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/config/rector/sets/cakephp36.php:
--------------------------------------------------------------------------------
1 | ruleWithConfiguration(RenameMethodRector::class, [
14 | new MethodCallRename('Cake\ORM\Table', 'association', 'getAssociation'),
15 | new MethodCallRename('Cake\Validation\ValidationSet', 'isPresenceRequired', 'requirePresence'),
16 | new MethodCallRename('Cake\Validation\ValidationSet', 'isEmptyAllowed', 'allowEmpty'),
17 | ]);
18 |
19 | $rectorConfig->ruleWithConfiguration(PropertyFetchToMethodCallRector::class, [
20 | new PropertyFetchToMethodCall('Cake\Controller\Controller', 'name', 'getName', 'setName'),
21 | new PropertyFetchToMethodCall('Cake\Controller\Controller', 'plugin', 'getPlugin', 'setPlugin'),
22 | new PropertyFetchToMethodCall('Cake\Form\Form', 'validator', 'getValidator', 'setValidator'),
23 | ]);
24 |
25 | $rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
26 | 'Cake\Cache\Engine\ApcEngine' => 'Cake\Cache\Engine\ApcuEngine',
27 | 'Cake\Network\Exception\BadRequestException' => 'Cake\Http\Exception\BadRequestException',
28 | 'Cake\Network\Exception\ConflictException' => 'Cake\Http\Exception\ConflictException',
29 | 'Cake\Network\Exception\ForbiddenException' => 'Cake\Http\Exception\ForbiddenException',
30 | 'Cake\Network\Exception\GoneException' => 'Cake\Http\Exception\GoneException',
31 | 'Cake\Network\Exception\HttpException' => 'Cake\Http\Exception\HttpException',
32 | 'Cake\Network\Exception\InternalErrorException' => 'Cake\Http\Exception\InternalErrorException',
33 | 'Cake\Network\Exception\InvalidCsrfTokenException' => 'Cake\Http\Exception\InvalidCsrfTokenException',
34 | 'Cake\Network\Exception\MethodNotAllowedException' => 'Cake\Http\Exception\MethodNotAllowedException',
35 | 'Cake\Network\Exception\NotAcceptableException' => 'Cake\Http\Exception\NotAcceptableException',
36 | 'Cake\Network\Exception\NotFoundException' => 'Cake\Http\Exception\NotFoundException',
37 | 'Cake\Network\Exception\NotImplementedException' => 'Cake\Http\Exception\NotImplementedException',
38 | 'Cake\Network\Exception\ServiceUnavailableException' => 'Cake\Http\Exception\ServiceUnavailableException',
39 | 'Cake\Network\Exception\UnauthorizedException' => 'Cake\Http\Exception\UnauthorizedException',
40 | 'Cake\Network\Exception\UnavailableForLegalReasonsException'
41 | => 'Cake\Http\Exception\UnavailableForLegalReasonsException',
42 | 'Cake\Network\Session' => 'Cake\Http\Session',
43 | 'Cake\Network\Session\DatabaseSession' => 'Cake\Http\Session\DatabaseSession',
44 | 'Cake\Network\Session\CacheSession' => 'Cake\Http\Session\CacheSession',
45 | 'Cake\Network\CorsBuilder' => 'Cake\Http\CorsBuilder',
46 | 'Cake\View\Widget\WidgetRegistry' => 'Cake\View\Widget\WidgetLocator',
47 | ]);
48 | };
49 |
--------------------------------------------------------------------------------
/tests/TestCase/TestCase.php:
--------------------------------------------------------------------------------
1 | testAppDir = $className . '-' . $testName;
41 | $testAppPath = ORIGINAL_APPS . $this->testAppDir;
42 |
43 | if (file_exists($testAppPath)) {
44 | $fs = new Filesystem();
45 | $fs->deleteDir(TEST_APP);
46 | $fs->copyDir($testAppPath, TEST_APP);
47 | }
48 | }
49 |
50 | protected function assertTestAppUpgraded(): void
51 | {
52 | $appFs = $this->getFsInfo(TEST_APP);
53 | $upgradedFs = $this->getFsInfo(UPGRADED_APPS . $this->testAppDir);
54 | $this->assertEquals($upgradedFs['tree'], $appFs['tree'], 'Upgraded test_app does not match `upgraded_apps`');
55 |
56 | foreach ($upgradedFs['files'] as $relativePath) {
57 | $this->assertFileEquals(UPGRADED_APPS . $this->testAppDir . DS . $relativePath, TEST_APP . $relativePath, $relativePath);
58 | }
59 | }
60 |
61 | protected function getFsInfo(string $path): array
62 | {
63 | if ($path[-1] !== DS) {
64 | $path .= DS;
65 | }
66 |
67 | $iterator = new RecursiveIteratorIterator(
68 | new RecursiveDirectoryIterator(
69 | $path,
70 | RecursiveDirectoryIterator::KEY_AS_PATHNAME |
71 | RecursiveDirectoryIterator::CURRENT_AS_FILEINFO |
72 | RecursiveDirectoryIterator::SKIP_DOTS,
73 | ),
74 | RecursiveIteratorIterator::SELF_FIRST,
75 | );
76 |
77 | $tree = [];
78 | $files = [];
79 | foreach ($iterator as $filePath => $fileInfo) {
80 | $relativePath = substr($filePath, strlen($path));
81 | if ($fileInfo->isDir()) {
82 | $tree[$relativePath] = [];
83 | } elseif ($fileInfo->isFile() && $fileInfo->getFileName() !== 'empty') {
84 | $tree[$relativePath] = $fileInfo->getFileName();
85 | $files[] = $relativePath;
86 | }
87 | }
88 |
89 | return ['tree' => Hash::expand($tree, DS), 'files' => $files];
90 | }
91 | }
92 |
--------------------------------------------------------------------------------