├── .editorconfig ├── .gitattributes ├── .github ├── codecov.yml ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE.md ├── Makefile ├── README.md ├── bin ├── cake ├── cake.bat └── cake.php ├── composer.json ├── config ├── app.php ├── bootstrap.php ├── paths.php ├── rector │ ├── cakephp40.php │ ├── cakephp41.php │ ├── cakephp42.php │ ├── cakephp43.php │ ├── cakephp44.php │ ├── cakephp45.php │ ├── cakephp50.php │ ├── cakephp51.php │ ├── cakephp52.php │ ├── chronos3.php │ ├── migrations45.php │ ├── phpunit80.php │ └── sets │ │ ├── cakephp-fluent-options.php │ │ ├── cakephp30.php │ │ ├── cakephp34.php │ │ ├── cakephp35.php │ │ ├── cakephp36.php │ │ ├── cakephp37.php │ │ ├── cakephp38.php │ │ ├── cakephp40.php │ │ ├── cakephp41.php │ │ ├── cakephp42.php │ │ ├── cakephp43.php │ │ ├── cakephp44.php │ │ ├── cakephp45.php │ │ ├── cakephp50.php │ │ ├── cakephp51.php │ │ ├── cakephp52.php │ │ ├── chronos3.php │ │ └── migrations45.php └── requirements.php ├── phpcs.xml ├── phpunit.xml.dist ├── src ├── Application.php ├── Command │ ├── FileRenameCommand.php │ ├── RectorCommand.php │ └── UpgradeCommand.php └── Rector │ ├── NodeAnalyzer │ └── FluentChainMethodCallNodeAnalyzer.php │ ├── Rector │ ├── MethodCall │ │ ├── AddMethodCallArgsRector.php │ │ ├── ArrayToFluentCallRector.php │ │ ├── ChangeEntityTraitSetArrayToPatchRector.php │ │ ├── ModalToGetSetRector.php │ │ ├── OptionsArrayToNamedParametersRector.php │ │ ├── RemoveIntermediaryMethodRector.php │ │ ├── RemoveMethodCallRector.php │ │ ├── RenameMethodCallBasedOnParameterRector.php │ │ ├── SetSerializeToViewBuilderRector.php │ │ ├── StaticConnectionHelperRector.php │ │ └── TableRegistryLocatorRector.php │ ├── Namespace_ │ │ └── AppUsesStaticCallToUseStatementRector.php │ └── Property │ │ └── ChangeSnakedFixtureNameToPascalRector.php │ ├── Set │ ├── CakePHPLevelSetList.php │ └── CakePHPSetList.php │ ├── ShortClassNameResolver.php │ └── ValueObject │ ├── AddMethodCallArgs.php │ ├── ArrayItemsAndFluentClass.php │ ├── ArrayToFluentCall.php │ ├── FactoryMethod.php │ ├── ModalToGetSet.php │ ├── OptionsArrayToNamedParameters.php │ ├── RemoveIntermediaryMethod.php │ ├── RemoveMethodCall.php │ ├── RenameMethodCallBasedOnParameter.php │ └── SetSerializeToView.php └── tests ├── TestCase ├── Command │ ├── FileRenameCommandTest.php │ └── RectorCommandTest.php ├── Rector │ ├── MethodCall │ │ ├── AddMethodCallArgsRector │ │ │ ├── AddMethodCallArgsRectorTest.php │ │ │ ├── Fixture │ │ │ │ └── fixture.php.inc │ │ │ ├── Source │ │ │ │ └── SomeModelType.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ ├── ArrayToFluentCallRector │ │ │ ├── ArrayToFluentCallRectorTest.php │ │ │ ├── Fixture │ │ │ │ ├── array_to_fluent_call.php.inc │ │ │ │ └── fluent_factory.php.inc │ │ │ ├── Source │ │ │ │ ├── ConfigurableClass.php │ │ │ │ └── FactoryClass.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ ├── ChangeEntityTraitSetArrayToPatch │ │ │ ├── ChangeEntityTraitSetArrayToPatchTest.php │ │ │ ├── Fixture │ │ │ │ └── fixture.php.inc │ │ │ ├── Source │ │ │ │ └── OtherClassWithSetMethod.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ ├── ModalToGetSetRector │ │ │ ├── Fixture │ │ │ │ ├── fixture.php.inc │ │ │ │ ├── fixture2.php.inc │ │ │ │ ├── fixture3.php.inc │ │ │ │ └── fixture4.php.inc │ │ │ ├── ModalToGetSetRectorTest.php │ │ │ ├── Source │ │ │ │ ├── Entity.php │ │ │ │ └── SomeModelType.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ ├── OptionsArrayToNamedParametersRector │ │ │ ├── Fixture │ │ │ │ └── options_to_named_parameters.php.inc │ │ │ ├── OptionsArrayToNamedParametersRectorTest.php │ │ │ ├── Source │ │ │ │ └── ConfigurableClass.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ ├── RemoveIntermediaryMethodRector │ │ │ ├── Fixture │ │ │ │ └── fixture.php.inc │ │ │ ├── RemoveIntermediaryMethodRectorTest.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ ├── RemoveMethodCallArgsRector │ │ │ ├── Fixture │ │ │ │ └── fixture.php.inc │ │ │ ├── RemoveMethodCallArgsRectorTest.php │ │ │ ├── Source │ │ │ │ └── SomeModelType.php │ │ │ └── config │ │ │ │ └── configured_rule.php │ │ └── RenameMethodCallBasedOnParameterRector │ │ │ ├── Fixture │ │ │ ├── fixture.php.inc │ │ │ └── skip_fixture2.php.inc │ │ │ ├── RenameMethodCallBasedOnParameterRectorTest.php │ │ │ ├── Source │ │ │ └── SomeModelType.php │ │ │ └── config │ │ │ └── configured_rule.php │ ├── Namespace_ │ │ └── AppUsesStaticCallToUseStatementRector │ │ │ ├── AppUsesStaticCallToUseStatementRectorTest.php │ │ │ ├── Fixture │ │ │ ├── cakephp_controller.php.inc │ │ │ ├── cakephp_controller_with_strict_types.php.inc │ │ │ ├── cakephp_fixture.php.inc │ │ │ ├── cakephp_import_namespaces_up.php.inc │ │ │ ├── fixture.php.inc │ │ │ ├── inside_if.php.inc │ │ │ ├── skip_different_static_call.php.inc │ │ │ ├── without_namespace.php.inc │ │ │ └── without_namespace_with_strict_types.php.inc │ │ │ ├── Source │ │ │ ├── App.php │ │ │ └── Xml.php │ │ │ └── config │ │ │ └── configured_rule.php │ └── Property │ │ └── ChangeSnakedFixtureNameToPascal │ │ ├── ChangeSnakedFixtureNameToPascalTest.php │ │ ├── Fixture │ │ └── fixture.php.inc │ │ └── config │ │ └── configured_rule.php └── TestCase.php ├── bootstrap.php └── test_apps ├── original ├── FileRenameCommand-testLocales │ ├── plugins │ │ ├── TestPlugin │ │ │ └── src │ │ │ │ ├── Locale │ │ │ │ └── default.pot │ │ │ │ └── Template │ │ │ │ └── empty │ │ └── WithoutLocalesPlugin │ │ │ └── src │ │ │ └── Template │ │ │ └── empty │ └── src │ │ ├── Locale │ │ └── default.pot │ │ └── Template │ │ └── empty ├── FileRenameCommand-testTemplates │ ├── plugins │ │ ├── TestPlugin │ │ │ └── src │ │ │ │ ├── Locale │ │ │ │ └── default.pot │ │ │ │ └── Template │ │ │ │ ├── Cell │ │ │ │ └── TestPluginCell │ │ │ │ │ └── bar.ctp │ │ │ │ ├── Element │ │ │ │ └── Flash │ │ │ │ │ └── default.ctp │ │ │ │ ├── Email │ │ │ │ ├── html │ │ │ │ │ └── default.ctp │ │ │ │ └── text │ │ │ │ │ └── default.ctp │ │ │ │ ├── Error │ │ │ │ ├── error400.ctp │ │ │ │ └── error500.ctp │ │ │ │ ├── Layout │ │ │ │ └── default.ctp │ │ │ │ └── Pages │ │ │ │ └── home.ctp │ │ └── WithoutTemplatesPlugin │ │ │ └── src │ │ │ ├── Locale │ │ │ └── default.pot │ │ │ └── empty │ └── src │ │ ├── Locale │ │ └── default.pot │ │ ├── Template │ │ ├── Cell │ │ │ └── TestCell │ │ │ │ └── display.ctp │ │ ├── Element │ │ │ └── Flash │ │ │ │ └── default.ctp │ │ ├── Email │ │ │ ├── html │ │ │ │ └── default.ctp │ │ │ └── text │ │ │ │ └── default.ctp │ │ ├── Error │ │ │ ├── error400.ctp │ │ │ └── error500.ctp │ │ ├── Layout │ │ │ └── default.ctp │ │ └── Pages │ │ │ └── home.ctp │ │ └── View │ │ ├── AjaxView.php │ │ ├── AppView.php │ │ ├── Cell │ │ └── empty │ │ └── Helper │ │ └── empty ├── RectorCommand-testApply45 │ └── src │ │ └── View │ │ └── AppView.php ├── RectorCommand-testApply50 │ └── src │ │ ├── CommandExecuteReturn.php │ │ ├── DateTimeRename.php │ │ ├── FixtureProperties.php │ │ ├── HelperProperties.php │ │ ├── Model │ │ └── Entity │ │ │ └── Category.php │ │ ├── Plugin.php │ │ ├── QueryUpgrade.php │ │ ├── SomeCell.php │ │ ├── SomeComponent.php │ │ ├── SomeMailer.php │ │ ├── SomeTest.php │ │ ├── SomeView.php │ │ └── SomeWidget.php ├── RectorCommand-testApply51 │ └── src │ │ └── SomeTest.php ├── RectorCommand-testApply52 │ └── src │ │ └── SomeTest.php ├── RectorCommand-testApplyAppDir │ └── Command │ │ └── HelloCommand.php ├── RectorCommand-testApplyChronos3Date │ └── src │ │ └── Chronos3.php ├── RectorCommand-testApplyChronos3DateTime │ └── src │ │ └── Chronos3.php └── RectorCommand-testApplyMigrations45 │ └── src │ └── Migrations45.php └── upgraded ├── FileRenameCommand-testLocales ├── plugins │ ├── TestPlugin │ │ ├── resources │ │ │ └── locales │ │ │ │ └── default.pot │ │ └── src │ │ │ └── Template │ │ │ └── empty │ └── WithoutLocalesPlugin │ │ └── src │ │ └── Template │ │ └── empty ├── resources │ └── locales │ │ └── default.pot └── src │ └── Template │ └── empty ├── FileRenameCommand-testTemplates ├── plugins │ ├── TestPlugin │ │ ├── src │ │ │ └── Locale │ │ │ │ └── default.pot │ │ └── templates │ │ │ ├── Error │ │ │ ├── error400.php │ │ │ └── error500.php │ │ │ ├── Pages │ │ │ └── home.php │ │ │ ├── cell │ │ │ └── TestPluginCell │ │ │ │ └── bar.php │ │ │ ├── element │ │ │ └── flash │ │ │ │ └── default.php │ │ │ ├── email │ │ │ ├── html │ │ │ │ └── default.php │ │ │ └── text │ │ │ │ └── default.php │ │ │ └── layout │ │ │ └── default.php │ └── WithoutTemplatesPlugin │ │ └── src │ │ ├── Locale │ │ └── default.pot │ │ └── empty ├── src │ ├── Locale │ │ └── default.pot │ └── View │ │ ├── AjaxView.php │ │ ├── AppView.php │ │ ├── Cell │ │ └── empty │ │ └── Helper │ │ └── empty └── templates │ ├── Error │ ├── error400.php │ └── error500.php │ ├── Pages │ └── home.php │ ├── cell │ └── TestCell │ │ └── display.php │ ├── element │ └── flash │ │ └── default.php │ ├── email │ ├── html │ │ └── default.php │ └── text │ │ └── default.php │ └── layout │ └── default.php ├── RectorCommand-testApply45 └── src │ └── View │ └── AppView.php ├── RectorCommand-testApply50 └── src │ ├── CommandExecuteReturn.php │ ├── DateTimeRename.php │ ├── FixtureProperties.php │ ├── HelperProperties.php │ ├── Model │ └── Entity │ │ └── Category.php │ ├── Plugin.php │ ├── QueryUpgrade.php │ ├── SomeCell.php │ ├── SomeComponent.php │ ├── SomeMailer.php │ ├── SomeTest.php │ ├── SomeView.php │ └── SomeWidget.php ├── RectorCommand-testApply51 └── src │ └── SomeTest.php ├── RectorCommand-testApply52 └── src │ └── SomeTest.php ├── RectorCommand-testApplyChronos3Date └── src │ └── Chronos3.php ├── RectorCommand-testApplyChronos3DateTime └── src │ └── Chronos3.php └── RectorCommand-testApplyMigrations45 └── src └── Migrations45.php /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at https://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 4 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.bat] 14 | end_of_line = crlf 15 | 16 | [*.yml] 17 | indent_size = 2 18 | 19 | [Makefile] 20 | indent_style = tab 21 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Define the line ending behavior of the different file extensions 2 | # Set default behaviour, in case users don't have core.autocrlf set. 3 | * text=auto eol=lf 4 | 5 | # Declare files that will always have CRLF line endings on checkout. 6 | *.bat eol=crlf 7 | -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: yes 3 | 4 | coverage: 5 | range: "90...100" 6 | 7 | comment: false 8 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: composer 4 | directory: "/" 5 | schedule: 6 | interval: weekly 7 | open-pull-requests-limit: 10 8 | - package-ecosystem: github-actions 9 | directory: "/" 10 | schedule: 11 | interval: weekly 12 | open-pull-requests-limit: 10 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - 3.x 7 | - 4.x 8 | - 5.x 9 | pull_request: 10 | branches: 11 | - '*' 12 | workflow_dispatch: 13 | 14 | jobs: 15 | testsuite: 16 | runs-on: ubuntu-22.04 17 | strategy: 18 | fail-fast: false 19 | matrix: 20 | php-version: ['8.1'] 21 | prefer-lowest: [''] 22 | include: 23 | - php-version: '8.1' 24 | prefer-lowest: 'prefer-lowest' 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - name: Setup PHP 30 | uses: shivammathur/setup-php@v2 31 | with: 32 | php-version: ${{ matrix.php-version }} 33 | extensions: mbstring, intl 34 | coverage: pcov 35 | 36 | - name: Get composer cache directory 37 | id: composer-cache 38 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 39 | 40 | - name: Get date part for cache key 41 | id: key-date 42 | run: echo "::set-output name=date::$(date +'%Y-%m')" 43 | 44 | - name: Cache composer dependencies 45 | uses: actions/cache@v4 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: | 66 | if [[ ${{ matrix.php-version }} == '8.1' ]]; then 67 | export CODECOVERAGE=1 && vendor/bin/phpunit --display-incomplete --display-skipped --coverage-clover=coverage.xml 68 | else 69 | vendor/bin/phpunit 70 | fi 71 | 72 | - name: Submit code coverage 73 | if: matrix.php-version == '8.1' 74 | uses: codecov/codecov-action@v5 75 | 76 | cs-stan: 77 | name: Coding Standard & Static Analysis 78 | runs-on: ubuntu-22.04 79 | 80 | steps: 81 | - uses: actions/checkout@v4 82 | 83 | - name: Setup PHP 84 | uses: shivammathur/setup-php@v2 85 | with: 86 | php-version: '8.1' 87 | extensions: mbstring, intl 88 | coverage: none 89 | 90 | - name: Get composer cache directory 91 | id: composer-cache 92 | run: echo "::set-output name=dir::$(composer config cache-files-dir)" 93 | 94 | - name: Get date part for cache key 95 | id: key-date 96 | run: echo "::set-output name=date::$(date +'%Y-%m')" 97 | 98 | - name: Cache composer dependencies 99 | uses: actions/cache@v4 100 | with: 101 | path: ${{ steps.composer-cache.outputs.dir }} 102 | key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }} 103 | 104 | - name: Composer install 105 | run: make install-dev 106 | 107 | - name: Run PHP CodeSniffer 108 | run: vendor/bin/phpcs --report=checkstyle src/ tests/ 109 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /tmp/ 2 | /vendor/ 3 | /logs/ 4 | /composer.lock 5 | /plugins/DebugKit 6 | /phpunit.phar 7 | .phpunit* 8 | /.idea/ 9 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: install-dev test check-cs 2 | 3 | DEV_DEPENDENCIES = cakephp/cakephp:5.x-dev \ 4 | cakephp/cakephp-codesniffer:^5.0 \ 5 | mikey179/vfsstream:^1.6.8 \ 6 | phpunit/phpunit:^10.5.38 \ 7 | cakephp/migrations:^4.5.0 8 | 9 | install-dev: 10 | composer require --dev $(DEV_DEPENDENCIES) 11 | 12 | install-dev-lowest: 13 | composer require --dev --prefer-lowest $(DEV_DEPENDENCIES) 14 | 15 | install-dev-ignore-reqs: 16 | composer require --dev --ignore-platform-reqs $(DEV_DEPENDENCIES) 17 | 18 | test: install-dev 19 | composer test 20 | 21 | cs-check: install-dev 22 | composer cs-check 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CakePHP Upgrade tool 2 | 3 | [![CI](https://github.com/cakephp/upgrade/actions/workflows/ci.yml/badge.svg)](https://github.com/cakephp/upgrade/actions/workflows/ci.yml) 4 | 5 | Upgrade tools for CakePHP meant to facilitate migrating between CakePHP 4.x 6 | versions and from CakePHP 4.x to CakePHP 5.x. This repository should be used as a standalone 7 | application and *not* as a plugin. 8 | 9 | ## Installation 10 | 11 | First clone this repository or download a zipball: 12 | 13 | ```bash 14 | git clone git://github.com/cakephp/upgrade 15 | ``` 16 | 17 | Then to install dependencies with `composer` 18 | 19 | ```bash 20 | php composer.phar install --no-dev 21 | ``` 22 | 23 | ## Usage 24 | 25 | The upgrade tool provides a standalone application that can be used to upgrade 26 | other applications or cakephp plugins. Each of the subcommands accepts a path 27 | that points to the application you want to upgrade. 28 | 29 | ## Upgrading between CakePHP 4.x versions 30 | 31 | When upgrading between CakePHP 4.x versions the `rector` command can automate 32 | updates for many deprecation warnings. To get the most value from the `rector` 33 | command you should be sure to add as many typehints or parameter docblock 34 | annotations as you can. Without these annotations or typehints rector will not 35 | be able to be as effective as it cannot infer types. 36 | 37 | ```bash 38 | cd /path/to/upgrade 39 | 40 | # To apply upgrade rules from 4.3 to 4.4 41 | bin/cake upgrade rector --rules cakephp44 /path/to/your/app/src 42 | ``` 43 | 44 | There are rules included for: 45 | 46 | - cakephp41 47 | - cakephp42 48 | - cakephp43 49 | - cakephp44 50 | 51 | ## Upgrading from CakePHP 3.x to CakePHP 4.x 52 | 53 | The upgrade tool is intended to be run *before* you update your application's 54 | dependencies to 4.0. The rector based tasks will not run correctly if your 55 | application already has its dependencies updated to 4.x. 56 | 57 | Once you have installed the upgrade tool dependencies there are several commands 58 | you should run: 59 | 60 | ```bash 61 | cd /path/to/upgrade 62 | 63 | # Run all upgrade tasks at once. 64 | bin/cake upgrade /home/mark/Sites/my-app 65 | 66 | # OR run upgrade tasks individually. 67 | # Rename locale files 68 | bin/cake upgrade file_rename locales /home/mark/Sites/my-app 69 | 70 | # Rename template files 71 | bin/cake upgrade file_rename templates /home/mark/Sites/my-app 72 | 73 | # Run rector rules. 74 | bin/cake upgrade rector /home/mark/Sites/my-app/src 75 | bin/cake upgrade rector /home/mark/Sites/my-app/tests 76 | bin/cake upgrade rector /home/mark/Sites/my-app/config 77 | ``` 78 | 79 | ## Development 80 | 81 | To ease installation & usage, this package does not 82 | use `require-dev` in `composer.json` as the installed PHPUnit and 83 | CakePHP packages cause conflicts with the rector tasks. 84 | 85 | To install dev-dependencies use `make install-dev`. Then you will be able to 86 | run `vendor/bin/phpunit`. You can also use `make test` to install dependencies 87 | and run tests. 88 | -------------------------------------------------------------------------------- /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 "" | $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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /bin/cake.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/php -q 2 | run($argv)); 13 | -------------------------------------------------------------------------------- /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.0.0", 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 | "cs-check": "phpcs --colors --parallel=16 -p -s src/ tests/", 28 | "cs-fix": "phpcbf --colors --parallel=16 -p src/ tests/", 29 | "test": "phpunit" 30 | }, 31 | "config": { 32 | "sort-packages": true, 33 | "allow-plugins": { 34 | "dealerdirect/phpcodesniffer-composer-installer": true, 35 | "rector/extension-installer": true 36 | } 37 | }, 38 | "support": { 39 | "source": "https://github.com/cakephp/upgrade" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /config/app.php: -------------------------------------------------------------------------------- 1 | filter_var(env('DEBUG', true), FILTER_VALIDATE_BOOLEAN), 16 | 17 | /** 18 | * Configure basic information about the application. 19 | * 20 | * - namespace - The namespace to find app classes under. 21 | * - defaultLocale - The default locale for translation, formatting currencies and numbers, date and time. 22 | * - encoding - The encoding used for HTML + database connections. 23 | * - base - The base directory the app resides in. If false this 24 | * will be auto detected. 25 | * - dir - Name of app directory. 26 | */ 27 | 'App' => [ 28 | 'namespace' => 'Cake\Upgrade', 29 | 'encoding' => env('APP_ENCODING', 'UTF-8'), 30 | 'defaultLocale' => env('APP_DEFAULT_LOCALE', 'en_US'), 31 | 'defaultTimezone' => env('APP_DEFAULT_TIMEZONE', 'UTC'), 32 | 'base' => false, 33 | 'dir' => 'src', 34 | ], 35 | 36 | /** 37 | * Configure the Error and Exception handlers used by your application. 38 | * 39 | * By default errors are displayed using Debugger, when debug is true and logged 40 | * by Cake\Log\Log when debug is false. 41 | * 42 | * In CLI environments exceptions will be printed to stderr with a backtrace. 43 | * In web environments an HTML page will be displayed for the exception. 44 | * With debug true, framework errors like Missing Controller will be displayed. 45 | * When debug is false, framework errors will be coerced into generic HTTP errors. 46 | * 47 | * Options: 48 | * 49 | * - `errorLevel` - int - The level of errors you are interested in capturing. 50 | * - `trace` - boolean - Whether or not backtraces should be included in 51 | * logged errors/exceptions. 52 | * - `log` - boolean - Whether or not you want exceptions logged. 53 | * - `exceptionRenderer` - string - The class responsible for rendering 54 | * uncaught exceptions. If you choose a custom class you should place 55 | * the file for that class in src/Error. This class needs to implement a 56 | * render method. 57 | * - `skipLog` - array - List of exceptions to skip for logging. Exceptions that 58 | * extend one of the listed exceptions will also be skipped for logging. 59 | * E.g.: 60 | * `'skipLog' => ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException']` 61 | * - `extraFatalErrorMemory` - int - The number of megabytes to increase 62 | * the memory limit by when a fatal error is encountered. This allows 63 | * breathing room to complete logging or error handling. 64 | */ 65 | 'Error' => [ 66 | 'errorLevel' => E_ALL, 67 | 'exceptionRenderer' => 'Cake\Error\ExceptionRenderer', 68 | 'skipLog' => [], 69 | 'log' => true, 70 | 'trace' => true, 71 | ], 72 | 73 | /** 74 | * Configures logging options 75 | */ 76 | 'Log' => [ 77 | 'debug' => [ 78 | 'className' => 'Cake\Log\Engine\FileLog', 79 | 'path' => LOGS, 80 | 'file' => 'debug', 81 | 'url' => env('LOG_DEBUG_URL', null), 82 | 'scopes' => null, 83 | 'levels' => ['notice', 'info', 'debug'], 84 | ], 85 | 'error' => [ 86 | 'className' => 'Cake\Log\Engine\FileLog', 87 | 'path' => LOGS, 88 | 'file' => 'error', 89 | 'url' => env('LOG_ERROR_URL', null), 90 | 'scopes' => null, 91 | 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], 92 | ], 93 | ], 94 | ]; 95 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/paths.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/chronos3.php: -------------------------------------------------------------------------------- 1 | sets([CakePHPSetList::CHRONOS_3]); 9 | }; 10 | -------------------------------------------------------------------------------- /config/rector/migrations45.php: -------------------------------------------------------------------------------- 1 | sets([CakePHPSetList::MIGRATIONS_45]); 9 | }; 10 | -------------------------------------------------------------------------------- /config/rector/phpunit80.php: -------------------------------------------------------------------------------- 1 | sets([PHPUnitSetList::PHPUNIT_80]); 9 | }; 10 | -------------------------------------------------------------------------------- /config/rector/sets/cakephp-fluent-options.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(ArrayToFluentCallRector::class, [ 11 | ArrayToFluentCallRector::ARRAYS_TO_FLUENT_CALLS => [ 12 | new ArrayToFluentCall('Cake\ORM\Association', [ 13 | 'bindingKey' => 'setBindingKey', 14 | 'cascadeCallbacks' => 'setCascadeCallbacks', 15 | 'className' => 'setClassName', 16 | 'conditions' => 'setConditions', 17 | 'dependent' => 'setDependent', 18 | 'finder' => 'setFinder', 19 | 'foreignKey' => 'setForeignKey', 20 | 'joinType' => 'setJoinType', 21 | 'propertyName' => 'setProperty', 22 | 'sourceTable' => 'setSource', 23 | 'strategy' => 'setStrategy', 24 | 'targetTable' => 'setTarget', 25 | # BelongsToMany and HasMany only 26 | 'saveStrategy' => 'setSaveStrategy', 27 | 'sort' => 'setSort', 28 | # BelongsToMany only 29 | 'targetForeignKey' => 'setTargetForeignKey', 30 | 'through' => 'setThrough', 31 | ]), 32 | new ArrayToFluentCall('Cake\ORM\Query', [ 33 | 'fields' => 'select', 34 | 'conditions' => 'where', 35 | 'join' => 'join', 36 | 'order' => 'order', 37 | 'limit' => 'limit', 38 | 'offset' => 'offset', 39 | 'group' => 'group', 40 | 'having' => 'having', 41 | 'contain' => 'contain', 42 | 'page' => 'page', 43 | ]), 44 | new ArrayToFluentCall('Cake\ORM\Association', [ 45 | 'bindingKey' => 'setBindingKey', 46 | 'cascadeCallbacks' => 'setCascadeCallbacks', 47 | 'className' => 'setClassName', 48 | 'conditions' => 'setConditions', 49 | 'dependent' => 'setDependent', 50 | 'finder' => 'setFinder', 51 | 'foreignKey' => 'setForeignKey', 52 | 'joinType' => 'setJoinType', 53 | 'propertyName' => 'setProperty', 54 | 'sourceTable' => 'setSource', 55 | 'strategy' => 'setStrategy', 56 | 'targetTable' => 'setTarget', 57 | # BelongsToMany and HasMany only 58 | 'saveStrategy' => 'setSaveStrategy', 59 | 'sort' => 'setSort', 60 | # BelongsToMany only 61 | 'targetForeignKey' => 'setTargetForeignKey', 62 | 'through' => 'setThrough', 63 | ]), 64 | new ArrayToFluentCall('Cake\ORM\Query', [ 65 | 'fields' => 'select', 66 | 'conditions' => 'where', 67 | 'join' => 'join', 68 | 'order' => 'order', 69 | 'limit' => 'limit', 70 | 'offset' => 'offset', 71 | 'group' => 'group', 72 | 'having' => 'having', 73 | 'contain' => 'contain', 74 | 'page' => 'page', 75 | ]), 76 | ], 77 | ArrayToFluentCallRector::FACTORY_METHODS => [ 78 | new FactoryMethod('Cake\ORM\Table', 'belongsTo', 'Cake\ORM\Association', 2), 79 | new FactoryMethod('Cake\ORM\Table', 'belongsToMany', 'Cake\ORM\Association', 2), 80 | new FactoryMethod('Cake\ORM\Table', 'hasMany', 'Cake\ORM\Association', 2), 81 | new FactoryMethod('Cake\ORM\Table', 'hasOne', 'Cake\ORM\Association', 2), 82 | new FactoryMethod('Cake\ORM\Table', 'find', 'Cake\ORM\Query', 2), 83 | ], 84 | ]); 85 | }; 86 | -------------------------------------------------------------------------------- /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/cakephp35.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RenameClassRector::class, [ 14 | 'Cake\Http\Client\CookieCollection' => 'Cake\Http\Cookie\CookieCollection', 15 | 'Cake\Console\ShellDispatcher' => 'Cake\Console\CommandRunner', 16 | ]); 17 | 18 | $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, [ 19 | new MethodCallRename('Cake\Database\Schema\TableSchema', 'column', 'getColumn'), 20 | new MethodCallRename('Cake\Database\Schema\TableSchema', 'constraint', 'getConstraint'), 21 | new MethodCallRename('Cake\Database\Schema\TableSchema', 'index', 'getIndex'), 22 | ]); 23 | 24 | $rectorConfig->ruleWithConfiguration(ModalToGetSetRector::class, [ 25 | new ModalToGetSet('Cake\Cache\Cache', 'config'), 26 | new ModalToGetSet('Cake\Cache\Cache', 'registry'), 27 | new ModalToGetSet('Cake\Console\Shell', 'io'), 28 | new ModalToGetSet('Cake\Console\ConsoleIo', 'outputAs'), 29 | new ModalToGetSet('Cake\Console\ConsoleOutput', 'outputAs'), 30 | new ModalToGetSet('Cake\Database\Connection', 'logger'), 31 | new ModalToGetSet('Cake\Database\TypedResultInterface', 'returnType'), 32 | new ModalToGetSet('Cake\Database\TypedResultTrait', 'returnType'), 33 | new ModalToGetSet('Cake\Database\Log\LoggingStatement', 'logger'), 34 | new ModalToGetSet('Cake\Datasource\ModelAwareTrait', 'modelType'), 35 | new ModalToGetSet('Cake\Database\Query', 'valueBinder', 'getValueBinder', 'valueBinder'), 36 | new ModalToGetSet('Cake\Database\Schema\TableSchema', 'columnType'), 37 | new ModalToGetSet('Cake\Datasource\QueryTrait', 'eagerLoaded', 'isEagerLoaded', 'eagerLoaded'), 38 | new ModalToGetSet('Cake\Event\EventDispatcherInterface', 'eventManager'), 39 | new ModalToGetSet('Cake\Event\EventDispatcherTrait', 'eventManager'), 40 | new ModalToGetSet('Cake\Error\Debugger', 'outputAs', 'getOutputFormat', 'setOutputFormat'), 41 | new ModalToGetSet('Cake\Http\ServerRequest', 'env', 'getEnv', 'withEnv'), 42 | new ModalToGetSet('Cake\Http\ServerRequest', 'charset', 'getCharset', 'withCharset'), 43 | new ModalToGetSet('Cake\I18n\I18n', 'locale'), 44 | new ModalToGetSet('Cake\I18n\I18n', 'translator'), 45 | new ModalToGetSet('Cake\I18n\I18n', 'defaultLocale'), 46 | new ModalToGetSet('Cake\I18n\I18n', 'defaultFormatter'), 47 | new ModalToGetSet('Cake\ORM\Association\BelongsToMany', 'sort'), 48 | new ModalToGetSet('Cake\ORM\LocatorAwareTrait', 'tableLocator'), 49 | new ModalToGetSet('Cake\ORM\Table', 'validator'), 50 | new ModalToGetSet('Cake\Routing\RouteBuilder', 'extensions'), 51 | new ModalToGetSet('Cake\Routing\RouteBuilder', 'routeClass'), 52 | new ModalToGetSet('Cake\Routing\RouteCollection', 'extensions'), 53 | new ModalToGetSet('Cake\TestSuite\TestFixture', 'schema'), 54 | new ModalToGetSet('Cake\Utility\Security', 'salt'), 55 | new ModalToGetSet('Cake\View\View', 'template'), 56 | new ModalToGetSet('Cake\View\View', 'layout'), 57 | new ModalToGetSet('Cake\View\View', 'theme'), 58 | new ModalToGetSet('Cake\View\View', 'templatePath'), 59 | new ModalToGetSet('Cake\View\View', 'layoutPath'), 60 | new ModalToGetSet('Cake\View\View', 'autoLayout', 'isAutoLayoutEnabled', 'enableAutoLayout'), 61 | ]); 62 | }; 63 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/rector/sets/cakephp37.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RenameMethodRector::class, [ 18 | new MethodCallRename('Cake\Form\Form', 'errors', 'getErrors'), 19 | new MethodCallRename('Cake\Validation\Validation', 'cc', 'creditCard'), 20 | new MethodCallRename('Cake\Filesystem\Folder', 'normalizePath', 'correctSlashFor'), 21 | new MethodCallRename('Cake\Http\Client\Response', 'body', 'getStringBody'), 22 | new MethodCallRename('Cake\Core\Plugin', 'unload', 'clear'), 23 | ]); 24 | 25 | $rectorConfig->ruleWithConfiguration(PropertyFetchToMethodCallRector::class, [ 26 | new PropertyFetchToMethodCall('Cake\Http\Client\Response', 'body', 'getStringBody'), 27 | new PropertyFetchToMethodCall('Cake\Http\Client\Response', 'json', 'getJson'), 28 | new PropertyFetchToMethodCall('Cake\Http\Client\Response', 'xml', 'getXml'), 29 | new PropertyFetchToMethodCall('Cake\Http\Client\Response', 'cookies', 'getCookies'), 30 | new PropertyFetchToMethodCall('Cake\Http\Client\Response', 'code', 'getStatusCode'), 31 | 32 | new PropertyFetchToMethodCall('Cake\View\View', 'request', 'getRequest', 'setRequest'), 33 | new PropertyFetchToMethodCall('Cake\View\View', 'response', 'getResponse', 'setResponse'), 34 | new PropertyFetchToMethodCall('Cake\View\View', 'templatePath', 'getTemplatePath', 'setTemplatePath'), 35 | new PropertyFetchToMethodCall('Cake\View\View', 'template', 'getTemplate', 'setTemplate'), 36 | new PropertyFetchToMethodCall('Cake\View\View', 'layout', 'getLayout', 'setLayout'), 37 | new PropertyFetchToMethodCall('Cake\View\View', 'layoutPath', 'getLayoutPath', 'setLayoutPath'), 38 | new PropertyFetchToMethodCall('Cake\View\View', 'autoLayout', 'isAutoLayoutEnabled', 'enableAutoLayout'), 39 | new PropertyFetchToMethodCall('Cake\View\View', 'theme', 'getTheme', 'setTheme'), 40 | new PropertyFetchToMethodCall('Cake\View\View', 'subDir', 'getSubDir', 'setSubDir'), 41 | new PropertyFetchToMethodCall('Cake\View\View', 'plugin', 'getPlugin', 'setPlugin'), 42 | new PropertyFetchToMethodCall('Cake\View\View', 'name', 'getName', 'setName'), 43 | new PropertyFetchToMethodCall('Cake\View\View', 'elementCache', 'getElementCache', 'setElementCache'), 44 | new PropertyFetchToMethodCall('Cake\View\View', 'helpers', 'helpers'), 45 | ]); 46 | 47 | // These rector rules were removed in rector 0.17 - see https://github.com/rectorphp/rector-src/pull/3777 48 | //$rectorConfig->ruleWithConfiguration(MethodCallToAnotherMethodCallWithArgumentsRector::class, [ 49 | // new MethodCallToAnotherMethodCallWithArguments('Cake\Database\Query', 'join', 'clause', ['join']), 50 | // new MethodCallToAnotherMethodCallWithArguments('Cake\Database\Query', 'from', 'clause', ['from']), 51 | //]); 52 | 53 | $rectorConfig->ruleWithConfiguration(ModalToGetSetRector::class, [ 54 | new ModalToGetSet('Cake\Database\Connection', 'logQueries', 'isQueryLoggingEnabled', 'enableQueryLogging'), 55 | new ModalToGetSet('Cake\ORM\Association', 'className', 'getClassName', 'setClassName'), 56 | ]); 57 | 58 | $rectorConfig->rule(ChangeSnakedFixtureNameToPascalRector::class); 59 | }; 60 | -------------------------------------------------------------------------------- /config/rector/sets/cakephp38.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration( 12 | RenameMethodRector::class, 13 | [new MethodCallRename('Cake\ORM\Entity', 'visibleProperties', 'getVisible')] 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/rector/sets/cakephp44.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RenameClassRector::class, [ 12 | 'Cake\TestSuite\ConsoleIntegrationTestTrait' => 'Cake\Console\TestSuite\ConsoleIntegrationTestTrait', 13 | 'Cake\TestSuite\Stub\ConsoleInput' => 'Cake\Console\TestSuite\StubConsoleInput', 14 | 'Cake\TestSuite\Stub\ConsoleOutput' => 'Cake\Console\TestSuite\StubConsoleOutput', 15 | 'Cake\TestSuite\Stub\MissingConsoleInputException' => 'Cake\Console\TestSuite\MissingConsoleInputException', 16 | 'Cake\TestSuite\HttpClientTrait' => 'Cake\Http\TestSuite\HttpClientTrait', 17 | ]); 18 | 19 | $rectorConfig->ruleWithConfiguration( 20 | RenameMethodRector::class, 21 | [new MethodCallRename('Cake\Database\Query', 'newExpr', 'expr')] 22 | ); 23 | }; 24 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/rector/sets/cakephp52.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RenameMethodRector::class, [ 12 | new MethodCallRename('Cake\Console\Arguments', 'getMultipleOption', 'getArrayOption'), 13 | ]); 14 | $rectorConfig->rule(ChangeEntityTraitSetArrayToPatchRector::class); 15 | }; 16 | -------------------------------------------------------------------------------- /config/rector/sets/chronos3.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RenameClassRector::class, [ 17 | // Date 18 | 'Cake\Chronos\Date' => 'Cake\Chronos\ChronosDate', 19 | 'Cake\Chronos\MutableDate' => 'Cake\Chronos\ChronosDate', 20 | 21 | // DateTime 22 | 'Cake\Chronos\MutableDateTime' => 'Cake\Chronos\Chronos', 23 | ]); 24 | 25 | $dateTimeMutationMethods = [ 26 | 'addYear' => 'addYears', 27 | 'subYear' => 'subYears', 28 | 'addYearWithOverflow' => 'addYearsWithOverflow', 29 | 'subYearWithOverflow' => 'subYearsWithOverflow', 30 | 'addMonth' => 'addMonths', 31 | 'subMonth' => 'subMonths', 32 | 'addMonthWithOverflow' => 'addMonthsWithOverflow', 33 | 'subMonthWithOverflow' => 'subMonthsWithOverflow', 34 | 'addDay' => 'addDays', 35 | 'subDay' => 'subDays', 36 | 'addWeekday' => 'addWeekdays', 37 | 'subWeekday' => 'subWeekdays', 38 | 'addWeek' => 'addWeeks', 39 | 'subWeek' => 'subWeeks', 40 | 41 | // Time specific methods 42 | 'addHour' => 'addHours', 43 | 'subHour' => 'subHours', 44 | 'addMinute' => 'addMinutes', 45 | 'subMinute' => 'subMinutes', 46 | 'addSecond' => 'addSeconds', 47 | 'subSecond' => 'subSeconds', 48 | ]; 49 | 50 | $renameMethods = $addMethodCallArgs = []; 51 | 52 | foreach ($dateTimeMutationMethods as $oldMethod => $newMethod) { 53 | $renameMethods[] = new MethodCallRename('Cake\Chronos\Chronos', $oldMethod, $newMethod); 54 | $addMethodCallArgs[] = new AddMethodCallArgs('Cake\Chronos\Chronos', $newMethod, 1); 55 | } 56 | 57 | $dateMutationMethods = [ 58 | 'addYear' => 'addYears', 59 | 'subYear' => 'subYears', 60 | 'addYearWithOverflow' => 'addYearsWithOverflow', 61 | 'subYearWithOverflow' => 'subYearsWithOverflow', 62 | 'addMonth' => 'addMonths', 63 | 'subMonth' => 'subMonths', 64 | 'addMonthWithOverflow' => 'addMonthsWithOverflow', 65 | 'subMonthWithOverflow' => 'subMonthsWithOverflow', 66 | 'addDay' => 'addDays', 67 | 'subDay' => 'subDays', 68 | 'addWeekday' => 'addWeekdays', 69 | 'subWeekday' => 'subWeekdays', 70 | 'addWeek' => 'addWeeks', 71 | 'subWeek' => 'subWeeks', 72 | ]; 73 | 74 | foreach ($dateMutationMethods as $oldMethod => $newMethod) { 75 | $renameMethods[] = new MethodCallRename('Cake\Chronos\ChronosDate', $oldMethod, $newMethod); 76 | $addMethodCallArgs[] = new AddMethodCallArgs('Cake\Chronos\ChronosDate', $newMethod, 1); 77 | } 78 | 79 | $rectorConfig->ruleWithConfiguration(RenameMethodRector::class, $renameMethods); 80 | $rectorConfig->ruleWithConfiguration(AddMethodCallArgsRector::class, $addMethodCallArgs); 81 | }; 82 | -------------------------------------------------------------------------------- /config/rector/sets/migrations45.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RenameClassRector::class, [ 12 | 'Migrations\AbstractMigration' => 'Migrations\BaseMigration', 13 | 'Migrations\AbstractSeed' => 'Migrations\BaseSeed', 14 | ]); 15 | }; 16 | -------------------------------------------------------------------------------- /config/requirements.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tests/test_apps 8 | tests/TestCase/Rector 9 | 10 | 11 | 0 12 | 13 | 14 | 0 15 | 16 | 17 | 0 18 | 19 | 20 | 0 21 | 22 | 23 | 0 24 | 25 | 26 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | tests/TestCase/ 9 | 10 | 11 | 12 | 13 | 14 | src/ 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /src/Rector/Rector/MethodCall/AddMethodCallArgsRector.php: -------------------------------------------------------------------------------- 1 | 29 | */ 30 | private array $callsWithAddMethodCallArgs = []; 31 | 32 | public function getRuleDefinition(): RuleDefinition 33 | { 34 | $configuration = [ 35 | self::ADD_METHOD_CALL_ARGS => [ 36 | new AddMethodCallArgs('ServerRequest', 'getParam', 'paging', 1, true), 37 | ], 38 | ]; 39 | 40 | return new RuleDefinition( 41 | 'Adds method call arguments', 42 | [ 43 | new ConfiguredCodeSample( 44 | <<<'CODE_SAMPLE' 45 | $object = new ServerRequest(); 46 | $config = $object->getParam(); 47 | CODE_SAMPLE 48 | , 49 | <<<'CODE_SAMPLE' 50 | $object = new ServerRequest(); 51 | $config = $object->getParam('paging', 1, true); 52 | CODE_SAMPLE 53 | , 54 | $configuration, 55 | ), 56 | ], 57 | ); 58 | } 59 | 60 | /** 61 | * @return array> 62 | */ 63 | public function getNodeTypes(): array 64 | { 65 | return [MethodCall::class]; 66 | } 67 | 68 | /** 69 | * @param \PhpParser\Node\Expr\MethodCall $node 70 | */ 71 | public function refactor(Node $node): ?Node 72 | { 73 | foreach ($this->callsWithAddMethodCallArgs as $methodCallRenameWithAddedArgument) { 74 | if (! $this->isObjectType($node->var, $methodCallRenameWithAddedArgument->getObjectType())) { 75 | continue; 76 | } 77 | 78 | if (! $this->isName($node->name, $methodCallRenameWithAddedArgument->getMethodName())) { 79 | continue; 80 | } 81 | 82 | $values = $methodCallRenameWithAddedArgument->getValues(); 83 | if ($node->args) { 84 | $newArgs = []; 85 | foreach ($node->args as $arg) { 86 | $newArgs[] = $arg->value; 87 | } 88 | $node->args = $this->nodeFactory->createArgs([...$newArgs, ...$values]); 89 | } else { 90 | $node->args = $this->nodeFactory->createArgs($values); 91 | } 92 | 93 | return $node; 94 | } 95 | 96 | return null; 97 | } 98 | 99 | /** 100 | * @param array $configuration 101 | */ 102 | public function configure(array $configuration): void 103 | { 104 | $this->callsWithAddMethodCallArgs = $configuration[self::ADD_METHOD_CALL_ARGS] ?? $configuration; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /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/RemoveMethodCallRector.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/RenameMethodCallBasedOnParameterRector.php: -------------------------------------------------------------------------------- 1 | 31 | */ 32 | private array $callsWithParamRenames = []; 33 | 34 | public function __construct(private ValueResolver $valueResolver) 35 | { 36 | } 37 | 38 | public function getRuleDefinition(): RuleDefinition 39 | { 40 | $configuration = [ 41 | self::CALLS_WITH_PARAM_RENAMES => [ 42 | new RenameMethodCallBasedOnParameter('ServerRequest', 'getParam', 'paging', 'getAttribute'), 43 | new RenameMethodCallBasedOnParameter('ServerRequest', 'withParam', 'paging', 'withAttribute'), 44 | ], 45 | ]; 46 | 47 | return new RuleDefinition( 48 | 'Changes method calls based on matching the first parameter value.', 49 | [ 50 | new ConfiguredCodeSample( 51 | <<<'CODE_SAMPLE' 52 | $object = new ServerRequest(); 53 | 54 | $config = $object->getParam('paging'); 55 | $object = $object->withParam('paging', ['a value']); 56 | CODE_SAMPLE 57 | , 58 | <<<'CODE_SAMPLE' 59 | $object = new ServerRequest(); 60 | 61 | $config = $object->getAttribute('paging'); 62 | $object = $object->withAttribute('paging', ['a value']); 63 | CODE_SAMPLE 64 | , 65 | $configuration, 66 | ), 67 | ], 68 | ); 69 | } 70 | 71 | /** 72 | * @return array> 73 | */ 74 | public function getNodeTypes(): array 75 | { 76 | return [MethodCall::class]; 77 | } 78 | 79 | /** 80 | * @param \PhpParser\Node\Expr\MethodCall $node 81 | */ 82 | public function refactor(Node $node): ?Node 83 | { 84 | $renameMethodCallBasedOnParameter = $this->matchTypeAndMethodName($node); 85 | if (! $renameMethodCallBasedOnParameter instanceof RenameMethodCallBasedOnParameter) { 86 | return null; 87 | } 88 | 89 | $node->name = new Identifier($renameMethodCallBasedOnParameter->getNewMethod()); 90 | 91 | return $node; 92 | } 93 | 94 | /** 95 | * @param array $configuration 96 | */ 97 | public function configure(array $configuration): void 98 | { 99 | $this->callsWithParamRenames = $configuration[self::CALLS_WITH_PARAM_RENAMES] ?? $configuration; 100 | } 101 | 102 | private function matchTypeAndMethodName(MethodCall $methodCall): ?RenameMethodCallBasedOnParameter 103 | { 104 | if (count($methodCall->args) < 1) { 105 | return null; 106 | } 107 | 108 | $firstArgValue = $methodCall->args[0]->value; 109 | 110 | foreach ($this->callsWithParamRenames as $callWithParamRename) { 111 | if (! $this->isObjectType($methodCall->var, $callWithParamRename->getOldObjectType())) { 112 | continue; 113 | } 114 | 115 | if (! $this->isName($methodCall->name, $callWithParamRename->getOldMethod())) { 116 | continue; 117 | } 118 | 119 | if (! $this->valueResolver->isValue($firstArgValue, $callWithParamRename->getParameterName())) { 120 | continue; 121 | } 122 | 123 | return $callWithParamRename; 124 | } 125 | 126 | return null; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /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 | return null; 56 | } 57 | } 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 | -------------------------------------------------------------------------------- /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/Property/ChangeSnakedFixtureNameToPascalRector.php: -------------------------------------------------------------------------------- 1 | > 57 | */ 58 | public function getNodeTypes(): array 59 | { 60 | return [Property::class]; 61 | } 62 | 63 | /** 64 | * @param \PhpParser\Node\Stmt\Property $node 65 | */ 66 | public function refactor(Node $node): ?Node 67 | { 68 | if (! $this->isName($node, 'fixtures')) { 69 | return null; 70 | } 71 | 72 | foreach ($node->props as $prop) { 73 | $this->refactorPropertyWithArrayDefault($prop); 74 | } 75 | 76 | return $node; 77 | } 78 | 79 | private function refactorPropertyWithArrayDefault(PropertyItem $propertyProperty): void 80 | { 81 | if (! $propertyProperty->default instanceof Array_) { 82 | return; 83 | } 84 | 85 | $array = $propertyProperty->default; 86 | foreach ($array->items as $arrayItem) { 87 | if (! $arrayItem instanceof ArrayItem) { 88 | continue; 89 | } 90 | 91 | $itemValue = $arrayItem->value; 92 | if (! $itemValue instanceof String_) { 93 | continue; 94 | } 95 | 96 | $this->renameFixtureName($itemValue); 97 | } 98 | } 99 | 100 | private function renameFixtureName(String_ $string): void 101 | { 102 | [$prefix, $table] = explode('.', $string->value, 2); 103 | 104 | $tableParts = explode('/', $table); 105 | 106 | $pascalCaseTableParts = array_map( 107 | function (string $token): string { 108 | return Inflector::camelize($token); 109 | }, 110 | $tableParts, 111 | ); 112 | 113 | $table = implode('/', $pascalCaseTableParts); 114 | 115 | $string->value = sprintf('%s.%s', $prefix, $table); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Rector/Set/CakePHPLevelSetList.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/Command/RectorCommandTest.php: -------------------------------------------------------------------------------- 1 | configApplication('\Cake\Upgrade\Application', []); 44 | } 45 | 46 | /** 47 | * @return void 48 | */ 49 | public function testInvalidAppDir() 50 | { 51 | $this->exec('upgrade rector --dry-run ./something/invalid'); 52 | 53 | $this->assertExitError(); 54 | $this->assertErrorContains('`./something/invalid` does not exist.'); 55 | } 56 | 57 | /** 58 | * @return void 59 | */ 60 | public function testApplyAppDir() 61 | { 62 | $this->setupTestApp(__FUNCTION__); 63 | $this->exec('upgrade rector --rules cakephp40 --dry-run ' . TEST_APP); 64 | 65 | $this->assertExitSuccess(); 66 | $this->assertOutputContains('HelloCommand.php'); 67 | $this->assertOutputContains('begin diff'); 68 | $this->assertOutputContains('Rector applied successfully'); 69 | } 70 | 71 | /** 72 | * @return void 73 | */ 74 | public function testApply45() 75 | { 76 | $this->setupTestApp(__FUNCTION__); 77 | $this->exec('upgrade rector --rules cakephp45 ' . TEST_APP); 78 | $this->assertTestAppUpgraded(); 79 | } 80 | 81 | public function testApplyChronos3DateTime() 82 | { 83 | $this->setupTestApp(__FUNCTION__); 84 | $this->exec('upgrade rector --rules chronos3 ' . TEST_APP); 85 | $this->assertTestAppUpgraded(); 86 | } 87 | 88 | public function testApply50() 89 | { 90 | $this->setupTestApp(__FUNCTION__); 91 | $this->exec('upgrade rector --rules cakephp50 ' . TEST_APP); 92 | $this->assertTestAppUpgraded(); 93 | } 94 | 95 | public function testApply51() 96 | { 97 | $this->setupTestApp(__FUNCTION__); 98 | $this->exec('upgrade rector --rules cakephp51 ' . TEST_APP); 99 | $this->assertTestAppUpgraded(); 100 | } 101 | 102 | public function testApply52() 103 | { 104 | $this->setupTestApp(__FUNCTION__); 105 | $this->exec('upgrade rector --rules cakephp52 ' . TEST_APP); 106 | $this->assertTestAppUpgraded(); 107 | } 108 | 109 | public function testApplyMigrations45() 110 | { 111 | $this->setupTestApp(__FUNCTION__); 112 | $this->exec('upgrade rector --rules migrations45 ' . TEST_APP); 113 | $this->assertTestAppUpgraded(); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/MethodCall/AddMethodCallArgsRector/Source/SomeModelType.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(AddMethodCallArgsRector::class, [ 11 | new AddMethodCallArgs(SomeModelType::class, 'getAttribute', '2ndArg', 1, true), 12 | ]); 13 | }; 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/MethodCall/ArrayToFluentCallRector/Source/ConfigurableClass.php: -------------------------------------------------------------------------------- 1 | setName($options['name']); 13 | 14 | return $configurableClass; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /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/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/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/ChangeEntityTraitSetArrayToPatch/Source/OtherClassWithSetMethod.php: -------------------------------------------------------------------------------- 1 | rule(ChangeEntityTraitSetArrayToPatchRector::class); 9 | }; 10 | -------------------------------------------------------------------------------- /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/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/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/ModalToGetSetRector/Fixture/fixture4.php.inc: -------------------------------------------------------------------------------- 1 | makeEntity(); 12 | } 13 | 14 | ?> 15 | ----- 16 | createEntity(); 27 | } 28 | 29 | ?> 30 | -------------------------------------------------------------------------------- /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/ModalToGetSetRector/Source/Entity.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/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 | -------------------------------------------------------------------------------- /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/MethodCall/OptionsArrayToNamedParametersRector/Source/ConfigurableClass.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/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/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/MethodCall/RemoveIntermediaryMethodRector/config/configured_rule.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration( 10 | RemoveIntermediaryMethodRector::class, 11 | [new RemoveIntermediaryMethod('getTableLocator', 'get', 'fetchTable')] 12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/MethodCall/RemoveMethodCallArgsRector/Source/SomeModelType.php: -------------------------------------------------------------------------------- 1 | ruleWithConfiguration(RemoveMethodCallRector::class, [ 11 | new RemoveMethodCall(SomeModelType::class, 'getAttribute'), 12 | ]); 13 | }; 14 | -------------------------------------------------------------------------------- /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/RenameMethodCallBasedOnParameterRector/Fixture/skip_fixture2.php.inc: -------------------------------------------------------------------------------- 1 | getParam($value); 12 | $config = $object->getParam('other'); 13 | $object->withParam('other', 'value'); 14 | } 15 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/MethodCall/RenameMethodCallBasedOnParameterRector/Source/SomeModelType.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/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/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_controller.php.inc: -------------------------------------------------------------------------------- 1 | 12 | ----- 13 | 24 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_controller_with_strict_types.php.inc: -------------------------------------------------------------------------------- 1 | 14 | ----- 15 | 28 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_fixture.php.inc: -------------------------------------------------------------------------------- 1 | 18 | ----- 19 | 36 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/cakephp_import_namespaces_up.php.inc: -------------------------------------------------------------------------------- 1 | 17 | ----- 18 | 34 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/fixture.php.inc: -------------------------------------------------------------------------------- 1 | 16 | ----- 17 | 32 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/inside_if.php.inc: -------------------------------------------------------------------------------- 1 | 19 | ----- 20 | 38 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/skip_different_static_call.php.inc: -------------------------------------------------------------------------------- 1 | 14 | ----- 15 | 28 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Fixture/without_namespace_with_strict_types.php.inc: -------------------------------------------------------------------------------- 1 | 16 | ----- 17 | 32 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Namespace_/AppUsesStaticCallToUseStatementRector/Source/App.php: -------------------------------------------------------------------------------- 1 | rule(AppUsesStaticCallToUseStatementRector::class); 9 | }; 10 | -------------------------------------------------------------------------------- /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/Property/ChangeSnakedFixtureNameToPascal/Fixture/fixture.php.inc: -------------------------------------------------------------------------------- 1 | 18 | ----- 19 | 36 | -------------------------------------------------------------------------------- /tests/TestCase/Rector/Property/ChangeSnakedFixtureNameToPascal/config/configured_rule.php: -------------------------------------------------------------------------------- 1 | rule(ChangeSnakedFixtureNameToPascalRector::class); 9 | }; 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | response = $this->response->withType('ajax'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /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/original/FileRenameCommand-testTemplates/src/View/Cell/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/original/FileRenameCommand-testTemplates/src/View/Cell/empty -------------------------------------------------------------------------------- /tests/test_apps/original/FileRenameCommand-testTemplates/src/View/Helper/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/original/FileRenameCommand-testTemplates/src/View/Helper/empty -------------------------------------------------------------------------------- /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/original/RectorCommand-testApply50/src/CommandExecuteReturn.php: -------------------------------------------------------------------------------- 1 | set('_serialize', 'result'); 40 | } 41 | } 42 | 43 | class CustomBehavior extends Behavior 44 | { 45 | protected $_defaultConfig = []; 46 | } 47 | -------------------------------------------------------------------------------- /tests/test_apps/original/RectorCommand-testApply50/src/Model/Entity/Category.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/original/RectorCommand-testApply50/src/SomeCell.php: -------------------------------------------------------------------------------- 1 | set('_serialize', 'result'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/test_apps/original/RectorCommand-testApply50/src/SomeComponent.php: -------------------------------------------------------------------------------- 1 | useCommandRunner(); 16 | $this->useHttpServer(); 17 | $this->get('/'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/test_apps/original/RectorCommand-testApply50/src/SomeView.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/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/original/RectorCommand-testApplyAppDir/Command/HelloCommand.php: -------------------------------------------------------------------------------- 1 | styles('green', ['background' => 'green']); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /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-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/test_apps/original/RectorCommand-testApplyMigrations45/src/Migrations45.php: -------------------------------------------------------------------------------- 1 | response = $this->response->withType('ajax'); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /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/upgraded/FileRenameCommand-testTemplates/src/View/Cell/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/View/Cell/empty -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/View/Helper/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/src/View/Helper/empty -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Error/error400.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Error/error400.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Error/error500.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Error/error500.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Pages/home.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/Pages/home.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/cell/TestCell/display.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/cell/TestCell/display.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/element/flash/default.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/element/flash/default.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/email/html/default.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/email/html/default.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/email/text/default.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/email/text/default.php -------------------------------------------------------------------------------- /tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/layout/default.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cakephp/upgrade/3f199706cb7560d4e1e599371c239f6df9d02ee0/tests/test_apps/upgraded/FileRenameCommand-testTemplates/templates/layout/default.php -------------------------------------------------------------------------------- /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-testApply50/src/CommandExecuteReturn.php: -------------------------------------------------------------------------------- 1 | viewBuilder()->setOption('serialize', 'result'); 40 | } 41 | } 42 | 43 | class CustomBehavior extends Behavior 44 | { 45 | protected array $_defaultConfig = []; 46 | } 47 | -------------------------------------------------------------------------------- /tests/test_apps/upgraded/RectorCommand-testApply50/src/Model/Entity/Category.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/test_apps/upgraded/RectorCommand-testApply50/src/SomeCell.php: -------------------------------------------------------------------------------- 1 | viewBuilder()->setOption('serialize', 'result'); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/test_apps/upgraded/RectorCommand-testApply50/src/SomeComponent.php: -------------------------------------------------------------------------------- 1 | get('MyTable'); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tests/test_apps/upgraded/RectorCommand-testApply50/src/SomeMailer.php: -------------------------------------------------------------------------------- 1 | get('/'); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/test_apps/upgraded/RectorCommand-testApply50/src/SomeView.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/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/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/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-testApplyMigrations45/src/Migrations45.php: -------------------------------------------------------------------------------- 1 |