A Composer script that copies vendor packages into your project and rewrites their namespaces, preventing conflicts when the same package is used across multiple projects in the same WordPress installation.
- PHP 8.1+
- Composer 2.0+
composer require-dev x3p0-dev/x3p0-preludeAdd an x3p0.prelude block to the extra section of your composer.json, then register the script entry point:
{
"scripts": {
"post-install-cmd": [
"@x3p0-prelude"
],
"post-update-cmd": [
"@x3p0-prelude"
],
"x3p0-prelude": "X3P0\\Prelude\\Compose::run"
},
"extra": {
"x3p0": {
"prelude": {
"prefix": "MyProject\\Vendor",
"output-path": "packages",
"packages": {
"vendor/package-name": {
"replace": "OriginalNamespace\\"
}
}
}
}
}
}| Key | Required | Description |
|---|---|---|
prefix |
Yes | The namespace prefix to apply to all copied packages. |
output-path |
Yes | Directory to copy packages into, relative to your project root. |
packages |
Yes | Map of packages to copy, keyed by vendor/package path. |
Each entry under packages is keyed by the vendor/package path as it appears in your vendor/ directory. Glob-style wildcards are supported.
| Key | Required | Description |
|---|---|---|
replace |
No | The original namespace root to rewrite. If omitted, files are copied without modification. |
Use * within a package key to match multiple packages under a vendor:
"packages": {
"some-vendor/*": {
"replace": "SomeVendor\\"
}
}Use "*" alone to match all remaining packages in vendor/:
"packages": {
"my-vendor/specific-package": {
"replace": "SpecificNS\\"
},
"*": {}
}When the script runs, it:
- Clears the output directory.
- Copies each configured package from
vendor/into the output directory. - Rewrites every occurrence of the original namespace root in copied PHP files, prepending your
prefix.
For example, with prefix set to MyProject and replace set to X3P0\\, a copied file containing X3P0\Framework\Container becomes MyProject\Framework\Container.
Register the copied packages in your autoload block. The exact approach depends on the package structure; a classmap is the simplest option:
"autoload": {
"classmap": ["packages/"]
}Or use PSR-4 if the package has a known src/ layout:
"autoload": {
"psr-4": {
"MyProject\\Framework\\": "packages/vendor/package/src/"
}
}GPL-3.0-or-later.