We were working on something else against a checkout of master and ran into this, so passing it along in case it is useful. Not sure whether it is intentional, since the released plugin is unaffected.
Summary: a clean git clone of master cannot be activated. The committed autoloader eagerly requires vendor/phpstan/phpstan/bootstrap.php, which is a dev dependency and is correctly not committed, so the plugin fatals before any of its own code runs.
Steps to reproduce
git clone https://github.com/WPManageNinja/fluent-smtp.git wp-content/plugins/fluent-smtp
wp plugin activate fluent-smtp
No composer install in between. Result:
PHP Fatal error: Uncaught Error: Failed opening required
'.../wp-content/plugins/fluent-smtp/vendor/composer/../phpstan/phpstan/bootstrap.php'
(include_path='.:/usr/local/lib/php')
in .../wp-content/plugins/fluent-smtp/vendor/composer/autoload_real.php:39
What seems to be going on
vendor/ is committed, but only the autoloader plumbing, which makes sense given composer.json has no runtime require section at all and only require-dev. Eight files are tracked:
vendor/autoload.php
vendor/composer/ClassLoader.php
vendor/composer/LICENSE
vendor/composer/autoload_{classmap,namespaces,psr4,real,static}.php
The committed vendor/composer/autoload_static.php carries a files entry:
public static $files = array (
'9b38cf48e83f5d8f60375221cd213eee' => __DIR__ . '/..' . '/phpstan/phpstan/bootstrap.php',
);
Composer's files autoloads are eager rather than lazy, so they are required unconditionally on every request rather than when a class is first referenced. The load chain:
fluent-smtp.php:21 require_once .../boot.php
boot.php:13 require .../vendor/autoload.php
vendor/autoload.php:22 ComposerAutoloaderInit...::getLoader()
autoload_real.php:39 require $file; <-- fatal, the file is not there
The same committed classmap also lists sixteen szepeviktor/phpstan-wordpress classes whose files are likewise absent, but those are harmless: classmap entries are lazy and nothing requests those classes at runtime. It is specifically the eager files entry that is fatal.
We reproduced the entry by running composer install with dev dependencies present against a copy of composer.json. The generated autoload_static.php contains the identical entry, hash included. It appears to have arrived with 7fd93b3b ("Register a void http_api_curl callback and regenerate the classmap"), which regenerated the autoloader on a machine that had dev dependencies installed.
Who this affects
| Install path |
Affected |
| wordpress.org, or any release zip |
No |
A zip built by build.sh |
No |
A developer working copy where composer install has been run |
No |
A git clone where composer has not been run |
Yes |
Release users are fine because build.sh:79 runs composer install --no-dev --optimize-autoloader --classmap-authoritative before zipping, which regenerates the autoloader with an empty files array. build.sh:148 already fails the build if phpstan leaks into the zip.
It only shows up on a checkout where composer has not been run, which is the path someone takes when testing a branch or contributing.
Verified on
master at 78c462c, activated from a pristine clone:
| WordPress |
PHP |
Result |
| 6.9.8 |
8.3 |
fatal at autoload_real.php:39 |
| 6.8.9 |
8.1 |
fatal at autoload_real.php:39 |
| 6.8.9 |
7.4 |
fatal at autoload_real.php:39 |
Nothing about it looks version-specific, since the failure happens in the autoloader before any plugin or WordPress code runs.
We were working on something else against a checkout of
masterand ran into this, so passing it along in case it is useful. Not sure whether it is intentional, since the released plugin is unaffected.Summary: a clean
git cloneofmastercannot be activated. The committed autoloader eagerlyrequiresvendor/phpstan/phpstan/bootstrap.php, which is a dev dependency and is correctly not committed, so the plugin fatals before any of its own code runs.Steps to reproduce
No
composer installin between. Result:What seems to be going on
vendor/is committed, but only the autoloader plumbing, which makes sense givencomposer.jsonhas no runtimerequiresection at all and onlyrequire-dev. Eight files are tracked:The committed
vendor/composer/autoload_static.phpcarries afilesentry:Composer's
filesautoloads are eager rather than lazy, so they arerequired unconditionally on every request rather than when a class is first referenced. The load chain:The same committed classmap also lists sixteen
szepeviktor/phpstan-wordpressclasses whose files are likewise absent, but those are harmless: classmap entries are lazy and nothing requests those classes at runtime. It is specifically the eagerfilesentry that is fatal.We reproduced the entry by running
composer installwith dev dependencies present against a copy ofcomposer.json. The generatedautoload_static.phpcontains the identical entry, hash included. It appears to have arrived with7fd93b3b("Register a void http_api_curl callback and regenerate the classmap"), which regenerated the autoloader on a machine that had dev dependencies installed.Who this affects
build.shcomposer installhas been rungit clonewhere composer has not been runRelease users are fine because
build.sh:79runscomposer install --no-dev --optimize-autoloader --classmap-authoritativebefore zipping, which regenerates the autoloader with an emptyfilesarray.build.sh:148already fails the build if phpstan leaks into the zip.It only shows up on a checkout where composer has not been run, which is the path someone takes when testing a branch or contributing.
Verified on
masterat78c462c, activated from a pristine clone:autoload_real.php:39autoload_real.php:39autoload_real.php:39Nothing about it looks version-specific, since the failure happens in the autoloader before any plugin or WordPress code runs.