├── .laminas-ci.json ├── .laminas-ci └── pre-install.sh ├── CHANGELOG.md ├── COPYRIGHT.md ├── LICENSE.md ├── README.md ├── autoload └── composer-2.0.php ├── composer.json ├── composer.lock ├── phpcs.xml ├── psalm-baseline.xml ├── psalm.xml.dist ├── renovate.json └── src ├── AbstractDependencyRewriter.php ├── AutoloadDumpCapableInterface.php ├── DependencyRewriterPlugin.php ├── DependencyRewriterPluginDelegator.php ├── DependencyRewriterV1.php ├── DependencyRewriterV2.php ├── DependencySolvingCapableInterface.php ├── PoolCapableInterface.php ├── Replacements.php └── RewriterInterface.php /.laminas-ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_php_platform_requirements": { 3 | "8.1": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /.laminas-ci/pre-install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | composer_version=$(composer --version | cut -d' ' -f3) 6 | 7 | if [[ $composer_version =~ ^2\.(3|4|5|6|7|8|9) ]];then 8 | echo "Rolling Composer version back to 2.2 LTS" 9 | composer self-update --2.2 10 | fi 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file, in reverse chronological order by release. 4 | 5 | ## 2.8.0 - TBD 6 | 7 | ### Added 8 | 9 | - Nothing. 10 | 11 | ### Changed 12 | 13 | - Nothing. 14 | 15 | ### Deprecated 16 | 17 | - Nothing. 18 | 19 | ### Removed 20 | 21 | - Nothing. 22 | 23 | ### Fixed 24 | 25 | - Nothing. 26 | 27 | ## 2.7.0 - 2025-04-14 28 | 29 | 30 | ----- 31 | 32 | ### Release Notes for [2.7.0](https://github.com/laminas/laminas-dependency-plugin/milestone/19) 33 | 34 | Feature release (minor) 35 | 36 | ### 2.7.0 37 | 38 | - Total issues resolved: **0** 39 | - Total pull requests resolved: **1** 40 | - Total contributors: **1** 41 | 42 | - [68: Add PHP 8.4 support](https://github.com/laminas/laminas-dependency-plugin/pull/68) thanks to @AlEscarcha 43 | 44 | ## 2.6.0 - 2023-12-14 45 | 46 | 47 | ----- 48 | 49 | ### Release Notes for [2.6.0](https://github.com/laminas/laminas-dependency-plugin/milestone/17) 50 | 51 | Feature release (minor) 52 | 53 | ### 2.6.0 54 | 55 | - Total issues resolved: **0** 56 | - Total pull requests resolved: **1** 57 | - Total contributors: **1** 58 | 59 | #### Enhancement 60 | 61 | - [57: Update dependency php to ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0](https://github.com/laminas/laminas-dependency-plugin/pull/57) thanks to @renovate[bot] 62 | 63 | ## 2.5.0 - 2022-10-16 64 | 65 | 66 | ----- 67 | 68 | ### Release Notes for [2.5.0](https://github.com/laminas/laminas-dependency-plugin/milestone/15) 69 | 70 | Feature release (minor) 71 | 72 | ### 2.5.0 73 | 74 | - Total issues resolved: **0** 75 | - Total pull requests resolved: **2** 76 | - Total contributors: **2** 77 | 78 | #### Enhancement 79 | 80 | - [50: Drop support php 7, add php 8.2 support](https://github.com/laminas/laminas-dependency-plugin/pull/50) thanks to @fezfez 81 | - [48: Apply PHP 7.4 syntax and typed property](https://github.com/laminas/laminas-dependency-plugin/pull/48) thanks to @samsonasik 82 | 83 | ## 2.4.0 - 2022-09-12 84 | 85 | 86 | ----- 87 | 88 | ### Release Notes for [2.4.0](https://github.com/laminas/laminas-dependency-plugin/milestone/13) 89 | 90 | Feature release (minor) 91 | 92 | ### 2.4.0 93 | 94 | - Total issues resolved: **0** 95 | - Total pull requests resolved: **4** 96 | - Total contributors: **2** 97 | 98 | - [47: Update minimum PHP to 7.4, update `laminas/laminas-coding-standard` to `~2.4.0`, restrict `composer` `<2.3.0` in renovate](https://github.com/laminas/laminas-dependency-plugin/pull/47) thanks to @internalsystemerror 99 | 100 | #### renovate 101 | 102 | - [45: Lock file maintenance](https://github.com/laminas/laminas-dependency-plugin/pull/45) thanks to @renovate[bot] 103 | - [43: Update dependency psalm/plugin-phpunit to ^0.17.0](https://github.com/laminas/laminas-dependency-plugin/pull/43) thanks to @renovate[bot] 104 | - [42: Configure Renovate](https://github.com/laminas/laminas-dependency-plugin/pull/42) thanks to @renovate[bot] 105 | 106 | ## 2.3.0 - 2022-07-14 107 | 108 | 109 | ----- 110 | 111 | ### Release Notes for [2.3.0](https://github.com/laminas/laminas-dependency-plugin/milestone/11) 112 | 113 | Feature release (minor) 114 | 115 | ### 2.3.0 116 | 117 | - Total issues resolved: **0** 118 | - Total pull requests resolved: **2** 119 | - Total contributors: **2** 120 | 121 | #### Enhancement 122 | 123 | - [41: Mark package security-only](https://github.com/laminas/laminas-dependency-plugin/pull/41) thanks to @weierophinney 124 | - [39: Prepare for Renovate with reusable workflows](https://github.com/laminas/laminas-dependency-plugin/pull/39) thanks to @ghostwriter 125 | 126 | ## 2.2.0 - 2021-09-08 127 | 128 | 129 | ----- 130 | 131 | ### Release Notes for [2.2.0](https://github.com/laminas/laminas-dependency-plugin/milestone/7) 132 | 133 | ### Added 134 | 135 | - This release adds support for PHP 8.1. 136 | 137 | ### 2.2.0 138 | 139 | - Total issues resolved: **0** 140 | - Total pull requests resolved: **2** 141 | - Total contributors: **2** 142 | 143 | #### Enhancement 144 | 145 | - [37: Provide PHP 8.1 support](https://github.com/laminas/laminas-dependency-plugin/pull/37) thanks to @weierophinney 146 | 147 | #### dependencies 148 | 149 | - [35: build(deps-dev): bump composer/composer from 2.0.9 to 2.0.13](https://github.com/laminas/laminas-dependency-plugin/pull/35) thanks to @dependabot[bot] 150 | 151 | ## 2.1.2 - 2021-02-15 152 | 153 | 154 | ----- 155 | 156 | ### Release Notes for [2.1.2](https://github.com/laminas/laminas-dependency-plugin/milestone/8) 157 | 158 | 2.1.x bugfix release (patch) 159 | 160 | ### 2.1.2 161 | 162 | - Total issues resolved: **0** 163 | - Total pull requests resolved: **1** 164 | - Total contributors: **1** 165 | 166 | #### Bug,Enhancement 167 | 168 | - [32: bugfix: use proper methods to receive input option informations](https://github.com/laminas/laminas-dependency-plugin/pull/32) thanks to @boesing 169 | 170 | ## 2.1.1 - 2021-02-15 171 | 172 | ### Fixed 173 | 174 | - [#29](https://github.com/laminas/laminas-dependency-plugin/pull/29) Pass `ignore-platform-reqs` **and/or** `ignore-platform-req=` options to the `composer update --lock` command when these were originally passed to the composer command aswell. 175 | 176 | 177 | ----- 178 | 179 | ### Release Notes for [2.1.1](https://github.com/laminas/laminas-dependency-plugin/milestone/6) 180 | 181 | 2.1.x bugfix release (patch) 182 | 183 | ### 2.1.1 184 | 185 | - Total issues resolved: **1** 186 | - Total pull requests resolved: **1** 187 | - Total contributors: **1** 188 | 189 | #### Bug 190 | 191 | - [29: bugfix: pass `--ignore-platform-reqs` and `--ignore-platform-req` to `composer update --lock`](https://github.com/laminas/laminas-dependency-plugin/pull/29) thanks to @boesing 192 | 193 | ## 2.1.0 - 2020-11-02 194 | 195 | ### Added 196 | 197 | - [#25](https://github.com/laminas/laminas-dependency-plugin/pull/25) adds support for PHP 8. 198 | 199 | ### Removed 200 | 201 | - [#25](https://github.com/laminas/laminas-dependency-plugin/pull/25) removes support for PHP versions prior to 7.3. 202 | 203 | 204 | ----- 205 | 206 | ### Release Notes for [2.1.0](https://github.com/laminas/laminas-dependency-plugin/milestone/4) 207 | 208 | Feature release (minor) 209 | 210 | ### 2.1.0 211 | 212 | - Total issues resolved: **1** 213 | - Total pull requests resolved: **2** 214 | - Total contributors: **2** 215 | 216 | #### Enhancement 217 | 218 | - [26: Add psalm integration](https://github.com/laminas/laminas-dependency-plugin/pull/26) thanks to @weierophinney and @boesing 219 | - [25: Add support for PHP 8](https://github.com/laminas/laminas-dependency-plugin/pull/25) thanks to @weierophinney 220 | 221 | ## 2.0.0 - 2020-10-30 222 | 223 | ### Added 224 | 225 | - Adds support for Composer version 2 releases. 226 | 227 | 228 | ----- 229 | 230 | ### Release Notes for [2.0.0](https://github.com/laminas/laminas-dependency-plugin/milestone/2) 231 | 232 | 233 | 234 | ### 2.0.0 235 | 236 | - Total issues resolved: **1** 237 | - Total pull requests resolved: **1** 238 | - Total contributors: **1** 239 | 240 | #### Bug 241 | 242 | - [24: Fix: DependencyRewriterV1 should implement DependencySolvingCapableInterface](https://github.com/laminas/laminas-dependency-plugin/pull/24) thanks to @rieschl 243 | 244 | ## 2.0.0beta1 - 2020-07-01 245 | 246 | ### Added 247 | 248 | - [#18](https://github.com/laminas/laminas-dependency-plugin/pull/18) adds support for Composer version 2 releases. 249 | 250 | ### Changed 251 | 252 | - Nothing. 253 | 254 | ### Deprecated 255 | 256 | - Nothing. 257 | 258 | ### Removed 259 | 260 | - Nothing. 261 | 262 | ### Fixed 263 | 264 | - Nothing. 265 | 266 | ## 1.0.4 - 2020-05-20 267 | 268 | ### Added 269 | 270 | - Nothing. 271 | 272 | ### Changed 273 | 274 | - Nothing. 275 | 276 | ### Deprecated 277 | 278 | - Nothing. 279 | 280 | ### Removed 281 | 282 | - Nothing. 283 | 284 | ### Fixed 285 | 286 | - [#17](https://github.com/laminas/laminas-dependency-plugin/pull/17) fixes how the various Expressive packages referencing Zend Framework components are detected and rewritten, so that they now properly reference Laminas instead of Zend in the rewritten names. 287 | 288 | ## 1.0.3 - 2020-01-14 289 | 290 | ### Added 291 | 292 | - Nothing. 293 | 294 | ### Changed 295 | 296 | - Nothing. 297 | 298 | ### Deprecated 299 | 300 | - Nothing. 301 | 302 | ### Removed 303 | 304 | - Nothing. 305 | 306 | ### Fixed 307 | 308 | - [#12](https://github.com/laminas/laminas-dependency-plugin/pull/12) adds exclusion for zendframework/zend-debug as it was not migrated to Laminas. 309 | 310 | ## 1.0.2 - 2020-01-07 311 | 312 | ### Added 313 | 314 | - Nothing. 315 | 316 | ### Changed 317 | 318 | - Nothing. 319 | 320 | ### Deprecated 321 | 322 | - Nothing. 323 | 324 | ### Removed 325 | 326 | - Nothing. 327 | 328 | ### Fixed 329 | 330 | - [#10](https://github.com/laminas/laminas-dependency-plugin/pull/10) fixes a bad comparison in the `DependecyRewriterPlugin`. 331 | 332 | ## 1.0.1 - 2020-01-07 333 | 334 | ### Added 335 | 336 | - Nothing. 337 | 338 | ### Changed 339 | 340 | - Nothing. 341 | 342 | ### Deprecated 343 | 344 | - Nothing. 345 | 346 | ### Removed 347 | 348 | - Nothing. 349 | 350 | ### Fixed 351 | 352 | - [#7](https://github.com/laminas/laminas-dependency-plugin/pull/7) adds exclusions for zendframework/zend-version, zendframework/zendservice-apple-apns, zendframework/zendservice-google-gcm, zfcampus/zf-apigility-example, zfcampus/zf-angular, and zfcampus/zf-deploy, as none of these packages were migrated to Laminas. 353 | 354 | ## 1.0.0 - 2019-12-31 355 | 356 | ### Added 357 | 358 | - First stable release. 359 | 360 | ### Changed 361 | 362 | - Nothing. 363 | 364 | ### Deprecated 365 | 366 | - Nothing. 367 | 368 | ### Removed 369 | 370 | - Nothing. 371 | 372 | ### Fixed 373 | 374 | - Nothing. 375 | 376 | ## 0.2.0 - 2019-12-02 377 | 378 | ### Added 379 | 380 | - Nothing. 381 | 382 | ### Changed 383 | 384 | - [#3](https://github.com/laminas/laminas-dependency-plugin/pull/3) updates the tooling to rewrite Apigility packages to reference laminas-api-tools and api-tools. 385 | 386 | - [#3](https://github.com/laminas/laminas-dependency-plugin/pull/3) updates the tooling to rewrite Expressive packages to reference Mezzio. 387 | 388 | ### Deprecated 389 | 390 | - Nothing. 391 | 392 | ### Removed 393 | 394 | - Nothing. 395 | 396 | ### Fixed 397 | 398 | - Nothing. 399 | 400 | ## 0.1.3 - 2019-11-01 401 | 402 | ### Added 403 | 404 | - Nothing. 405 | 406 | ### Changed 407 | 408 | - Nothing. 409 | 410 | ### Deprecated 411 | 412 | - Nothing. 413 | 414 | ### Removed 415 | 416 | - Nothing. 417 | 418 | ### Fixed 419 | 420 | - [#2](https://github.com/laminas/laminas-dependency-plugin/pull/2) fixes how package replacements are slip-streamed in, ensuring nested dependencies use the correct packages. Previously, Composer would report the replacement, but the original ZF package would actually be installed. 421 | 422 | ## 0.1.2 - 2019-10-29 423 | 424 | ### Added 425 | 426 | - [#1](https://github.com/laminas/laminas-dependency-plugin/pull/1) adds support for PHP 5.6 and 7.0. 427 | 428 | ### Changed 429 | 430 | - Nothing. 431 | 432 | ### Deprecated 433 | 434 | - Nothing. 435 | 436 | ### Removed 437 | 438 | - Nothing. 439 | 440 | ### Fixed 441 | 442 | - Nothing. 443 | 444 | ## 0.1.1 - 2019-10-28 445 | 446 | ### Added 447 | 448 | - Nothing. 449 | 450 | ### Changed 451 | 452 | - Nothing. 453 | 454 | ### Deprecated 455 | 456 | - Nothing. 457 | 458 | ### Removed 459 | 460 | - Nothing. 461 | 462 | ### Fixed 463 | 464 | - Adds rewrite rules for known archived packages, ensuring the plugin will not attempt to rewrite those packages to Laminas variants. 465 | 466 | ## 0.1.0 - 2019-10-23 467 | 468 | ### Added 469 | 470 | - Adds a pre-command-run listener in order to rewrite requests to install zendframework and zfcampus packages to their Laminas Project equivalents. 471 | 472 | - Adds a pre-dependencies-solving listener in order to replace requests for zendframework and zfcampus packages with their Laminas Project equivalents. 473 | 474 | - Adds a pre-package-install listener to intercept install requests for zendframework and zfcampus packages and replace them with Laminas Project equivalents. 475 | 476 | ### Changed 477 | 478 | - Nothing. 479 | 480 | ### Deprecated 481 | 482 | - Nothing. 483 | 484 | ### Removed 485 | 486 | - Nothing. 487 | 488 | ### Fixed 489 | 490 | - Nothing. 491 | -------------------------------------------------------------------------------- /COPYRIGHT.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) 2 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | - Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | - Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | - Neither the name of Laminas Foundation nor the names of its contributors may 14 | be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # laminas-dependency-plugin 2 | 3 | > This package is considered feature-complete, and is now in **security-only** maintenance mode, following a [decision by the Technical Steering Committee](https://github.com/laminas/technical-steering-committee/blob/6dc4d8a798021f690ad8c65d0d9a0c4b21835a1e/meetings/minutes/2022-07-11-TSC-Minutes.md#future-of-the-migration-layer). 4 | > If you have a security issue, please [follow our security reporting guidelines](https://getlaminas.org/security/). 5 | > If you wish to take on the role of maintainer, please [nominate yourself](https://github.com/laminas/technical-steering-committee/issues/new?assignees=&labels=Nomination&template=Maintainer_Nomination.md&title=%5BNOMINATION%5D%5BMAINTAINER%5D%3A+%7Bname+of+person+being+nominated%7D) 6 | 7 | > ## 🇷🇺 Русским гражданам 8 | > 9 | > Мы, участники Laminas, родились и живем в разных странах. У многих из нас есть друзья, родственники и коллеги как в России, так и в Украине. Некоторые из нас родились в России. Некоторые из нас живут в России. У некоторых бабушки и дедушки сражались с фашистами во Второй мировой войне. Здесь никто не поддерживает фашизм. 10 | > 11 | > У одного из нас есть украинская родственница, которая спаслась из дома вместе с сыном. Поезд задержался из-за бомбежки на дороге впереди. У нас есть друзья, которые прячутся в бомбоубежищах. Мы с тревогой ждем весточки от них после воздушных налетов, которые беспорядочно наносят удары и попадают по больницам, школам, детским садам и домам. Мы не берем это из каких-либо СМИ. Мы наблюдаем это напрямую. 12 | > 13 | > Вы доверяете нам достаточно, чтоб использовать наши программы, и мы просим вас довериться нам вновь. Мы нуждаемся в помощи. Выходите и протестуйте против этой бесполезной войны. Остановите кровопролитие. Скажите "Нет войне!" 14 | > 15 | > ## 🇺🇸 To Citizens of Russia 16 | > 17 | > We at Laminas come from all over the world. Many of us have friends, family and colleagues in both Russia and Ukraine. Some of us were born in Russia. Some of us currently live in Russia. Some have grandparents who fought Nazis in World War II. Nobody here supports fascism. 18 | > 19 | > One team member has a Ukrainian relative who fled her home with her son. The train was delayed due to bombing on the road ahead. We have friends who are hiding in bomb shelters. We anxiously follow up on them after the air raids, which indiscriminately fire at hospitals, schools, kindergartens and houses. We're not taking this from any media. These are our actual experiences. 20 | > 21 | > You trust us enough to use our software. We ask that you trust us to say the truth on this. We need your help. Go out and protest this unnecessary war. Stop the bloodshed. Say "stop the war!" 22 | 23 | This Composer plugin, when enabled in a project, intercepts requests to install 24 | packages from the zendframework and zfcampus vendors, and will replace them with 25 | the equivalents from the Laminas Project. 26 | 27 | ## Installation 28 | 29 | ```bash 30 | $ composer require laminas/laminas-dependency-plugin 31 | ``` 32 | 33 | ### Composer version 34 | 35 | This package only works with Composer versions prior to 2.3; we recommend using the 2.2 LTS version. 36 | The [Composer download documentation](https://getcomposer.org/download/) details how to select the 2.2 LTS: 37 | 38 | ```bash 39 | php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" 40 | php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" 41 | php composer-setup.php --2.2 42 | ``` 43 | 44 | If you are on a later version of Composer, you can choose to rollback to the LTS version using the `self-update` command: 45 | 46 | ```bash 47 | composer self-update --2.2 48 | ``` 49 | -------------------------------------------------------------------------------- /autoload/composer-2.0.php: -------------------------------------------------------------------------------- 1 | =1.1.0 <2.3.0" 18 | }, 19 | "require-dev": { 20 | "amphp/dns": "^2.4.0", 21 | "amphp/socket": "^2.3.1", 22 | "amphp/byte-stream": "^2.0.0", 23 | "composer/composer": ">=1.9.0 <2.3.0", 24 | "laminas/laminas-coding-standard": "~2.5.0", 25 | "mikey179/vfsstream": "^1.6.11", 26 | "phpunit/phpunit": "^9.6.22", 27 | "psalm/plugin-phpunit": "^0.18.0 || ^0.19.0", 28 | "roave/security-advisories": "dev-master", 29 | "vimeo/psalm": "^4.5 || ^5.0 || ^6.0" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "Laminas\\DependencyPlugin\\": "src/" 34 | } 35 | }, 36 | "autoload-dev": { 37 | "psr-4": { 38 | "LaminasTest\\DependencyPlugin\\": "test/" 39 | }, 40 | "files": ["autoload/composer-2.0.php"] 41 | }, 42 | "extra": { 43 | "class": "Laminas\\DependencyPlugin\\DependencyRewriterPluginDelegator" 44 | }, 45 | "scripts": { 46 | "check": [ 47 | "@cs-check", 48 | "@compat", 49 | "@test" 50 | ], 51 | "cs-check": "phpcs", 52 | "cs-fix": "phpcbf", 53 | "static-analysis": "psalm --shepherd --stats", 54 | "test": "phpunit --colors=always", 55 | "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /phpcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | src 16 | test 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /psalm-baseline.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /psalm.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "local>laminas/.github:renovate-config" 5 | ], 6 | "packageRules": [ 7 | {"matchPackageNames": ["composer-plugin-api", "composer/composer"], "allowedVersions": "<2.3.0"} 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/AbstractDependencyRewriter.php: -------------------------------------------------------------------------------- 1 | replacements = new Replacements(); 41 | } 42 | 43 | /** 44 | * @return void 45 | */ 46 | public function activate(Composer $composer, IOInterface $io) 47 | { 48 | $this->composer = $composer; 49 | $this->io = $io; 50 | $this->output(sprintf('Activating %s', static::class), IOInterface::DEBUG); 51 | } 52 | 53 | /** 54 | * When a ZF package is requested, replace with the Laminas variant. 55 | * 56 | * When a `require` operation is requested, and a ZF package is detected, 57 | * this listener will replace the argument with the equivalent Laminas 58 | * package. This ensures that the `composer.json` file is written to 59 | * reflect the package installed. 60 | * 61 | * @return void 62 | */ 63 | public function onPreCommandRun(PreCommandRunEvent $event) 64 | { 65 | $this->output( 66 | sprintf( 67 | 'In %s::%s', 68 | static::class, 69 | __FUNCTION__ 70 | ), 71 | IOInterface::DEBUG 72 | ); 73 | 74 | if (! in_array($event->getCommand(), ['require', 'update'], true)) { 75 | // Nothing to do here. 76 | return; 77 | } 78 | 79 | $input = $event->getInput(); 80 | if (! $input->hasArgument('packages')) { 81 | return; 82 | } 83 | 84 | /** @psalm-var null|array $packages */ 85 | $packages = $input->getArgument('packages'); 86 | 87 | // Ensure we have an array of strings 88 | $packages = is_array($packages) ? $packages : []; 89 | $packages = array_map( 90 | /** @param scalar $value */ 91 | static fn($value): string => (string) $value, 92 | $packages 93 | ); 94 | 95 | $input->setArgument( 96 | 'packages', 97 | array_map([$this, 'updatePackageArgument'], $packages) 98 | ); 99 | } 100 | 101 | abstract public function onPrePackageInstallOrUpdate(PackageEvent $event); 102 | 103 | /** 104 | * @param string $message 105 | * @param int $verbosity 106 | */ 107 | protected function output($message, $verbosity = IOInterface::NORMAL): void 108 | { 109 | $this->io->write($message, true, $verbosity); 110 | } 111 | 112 | /** 113 | * Parses a package argument from the command line, replacing it with the 114 | * Laminas variant if it exists. 115 | * 116 | * @param string $package Package specification from command line 117 | * @return string Modified package specification containing Laminas 118 | * substitution, or original if no changes required. 119 | */ 120 | private function updatePackageArgument($package) 121 | { 122 | $result = preg_split('/[ :=]/', $package, 2); 123 | if ($result === false) { 124 | return $package; 125 | } 126 | $name = array_shift($result); 127 | 128 | if (! $this->isZendPackage($name)) { 129 | return $package; 130 | } 131 | 132 | $replacementName = $this->transformPackageName($name); 133 | if ($replacementName === $name) { 134 | return $package; 135 | } 136 | 137 | $this->io->write( 138 | sprintf( 139 | 'Changing package in current command from %s to %s', 140 | $name, 141 | $replacementName 142 | ), 143 | true, 144 | IOInterface::DEBUG 145 | ); 146 | 147 | $version = reset($result); 148 | 149 | if ($version === false) { 150 | return $replacementName; 151 | } 152 | 153 | return sprintf('%s:%s', $replacementName, $version); 154 | } 155 | 156 | /** 157 | * @param string $name 158 | * @return bool 159 | */ 160 | protected function isZendPackage($name) 161 | { 162 | return $this->replacements->isZendPackage($name); 163 | } 164 | 165 | /** 166 | * @param string $name 167 | * @return string 168 | */ 169 | protected function transformPackageName($name) 170 | { 171 | return $this->replacements->transformPackageName($name); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /src/AutoloadDumpCapableInterface.php: -------------------------------------------------------------------------------- 1 | rewriter = $rewriter 32 | ?: $this->createDependencyRewriterForPluginVersion(PluginInterface::PLUGIN_API_VERSION); 33 | } 34 | 35 | /** 36 | * @return array Returns in following format: 37 | * => array 38 | */ 39 | public static function getSubscribedEvents() 40 | { 41 | if (version_compare(PluginInterface::PLUGIN_API_VERSION, '2.0', 'lt')) { 42 | /** @psalm-suppress UndefinedConstant,MixedArrayOffset */ 43 | return [ 44 | InstallerEvents::PRE_DEPENDENCIES_SOLVING => ['onPreDependenciesSolving', 1000], 45 | PackageEvents::PRE_PACKAGE_INSTALL => ['onPrePackageInstallOrUpdate', 1000], 46 | PackageEvents::PRE_PACKAGE_UPDATE => ['onPrePackageInstallOrUpdate', 1000], 47 | PluginEvents::PRE_COMMAND_RUN => ['onPreCommandRun', 1000], 48 | ]; 49 | } 50 | 51 | return [ 52 | PluginEvents::PRE_POOL_CREATE => ['onPrePoolCreate', 1000], 53 | PackageEvents::PRE_PACKAGE_INSTALL => ['onPrePackageInstallOrUpdate', 1000], 54 | PackageEvents::PRE_PACKAGE_UPDATE => ['onPrePackageInstallOrUpdate', 1000], 55 | PluginEvents::PRE_COMMAND_RUN => ['onPreCommandRun', 1000], 56 | ScriptEvents::POST_AUTOLOAD_DUMP => ['onPostAutoloadDump', -1000], 57 | ]; 58 | } 59 | 60 | /** 61 | * @return void 62 | * @psalm-suppress PossiblyUnusedMethod 63 | */ 64 | public function onPreDependenciesSolving(InstallerEvent $event) 65 | { 66 | $rewriter = $this->rewriter; 67 | assert($rewriter instanceof DependencySolvingCapableInterface); 68 | $rewriter->onPreDependenciesSolving($event); 69 | } 70 | 71 | /** 72 | * @return void 73 | * @psalm-suppress PossiblyUnusedMethod 74 | */ 75 | public function onPrePackageInstallOrUpdate(PackageEvent $event) 76 | { 77 | $this->rewriter->onPrePackageInstallOrUpdate($event); 78 | } 79 | 80 | /** 81 | * @return void 82 | * @psalm-suppress PossiblyUnusedMethod 83 | */ 84 | public function onPreCommandRun(PreCommandRunEvent $event) 85 | { 86 | $this->rewriter->onPreCommandRun($event); 87 | } 88 | 89 | /** 90 | * @return void 91 | * @psalm-suppress PossiblyUnusedMethod 92 | */ 93 | public function onPrePoolCreate(PrePoolCreateEvent $event) 94 | { 95 | $rewriter = $this->rewriter; 96 | assert($rewriter instanceof PoolCapableInterface); 97 | $rewriter->onPrePoolCreate($event); 98 | } 99 | 100 | /** 101 | * @return void 102 | * @psalm-suppress PossiblyUnusedMethod 103 | */ 104 | public function onPostAutoloadDump(Event $event) 105 | { 106 | $rewriter = $this->rewriter; 107 | assert($rewriter instanceof AutoloadDumpCapableInterface); 108 | $rewriter->onPostAutoloadDump($event); 109 | } 110 | 111 | /** 112 | * @return void 113 | */ 114 | public function activate(Composer $composer, IOInterface $io) 115 | { 116 | $this->rewriter->activate($composer, $io); 117 | } 118 | 119 | /** 120 | * @return void 121 | */ 122 | public function deactivate(Composer $composer, IOInterface $io) 123 | { 124 | } 125 | 126 | /** 127 | * @return void 128 | */ 129 | public function uninstall(Composer $composer, IOInterface $io) 130 | { 131 | } 132 | 133 | /** 134 | * @param string $pluginApiVersion 135 | * @return DependencyRewriterV1|DependencyRewriterV2 136 | */ 137 | private function createDependencyRewriterForPluginVersion($pluginApiVersion) 138 | { 139 | if (version_compare($pluginApiVersion, '2.0', 'lt')) { 140 | return new DependencyRewriterV1(); 141 | } 142 | 143 | return new DependencyRewriterV2(); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/DependencyRewriterV1.php: -------------------------------------------------------------------------------- 1 | output(sprintf('In %s', __METHOD__), IOInterface::DEBUG); 33 | /** @psalm-suppress UndefinedMethod,MixedAssignment */ 34 | $request = $event->getRequest(); 35 | $changes = false; 36 | 37 | /** 38 | * @psalm-suppress MixedMethodCall 39 | * @psalm-var array> $jobs 40 | */ 41 | $jobs = $request->getJobs(); 42 | 43 | foreach ($jobs as $index => $job) { 44 | if (! isset($job['cmd']) || ! in_array($job['cmd'], ['install', 'update'], true)) { 45 | continue; 46 | } 47 | 48 | if (! isset($job['packageName'])) { 49 | continue; 50 | } 51 | 52 | $name = $job['packageName']; 53 | if (! $this->isZendPackage($name)) { 54 | continue; 55 | } 56 | 57 | $replacementName = $this->transformPackageName($name); 58 | if ($replacementName === $name) { 59 | continue; 60 | } 61 | 62 | $this->output(sprintf( 63 | 'Replacing package "%s" with package "%s"', 64 | $name, 65 | $replacementName 66 | ), IOInterface::VERBOSE); 67 | 68 | $job['packageName'] = $replacementName; 69 | $jobs[$index] = $job; 70 | $changes = true; 71 | } 72 | 73 | if (! $changes) { 74 | return; 75 | } 76 | 77 | /** @psalm-suppress MixedArgument */ 78 | $this->updateProperty($request, 'jobs', $jobs); 79 | } 80 | 81 | /** 82 | * Ensure nested dependencies on ZF packages install equivalent Laminas packages. 83 | * 84 | * When a 3rd party package has dependencies on ZF packages, this method 85 | * will detect the request to install a ZF package, and rewrite it to use a 86 | * Laminas variant at the equivalent version, if one exists. 87 | * 88 | * @return void 89 | */ 90 | public function onPrePackageInstallOrUpdate(PackageEvent $event) 91 | { 92 | $this->output(sprintf('In %s', __METHOD__), IOInterface::DEBUG); 93 | $operation = $event->getOperation(); 94 | 95 | switch (true) { 96 | case $operation instanceof Operation\InstallOperation: 97 | $package = $operation->getPackage(); 98 | break; 99 | case $operation instanceof Operation\UpdateOperation: 100 | $package = $operation->getTargetPackage(); 101 | break; 102 | default: 103 | // Nothing to do 104 | $this->output(sprintf( 105 | 'Exiting; operation of type %s not supported', 106 | $operation::class 107 | ), IOInterface::DEBUG); 108 | return; 109 | } 110 | 111 | $name = $package->getName(); 112 | if (! $this->isZendPackage($name)) { 113 | // Nothing to do 114 | $this->output(sprintf( 115 | 'Exiting; package "%s" does not have a replacement', 116 | $name 117 | ), IOInterface::DEBUG); 118 | return; 119 | } 120 | 121 | $replacementName = $this->transformPackageName($name); 122 | if ($replacementName === $name) { 123 | // Nothing to do 124 | $this->output(sprintf( 125 | 'Exiting; while package "%s" is a ZF package, it does not have a replacement', 126 | $name 127 | ), IOInterface::DEBUG); 128 | return; 129 | } 130 | 131 | $version = $package->getVersion(); 132 | $replacementPackage = $this->composer->getRepositoryManager()->findPackage($replacementName, $version); 133 | 134 | if ($replacementPackage === null) { 135 | // No matching replacement package found 136 | $this->output(sprintf( 137 | 'Exiting; no replacement package found for package "%s" with version %s', 138 | $replacementName, 139 | $version 140 | ), IOInterface::DEBUG); 141 | return; 142 | } 143 | 144 | $this->output(sprintf( 145 | 'Replacing package %s with package %s, using version %s', 146 | $name, 147 | $replacementName, 148 | $version 149 | ), IOInterface::VERBOSE); 150 | 151 | $this->replacePackageInOperation($replacementPackage, $operation); 152 | } 153 | 154 | private function replacePackageInOperation( 155 | PackageInterface $replacement, 156 | Operation\OperationInterface $operation 157 | ): void { 158 | $this->updateProperty( 159 | $operation, 160 | $operation instanceof Operation\UpdateOperation ? 'targetPackage' : 'package', 161 | $replacement 162 | ); 163 | } 164 | 165 | /** 166 | * @param mixed $value 167 | */ 168 | private function updateProperty(object $object, string $property, $value): void 169 | { 170 | // phpcs:disable WebimpressCodingStandard.PHP.StaticCallback.Static 171 | /** 172 | * @param mixed $value 173 | * @psalm-suppress MissingClosureParamType 174 | * @psalm-suppress PossiblyInvalidFunctionCall 175 | * @psalm-suppress PossiblyNullFunctionCall 176 | */ 177 | (function (object $object, string $property, $value): void { 178 | $object->$property = $value; 179 | })->bindTo($object, $object)($object, $property, $value); 180 | // phpcs:enable 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/DependencyRewriterV2.php: -------------------------------------------------------------------------------- 1 | composerFile = $composerFile ?: Factory::getComposerFile(); 60 | $this->applicationFactory = $applicationFactory ?? static fn(): Application => new Application(); 61 | $this->input = $input ?? new ArgvInput(); 62 | } 63 | 64 | /** 65 | * Ensure nested dependencies on ZF packages install equivalent Laminas packages. 66 | * 67 | * When a 3rd party package has dependencies on ZF packages, this method 68 | * will detect the request to install a ZF package, and rewrite it to use a 69 | * Laminas variant at the equivalent version, if one exists. 70 | * 71 | * @return void 72 | */ 73 | public function onPrePackageInstallOrUpdate(PackageEvent $event) 74 | { 75 | $this->output(sprintf('In %s', __METHOD__), IOInterface::DEBUG); 76 | $operation = $event->getOperation(); 77 | 78 | switch (true) { 79 | case $operation instanceof Operation\InstallOperation: 80 | $package = $operation->getPackage(); 81 | break; 82 | case $operation instanceof Operation\UpdateOperation: 83 | $package = $operation->getTargetPackage(); 84 | break; 85 | default: 86 | // Nothing to do 87 | $this->output(sprintf( 88 | 'Exiting; operation of type %s not supported', 89 | $operation::class 90 | ), IOInterface::DEBUG); 91 | return; 92 | } 93 | 94 | $name = $package->getName(); 95 | if (! $this->isZendPackage($name)) { 96 | // Nothing to do 97 | $this->output(sprintf( 98 | 'Exiting; package "%s" does not have a replacement', 99 | $name 100 | ), IOInterface::DEBUG); 101 | return; 102 | } 103 | 104 | $replacementName = $this->transformPackageName($name); 105 | if ($replacementName === $name) { 106 | // Nothing to do 107 | $this->output(sprintf( 108 | 'Exiting; while package "%s" is a ZF package, it does not have a replacement', 109 | $name 110 | ), IOInterface::DEBUG); 111 | return; 112 | } 113 | 114 | $version = $package->getVersion(); 115 | $repositoryManager = $this->composer->getRepositoryManager(); 116 | $replacementPackage = $repositoryManager->findPackage($replacementName, $version); 117 | 118 | if ($replacementPackage === null) { 119 | // No matching replacement package found 120 | $this->output(sprintf( 121 | 'Exiting; no replacement package found for package "%s" with version %s', 122 | $replacementName, 123 | $version 124 | ), IOInterface::DEBUG); 125 | return; 126 | } 127 | 128 | $this->output(sprintf( 129 | 'Could replace package %s with package %s, using version %s', 130 | $name, 131 | $replacementName, 132 | $version 133 | ), IOInterface::VERBOSE); 134 | 135 | $this->zendPackagesInstalled[] = $package; 136 | } 137 | 138 | /** 139 | * @return void 140 | */ 141 | public function onPostAutoloadDump(Event $event) 142 | { 143 | if (! $this->zendPackagesInstalled) { 144 | return; 145 | } 146 | 147 | // Remove zend-packages from vendor/ directory 148 | $composer = $event->getComposer(); 149 | $installers = $composer->getInstallationManager(); 150 | $repository = $composer->getRepositoryManager()->getLocalRepository(); 151 | 152 | $composerFile = $this->createComposerFile(); 153 | $definition = $composerFile->read(); 154 | assert(is_array($definition)); 155 | $definitionChanged = false; 156 | 157 | foreach ($this->zendPackagesInstalled as $package) { 158 | $packageName = $package->getName(); 159 | $replacementName = $this->transformPackageName($packageName); 160 | if ($this->isRootRequirement($definition, $packageName)) { 161 | $this->output(sprintf( 162 | 'Package %s is a root requirement. laminas-dependency-plugin changes your composer.json' 163 | . ' to require laminas equivalent directly!', 164 | $packageName 165 | )); 166 | 167 | $definitionChanged = true; 168 | $definition = $this->updateRootRequirements( 169 | $definition, 170 | $packageName, 171 | $replacementName 172 | ); 173 | } 174 | 175 | $uninstallOperation = new Operation\UninstallOperation($package); 176 | $installers->uninstall($repository, $uninstallOperation); 177 | } 178 | 179 | if ($definitionChanged) { 180 | $composerFile->write($definition); 181 | } 182 | 183 | $this->updateLockFile(); 184 | } 185 | 186 | /** 187 | * @return void 188 | */ 189 | public function onPrePoolCreate(PrePoolCreateEvent $event) 190 | { 191 | $this->output(sprintf('In %s', __METHOD__)); 192 | 193 | $installedRepository = $this->createInstalledRepository($this->composer, $this->io); 194 | $installedPackages = $installedRepository->getPackages(); 195 | 196 | $installedZendPackages = []; 197 | 198 | foreach ($installedPackages as $package) { 199 | if (! $this->isZendPackage($package->getName())) { 200 | continue; 201 | } 202 | 203 | $installedZendPackages[] = $package->getName(); 204 | } 205 | 206 | if (! $installedZendPackages) { 207 | return; 208 | } 209 | 210 | $unacceptableFixedPackages = $event->getUnacceptableFixedPackages(); 211 | $repository = $this->composer->getRepositoryManager(); 212 | $packages = $event->getPackages(); 213 | 214 | foreach ($packages as $index => $package) { 215 | if (! in_array($package->getName(), $installedZendPackages, true)) { 216 | continue; 217 | } 218 | 219 | $replacement = $this->transformPackageName($package->getName()); 220 | if ($replacement === $package->getName()) { 221 | continue; 222 | } 223 | 224 | $replacementPackage = $repository->findPackage($replacement, $package->getVersion()); 225 | if (! $replacementPackage instanceof PackageInterface) { 226 | continue; 227 | } 228 | 229 | $unacceptableFixedPackages[] = $package; 230 | 231 | $this->output(sprintf('Slipstreaming %s => %s', $package->getName(), $replacement)); 232 | $packages[$index] = $replacementPackage; 233 | } 234 | 235 | $event->setUnacceptableFixedPackages($unacceptableFixedPackages); 236 | $event->setPackages($packages); 237 | } 238 | 239 | /** 240 | * With `composer update --lock`, all missing packages are being installed aswell. 241 | * This is where we slip-stream in with our plugin. 242 | */ 243 | private function updateLockFile(): void 244 | { 245 | $application = call_user_func($this->applicationFactory); 246 | assert($application instanceof Application); 247 | 248 | $application->setAutoExit(false); 249 | 250 | $input = [ 251 | 'command' => 'update', 252 | '--lock' => true, 253 | '--no-scripts' => true, 254 | '--working-dir' => dirname($this->composerFile), 255 | ]; 256 | 257 | $input = array_merge($input, $this->extractAdditionalInputOptionsFromInput( 258 | $this->input, 259 | self::COMPOSER_LOCK_UPDATE_OPTIONS 260 | )); 261 | 262 | $application->run(new ArrayInput($input)); 263 | } 264 | 265 | /** 266 | * @return InstalledFilesystemRepository 267 | */ 268 | private function createInstalledRepository(Composer $composer, IOInterface $io) 269 | { 270 | /** @var string $vendor */ 271 | $vendor = $composer->getConfig()->get('vendor-dir'); 272 | 273 | return new InstalledFilesystemRepository( 274 | new JsonFile($vendor . '/composer/installed.json', null, $io), 275 | true, 276 | $composer->getPackage() 277 | ); 278 | } 279 | 280 | /** 281 | * @param string $packageName 282 | * @return bool 283 | */ 284 | private function isRootRequirement(array $definition, $packageName) 285 | { 286 | return isset($definition['require'][$packageName]) || isset($definition['require-dev'][$packageName]); 287 | } 288 | 289 | /** 290 | * @param string $packageName 291 | * @param string $replacementPackageName 292 | * @return array 293 | */ 294 | private function updateRootRequirements(array $definition, $packageName, $replacementPackageName) 295 | { 296 | /** @var bool $sortPackages */ 297 | $sortPackages = $definition['config']['sort-packages'] ?? false; 298 | 299 | foreach (['require', 'require-dev'] as $key) { 300 | if (! isset($definition[$key])) { 301 | continue; 302 | } 303 | 304 | /** @var array $requirements */ 305 | $requirements = $definition[$key]; 306 | if (! isset($requirements[$packageName])) { 307 | continue; 308 | } 309 | 310 | /** @psalm-suppress MixedAssignment */ 311 | $requirements[$replacementPackageName] = $requirements[$packageName]; 312 | unset($requirements[$packageName]); 313 | if ($sortPackages) { 314 | ksort($requirements); 315 | } 316 | 317 | $definition[$key] = $requirements; 318 | } 319 | 320 | return $definition; 321 | } 322 | 323 | /** 324 | * @deprecated Please use public property {@see DependencyRewriterV2::$zendPackagesInstalled} instead. 325 | * 326 | * @psalm-suppress PossiblyUnusedMethod 327 | * 328 | * @return PackageInterface[] 329 | */ 330 | public function getZendPackagesInstalled() 331 | { 332 | return $this->zendPackagesInstalled; 333 | } 334 | 335 | /** 336 | * @return JsonFile 337 | */ 338 | private function createComposerFile() 339 | { 340 | return new JsonFile($this->composerFile, null, $this->io); 341 | } 342 | 343 | /** 344 | * @psalm-param list $options 345 | * @psalm-return array 346 | */ 347 | private function extractAdditionalInputOptionsFromInput(InputInterface $input, array $options): array 348 | { 349 | $additionalInputOptions = []; 350 | foreach ($options as $optionName) { 351 | $option = sprintf('--%s', $optionName); 352 | assert(! empty($option)); 353 | if (! $input->hasParameterOption($option, true)) { 354 | continue; 355 | } 356 | /** @psalm-suppress MixedAssignment */ 357 | $additionalInputOptions[$option] = $input->getParameterOption($option, false, true); 358 | } 359 | 360 | return $additionalInputOptions; 361 | } 362 | } 363 | -------------------------------------------------------------------------------- /src/DependencySolvingCapableInterface.php: -------------------------------------------------------------------------------- 1 | ignore, true): 34 | /** 35 | * @psalm-suppress MixedReturnStatement 36 | * @psalm-suppress NoValue 37 | */ 38 | return $name; 39 | // Packages with non-standard naming: 40 | case 'zendframework/zenddiagnostics': 41 | return 'laminas/laminas-diagnostics'; 42 | case 'zendframework/zendoauth': 43 | return 'laminas/laminas-oauth'; 44 | case 'zendframework/zendservice-recaptcha': 45 | return 'laminas/laminas-recaptcha'; 46 | case 'zendframework/zendservice-twitter': 47 | return 'laminas/laminas-twitter'; 48 | case 'zendframework/zendxml': 49 | return 'laminas/laminas-xml'; 50 | case 'zendframework/zend-expressive': 51 | return 'mezzio/mezzio'; 52 | case 'zendframework/zend-problem-details': 53 | return 'mezzio/mezzio-problem-details'; 54 | case 'zfcampus/zf-apigility': 55 | return 'laminas-api-tools/api-tools'; 56 | case 'zfcampus/zf-composer-autoloading': 57 | return 'laminas/laminas-composer-autoloading'; 58 | case 'zfcampus/zf-development-mode': 59 | return 'laminas/laminas-development-mode'; 60 | // All other packages: 61 | default: 62 | if (preg_match('#^zendframework/zend-expressive-zend(?.*)$#', $name, $matches)) { 63 | return sprintf('mezzio/mezzio-laminas%s', $matches['name']); 64 | } 65 | if (preg_match('#^zendframework/zend-expressive-(?.*)$#', $name, $matches)) { 66 | return sprintf('mezzio/mezzio-%s', $matches['name']); 67 | } 68 | if (preg_match('#^zfcampus/zf-apigility-(?.*)$#', $name, $matches)) { 69 | return sprintf('laminas-api-tools/api-tools-%s', $matches['name']); 70 | } 71 | if (preg_match('#^zfcampus/zf-(?.*)$#', $name, $matches)) { 72 | return sprintf('laminas-api-tools/api-tools-%s', $matches['name']); 73 | } 74 | if (preg_match('#^zendframework/zend-(?.*)$#', $name, $matches)) { 75 | return sprintf('laminas/laminas-%s', $matches['name']); 76 | } 77 | return $name; 78 | } 79 | } 80 | 81 | /** 82 | * @param string $name Original package name 83 | * @return bool 84 | */ 85 | public function isZendPackage($name) 86 | { 87 | if (! preg_match('#^(zendframework|zfcampus)/#', $name)) { 88 | return false; 89 | } 90 | 91 | return true; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/RewriterInterface.php: -------------------------------------------------------------------------------- 1 |