Skip to content

fix(core): make get_feature_classes's return docblock scoper-safe#6

Merged
ahegyes merged 1 commit into
trunkfrom
framework/plugininterface-feature-docblock
Jun 29, 2026
Merged

fix(core): make get_feature_classes's return docblock scoper-safe#6
ahegyes merged 1 commit into
trunkfrom
framework/plugininterface-feature-docblock

Conversation

@ahegyes

@ahegyes ahegyes commented Jun 29, 2026

Copy link
Copy Markdown
Owner

The @return used an absolute …\Feature\FeatureInterface FQCN inside the class-string generic, which php-scoper does not rewrite in docblocks — so a scoped consumer's get_feature_classes() implementation is analysed against the unscoped interface and fails static analysis, forcing a per-consumer @PHPStan-Ignore. Import FeatureInterface and reference the short name (as every other class-string docblock in the package already does); php-scoper rewrites the use statement, so the scoped return type resolves to the scoped interface and consumers need no workaround.

Assisted-by: Claude Code:claude-opus-4-8

Summary

Affected packages

  • wp-framework-bootstrap
  • wp-framework-shared
  • wp-framework-storage
  • wp-framework-core
  • wp-framework-utilities
  • wp-framework-settings
  • wp-framework-woocommerce

Checklist

  • Changelog fragment added via composer changelog:add:<package> (one per affected package)
  • Tests added or updated (Unit and/or Integration as appropriate)
  • composer quality-check passes locally (PHPCS + PHPStan + Deptrac + unit tests)
  • Public API changes are documented in the affected package's README.md
  • Breaking changes (significance: major) are explicitly justified below

Breaking changes / migration notes

The @return used an absolute …\Feature\FeatureInterface FQCN inside the class-string generic, which php-scoper does not rewrite in docblocks — so a scoped consumer's get_feature_classes() implementation is analysed against the unscoped interface and fails static analysis, forcing a per-consumer @PHPStan-Ignore. Import FeatureInterface and reference the short name (as every other class-string docblock in the package already does); php-scoper rewrites the use statement, so the scoped return type resolves to the scoped interface and consumers need no workaround.

Assisted-by: Claude Code:claude-opus-4-8
@ahegyes ahegyes self-assigned this Jun 29, 2026
@ahegyes ahegyes merged commit 54bbbb7 into trunk Jun 29, 2026
21 of 24 checks passed
@ahegyes ahegyes deleted the framework/plugininterface-feature-docblock branch June 29, 2026 08:19
ahegyes added a commit that referenced this pull request Jul 4, 2026
… boot report carrier, CRUD field stores, VO grammar, PHP 8.5 idioms

Scheduler becomes an ordered-backend-list facade with readiness on the
backend contract (SchedulerBackendInterface::is_ready()): schedule writes
target the first ready backend, clears and queries span every ready one
with declaration-order failure precedence, and create_scheduler() keeps
its signature. An empty backend list throws
InvalidSchedulerConfigurationException.

The kernel exposes boot diagnostics as a PluginBootReport value carrier
(BootStatus enum) through a public protected(set) property — plain data
rides properties, get_*() stays for derived access. The four
group-registering field stores earn their name with descriptor-addressed
CRUD (get/set/has/delete + meta_keys) over the form path's storage keys
and store-or-revoke semantics; on the form path the processed value is
stored verbatim, so validation is the final transformation before
persistence. Both settings backends enumerate their option rows for
uninstall (option_keys). WPPluginVersionConditional gates third-party
plugin dependencies by minimum version. AdminNoticesService self-wires
its hooks, validates its dismiss action, and drops the dead pre-6.4
fallback; the stores hook WordPress through instance-addressed callables.

The value-object grammar becomes semantic (identity-free + structurally
safe property graph; consumption is not a criterion): AdminNotice,
FieldProcessingError, and MetaBoxPlacement join Version and PluginHeader;
InvalidAdminNoticeException moves to the InvalidValueObjectException
family and DependencyRequirement throws its own
InvalidDependencyRequirementException. WordPress-global name prefixes are
validated at construction in utilities. PHP 8.5 idioms applied where the
tooling accepts them: asymmetric-visibility properties replace
derivation-free getters (HookHandlerInterface declares $id as a property),
readonly classes hoisted, parameter defaults use new-in-initializers, and
the scalar output-coercion policy is one shared stringify_for_output().

Remediates 2026-07-03 audit findings #6 #14 #19 #20 #23(doc) #36 #37 #89
#91 #100 #102 #106 #109 #110 #111 and the owner-ruled Scheduler
genericity, PluginBootReport, VO-grammar, and modernization decisions.

Assisted-by: Claude Code:claude-fable-5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant