Automattic / Automattic/WP-Job-Manager
Add composer classmap autoloader for plugin classes
- Dominant language
- PHP
- Stars
- 899
- Forks
- 369
- Avg merge
- 11h 37m
- Merged PRs (30d)
- 12
Description
> *This was generated by AI during triage.*
Split out from #2681 (which was an empty-body "migrate to namespaces" placeholder) as a concrete, low-risk first slice. This issue is the foundation that unblocks future per-subsystem namespace migrations without big-bang renames or BC breaks.
## Enhancement
**Current behavior:**
The plugin loads classes via explicit `include_once` calls scattered across the bootstrap (`includes/class-wp-job-manager.php`). About 21 of 92 files in `includes/` already declare `namespace WP_Job_Manager` (or sub-namespaces like `WP_Job_Manager\UI`); the rest are global-prefix classes (`WP_Job_Manager_*`). There is no autoloader for these namespaced classes — they too are loaded via manual requires. `composer.json` defines no `autoload` section. `vendor/` is gitignored and excluded from the release zip pipeline.
**Desired behavior:**
Register a composer **classmap autoloader** scanning `includes/` so:
- All namespaced classes load on first reference, removing the need to add a manual `include_once` for each new class.
- Legacy global-prefix classes continue to work exactly as before (the classmap covers them too).
- The plugin bootstrap `require`s the autoloader early (`vendor/autoload.php`) when it exists.
PSR-4 isn't a fit because file names use the WordPress `class-{kebab}.php` convention rather than `{ClassName}.php`. Classmap autoloading handles arbitrary file naming.
The build/release pipeline must ensure `vendor/` (or at least the generated `vendor/autoload.php` + `composer/` autoloader files) is present in the deployed plugin zip. Today `vendor/` is gitignored *and* not excluded from the release zip, so either commit the autoloader artifacts, or run `composer install --no-dev -o` as part of the build step that produces the zip.
**Key interfaces:**
- `composer.json` — add an `autoload` section with `classmap: ["includes/"]` (and `exclude-from-classmap` for test or example folders if present).
- Plugin bootstrap (`wp-job-manager.php`) — `require_once dirname(__FILE__) . '/vendor/autoload.php';` before any other code that might reference plugin classes.
- The build/release pipeline (`scripts/exclude.lst` + the GitHub Actions release workflow `.github/workflows/create-release.yml`) — make sure the autoloader files end up in the release zip without bundling dev dependencies. Add `vendor/*` to the zip but only after `composer install --no-dev -o` runs.
- The existing manual `include_once` calls for namespaced files can stay in place initially (no functional change); a later cleanup can remove them.
**Acceptance criteria:**
- [ ] `composer.json` includes a classmap autoload covering `includes/` (and any other directories holding plugin classes).
- [ ] The plugin bootstrap requires `vendor/autoload.php` (guarded with a `file_exists()` check so a contributor without `composer install` gets a clear error path rather than a fatal).
- [ ] Removing one of the manual `include_once` lines for a currently-namespaced class (e.g. `class-stats.php`) does not break the plugin — the class loads via the autoloader.
- [ ] Removing one of the manual `include_once` lines for a legacy global-prefix class (e.g. `class-wp-job-manager-cache-helper.php`) does not break the plugin — the class loads via the classmap.
- [ ] The release zip produced by the release workflow contains a working `vendor/autoload.php` and the composer autoload files, but no dev dependencies (`require-dev` packages absent).
- [ ] PHPUnit suite passes unchanged.
- [ ] No new PHP deprecation/warnings at boot on the supported PHP range (7.4 / 8.x).
- [ ] CONTRIBUTING / build docs note that `composer install` is required for development.
**Out of scope:**
- Actually migrating any legacy `WP_Job_Manager_*` class to a namespace. That happens later, per-subsystem, each behind its own issue. This issue only adds the autoloader.
- Removing the existing manual `include_once` calls in bulk. Touch only what's needed to prove the autoloader works (an item or two in acceptance criteria). Bulk removal is a separate cleanup.
- `class_alias()` BC shims for renamed classes — only needed when a rename actually happens.
- Adding `psr-4` mapping to `composer.json` — defer until file naming changes (a much larger undertaking).
Contributor guide
Research direction
Start with composer.json and wp-job-manager.php, then inspect scripts/exclude.lst and .github/workflows/create-release.yml to trace how the release zip is built. Run composer install --no-dev -o and the PHPUnit suite while checking the named namespaced and legacy classes. Done means the classmap loads both class styles, the guarded autoloader is included, and the release zip contains only the required Composer autoloader files without dev dependencies.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github-actions, php
- Domain
- backend, build-system, ci-cd
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100