You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PHP can only load one class with a given name per request. WordPress loads every active plugin into the same process, so if another plugin ships the same library, whichever plugin loads first "wins" and the other one gets that version, whether it is compatible or not.
This is not theoretical for WP-Parsidate:
🧨 enshrined\svgSanitize\Sanitizer is also bundled by Safe SVG (1M+ active installs) and by several theme frameworks. If Safe SVG loads an older/newer release first, WPParsidate\Helper\Sanitizing::svg() runs against a class with a different API and different allow-lists. Depending on the version mix this is a wrong result (SVG not cleaned the way we expect) or a fatal error ("Call to undefined method").
🧨 Symfony\Polyfill\Php80\Php80 (and Php81, Php83) are bundled by a large number of plugins. The polyfill functions (str_contains, array_is_list, json_validate, ...) are guarded with function_exists(), but the helper classes are not: an older polyfill loaded by another plugin can be missing a method that our bootstrap file calls.
On every composer install, wp-scoper copies the dependencies to packages/, rewrites their namespaces, generates packages/autoload.php and updates our own use statements:
The main plugin file loads packages/autoload.php instead of vendor/autoload.php. packages/ is committed, vendor/ becomes dev-only and leaves the release ZIP.
🎁 Benefits
🛡️ No more class conflicts.WPParsidate\Dependencies\enshrined\svgSanitize\Sanitizer can never collide with anyone else's enshrined\svgSanitize\Sanitizer.
📌 We always run the exact library version we tested, regardless of what other plugins ship.
📦 Smaller release. Only the PHP files we need are copied (tests, docs and config files of the libraries are skipped): 77 KB instead of 107 KB for the current dependency set.
🤖 Zero manual work. It runs as part of composer install; there is no separate build step to remember. Call sites in inc/ are updated automatically.
🔍 Verifiable in CI. A workflow job can re-run composer install and fail if packages/ is out of date.
🚨 Problem
The plugin ships its Composer dependencies in
vendor/without any namespace prefixing:enshrined/svg-sanitizesymfony/polyfill-php80,symfony/polyfill-php81,symfony/polyfill-php83PHP can only load one class with a given name per request. WordPress loads every active plugin into the same process, so if another plugin ships the same library, whichever plugin loads first "wins" and the other one gets that version, whether it is compatible or not.
This is not theoretical for WP-Parsidate:
enshrined\svgSanitize\Sanitizeris also bundled by Safe SVG (1M+ active installs) and by several theme frameworks. If Safe SVG loads an older/newer release first,WPParsidate\Helper\Sanitizing::svg()runs against a class with a different API and different allow-lists. Depending on the version mix this is a wrong result (SVG not cleaned the way we expect) or a fatal error ("Call to undefined method").Symfony\Polyfill\Php80\Php80(andPhp81,Php83) are bundled by a large number of plugins. The polyfill functions (str_contains,array_is_list,json_validate, ...) are guarded withfunction_exists(), but the helper classes are not: an older polyfill loaded by another plugin can be missing a method that our bootstrap file calls.✅ Proposal
Use wp-scoper, the same tool wp-sms and its add-ons use. It is a Composer plugin, so it needs no global tool or PHAR:
composer require --dev veronalabs/wp-scoperextra.wp-scoperblock tocomposer.json:composer install, wp-scoper copies the dependencies topackages/, rewrites their namespaces, generatespackages/autoload.phpand updates our ownusestatements:packages/autoload.phpinstead ofvendor/autoload.php.packages/is committed,vendor/becomes dev-only and leaves the release ZIP.🎁 Benefits
WPParsidate\Dependencies\enshrined\svgSanitize\Sanitizercan never collide with anyone else'senshrined\svgSanitize\Sanitizer.composer install; there is no separate build step to remember. Call sites ininc/are updated automatically.composer installand fail ifpackages/is out of date.🔍 How it works in wp-sms (demo)
extra.wp-scoper)I have a pull request ready for this.