Skip to content

[Regression]: Plugins are not subscribed to events if they are installed as part of the same operation #12433

@savemetenminutes

Description

@savemetenminutes

My composer.json:

{
    "name": "devision/adex-mezzio-skeleton",
    "description": "Devision - project - Laminas+Mezzio skeleton",
    "type": "project",
    "license": "BSD-3-Clause",
    "keywords": [
        "devision",
        "project",
        "laminas",
        "mezzio",
        "skeleton",
        "middleware",
        "psr",
        "psr-7",
        "psr-11",
        "psr-15"
    ],
    "homepage": "https://gitlab.com/devisionbg/apps/devision-mezzio-skeleton",
    "config": {
        "sort-packages": true,
        "allow-plugins": {
            "composer/package-versions-deprecated": true,
            "devision/devision-composer-plugin-run-package-scripts": true,
            "laminas/laminas-component-installer": true,
            "wikimedia/composer-merge-plugin": true,
            "dealerdirect/phpcodesniffer-composer-installer": true,
            "php-http/discovery": true
        },
        "preferred-install": {
            "*": "source"
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "repositories": {
        "devision/adex-auth": {
            "type": "git",
            "url": "git@gitlab.com:adexenergy/packages/adex-auth.git"
        },
        "adex": {
            "type": "composer",
            "url": "https://gitlab.com/api/v4/group/76796855/-/packages/composer/"
        }
    },
    "extra": {
        "laminas": {
            "component-auto-installs": [
                "devision/adex-auth",
                "devision/devision-auth",
                "devision/devision-auth-consumer",
                "devision/devision-auth-provider",
                "devision/devision-barcode",
                "devision/devision-base",
                "devision/devision-devision",
                "devision/devision-elastic",
                "devision/devision-email",
                "devision/devision-health-check",
                "devision/devision-i18n",
                "devision/devision-i18n-territorial-division",
                "devision/devision-message-queue",
                "devision/devision-session",
                "devision/devision-sso",
                "devision/devision-view",
                "doctrine/doctrine-module",
                "doctrine/doctrine-orm-module",
                "laminas/laminas-cache",
                "laminas/laminas-cache-storage-adapter-apcu",
                "laminas/laminas-cache-storage-adapter-filesystem",
                "laminas/laminas-cache-storage-adapter-memory",
                "laminas/laminas-cache-storage-adapter-redis",
                "laminas/laminas-diactoros",
                "laminas/laminas-eventmanager",
                "laminas/laminas-filter",
                "laminas/laminas-form",
                "laminas/laminas-httphandlerrunner",
                "laminas/laminas-hydrator",
                "laminas/laminas-i18n",
                "laminas/laminas-inputfilter",
                "laminas/laminas-mail",
                "laminas/laminas-paginator",
                "laminas/laminas-log",
                "laminas/laminas-router",
                "laminas/laminas-session",
                "laminas/laminas-serializer",
                "laminas/laminas-validator",
                "mezzio/mezzio",
                "mezzio/mezzio-cors",
                "mezzio/mezzio-fastroute",
                "mezzio/mezzio-helpers",
                "mezzio/mezzio-laminasviewrenderer",
                "mezzio/mezzio-problem-details",
                "mezzio/mezzio-router",
                "mezzio/mezzio-session",
                "mezzio/mezzio-session-ext"
            ]
        },
        "merge-plugin": {
            "include": [
            ],
            "recurse": false,
            "replace": false,
            "ignore-duplicates": false,
            "merge-dev": true,
            "merge-extra": false,
            "merge-extra-deep": false,
            "merge-replace": false,
            "merge-scripts": false
        }
    },
    "require": {
        "php": "^8.1",

        "composer/package-versions-deprecated": "^1.11.99",
        "laminas/laminas-component-installer": "^2.6 || ^3.0",

        "devision/adex-auth": "dev-master",
        "doctrine/orm": "3.3.0"
    },
    "require-dev": {
        "phploc/phploc": "^7.0.2",
        "laminas/laminas-development-mode": "^3.4.x-dev",
        "phpspec/prophecy": "^1.12.2",
        "phpspec/prophecy-phpunit": "^2.0",
        "phpunit/phpunit": "^9.5.2",
        "roave/security-advisories": "dev-master",
        "filp/whoops": "^2.9.2",
        "wikimedia/composer-merge-plugin": "^v2.0.1"
    },
    "scripts": {
        "post-create-project-cmd": [
            "@development-enable"
        ],
        "development-disable": "laminas-development-mode disable",
        "development-enable": "laminas-development-mode enable",
        "development-status": "laminas-development-mode status",
        "mezzio": "mezzio --ansi",
        "clear-config-cache": "php bin/clear-config-cache.php",
        "phpinfo-html": "php-fpm-cli.sh vendor/devision/devision-base/bin/phpinfo.php vendor/devision/devision-base/bin/phpinfo.php GET $(netstat -pantu | grep php-fpm.conf | awk '{print $4}' | sed 's/::://' | sed 's/127.0.0.1://' | sed 's/0.0.0.0://')",
        "phpinfo-html-file": "php-fpm-cli.sh vendor/devision/devision-base/bin/phpinfo.php vendor/devision/devision-base/bin/phpinfo.php GET $(netstat -pantu | grep php-fpm.conf | awk '{print $4}' | sed 's/::://' | sed 's/127.0.0.1://' | sed 's/0.0.0.0://') > data/reports/phpinfo/html/PhpInfo_$(date +'%Y-%m-%dT%H_%M_%SZ').html",
        "phpinfo-cli": "symfony-console base:phpinfo -vvv",
        "phpinfo-cli-file": "symfony-console base:phpinfo -vvv > data/reports/phpinfo/text/PhpInfo_$(date +'%Y-%m-%dT%H_%M_%SZ').txt",
        "generate-secrets-html": [
            "symfony-console base:config-map -vvv --file='devops/env/dev/dev-secret.yaml' --html --base64DecodeValues",
            "symfony-console base:config-map -vvv --file='devops/env/sta/sta-secret.yaml' --html --base64DecodeValues",
            "symfony-console base:config-map -vvv --file='devops/env/pre-prod/pre-prod-secret.yaml' --html --base64DecodeValues",
            "symfony-console base:config-map -vvv --file='devops/env/prod/prod-secret.yaml' --html --base64DecodeValues"
        ]
    }
}

the devision/adex-auth package requires a package called devision/devision-base, which ultimately requires a plugin package called devision/devision-composer-plugin-run-package-scripts.

{
    "name": "devision/devision-base",
    "description": "devision - library - base components",
    "license": "BSD-3-Clause",
    "keywords": [
        "devision",
        "library",
        "base"
    ],
    "homepage": "https://devision.com",
    "config": {
        "sort-packages": true
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "conflict": {
        "doctrine/migrations": "<3.0",
        "guzzlehttp/guzzle": "<7.1"
    },
    "require": {
        "php": "^8.1.0",
        "ext-bcmath": "*",
        "ext-http": "*",
        "ext-imagick": "*",
        "ext-json": "*",
        "ext-mailparse": "*",
        "ext-mbstring": "*",
        "ext-oauth": "*",
        "ext-openssl": "*",
        "ext-pdo": "*",
        "ext-pdo_mysql": "*",
        "ext-pdo_pgsql": "*",
        "ext-pdo_sqlsrv": "*",
        "ext-pdo_sqlite": "*",
        "ext-pspell": "*",
        "ext-sockets": "*",
        "ext-ssh2": "*",
        "ext-yaml": "*",
        "ext-zip": "*",

        "devision/devision-composer-plugin-run-package-scripts": "^1.0.0",

        "doctrine/dbal": "^4.0.0",
        "doctrine/doctrine-laminas-hydrator": "^3.0.0",
        "doctrine/doctrine-module": "^6.0.2",
        "doctrine/event-manager": "^1.1.1",
        "doctrine/orm": "^3.1.2",
        "doctrine/persistence": "^3.0.0",
        "doctrine/migrations": "^3.0",

        "laminas/laminas-cache": "^3.0.0",
        "laminas/laminas-component-installer": "^3.0.0",
        "laminas/laminas-config-aggregator": "^1.0.0",
        "laminas/laminas-diactoros": "^3.0.0",
        "laminas/laminas-development-mode": "^3.0.0",
        "laminas/laminas-eventmanager": "^3.0.0",
        "laminas/laminas-hydrator": "^4.0.0",
        "laminas/laminas-i18n": "^2.0.0",
        "laminas/laminas-inputfilter": "^2.0.0",
        "laminas/laminas-log": "^2.0.0",
        "laminas/laminas-serializer": "^2.0.0",
        "laminas/laminas-stdlib": "^3.0.0",

        "mezzio/mezzio": "^3.0.0",
        "mezzio/mezzio-helpers": "^5.0.0",
        "mezzio/mezzio-fastroute": "^3.0.0",
        "mezzio/mezzio-cors": "^1.0.0",
        "mezzio/mezzio-problem-details": "^1.0.0",

        "symfony/console": "^5.2",
        "symfony/process": "^6.0.11",

        "guzzlehttp/guzzle": "^7.0.0",
        "php-http/mock-client": "^1.5.0",
        "php-webdriver/webdriver": "^1.13.1",
        "gettext/gettext": "^v5.7.0",
        "defuse/php-encryption": "^2.0.0",
        "lcobucci/jwt": "^4.1.2",
        "phpoffice/phpspreadsheet": "^1.16.0",
        "ramsey/uuid": "^4.0.0",
        "vlucas/phpdotenv": "^5.2",
        "bjeavons/zxcvbn-php": "^1.0",
        "kwn/number-to-words": "dev-master",

        "filp/whoops": "^2.0.0",

        "slevomat/coding-standard": "^8.15.0",
        "squizlabs/php_codesniffer": "^3.10.1",
        "vimeo/psalm": "@stable",

        "codeception/codeception": "^5.2.1",
        "codeception/module-asserts": "^3.0.0",
        "codeception/module-cli": "^2.0.1",
        "codeception/module-datafactory": "^3.0.0",
        "codeception/module-doctrine": "^3.1.0",
        "codeception/module-rest": "^3.4.1",
        "codeception/module-mezzio": "^4.0.2",
        "codeception/mockery-module": "^0.5.0",
        "league/factory-muffin": "^3.3.0",
        "league/factory-muffin-faker": "^2.3.0",
        "mockery/mockery": "^1.6.12"
    },
    "autoload": {
        "psr-4": {
            "Devision\\Base\\": "src/",
            "DevisionTest\\Base\\": "test/"
        }
    },
    "extra": {
        "laminas": {
            "config-provider": "Devision\\Base\\ConfigProvider"
        },
        "run-package-scripts": true
    },
    "bin": [
        "bin/generate-defuse-key.php",
        "bin/generate-openssl-key-pair",
        "bin/php-fpm-cli.sh",
        "bin/doctrine-console",
        "bin/symfony-console",
        "bin/xplatform-copy"
    ],
    "scripts": {
        "pre-package-install": [
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.bcmath.example .env.devision.devision-base.bcmath",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.l10n.example .env.devision.devision-base.l10n",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.i18n.example .env.devision.devision-base.i18n",
            "xplatform-copy -n vendor/devision/devision-base/.env.doctrine.example .env.doctrine",
            "xplatform-copy -n vendor/devision/devision-base/.env.laminas.laminas-cache.example .env.laminas.laminas-cache",
            "xplatform-copy -n vendor/devision/devision-base/.env.laminas.laminas-diactoros.example .env.laminas.laminas-diactoros",
            "xplatform-copy -n vendor/devision/devision-base/.env.laminas.laminas-inputfilter.example .env.laminas.laminas-inputfilter",
            "xplatform-copy -n vendor/devision/devision-base/.env.mezzio.example .env.mezzio",
            "xplatform-copy -n vendor/devision/devision-base/.env.mezzio.mezzio-problem-details.example .env.mezzio.mezzio-problem-details",
            "xplatform-copy -n vendor/devision/devision-base/.env.mezzio.mezzio-cors.example .env.mezzio.mezzio-cors",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.http.error-handling.example .env.devision.devision-base.http.error-handling",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.http.handler.example .env.devision.devision-base.http.handler",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.crypto-service.example .env.devision.devision-base.infrastructure.crypto-service",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.jwt.example .env.devision.devision-base.infrastructure.jwt",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.laminas.log.example .env.devision.devision-base.infrastructure.laminas.log",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.remote-service-connector.example .env.devision.devision-base.infrastructure.remote-service-connector",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.webdriver.example .env.devision.devision-base.infrastructure.webdriver",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.application-cache-service.example .env.devision.devision-base.infrastructure.application-cache-service",
            "generate-defuse-key.php -n data/keys/defuse-key"
        ],
        "pre-package-update": [
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.bcmath.example .env.devision.devision-base.bcmath",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.l10n.example .env.devision.devision-base.l10n",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.i18n.example .env.devision.devision-base.i18n",
            "xplatform-copy -n vendor/devision/devision-base/.env.doctrine.example .env.doctrine",
            "xplatform-copy -n vendor/devision/devision-base/.env.laminas.laminas-cache.example .env.laminas.laminas-cache",
            "xplatform-copy -n vendor/devision/devision-base/.env.laminas.laminas-diactoros.example .env.laminas.laminas-diactoros",
            "xplatform-copy -n vendor/devision/devision-base/.env.laminas.laminas-inputfilter.example .env.laminas.laminas-inputfilter",
            "xplatform-copy -n vendor/devision/devision-base/.env.mezzio.example .env.mezzio",
            "xplatform-copy -n vendor/devision/devision-base/.env.mezzio.mezzio-problem-details.example .env.mezzio.mezzio-problem-details",
            "xplatform-copy -n vendor/devision/devision-base/.env.mezzio.mezzio-cors.example .env.mezzio.mezzio-cors",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.http.error-handling.example .env.devision.devision-base.http.error-handling",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.http.handler.example .env.devision.devision-base.http.handler",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.crypto-service.example .env.devision.devision-base.infrastructure.crypto-service",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.jwt.example .env.devision.devision-base.infrastructure.jwt",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.laminas.log.example .env.devision.devision-base.infrastructure.laminas.log",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.remote-service-connector.example .env.devision.devision-base.infrastructure.remote-service-connector",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.webdriver.example .env.devision.devision-base.infrastructure.webdriver",
            "xplatform-copy -n vendor/devision/devision-base/.env.devision.devision-base.infrastructure.application-cache-service.example .env.devision.devision-base.infrastructure.application-cache-service",
            "generate-defuse-key.php -n data/keys/defuse-key"
        ],
        "phpcs-devision-devision-base": "phpcs --standard=\"vendor/devision/devision-base/phpcs.xml\"",
        "phpinfo-html": "php-fpm-cli.sh vendor/devision/devision-base/bin/phpinfo.php vendor/devision/devision-base/bin/phpinfo.php GET $(netstat -pantu | grep php-fpm.conf | awk '{print $4}' | sed 's/::://' | sed 's/127.0.0.1://' | sed 's/0.0.0.0://')",
        "phpinfo-html-file": "php-fpm-cli.sh vendor/devision/devision-base/bin/phpinfo.php vendor/devision/devision-base/bin/phpinfo.php GET $(netstat -pantu | grep php-fpm.conf | awk '{print $4}' | sed 's/::://' | sed 's/127.0.0.1://' | sed 's/0.0.0.0://') > data/reports/phpinfo/html/PhpInfo_$(date +'%Y-%m-%dT%H_%M_%SZ').html",
        "phpinfo-cli": "symfony-console base:phpinfo -vvv",
        "phpinfo-cli-file": "symfony-console base:phpinfo -vvv > data/reports/phpinfo/text/PhpInfo_$(date +'%Y-%m-%dT%H_%M_%SZ').txt"
    }
}

Output of composer diagnose:

Checking composer.json: WARNING
require.doctrine/orm : exact version constraints (3.3.0) should be avoided if the package follows semantic versioning
Checking composer.lock: FAIL
platform-dev : Array value found, but an object is required
Checking platform settings: OK
Checking git settings: OK git version 2.47.2
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking connectivity to https://gitlab.com/api/v4/group/76796855/-/packages/composer/: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys: FAIL
Missing pubkey for tags verification
Missing pubkey for dev verification
Run composer self-update --update-keys to set them up
Checking Composer version: You are not running the latest stable version, run `composer self-update` to update (2.8.8 => 2.8.9)
Checking Composer and its dependencies for vulnerabilities: OK
Composer version: 2.8.8
PHP version: 8.1.32
PHP binary path: /usr/local/bin/php
OpenSSL version: OpenSSL 3.3.3 11 Feb 2025
curl version: 8.12.1 libz 1.3.1 brotli brotli/1.1.0 zstd missing ssl OpenSSL/3.3.3
zip: extension present, unzip present, 7-Zip not available

When I run this command:

rm -rf vendor/devision
composer install

I get the following output:

Installing dependencies from lock file (including require-dev)
Verifying lock file contents can be installed on current platform.
Package operations: 13 installs, 0 updates, 0 removals
  - Syncing devision/devision-composer-plugin-run-package-scripts (1.0.0) into cache
  - Syncing devision/devision-base (5.1.0) into cache
  - Syncing devision/devision-elastic (5.0.0) into cache
  - Syncing devision/devision-view (5.0.0) into cache
  - Syncing devision/devision-session (5.0.0) into cache
  - Syncing devision/devision-message-queue (5.0.0) into cache
  - Syncing devision/devision-devision (5.0.0) into cache
  - Syncing devision/devision-i18n-territorial-division (5.0.0) into cache
  - Syncing devision/devision-auth (5.0.0) into cache
  - Syncing devision/devision-email (5.9.0) into cache
  - Syncing devision/devision-auth-consumer (5.0.0) into cache
  - Syncing devision/devision-auth-provider (5.0.0) into cache
  - Syncing devision/adex-auth (dev-master 3bd7537) into cache
  - Installing devision/devision-composer-plugin-run-package-scripts (1.0.0): Cloning 3df007853d from cache
  - Installing devision/devision-base (5.1.0): Cloning 97448e3f4b from cache
    Skipped installation of bin bin/generate-defuse-key.php for package devision/devision-base: name conflicts with an existing file
    Skipped installation of bin bin/generate-openssl-key-pair for package devision/devision-base: name conflicts with an existing file
    Skipped installation of bin bin/php-fpm-cli.sh for package devision/devision-base: name conflicts with an existing file
    Skipped installation of bin bin/doctrine-console for package devision/devision-base: name conflicts with an existing file
    Skipped installation of bin bin/symfony-console for package devision/devision-base: name conflicts with an existing file
    Skipped installation of bin bin/xplatform-copy for package devision/devision-base: name conflicts with an existing file
  - Installing devision/devision-elastic (5.0.0): Cloning 9ad83a8e2c from cache
  - Installing devision/devision-view (5.0.0): Cloning 8517eaeba4 from cache
  - Installing devision/devision-session (5.0.0): Cloning 7f600a3c5b from cache
  - Installing devision/devision-message-queue (5.0.0): Cloning 2b60a9f56e from cache
  - Installing devision/devision-devision (5.0.0): Cloning 8bd3e7e41a from cache
  - Installing devision/devision-i18n-territorial-division (5.0.0): Cloning 0e5afde5e7 from cache
  - Installing devision/devision-auth (5.0.0): Cloning 0b7dee3e45 from cache
  - Installing devision/devision-email (5.9.0): Cloning 3d32601b23 from cache
  - Installing devision/devision-auth-consumer (5.0.0): Cloning d79912f932 from cache
  - Installing devision/devision-auth-provider (5.0.0): Cloning a1c2ef392e from cache
  - Installing devision/adex-auth (dev-master 3bd7537): Cloning 3bd7537de8 from cache
Package laminas/laminas-config is abandoned, you should avoid using it. No replacement was suggested.
Package laminas/laminas-json is abandoned, you should avoid using it. No replacement was suggested.
Package laminas/laminas-loader is abandoned, you should avoid using it. No replacement was suggested.
Package laminas/laminas-log is abandoned, you should avoid using it. Use monolog/monolog instead.
Package laminas/laminas-mail is abandoned, you should avoid using it. Use symfony/mailer instead.
Package laminas/laminas-mime is abandoned, you should avoid using it. Use symfony/mime instead.
Package phploc/phploc is abandoned, you should avoid using it. No replacement was suggested.
Generating autoload files
composer/package-versions-deprecated: Generating version class...
composer/package-versions-deprecated: ...done generating version class
145 packages you are using are looking for funding.
Use the `composer fund` command to find out more!

And I expected this to happen:
Prior to v2.8.4 and this commit specifically
5cb9733
plugins used to get loaded and subscribed to events, even if the plugins did not exist on the file system and had to be cloned from repo or installed from dist as part of the same composer operation. In the scenario outlined above, all devision/* packages are deleted. including devision/devision-composer-plugin-run-package-scripts. After running composer install the composer script would pass through \Composer\Plugin\PluginManager::registerPackage() twice - once before cloning/installation on the file system (at that time the plugin class does not exist) and once after the package has been downloaded and exists inside vendor/. With the addition of this line
5cb9733#diff-b78493d9f4f82c74a4597e5f450eaa054cf1ef9b738c15624d9729cf72af7aa9R204
the first pass will populate $this->registeredPlugins[$package->getName()], but the actual subscription to the events will not occur on the second pass due to the fulfulling of this condition
5cb9733#diff-b78493d9f4f82c74a4597e5f450eaa054cf1ef9b738c15624d9729cf72af7aa9R201

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions