From 492718ef134f67836c8a72a9a41aadc4921009a9 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 12 Oct 2026 14:54:46 +0200 Subject: [PATCH 1/3] refactor: let attributes declare what they register Post type and taxonomy attributes implement ConfiguresArguments, a pure function of their own values, and the method attributes ConfiguresArgumentsWithMethod; the discoveries apply them. #[Method] routes are registered by WpRestRouteRegistrar, default names come from an internal Naming helper matching Str, and the dead handle() methods of Action, Filter and WpRestRoute are gone. Pollora\Attributes no longer reaches Laravel or a framework service, which an architecture test keeps. Fixes an #[Action] or #[Filter] method of a post type or taxonomy class being registered a second time on the discovery's configuration object. --- CHANGELOG.md | 9 + phpstan-baseline.neon | 18 -- src/Attributes/Ability.php | 10 +- src/Attributes/Action.php | 66 +----- src/Attributes/Ajax.php | 4 +- .../Contracts/ConfiguresArguments.php | 24 ++ .../ConfiguresArgumentsWithMethod.php | 24 ++ src/Attributes/Filter.php | 34 +-- src/Attributes/Hook.php | 4 +- src/Attributes/Meta.php | 4 +- src/Attributes/PostType.php | 4 +- src/Attributes/PostType/AdminCol.php | 37 +--- src/Attributes/PostType/AdminCols.php | 13 +- src/Attributes/PostType/AdminFilters.php | 13 +- src/Attributes/PostType/Archive.php | 13 +- src/Attributes/PostType/BlockEditor.php | 13 +- src/Attributes/PostType/CanExport.php | 13 +- src/Attributes/PostType/Capabilities.php | 13 +- src/Attributes/PostType/CapabilityType.php | 13 +- src/Attributes/PostType/Chronological.php | 15 +- src/Attributes/PostType/DashboardActivity.php | 13 +- src/Attributes/PostType/DashboardGlance.php | 13 +- src/Attributes/PostType/DeleteWithUser.php | 13 +- src/Attributes/PostType/Description.php | 13 +- src/Attributes/PostType/ExcludeFromSearch.php | 13 +- src/Attributes/PostType/FeaturedImage.php | 13 +- src/Attributes/PostType/HasArchive.php | 13 +- src/Attributes/PostType/Hierarchical.php | 13 +- src/Attributes/PostType/Label.php | 13 +- src/Attributes/PostType/Labels.php | 12 +- src/Attributes/PostType/MapMetaCap.php | 13 +- src/Attributes/PostType/MenuIcon.php | 13 +- src/Attributes/PostType/MenuPosition.php | 13 +- src/Attributes/PostType/PostTypeAttribute.php | 5 +- src/Attributes/PostType/Priority.php | 13 +- src/Attributes/PostType/PublicPostType.php | 13 +- src/Attributes/PostType/PubliclyQueryable.php | 13 +- src/Attributes/PostType/QueryVar.php | 13 +- src/Attributes/PostType/QuickEdit.php | 13 +- src/Attributes/PostType/RegisterMetaBoxCb.php | 24 +- src/Attributes/PostType/RestBase.php | 13 +- .../PostType/RestControllerClass.php | 13 +- src/Attributes/PostType/RestNamespace.php | 13 +- src/Attributes/PostType/Rewrite.php | 13 +- src/Attributes/PostType/ShowInAdminBar.php | 13 +- src/Attributes/PostType/ShowInFeed.php | 13 +- src/Attributes/PostType/ShowInMenu.php | 13 +- src/Attributes/PostType/ShowInNavMenus.php | 13 +- src/Attributes/PostType/ShowInRest.php | 13 +- src/Attributes/PostType/ShowUI.php | 13 +- src/Attributes/PostType/SiteFilters.php | 13 +- src/Attributes/PostType/SiteSortables.php | 13 +- src/Attributes/PostType/Supports.php | 13 +- src/Attributes/PostType/Taxonomies.php | 13 +- src/Attributes/PostType/Template.php | 13 +- src/Attributes/PostType/TemplateLock.php | 13 +- src/Attributes/PostType/TitlePlaceholder.php | 13 +- src/Attributes/Support/Naming.php | 73 ++++++ src/Attributes/Taxonomy.php | 4 +- src/Attributes/Taxonomy/AllowHierarchy.php | 13 +- src/Attributes/Taxonomy/Args.php | 13 +- src/Attributes/Taxonomy/Capabilities.php | 13 +- src/Attributes/Taxonomy/CheckedOntop.php | 10 +- src/Attributes/Taxonomy/DefaultTerm.php | 13 +- src/Attributes/Taxonomy/Description.php | 13 +- src/Attributes/Taxonomy/Exclusive.php | 13 +- src/Attributes/Taxonomy/Hierarchical.php | 13 +- src/Attributes/Taxonomy/Label.php | 13 +- src/Attributes/Taxonomy/Labels.php | 12 +- src/Attributes/Taxonomy/MetaBoxCb.php | 24 +- src/Attributes/Taxonomy/MetaBoxSanitizeCb.php | 24 +- src/Attributes/Taxonomy/ObjectType.php | 13 +- src/Attributes/Taxonomy/Priority.php | 13 +- src/Attributes/Taxonomy/PublicTaxonomy.php | 13 +- src/Attributes/Taxonomy/QueryVar.php | 13 +- src/Attributes/Taxonomy/RestBase.php | 13 +- .../Taxonomy/RestControllerClass.php | 13 +- src/Attributes/Taxonomy/RestNamespace.php | 13 +- src/Attributes/Taxonomy/Rewrite.php | 13 +- src/Attributes/Taxonomy/ShowAdminColumn.php | 13 +- src/Attributes/Taxonomy/ShowInMenu.php | 13 +- src/Attributes/Taxonomy/ShowInNavMenus.php | 13 +- src/Attributes/Taxonomy/ShowInQuickEdit.php | 13 +- src/Attributes/Taxonomy/ShowInRest.php | 13 +- src/Attributes/Taxonomy/ShowTagcloud.php | 13 +- src/Attributes/Taxonomy/ShowUI.php | 13 +- src/Attributes/Taxonomy/Sort.php | 13 +- src/Attributes/Taxonomy/TaxonomyAttribute.php | 5 +- .../Taxonomy/UpdateCountCallback.php | 24 +- src/Attributes/WpCli.php | 4 +- src/Attributes/WpCli/Command.php | 4 +- src/Attributes/WpRestRoute.php | 20 +- src/Attributes/WpRestRoute/Method.php | 125 +---------- .../Services/PostTypeConfiguration.php | 10 + .../Services/PostTypeDiscovery.php | 21 +- src/Support/Slug.php | 45 +--- .../Services/TaxonomyConfiguration.php | 10 + .../Services/TaxonomyDiscovery.php | 21 +- .../Services/WpRestDiscovery.php | 21 +- .../Services/WpRestRouteRegistrar.php | 133 +++++++++++ .../Feature/Hook/Async/AsyncAttributeTest.php | 40 ---- tests/Feature/Hook/HookDiscoveryTest.php | 94 ++++++++ tests/Unit/Attributes/ActionTest.php | 187 ---------------- tests/Unit/Attributes/ArchitectureTest.php | 31 +++ tests/Unit/Attributes/FilterTest.php | 209 ------------------ tests/Unit/Attributes/HookTest.php | 12 +- tests/Unit/Attributes/LabelsAttributeTest.php | 13 +- tests/Unit/Attributes/NamingTest.php | 49 ++++ .../Unit/Attributes/TaxonomyAttributeTest.php | 15 +- tests/Unit/PostType/PostTypeDiscoveryTest.php | 114 ++++++++++ tests/Unit/Taxonomy/TaxonomyDiscoveryTest.php | 86 +++++++ tests/Unit/WpRest/CanPermissionTest.php | 6 +- .../Unit/WpRest/RestRequestInjectionTest.php | 8 +- 113 files changed, 1352 insertions(+), 1241 deletions(-) create mode 100644 src/Attributes/Contracts/ConfiguresArguments.php create mode 100644 src/Attributes/Contracts/ConfiguresArgumentsWithMethod.php create mode 100644 src/Attributes/Support/Naming.php create mode 100644 src/WpRest/Infrastructure/Services/WpRestRouteRegistrar.php create mode 100644 tests/Feature/Hook/HookDiscoveryTest.php delete mode 100644 tests/Unit/Attributes/ActionTest.php create mode 100644 tests/Unit/Attributes/ArchitectureTest.php delete mode 100644 tests/Unit/Attributes/FilterTest.php create mode 100644 tests/Unit/Attributes/NamingTest.php create mode 100644 tests/Unit/PostType/PostTypeDiscoveryTest.php create mode 100644 tests/Unit/Taxonomy/TaxonomyDiscoveryTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c41f41b6..92321442 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,14 +10,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Discovery lives in its own package, [`pollora/discovery`](https://github.com/Pollora/discovery), which the framework requires: the engine, its contracts, `DiscoveryManager`, the cache and the `#[SkipDiscovery]` attribute, with their tests and benchmarks. Class names do not change. The framework keeps what needs Laravel: the service provider, `discovery:run` / `discovery:clear`, `DiscoveryRegistrar`, `ServiceProviderDiscovery`, the Laravel adapters, and `HasConfiguringSupport`, which builds post types and taxonomies - Discovery can run without Laravel's application, the first step towards `pollora/discovery`: `new DiscoveryEngine()` works with no argument. Two contracts let an environment plug in — `InstanceResolverInterface` builds the classes discovery needs (Laravel's container in a Pollora application, `ReflectionInstanceResolver` otherwise) and `DiscoveryRegistrarInterface` adds the environment's discoveries before each run (`DiscoveryRegistrar` keeps scanning the container's `*Discovery` bindings). `Psr16DiscoverCacheDriver` caches scans in any PSR-16 cache +- Post type and taxonomy attributes say what they register: each implements `ConfiguresArguments`, a pure function that returns the registration arguments with its own contribution (`#[HasArchive('library')]` sets `has_archive`, `#[Labels]` merges into the generated labels), and the method attributes (`#[AdminCol]`, `#[RegisterMetaBoxCb]`, `#[MetaBoxCb]`, `#[MetaBoxSanitizeCb]`, `#[UpdateCountCallback]`) implement `ConfiguresArgumentsWithMethod`, the discovery handing them the method as a callback. The `Pollora\Attributes` namespace no longer reaches Laravel or a framework service, which an architecture test keeps: the first step towards `pollora/attributes`, a package to declare attributes without the framework ### Changed - `DiscoveryEngine`, `DiscoveryCacheManager`, `InstancePool` and `ReflectionCache` take their dependencies instead of reaching for `app()` and `config()`; reading `structure-discoverer.cache` moved to `LaravelDiscoveryCacheManagerFactory`. `DiscoveryRegistrar::registerFromContainer()` is now `registerInto()`. These are infrastructure classes, outside the public contracts (`Pollora\Discovery\Domain\*`), which do not change - One `DiscoveryCacheManager` is shared by the engine and the `pollora:doctor` discovery cache check, which built its own - The discovery benchmarks measure memory as PHP allocates it, from a reset peak: they read 2 MB whatever the load +- `#[WpRestRoute\Method]` no longer registers its route: `WpRestRouteRegistrar`, in the WpRest module, does, with the same arguments, permissions and request injection. Default slugs, meta keys and command names come from `Pollora\Attributes\Support\Naming`, which gives the same results as `Str::kebab()` and `Str::snake()`; `Pollora\Support\Slug` uses it ### Deprecated - `DiscoveryCacheInterface` and `LaravelDiscoveryCache`, removed in 15.0: nothing reads this cache, scans are cached by the Spatie driver given to `DiscoveryCacheManager` +- `Pollora\Attributes\PostType\PostTypeAttribute` and `Pollora\Attributes\Taxonomy\TaxonomyAttribute`, removed in 15.0: no built-in attribute extends them any more; implement `ConfiguresArguments` + +### Removed +- `handle()` on `#[Action]`, `#[Filter]`, `#[WpRestRoute]` and `#[WpRestRoute\Method]`, and `Hook` no longer implements `HandlesAttributes`: `HookDiscovery` and `WpRestDiscovery` register hooks and routes themselves. Only the bug below reached `Action::handle()`, and `WpRestRoute::handle()` wrote to a read-only wrapper + +### Fixed +- A public `#[Action]` or `#[Filter]` method in a `#[PostType]` or `#[Taxonomy]` class is registered once: the post type and taxonomy discoveries also handed it to `Action::handle()`, which registered it a second time on the discovery's configuration object, so the page firing that hook failed with `call_user_func(): Argument #1 ($callback) must be a valid callback, class Pollora\PostType\Infrastructure\Services\PostTypeConfiguration does not have a method …` ## [v13.35.6](https://github.com/Pollora/framework/compare/v13.35.5...v13.35.6) - 2026-10-12 diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f75c76db..c13e879f 100755 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -18,24 +18,6 @@ parameters: count: 1 path: src/Asset/Infrastructure/Services/ViteManager.php - - - message: '#^Access to an undefined property Pollora\\Attributes\\Attributable\:\:\$classPermission\.$#' - identifier: property.notFound - count: 1 - path: src/Attributes/WpRestRoute/Method.php - - - - message: '#^Access to an undefined property Pollora\\Attributes\\Attributable\:\:\$namespace\.$#' - identifier: property.notFound - count: 1 - path: src/Attributes/WpRestRoute/Method.php - - - - message: '#^Access to an undefined property Pollora\\Attributes\\Attributable\:\:\$route\.$#' - identifier: property.notFound - count: 2 - path: src/Attributes/WpRestRoute/Method.php - - message: '#^Constant AUTH_COOKIE not found\.$#' identifier: constant.notFound diff --git a/src/Attributes/Ability.php b/src/Attributes/Ability.php index 5d8dcc35..1367df84 100644 --- a/src/Attributes/Ability.php +++ b/src/Attributes/Ability.php @@ -5,16 +5,13 @@ namespace Pollora\Attributes; use Attribute; -use Pollora\Abilities\Domain\Contracts\AbilityHandler; use Pollora\Abilities\Domain\Model\Behaviour; -use Pollora\Ability\Infrastructure\Services\AbilityDiscovery; /** * Attribute for declarative WordPress ability registration. * - * Place this attribute on a class implementing {@see AbilityHandler}. The class - * is discovered and registered with the WordPress Abilities API through the - * {@see AbilityDiscovery} system, and published to AI clients — an MCP server, + * Place this attribute on a class implementing `AbilityHandler` (pollora/abilities). + * The class is discovered and registered with the WordPress Abilities API, and published to AI clients — an MCP server, * the core abilities REST controllers — by whatever consumes them. * * The attribute carries what the ability *is*; the handler carries what it @@ -33,8 +30,7 @@ * The category must exist. Declare it once — in a service provider, through the * `Ability` facade — before the abilities that file under it. * - * @see AbilityHandler The interface the decorated class implements. - * @see Behaviour How the ability's effect on the site is described to clients. + * @see Behaviour How the ability's effect on the site is described to clients. */ #[Attribute(Attribute::TARGET_CLASS)] class Ability diff --git a/src/Attributes/Action.php b/src/Attributes/Action.php index fad73f62..39987ebc 100755 --- a/src/Attributes/Action.php +++ b/src/Attributes/Action.php @@ -5,12 +5,6 @@ namespace Pollora\Attributes; use Attribute; -use Pollora\Hook\Application\Services\AsyncDeclarationFailures; -use Pollora\Hook\Domain\Contract\Action as ActionService; -use Pollora\Hook\Infrastructure\Services\AsyncAttributeRegistrar; -use Psr\Log\LoggerInterface; -use ReflectionClass; -use ReflectionMethod; /** * Class Action @@ -19,62 +13,4 @@ * This class is used to define an action hook in WordPress. */ #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] -class Action extends Hook -{ - /** - * Handle the attribute processing. - * - * @param object $serviceLocator Service locator used to resolve dependencies - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The reflection context - * @param object $attribute The attribute instance - */ - public function handle( - $serviceLocator, - object $instance, - ReflectionMethod|ReflectionClass $context, - object $attribute, - ): void { - // Retrieve the Action service from the locator - $actionService = $serviceLocator->get(ActionService::class); - if (! $actionService) { - return; - } - - // #[Action] targets methods only - if (! $context instanceof ReflectionMethod) { - return; - } - - // Asynchronously when the method or its class carries #[Async] - $logger = $this->optional($serviceLocator, LoggerInterface::class); - $failures = $this->optional($serviceLocator, AsyncDeclarationFailures::class); - - (new AsyncAttributeRegistrar($actionService, $logger, $failures))->register( - $attribute->hook, - $instance, - $context, - $attribute->priority, - $context->getNumberOfParameters() - ); - } - - /** - * A service the service locator may not provide: the logger, the record of ignored #[Async]. - * - * @template T of object - * - * @param class-string $class - * @return T|null - */ - private function optional(object $serviceLocator, string $class): ?object - { - try { - $service = $serviceLocator->get($class); - } catch (\Throwable) { - return null; - } - - return $service instanceof $class ? $service : null; - } -} +class Action extends Hook {} diff --git a/src/Attributes/Ajax.php b/src/Attributes/Ajax.php index 5dd17909..d4880a3f 100644 --- a/src/Attributes/Ajax.php +++ b/src/Attributes/Ajax.php @@ -6,14 +6,12 @@ use Attribute; use Pollora\Ajax\Domain\Model\AjaxAccess; -use Pollora\Ajax\Infrastructure\Services\AjaxDiscovery; /** * Attribute for declarative WordPress AJAX action registration. * * Place this attribute on a public method to register it as a WordPress AJAX - * handler. The method is automatically discovered and wired via the - * {@see AjaxDiscovery} system. + * handler. The method is discovered and wired automatically. * * By default, the action is restricted to **logged-in users** (security-by-default). * Use the `access` parameter to change targeting. diff --git a/src/Attributes/Contracts/ConfiguresArguments.php b/src/Attributes/Contracts/ConfiguresArguments.php new file mode 100644 index 00000000..139c560f --- /dev/null +++ b/src/Attributes/Contracts/ConfiguresArguments.php @@ -0,0 +1,24 @@ + $arguments The arguments gathered so far + * @return array + */ + public function configureArguments(array $arguments): array; +} diff --git a/src/Attributes/Contracts/ConfiguresArgumentsWithMethod.php b/src/Attributes/Contracts/ConfiguresArgumentsWithMethod.php new file mode 100644 index 00000000..934c04ce --- /dev/null +++ b/src/Attributes/Contracts/ConfiguresArgumentsWithMethod.php @@ -0,0 +1,24 @@ + $arguments The arguments gathered so far + * @param callable $method The decorated method, bound to an instance of its class + * @return array + */ + public function configureArguments(array $arguments, callable $method): array; +} diff --git a/src/Attributes/Filter.php b/src/Attributes/Filter.php index 2722e8b0..9f33c92f 100755 --- a/src/Attributes/Filter.php +++ b/src/Attributes/Filter.php @@ -5,9 +5,6 @@ namespace Pollora\Attributes; use Attribute; -use Pollora\Hook\Domain\Contract\Filter as FilterService; -use ReflectionClass; -use ReflectionMethod; /** * Class Filter @@ -16,33 +13,4 @@ * This class is used to define a filter hook in WordPress. */ #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] -class Filter extends Hook -{ - /** - * Handle the attribute processing. - * - * @param object $serviceLocator Service locator used to resolve dependencies - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The reflection context - * @param object $attribute The attribute instance - */ - public function handle( - $serviceLocator, - object $instance, - ReflectionMethod|ReflectionClass $context, - object $attribute - ): void { - // Retrieve the Filter service from the locator - $filterService = $serviceLocator->get(FilterService::class); - if (! $filterService) { - return; - } - - $filterService->add( - $attribute->hook, - [$instance, $context->getName()], - $attribute->priority, - $context->getNumberOfParameters() - ); - } -} +class Filter extends Hook {} diff --git a/src/Attributes/Hook.php b/src/Attributes/Hook.php index 511667ec..7f550c0a 100755 --- a/src/Attributes/Hook.php +++ b/src/Attributes/Hook.php @@ -4,15 +4,13 @@ namespace Pollora\Attributes; -use Pollora\Attributes\Contracts\HandlesAttributes; - /** * Class Hook * * Abstract base class for WordPress hook attributes. * Provides common properties for hook attributes. */ -abstract class Hook implements HandlesAttributes +abstract class Hook { /** * Constructor for the Hook class. diff --git a/src/Attributes/Meta.php b/src/Attributes/Meta.php index e9262f8d..d0acaa7e 100644 --- a/src/Attributes/Meta.php +++ b/src/Attributes/Meta.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes; use Attribute; -use Illuminate\Support\Str; +use Pollora\Attributes\Support\Naming; use Pollora\Meta\Domain\Enums\Control; /** @@ -71,6 +71,6 @@ public function __construct( */ public function resolveKey(string $property): string { - return $this->key ?? Str::snake($property); + return $this->key ?? Naming::snake($property); } } diff --git a/src/Attributes/PostType.php b/src/Attributes/PostType.php index 80ba791f..94fac8ed 100644 --- a/src/Attributes/PostType.php +++ b/src/Attributes/PostType.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes; use Attribute; -use Illuminate\Support\Str; +use Pollora\Attributes\Support\Naming; /** * PostType Attribute @@ -51,6 +51,6 @@ public function __construct( */ public function resolveSlug(string $className): string { - return $this->slug ?? substr(Str::kebab(class_basename($className)), 0, 20); + return $this->slug ?? substr(Naming::kebab(Naming::classBasename($className)), 0, 20); } } diff --git a/src/Attributes/PostType/AdminCol.php b/src/Attributes/PostType/AdminCol.php index 645c882e..d5696bd3 100755 --- a/src/Attributes/PostType/AdminCol.php +++ b/src/Attributes/PostType/AdminCol.php @@ -5,10 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\Attributes\Contracts\HandlesAttributes; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; -use ReflectionClass; -use ReflectionMethod; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; /** * Attribute to define an admin column for a post type. @@ -19,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_METHOD)] -class AdminCol implements HandlesAttributes +class AdminCol implements ConfiguresArgumentsWithMethod { /** * Constructor. @@ -57,32 +54,20 @@ public function __construct( ) {} /** - * Handle the attribute processing. + * Add this column to the admin_cols argument, rendered by the decorated method. * - * @param object $container The container instance - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The method the attribute is applied to - * @param object $attribute The attribute instance + * @param array $arguments The registration arguments gathered so far + * @param callable $method The decorated method + * @return array */ - public function handle($container, object $instance, ReflectionMethod|ReflectionClass $context, object $attribute): void + public function configureArguments(array $arguments, callable $method): array { - if (! $instance instanceof PostTypeAttributeInterface) { - return; - } - - // Initialize admin_cols array if it doesn't exist - $adminCols = $instance->getArg('admin_cols', []); - // Build column configuration based on extended-cpts options $columnConfig = [ 'title' => $this->title, + 'function' => $method, ]; - // Add custom function callback if this is a method-level attribute - if ($context instanceof ReflectionMethod) { - $columnConfig['function'] = [new $context->class, $context->getName()]; - } - // Add optional configuration based on extended-cpts features if ($this->titleIcon !== null) { $columnConfig['title_icon'] = $this->titleIcon; @@ -133,8 +118,8 @@ public function handle($container, object $instance, ReflectionMethod|Reflection $columnConfig['sortable'] = $this->sortable; } - // Add the column to the admin_cols array - $adminCols[$this->key] = $columnConfig; - $instance->setArg('admin_cols', $adminCols); + $arguments['admin_cols'] = [...$arguments['admin_cols'] ?? [], $this->key => $columnConfig]; + + return $arguments; } } diff --git a/src/Attributes/PostType/AdminCols.php b/src/Attributes/PostType/AdminCols.php index ac92f1ba..2b43b9e2 100755 --- a/src/Attributes/PostType/AdminCols.php +++ b/src/Attributes/PostType/AdminCols.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the admin_cols parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class AdminCols extends PostTypeAttribute +class AdminCols implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the admin_cols parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('admin_cols', $this->value); + $arguments['admin_cols'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/AdminFilters.php b/src/Attributes/PostType/AdminFilters.php index 6c6de4d1..4fbf2818 100755 --- a/src/Attributes/PostType/AdminFilters.php +++ b/src/Attributes/PostType/AdminFilters.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the admin_filters parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class AdminFilters extends PostTypeAttribute +class AdminFilters implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the admin_filters parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('admin_filters', $this->value); + $arguments['admin_filters'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Archive.php b/src/Attributes/PostType/Archive.php index d65294de..3d081ac4 100755 --- a/src/Attributes/PostType/Archive.php +++ b/src/Attributes/PostType/Archive.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the archive parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Archive extends PostTypeAttribute +class Archive implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the archive parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('archive', $this->value); + $arguments['archive'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/BlockEditor.php b/src/Attributes/PostType/BlockEditor.php index 145fdf1b..cdfc9f2b 100755 --- a/src/Attributes/PostType/BlockEditor.php +++ b/src/Attributes/PostType/BlockEditor.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the block_editor parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class BlockEditor extends PostTypeAttribute +class BlockEditor implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the block_editor parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_in_rest', $this->value); + $arguments['show_in_rest'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/CanExport.php b/src/Attributes/PostType/CanExport.php index 73199a2c..7f1f5d76 100755 --- a/src/Attributes/PostType/CanExport.php +++ b/src/Attributes/PostType/CanExport.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the can_export parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class CanExport extends PostTypeAttribute +class CanExport implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the can_export parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('can_export', $this->value); + $arguments['can_export'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Capabilities.php b/src/Attributes/PostType/Capabilities.php index 7fc3e65d..b3459422 100755 --- a/src/Attributes/PostType/Capabilities.php +++ b/src/Attributes/PostType/Capabilities.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the capabilities parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Capabilities extends PostTypeAttribute +class Capabilities implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the capabilities parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('capabilities', $this->value); + $arguments['capabilities'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/CapabilityType.php b/src/Attributes/PostType/CapabilityType.php index 886630d6..e7196eca 100755 --- a/src/Attributes/PostType/CapabilityType.php +++ b/src/Attributes/PostType/CapabilityType.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the capability_type parameter for a post type. @@ -21,7 +21,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class CapabilityType extends PostTypeAttribute +class CapabilityType implements ConfiguresArguments { /** * Constructor. @@ -35,10 +35,13 @@ public function __construct( /** * Configure the post type with the capability_type parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('capability_type', $this->value); + $arguments['capability_type'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Chronological.php b/src/Attributes/PostType/Chronological.php index 10065f3b..728fe084 100755 --- a/src/Attributes/PostType/Chronological.php +++ b/src/Attributes/PostType/Chronological.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the chronological parameter for a post type. @@ -17,7 +17,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Chronological extends PostTypeAttribute +class Chronological implements ConfiguresArguments { /** * Constructor. @@ -31,14 +31,17 @@ public function __construct( /** * Configure the post type with the chronological parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { if ($this->value) { // Set default ordering to date, descending - $postType->setArg('orderby', 'date'); - $postType->setArg('order', 'DESC'); + $arguments['orderby'] = 'date'; + $arguments['order'] = 'DESC'; } + + return $arguments; } } diff --git a/src/Attributes/PostType/DashboardActivity.php b/src/Attributes/PostType/DashboardActivity.php index 97ae5c52..a808f98a 100755 --- a/src/Attributes/PostType/DashboardActivity.php +++ b/src/Attributes/PostType/DashboardActivity.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the dashboard_activity parameter for a post type. @@ -17,7 +17,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class DashboardActivity extends PostTypeAttribute +class DashboardActivity implements ConfiguresArguments { /** * Constructor. @@ -31,10 +31,13 @@ public function __construct( /** * Configure the post type with the dashboard_activity parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('dashboard_activity', $this->value); + $arguments['dashboard_activity'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/DashboardGlance.php b/src/Attributes/PostType/DashboardGlance.php index 99a0e08f..81df2cfa 100755 --- a/src/Attributes/PostType/DashboardGlance.php +++ b/src/Attributes/PostType/DashboardGlance.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the dashboard_glance parameter for a post type. @@ -15,7 +15,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class DashboardGlance extends PostTypeAttribute +class DashboardGlance implements ConfiguresArguments { /** * Constructor. @@ -29,10 +29,13 @@ public function __construct( /** * Configure the post type with the dashboard_glance parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('dashboard_glance', $this->value); + $arguments['dashboard_glance'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/DeleteWithUser.php b/src/Attributes/PostType/DeleteWithUser.php index b762aeed..2abeb23c 100755 --- a/src/Attributes/PostType/DeleteWithUser.php +++ b/src/Attributes/PostType/DeleteWithUser.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the delete_with_user parameter for a post type. @@ -17,7 +17,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class DeleteWithUser extends PostTypeAttribute +class DeleteWithUser implements ConfiguresArguments { /** * Constructor. @@ -31,10 +31,13 @@ public function __construct( /** * Configure the post type with the delete_with_user parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('delete_with_user', $this->value); + $arguments['delete_with_user'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Description.php b/src/Attributes/PostType/Description.php index 7ba770eb..6654747f 100755 --- a/src/Attributes/PostType/Description.php +++ b/src/Attributes/PostType/Description.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the description parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Description extends PostTypeAttribute +class Description implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the description parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('description', $this->value); + $arguments['description'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ExcludeFromSearch.php b/src/Attributes/PostType/ExcludeFromSearch.php index 69e75e60..a6cb5d53 100755 --- a/src/Attributes/PostType/ExcludeFromSearch.php +++ b/src/Attributes/PostType/ExcludeFromSearch.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the exclude_from_search parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ExcludeFromSearch extends PostTypeAttribute +class ExcludeFromSearch implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the exclude_from_search parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('exclude_from_search', $this->value); + $arguments['exclude_from_search'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/FeaturedImage.php b/src/Attributes/PostType/FeaturedImage.php index 8e8c8daa..d2af7006 100755 --- a/src/Attributes/PostType/FeaturedImage.php +++ b/src/Attributes/PostType/FeaturedImage.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the featured_image parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class FeaturedImage extends PostTypeAttribute +class FeaturedImage implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the featured_image parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('featured_image', $this->value); + $arguments['featured_image'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/HasArchive.php b/src/Attributes/PostType/HasArchive.php index cc2c7786..59befcda 100755 --- a/src/Attributes/PostType/HasArchive.php +++ b/src/Attributes/PostType/HasArchive.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the has_archive parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class HasArchive extends PostTypeAttribute +class HasArchive implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the has_archive parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('has_archive', $this->value); + $arguments['has_archive'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Hierarchical.php b/src/Attributes/PostType/Hierarchical.php index f7e2610e..b4e085b8 100755 --- a/src/Attributes/PostType/Hierarchical.php +++ b/src/Attributes/PostType/Hierarchical.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the hierarchical parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Hierarchical extends PostTypeAttribute +class Hierarchical implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the hierarchical parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('hierarchical', $this->value); + $arguments['hierarchical'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Label.php b/src/Attributes/PostType/Label.php index 33720b71..b9bbb22a 100755 --- a/src/Attributes/PostType/Label.php +++ b/src/Attributes/PostType/Label.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the label parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Label extends PostTypeAttribute +class Label implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the label parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('label', $this->value); + $arguments['label'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Labels.php b/src/Attributes/PostType/Labels.php index 026fd71b..0ac367ff 100755 --- a/src/Attributes/PostType/Labels.php +++ b/src/Attributes/PostType/Labels.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set custom labels for a post type. @@ -23,7 +23,7 @@ * For runtime translations, use withArgs() in the class instead. */ #[Attribute(Attribute::TARGET_CLASS)] -class Labels extends PostTypeAttribute +class Labels implements ConfiguresArguments { /** @var array */ private readonly array $labels; @@ -92,9 +92,11 @@ public function __construct( ], fn (?string $v): bool => $v !== null); } - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $existing = $postType->getArg('labels', []); - $postType->setArg('labels', array_merge($existing, $this->labels)); + $existing = ($arguments['labels'] ?? []); + $arguments['labels'] = array_merge($existing, $this->labels); + + return $arguments; } } diff --git a/src/Attributes/PostType/MapMetaCap.php b/src/Attributes/PostType/MapMetaCap.php index 1dea4737..04b1ff39 100755 --- a/src/Attributes/PostType/MapMetaCap.php +++ b/src/Attributes/PostType/MapMetaCap.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the map_meta_cap parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class MapMetaCap extends PostTypeAttribute +class MapMetaCap implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the map_meta_cap parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('map_meta_cap', $this->value); + $arguments['map_meta_cap'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/MenuIcon.php b/src/Attributes/PostType/MenuIcon.php index 7450e6ea..f2218cdc 100755 --- a/src/Attributes/PostType/MenuIcon.php +++ b/src/Attributes/PostType/MenuIcon.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the menu_icon parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class MenuIcon extends PostTypeAttribute +class MenuIcon implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the menu_icon parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('menu_icon', $this->value); + $arguments['menu_icon'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/MenuPosition.php b/src/Attributes/PostType/MenuPosition.php index 41cb7b1c..0952d950 100755 --- a/src/Attributes/PostType/MenuPosition.php +++ b/src/Attributes/PostType/MenuPosition.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the menu_position parameter for a post type. @@ -27,7 +27,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class MenuPosition extends PostTypeAttribute +class MenuPosition implements ConfiguresArguments { /** * Constructor. @@ -41,10 +41,13 @@ public function __construct( /** * Configure the post type with the menu_position parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('menu_position', $this->value); + $arguments['menu_position'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/PostTypeAttribute.php b/src/Attributes/PostType/PostTypeAttribute.php index 0ecb963f..ef612c31 100755 --- a/src/Attributes/PostType/PostTypeAttribute.php +++ b/src/Attributes/PostType/PostTypeAttribute.php @@ -5,6 +5,7 @@ namespace Pollora\Attributes\PostType; use Pollora\Attributes\Attributable; +use Pollora\Attributes\Contracts\ConfiguresArguments; use Pollora\Attributes\Contracts\HandlesAttributes; use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; use ReflectionClass; @@ -16,7 +17,9 @@ * This attribute serves as the base for all post type configuration attributes. * It provides common functionality for handling post type registration arguments. * - * @Attribute + * @deprecated since 13.36, removed in 15.0. Implement + * {@see ConfiguresArguments}, as the + * built-in attributes now do. */ abstract class PostTypeAttribute implements HandlesAttributes { diff --git a/src/Attributes/PostType/Priority.php b/src/Attributes/PostType/Priority.php index a1176bb5..f416ca56 100755 --- a/src/Attributes/PostType/Priority.php +++ b/src/Attributes/PostType/Priority.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the priority a post type declaration. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Priority extends PostTypeAttribute +class Priority implements ConfiguresArguments { /** * Constructor. @@ -25,10 +25,13 @@ public function __construct( /** * Configure the post type priority declaration parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('priority', $this->priority); + $arguments['priority'] = $this->priority; + + return $arguments; } } diff --git a/src/Attributes/PostType/PublicPostType.php b/src/Attributes/PostType/PublicPostType.php index fdcc04a6..53b905c4 100755 --- a/src/Attributes/PostType/PublicPostType.php +++ b/src/Attributes/PostType/PublicPostType.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the public parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class PublicPostType extends PostTypeAttribute +class PublicPostType implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the public parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('public', $this->value); + $arguments['public'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/PubliclyQueryable.php b/src/Attributes/PostType/PubliclyQueryable.php index 1957ecbe..42c5b3e5 100755 --- a/src/Attributes/PostType/PubliclyQueryable.php +++ b/src/Attributes/PostType/PubliclyQueryable.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the publicly_queryable parameter for a post type. @@ -15,7 +15,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class PubliclyQueryable extends PostTypeAttribute +class PubliclyQueryable implements ConfiguresArguments { /** * Constructor. @@ -29,10 +29,13 @@ public function __construct( /** * Configure the post type with the publicly_queryable parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('publicly_queryable', $this->value); + $arguments['publicly_queryable'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/QueryVar.php b/src/Attributes/PostType/QueryVar.php index d70da40e..54091c73 100755 --- a/src/Attributes/PostType/QueryVar.php +++ b/src/Attributes/PostType/QueryVar.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the query_var parameter for a post type. @@ -18,7 +18,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class QueryVar extends PostTypeAttribute +class QueryVar implements ConfiguresArguments { /** * Constructor. @@ -32,10 +32,13 @@ public function __construct( /** * Configure the post type with the query_var parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('query_var', $this->value); + $arguments['query_var'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/QuickEdit.php b/src/Attributes/PostType/QuickEdit.php index bbc2cc47..9a7cbe77 100755 --- a/src/Attributes/PostType/QuickEdit.php +++ b/src/Attributes/PostType/QuickEdit.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the quick_edit parameter for a post type. @@ -17,7 +17,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class QuickEdit extends PostTypeAttribute +class QuickEdit implements ConfiguresArguments { /** * Constructor. @@ -31,10 +31,13 @@ public function __construct( /** * Configure the post type with the quick_edit parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('quick_edit', $this->value); + $arguments['quick_edit'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/RegisterMetaBoxCb.php b/src/Attributes/PostType/RegisterMetaBoxCb.php index 40e66c41..8daff699 100755 --- a/src/Attributes/PostType/RegisterMetaBoxCb.php +++ b/src/Attributes/PostType/RegisterMetaBoxCb.php @@ -5,10 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\Attributes\Contracts\HandlesAttributes; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; -use ReflectionClass; -use ReflectionMethod; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; /** * Attribute to define a callback function that will be called when setting up meta boxes for the edit form. @@ -21,22 +18,19 @@ * @Attribute */ #[Attribute(Attribute::TARGET_METHOD)] -class RegisterMetaBoxCb implements HandlesAttributes +class RegisterMetaBoxCb implements ConfiguresArgumentsWithMethod { /** - * Handle the attribute processing. + * Set the register_meta_box_cb argument to the decorated method. * - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The method the attribute is applied to - * @param object $attribute The attribute instance + * @param array $arguments The registration arguments gathered so far + * @param callable $method The decorated method + * @return array */ - public function handle($container, object $instance, ReflectionMethod|ReflectionClass $context, object $attribute): void + public function configureArguments(array $arguments, callable $method): array { - if (! $instance instanceof PostTypeAttributeInterface) { - return; - } + $arguments['register_meta_box_cb'] = $method; - // Set the register_meta_box_cb parameter to the method - $instance->setArg('register_meta_box_cb', [new $context->class, $context->getName()]); + return $arguments; } } diff --git a/src/Attributes/PostType/RestBase.php b/src/Attributes/PostType/RestBase.php index 0dff0967..8ca0e7fd 100755 --- a/src/Attributes/PostType/RestBase.php +++ b/src/Attributes/PostType/RestBase.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the rest_base parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class RestBase extends PostTypeAttribute +class RestBase implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the rest_base parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('rest_base', $this->value); + $arguments['rest_base'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/RestControllerClass.php b/src/Attributes/PostType/RestControllerClass.php index ac8ba8a6..d3d9004c 100755 --- a/src/Attributes/PostType/RestControllerClass.php +++ b/src/Attributes/PostType/RestControllerClass.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the rest_controller_class parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class RestControllerClass extends PostTypeAttribute +class RestControllerClass implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the rest_controller_class parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('rest_controller_class', $this->value); + $arguments['rest_controller_class'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/RestNamespace.php b/src/Attributes/PostType/RestNamespace.php index 77244233..1eae5ba9 100755 --- a/src/Attributes/PostType/RestNamespace.php +++ b/src/Attributes/PostType/RestNamespace.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the rest_namespace parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class RestNamespace extends PostTypeAttribute +class RestNamespace implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the rest_namespace parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('rest_namespace', $this->value); + $arguments['rest_namespace'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Rewrite.php b/src/Attributes/PostType/Rewrite.php index 122e1c0d..1fa15cfb 100755 --- a/src/Attributes/PostType/Rewrite.php +++ b/src/Attributes/PostType/Rewrite.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the rewrite parameter for a post type. @@ -18,7 +18,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Rewrite extends PostTypeAttribute +class Rewrite implements ConfiguresArguments { /** * Constructor. @@ -32,10 +32,13 @@ public function __construct( /** * Configure the post type with the rewrite parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('rewrite', $this->value); + $arguments['rewrite'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ShowInAdminBar.php b/src/Attributes/PostType/ShowInAdminBar.php index 99cf0690..cdcf1aa8 100755 --- a/src/Attributes/PostType/ShowInAdminBar.php +++ b/src/Attributes/PostType/ShowInAdminBar.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_in_admin_bar parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInAdminBar extends PostTypeAttribute +class ShowInAdminBar implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the show_in_admin_bar parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_in_admin_bar', $this->value); + $arguments['show_in_admin_bar'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ShowInFeed.php b/src/Attributes/PostType/ShowInFeed.php index b7cc0ce0..129b9f2b 100755 --- a/src/Attributes/PostType/ShowInFeed.php +++ b/src/Attributes/PostType/ShowInFeed.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_in_feed parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInFeed extends PostTypeAttribute +class ShowInFeed implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the show_in_feed parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_in_feed', $this->value); + $arguments['show_in_feed'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ShowInMenu.php b/src/Attributes/PostType/ShowInMenu.php index fd2371fa..b9724ac2 100755 --- a/src/Attributes/PostType/ShowInMenu.php +++ b/src/Attributes/PostType/ShowInMenu.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_in_menu parameter for a post type. @@ -18,7 +18,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInMenu extends PostTypeAttribute +class ShowInMenu implements ConfiguresArguments { /** * Constructor. @@ -32,10 +32,13 @@ public function __construct( /** * Configure the post type with the show_in_menu parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_in_menu', $this->value); + $arguments['show_in_menu'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ShowInNavMenus.php b/src/Attributes/PostType/ShowInNavMenus.php index c42b0f97..6dd21be9 100755 --- a/src/Attributes/PostType/ShowInNavMenus.php +++ b/src/Attributes/PostType/ShowInNavMenus.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_in_nav_menus parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInNavMenus extends PostTypeAttribute +class ShowInNavMenus implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the show_in_nav_menus parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_in_nav_menus', $this->value); + $arguments['show_in_nav_menus'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ShowInRest.php b/src/Attributes/PostType/ShowInRest.php index 81527a44..f83f97f2 100755 --- a/src/Attributes/PostType/ShowInRest.php +++ b/src/Attributes/PostType/ShowInRest.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_in_rest parameter for a post type. @@ -17,7 +17,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInRest extends PostTypeAttribute +class ShowInRest implements ConfiguresArguments { /** * Constructor. @@ -31,10 +31,13 @@ public function __construct( /** * Configure the post type with the show_in_rest parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_in_rest', $this->value); + $arguments['show_in_rest'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/ShowUI.php b/src/Attributes/PostType/ShowUI.php index eda88522..74c8eb82 100755 --- a/src/Attributes/PostType/ShowUI.php +++ b/src/Attributes/PostType/ShowUI.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_ui parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowUI extends PostTypeAttribute +class ShowUI implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the show_ui parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('show_ui', $this->value); + $arguments['show_ui'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/SiteFilters.php b/src/Attributes/PostType/SiteFilters.php index cc7ff9ab..a8b52288 100755 --- a/src/Attributes/PostType/SiteFilters.php +++ b/src/Attributes/PostType/SiteFilters.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the site_filters parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class SiteFilters extends PostTypeAttribute +class SiteFilters implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the site_filters parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('site_filters', $this->value); + $arguments['site_filters'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/SiteSortables.php b/src/Attributes/PostType/SiteSortables.php index 0462fa75..772c99c3 100755 --- a/src/Attributes/PostType/SiteSortables.php +++ b/src/Attributes/PostType/SiteSortables.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the site_sortables parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class SiteSortables extends PostTypeAttribute +class SiteSortables implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the site_sortables parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('site_sortables', $this->value); + $arguments['site_sortables'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Supports.php b/src/Attributes/PostType/Supports.php index 5ed03d98..9fe01558 100755 --- a/src/Attributes/PostType/Supports.php +++ b/src/Attributes/PostType/Supports.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the supports parameter for a post type. @@ -15,7 +15,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Supports extends PostTypeAttribute +class Supports implements ConfiguresArguments { /** * Constructor. @@ -29,10 +29,13 @@ public function __construct( /** * Configure the post type with the supports parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('supports', $this->features); + $arguments['supports'] = $this->features; + + return $arguments; } } diff --git a/src/Attributes/PostType/Taxonomies.php b/src/Attributes/PostType/Taxonomies.php index ec1fe97a..a4908587 100755 --- a/src/Attributes/PostType/Taxonomies.php +++ b/src/Attributes/PostType/Taxonomies.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the taxonomies parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Taxonomies extends PostTypeAttribute +class Taxonomies implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the taxonomies parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('taxonomies', $this->value); + $arguments['taxonomies'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/Template.php b/src/Attributes/PostType/Template.php index a4582bb8..ac33e809 100755 --- a/src/Attributes/PostType/Template.php +++ b/src/Attributes/PostType/Template.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the template parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Template extends PostTypeAttribute +class Template implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the template parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('template', $this->value); + $arguments['template'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/TemplateLock.php b/src/Attributes/PostType/TemplateLock.php index a06cb614..442afb56 100755 --- a/src/Attributes/PostType/TemplateLock.php +++ b/src/Attributes/PostType/TemplateLock.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the template_lock parameter for a post type. @@ -18,7 +18,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class TemplateLock extends PostTypeAttribute +class TemplateLock implements ConfiguresArguments { /** * Constructor. @@ -32,10 +32,13 @@ public function __construct( /** * Configure the post type with the template_lock parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('template_lock', $this->value); + $arguments['template_lock'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/PostType/TitlePlaceholder.php b/src/Attributes/PostType/TitlePlaceholder.php index 26418f29..c3ccd2b0 100755 --- a/src/Attributes/PostType/TitlePlaceholder.php +++ b/src/Attributes/PostType/TitlePlaceholder.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\PostType; use Attribute; -use Pollora\PostType\Domain\Contracts\PostTypeAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the title_placeholder parameter for a post type. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class TitlePlaceholder extends PostTypeAttribute +class TitlePlaceholder implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the post type with the title_placeholder parameter. * - * @param PostTypeAttributeInterface $postType The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(PostTypeAttributeInterface $postType): void + public function configureArguments(array $arguments): array { - $postType->setArg('title_placeholder', $this->value); + $arguments['title_placeholder'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Support/Naming.php b/src/Attributes/Support/Naming.php new file mode 100644 index 00000000..0640640e --- /dev/null +++ b/src/Attributes/Support/Naming.php @@ -0,0 +1,73 @@ +slug ?? substr(Str::kebab(class_basename($className)), 0, 20); + return $this->slug ?? substr(Naming::kebab(Naming::classBasename($className)), 0, 20); } } diff --git a/src/Attributes/Taxonomy/AllowHierarchy.php b/src/Attributes/Taxonomy/AllowHierarchy.php index d9eff1ea..ebdee900 100755 --- a/src/Attributes/Taxonomy/AllowHierarchy.php +++ b/src/Attributes/Taxonomy/AllowHierarchy.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether to allow hierarchy in the taxonomy's rewrite rules. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class AllowHierarchy extends TaxonomyAttribute +class AllowHierarchy implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the taxonomy with the allow_hierarchy parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('allow_hierarchy', $this->value); + $arguments['allow_hierarchy'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Args.php b/src/Attributes/Taxonomy/Args.php index fc4889b2..90740947 100755 --- a/src/Attributes/Taxonomy/Args.php +++ b/src/Attributes/Taxonomy/Args.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set arguments to automatically use inside wp_get_object_terms() for this taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Args extends TaxonomyAttribute +class Args implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the args parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('args', $this->value); + $arguments['args'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Capabilities.php b/src/Attributes/Taxonomy/Capabilities.php index 36d87d9a..f7fea2ce 100644 --- a/src/Attributes/Taxonomy/Capabilities.php +++ b/src/Attributes/Taxonomy/Capabilities.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the capabilities parameter for a taxonomy. @@ -22,7 +22,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Capabilities extends TaxonomyAttribute +class Capabilities implements ConfiguresArguments { /** * Constructor. @@ -36,10 +36,13 @@ public function __construct( /** * Configure the taxonomy with the capabilities parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('capabilities', $this->value); + $arguments['capabilities'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/CheckedOntop.php b/src/Attributes/Taxonomy/CheckedOntop.php index bb8b092c..72cb1d68 100755 --- a/src/Attributes/Taxonomy/CheckedOntop.php +++ b/src/Attributes/Taxonomy/CheckedOntop.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether checked terms should appear on top. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class CheckedOntop extends TaxonomyAttribute +class CheckedOntop implements ConfiguresArguments { /** * Constructor. @@ -30,8 +30,10 @@ public function __construct( /** * Configure the taxonomy with the checked_ontop parameter. */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('checked_ontop', $this->value); + $arguments['checked_ontop'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/DefaultTerm.php b/src/Attributes/Taxonomy/DefaultTerm.php index a6fa0e3a..8e7d553e 100755 --- a/src/Attributes/Taxonomy/DefaultTerm.php +++ b/src/Attributes/Taxonomy/DefaultTerm.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the default term name for this taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class DefaultTerm extends TaxonomyAttribute +class DefaultTerm implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the default_term parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('default_term', $this->value); + $arguments['default_term'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Description.php b/src/Attributes/Taxonomy/Description.php index 6a9d91ca..bc613822 100755 --- a/src/Attributes/Taxonomy/Description.php +++ b/src/Attributes/Taxonomy/Description.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the description for a taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Description extends TaxonomyAttribute +class Description implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the description parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('description', $this->value); + $arguments['description'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Exclusive.php b/src/Attributes/Taxonomy/Exclusive.php index 5a14a75e..d34334f0 100755 --- a/src/Attributes/Taxonomy/Exclusive.php +++ b/src/Attributes/Taxonomy/Exclusive.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether the taxonomy should be exclusive. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Exclusive extends TaxonomyAttribute +class Exclusive implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the taxonomy with the exclusive parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('exclusive', $this->value); + $arguments['exclusive'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Hierarchical.php b/src/Attributes/Taxonomy/Hierarchical.php index 96b633e4..afea0792 100755 --- a/src/Attributes/Taxonomy/Hierarchical.php +++ b/src/Attributes/Taxonomy/Hierarchical.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether the taxonomy is hierarchical. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Hierarchical extends TaxonomyAttribute +class Hierarchical implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the hierarchical parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('hierarchical', $this->value); + $arguments['hierarchical'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Label.php b/src/Attributes/Taxonomy/Label.php index 18d11a03..5f8ec4c3 100755 --- a/src/Attributes/Taxonomy/Label.php +++ b/src/Attributes/Taxonomy/Label.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the singular label for a taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Label extends TaxonomyAttribute +class Label implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the label parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('label', $this->value); + $arguments['label'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Labels.php b/src/Attributes/Taxonomy/Labels.php index 0f9173dc..09efa745 100755 --- a/src/Attributes/Taxonomy/Labels.php +++ b/src/Attributes/Taxonomy/Labels.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set custom labels for a taxonomy. @@ -24,7 +24,7 @@ * evaluated at runtime (PHP attributes only accept constants). */ #[Attribute(Attribute::TARGET_CLASS)] -class Labels extends TaxonomyAttribute +class Labels implements ConfiguresArguments { /** @var array */ private readonly array $labels; @@ -79,9 +79,11 @@ public function __construct( ], fn (?string $v): bool => $v !== null); } - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $existing = $taxonomy->getArg('labels', []); - $taxonomy->setArg('labels', array_merge($existing, $this->labels)); + $existing = ($arguments['labels'] ?? []); + $arguments['labels'] = array_merge($existing, $this->labels); + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/MetaBoxCb.php b/src/Attributes/Taxonomy/MetaBoxCb.php index 5eb310bd..6fe8045c 100755 --- a/src/Attributes/Taxonomy/MetaBoxCb.php +++ b/src/Attributes/Taxonomy/MetaBoxCb.php @@ -5,10 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Attributes\Contracts\HandlesAttributes; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; -use ReflectionClass; -use ReflectionMethod; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; /** * Attribute to define a callback function for the meta box display. @@ -19,22 +16,19 @@ * @Attribute */ #[Attribute(Attribute::TARGET_METHOD)] -class MetaBoxCb implements HandlesAttributes +class MetaBoxCb implements ConfiguresArgumentsWithMethod { /** - * Handle the attribute processing. + * Set the meta_box_cb argument to the decorated method. * - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The method the attribute is applied to - * @param object $attribute The attribute instance + * @param array $arguments The registration arguments gathered so far + * @param callable $method The decorated method + * @return array */ - public function handle($container, object $instance, ReflectionMethod|ReflectionClass $context, object $attribute): void + public function configureArguments(array $arguments, callable $method): array { - if (! $instance instanceof TaxonomyAttributeInterface) { - return; - } + $arguments['meta_box_cb'] = $method; - // Set the meta_box_cb parameter to the method - $instance->setArg('meta_box_cb', [new $context->class, $context->getName()]); + return $arguments; } } diff --git a/src/Attributes/Taxonomy/MetaBoxSanitizeCb.php b/src/Attributes/Taxonomy/MetaBoxSanitizeCb.php index e24dcdcf..994a2fc8 100755 --- a/src/Attributes/Taxonomy/MetaBoxSanitizeCb.php +++ b/src/Attributes/Taxonomy/MetaBoxSanitizeCb.php @@ -5,10 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Attributes\Contracts\HandlesAttributes; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; -use ReflectionClass; -use ReflectionMethod; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; /** * Attribute to define a callback function for sanitizing taxonomy data saved from a meta box. @@ -19,22 +16,19 @@ * @Attribute */ #[Attribute(Attribute::TARGET_METHOD)] -class MetaBoxSanitizeCb implements HandlesAttributes +class MetaBoxSanitizeCb implements ConfiguresArgumentsWithMethod { /** - * Handle the attribute processing. + * Set the meta_box_sanitize_cb argument to the decorated method. * - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The method the attribute is applied to - * @param object $attribute The attribute instance + * @param array $arguments The registration arguments gathered so far + * @param callable $method The decorated method + * @return array */ - public function handle($container, object $instance, ReflectionMethod|ReflectionClass $context, object $attribute): void + public function configureArguments(array $arguments, callable $method): array { - if (! $instance instanceof TaxonomyAttributeInterface) { - return; - } + $arguments['meta_box_sanitize_cb'] = $method; - // Set the meta_box_sanitize_cb parameter to the method - $instance->setArg('meta_box_sanitize_cb', [new $context->class, $context->getName()]); + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ObjectType.php b/src/Attributes/Taxonomy/ObjectType.php index c39a90e9..7c39b7f3 100755 --- a/src/Attributes/Taxonomy/ObjectType.php +++ b/src/Attributes/Taxonomy/ObjectType.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the post types this taxonomy is associated with. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ObjectType extends TaxonomyAttribute +class ObjectType implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the object_type parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('object_type', $this->value); + $arguments['object_type'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Priority.php b/src/Attributes/Taxonomy/Priority.php index fc9e3d44..7a37cbc4 100755 --- a/src/Attributes/Taxonomy/Priority.php +++ b/src/Attributes/Taxonomy/Priority.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the priority a post type declaration. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Priority extends TaxonomyAttribute +class Priority implements ConfiguresArguments { /** * Constructor. @@ -25,10 +25,13 @@ public function __construct( /** * Configure the post type priority declaration parameter. * - * @param TaxonomyAttributeInterface $taxonomy The post type to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('priority', $this->priority); + $arguments['priority'] = $this->priority; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/PublicTaxonomy.php b/src/Attributes/Taxonomy/PublicTaxonomy.php index b8205a15..29da08b8 100755 --- a/src/Attributes/Taxonomy/PublicTaxonomy.php +++ b/src/Attributes/Taxonomy/PublicTaxonomy.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the public parameter for a taxonomy. @@ -16,7 +16,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class PublicTaxonomy extends TaxonomyAttribute +class PublicTaxonomy implements ConfiguresArguments { /** * Constructor. @@ -30,10 +30,13 @@ public function __construct( /** * Configure the taxonomy with the public parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('public', $this->value); + $arguments['public'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/QueryVar.php b/src/Attributes/Taxonomy/QueryVar.php index 61e3a168..4fbd686f 100755 --- a/src/Attributes/Taxonomy/QueryVar.php +++ b/src/Attributes/Taxonomy/QueryVar.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the query_var key for this taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class QueryVar extends TaxonomyAttribute +class QueryVar implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the query_var parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('query_var', $this->value); + $arguments['query_var'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/RestBase.php b/src/Attributes/Taxonomy/RestBase.php index 9eb7c2ab..b7548aed 100755 --- a/src/Attributes/Taxonomy/RestBase.php +++ b/src/Attributes/Taxonomy/RestBase.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the base URL segment that will be used in REST API endpoints for this taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class RestBase extends TaxonomyAttribute +class RestBase implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the rest_base parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('rest_base', $this->value); + $arguments['rest_base'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/RestControllerClass.php b/src/Attributes/Taxonomy/RestControllerClass.php index e54a48c7..fcc5aaa4 100755 --- a/src/Attributes/Taxonomy/RestControllerClass.php +++ b/src/Attributes/Taxonomy/RestControllerClass.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the controller class that should be used for handling REST API requests for this taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class RestControllerClass extends TaxonomyAttribute +class RestControllerClass implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the rest_controller_class parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('rest_controller_class', $this->value); + $arguments['rest_controller_class'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/RestNamespace.php b/src/Attributes/Taxonomy/RestNamespace.php index c2a28acd..9bf20d6e 100755 --- a/src/Attributes/Taxonomy/RestNamespace.php +++ b/src/Attributes/Taxonomy/RestNamespace.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the REST API namespace for the taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class RestNamespace extends TaxonomyAttribute +class RestNamespace implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the rest_namespace parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('rest_namespace', $this->value); + $arguments['rest_namespace'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Rewrite.php b/src/Attributes/Taxonomy/Rewrite.php index ebd639d1..687946d7 100755 --- a/src/Attributes/Taxonomy/Rewrite.php +++ b/src/Attributes/Taxonomy/Rewrite.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the rewrite rules for the taxonomy. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Rewrite extends TaxonomyAttribute +class Rewrite implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the rewrite parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('rewrite', $this->value); + $arguments['rewrite'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowAdminColumn.php b/src/Attributes/Taxonomy/ShowAdminColumn.php index eef42295..b5521ef6 100755 --- a/src/Attributes/Taxonomy/ShowAdminColumn.php +++ b/src/Attributes/Taxonomy/ShowAdminColumn.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether to display a column for the taxonomy on its post type listing screens. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowAdminColumn extends TaxonomyAttribute +class ShowAdminColumn implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the show_admin_column parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_admin_column', $this->value); + $arguments['show_admin_column'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowInMenu.php b/src/Attributes/Taxonomy/ShowInMenu.php index 249546f6..6e40e179 100755 --- a/src/Attributes/Taxonomy/ShowInMenu.php +++ b/src/Attributes/Taxonomy/ShowInMenu.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set the show_in_menu parameter for a taxonomy. @@ -18,7 +18,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInMenu extends TaxonomyAttribute +class ShowInMenu implements ConfiguresArguments { /** * Constructor. @@ -32,10 +32,13 @@ public function __construct( /** * Configure the taxonomy with the show_in_menu parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_in_menu', $this->value); + $arguments['show_in_menu'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowInNavMenus.php b/src/Attributes/Taxonomy/ShowInNavMenus.php index 9bf014cc..e9a1a1ec 100755 --- a/src/Attributes/Taxonomy/ShowInNavMenus.php +++ b/src/Attributes/Taxonomy/ShowInNavMenus.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether this taxonomy is available for selection in navigation menus. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInNavMenus extends TaxonomyAttribute +class ShowInNavMenus implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the show_in_nav_menus parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_in_nav_menus', $this->value); + $arguments['show_in_nav_menus'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowInQuickEdit.php b/src/Attributes/Taxonomy/ShowInQuickEdit.php index 8105d502..49e29153 100755 --- a/src/Attributes/Taxonomy/ShowInQuickEdit.php +++ b/src/Attributes/Taxonomy/ShowInQuickEdit.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether to show the taxonomy in the quick/bulk edit panel. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInQuickEdit extends TaxonomyAttribute +class ShowInQuickEdit implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the show_in_quick_edit parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_in_quick_edit', $this->value); + $arguments['show_in_quick_edit'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowInRest.php b/src/Attributes/Taxonomy/ShowInRest.php index ed6fe08d..0cbaf204 100755 --- a/src/Attributes/Taxonomy/ShowInRest.php +++ b/src/Attributes/Taxonomy/ShowInRest.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether this taxonomy should appear in the REST API. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowInRest extends TaxonomyAttribute +class ShowInRest implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the show_in_rest parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_in_rest', $this->value); + $arguments['show_in_rest'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowTagcloud.php b/src/Attributes/Taxonomy/ShowTagcloud.php index 603d7d5a..c915f2a1 100755 --- a/src/Attributes/Taxonomy/ShowTagcloud.php +++ b/src/Attributes/Taxonomy/ShowTagcloud.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether to show the taxonomy in the tag cloud widget. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowTagcloud extends TaxonomyAttribute +class ShowTagcloud implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the show_tagcloud parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_tagcloud', $this->value); + $arguments['show_tagcloud'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/ShowUI.php b/src/Attributes/Taxonomy/ShowUI.php index 6c0e346d..908e13a1 100755 --- a/src/Attributes/Taxonomy/ShowUI.php +++ b/src/Attributes/Taxonomy/ShowUI.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether to generate a default UI for managing this taxonomy in the admin. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class ShowUI extends TaxonomyAttribute +class ShowUI implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the show_ui parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('show_ui', $this->value); + $arguments['show_ui'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/Sort.php b/src/Attributes/Taxonomy/Sort.php index f9902ada..bc65b152 100755 --- a/src/Attributes/Taxonomy/Sort.php +++ b/src/Attributes/Taxonomy/Sort.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; +use Pollora\Attributes\Contracts\ConfiguresArguments; /** * Attribute to set whether terms in this taxonomy should be sorted in the order they are provided. @@ -13,7 +13,7 @@ * @Attribute */ #[Attribute(Attribute::TARGET_CLASS)] -class Sort extends TaxonomyAttribute +class Sort implements ConfiguresArguments { /** * Constructor. @@ -27,10 +27,13 @@ public function __construct( /** * Configure the taxonomy with the sort parameter. * - * @param TaxonomyAttributeInterface $taxonomy The taxonomy to configure + * @param array $arguments The registration arguments gathered so far + * @return array */ - protected function configure(TaxonomyAttributeInterface $taxonomy): void + public function configureArguments(array $arguments): array { - $taxonomy->setArg('sort', $this->value); + $arguments['sort'] = $this->value; + + return $arguments; } } diff --git a/src/Attributes/Taxonomy/TaxonomyAttribute.php b/src/Attributes/Taxonomy/TaxonomyAttribute.php index 292210a3..9ca188dc 100755 --- a/src/Attributes/Taxonomy/TaxonomyAttribute.php +++ b/src/Attributes/Taxonomy/TaxonomyAttribute.php @@ -5,6 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Pollora\Attributes\Attributable; +use Pollora\Attributes\Contracts\ConfiguresArguments; use Pollora\Attributes\Contracts\HandlesAttributes; use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; use ReflectionClass; @@ -16,7 +17,9 @@ * This attribute serves as the base for all taxonomy configuration attributes. * It provides common functionality for handling taxonomy registration arguments. * - * @Attribute + * @deprecated since 13.36, removed in 15.0. Implement + * {@see ConfiguresArguments}, as the + * built-in attributes now do. */ abstract class TaxonomyAttribute implements HandlesAttributes { diff --git a/src/Attributes/Taxonomy/UpdateCountCallback.php b/src/Attributes/Taxonomy/UpdateCountCallback.php index 218a2465..b289db34 100755 --- a/src/Attributes/Taxonomy/UpdateCountCallback.php +++ b/src/Attributes/Taxonomy/UpdateCountCallback.php @@ -5,10 +5,7 @@ namespace Pollora\Attributes\Taxonomy; use Attribute; -use Pollora\Attributes\Contracts\HandlesAttributes; -use Pollora\Taxonomy\Domain\Contracts\TaxonomyAttributeInterface; -use ReflectionClass; -use ReflectionMethod; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; /** * Attribute to define a callback function that will be called when the count is updated. @@ -19,22 +16,19 @@ * @Attribute */ #[Attribute(Attribute::TARGET_METHOD)] -class UpdateCountCallback implements HandlesAttributes +class UpdateCountCallback implements ConfiguresArgumentsWithMethod { /** - * Handle the attribute processing. + * Set the update_count_callback argument to the decorated method. * - * @param object $instance The instance being processed - * @param ReflectionMethod|ReflectionClass $context The method the attribute is applied to - * @param object $attribute The attribute instance + * @param array $arguments The registration arguments gathered so far + * @param callable $method The decorated method + * @return array */ - public function handle($container, object $instance, ReflectionMethod|ReflectionClass $context, object $attribute): void + public function configureArguments(array $arguments, callable $method): array { - if (! $instance instanceof TaxonomyAttributeInterface) { - return; - } + $arguments['update_count_callback'] = $method; - // Set the update_count_callback parameter to the method - $instance->setArg('update_count_callback', [new $context->class, $context->getName()]); + return $arguments; } } diff --git a/src/Attributes/WpCli.php b/src/Attributes/WpCli.php index 7248b637..df7ff388 100644 --- a/src/Attributes/WpCli.php +++ b/src/Attributes/WpCli.php @@ -4,7 +4,7 @@ namespace Pollora\Attributes; -use Pollora\Support\Slug; +use Pollora\Attributes\Support\Naming; /** * Attribute to mark a class as a WordPress CLI command. @@ -39,6 +39,6 @@ public function __construct( */ public function getCommandName(string $className): string { - return $this->commandName ?? Slug::fromClassName($className); + return $this->commandName ?? Naming::commandFromClassName($className); } } diff --git a/src/Attributes/WpCli/Command.php b/src/Attributes/WpCli/Command.php index f6b02382..6e485bfd 100644 --- a/src/Attributes/WpCli/Command.php +++ b/src/Attributes/WpCli/Command.php @@ -5,7 +5,7 @@ namespace Pollora\Attributes\WpCli; use Attribute; -use Pollora\Support\Slug; +use Pollora\Attributes\Support\Naming; /** * WP CLI Command Attribute for Method-Level Subcommands @@ -42,6 +42,6 @@ public function __construct( */ public function getSubcommandName(string $methodName): string { - return $this->commandName ?? Slug::fromMethodName($methodName); + return $this->commandName ?? Naming::slug($methodName); } } diff --git a/src/Attributes/WpRestRoute.php b/src/Attributes/WpRestRoute.php index d3836ceb..2f40377e 100755 --- a/src/Attributes/WpRestRoute.php +++ b/src/Attributes/WpRestRoute.php @@ -5,16 +5,13 @@ namespace Pollora\Attributes; use Attribute; -use Pollora\Attributes\Contracts\HandlesAttributes; use Pollora\Attributes\WpRestRoute\Permission; -use ReflectionClass; -use ReflectionMethod; /** * Attribute for defining WordPress REST API routes. */ #[Attribute(Attribute::TARGET_CLASS)] -class WpRestRoute implements HandlesAttributes +class WpRestRoute { /** * Constructor for WpRestRoute attribute. @@ -28,19 +25,4 @@ public function __construct( public readonly string $route, public readonly string|Permission|null $permissionCallback = null ) {} - - /** - * Handle the attribute processing. - * - * @param object $serviceLocator Service locator used to resolve dependencies - * @param object $instance The instance to which the attribute applies - * @param ReflectionClass|ReflectionMethod $context The reflection context. - * @param object $attribute The attribute instance containing provided arguments. - */ - public function handle($serviceLocator, object $instance, ReflectionClass|ReflectionMethod $context, object $attribute): void - { - $instance->namespace = $attribute->namespace; - $instance->route = $attribute->route; - $instance->classPermission = $attribute->permissionCallback; - } } diff --git a/src/Attributes/WpRestRoute/Method.php b/src/Attributes/WpRestRoute/Method.php index a43417bb..53d4a066 100755 --- a/src/Attributes/WpRestRoute/Method.php +++ b/src/Attributes/WpRestRoute/Method.php @@ -6,16 +6,9 @@ use Attribute; use InvalidArgumentException; -use Pollora\Attributes\Attributable; -use Pollora\Attributes\Contracts\HandlesAttributes; -use Pollora\Support\WpGlobals; -use ReflectionClass; -use ReflectionMethod; -use WP_Error; -use WP_REST_Request; #[Attribute(Attribute::TARGET_METHOD | Attribute::IS_REPEATABLE)] -class Method implements HandlesAttributes +class Method { private const array ALLOWED_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']; @@ -64,120 +57,4 @@ public function getMethods(): array { return $this->methods; } - - /** - * Handles the registration of the REST route for the method. - * - * @param object $serviceLocator Service locator used to resolve dependencies - * @param Attributable $instance The class instance - * @param ReflectionMethod|ReflectionClass $context The reflection context - * @param object $attribute The attribute instance - */ - public function handle($serviceLocator, Attributable $instance, ReflectionMethod|ReflectionClass $context, object $attribute): void - { - $methodPermission = $attribute->permissionCallback; - $permissionCallback = $methodPermission ?? $instance->classPermission; - - register_rest_route( - $instance->namespace, - $instance->route, - [ - 'methods' => $attribute->getMethods(), - 'callback' => WpGlobals::wrap( - fn (WP_REST_Request $request): mixed => $this->handleRequest($instance, $context, $request) - ), - 'args' => $this->extractArgsFromRoute($instance->route), - 'permission_callback' => $this->resolvePermissionCallback($permissionCallback), - ] - ); - } - - /** - * Executes the class method associated with the REST request. - * - * @param Attributable $instance The class instance - * @param ReflectionMethod $method The method to invoke - * @param WP_REST_Request $request The REST request instance - * @return mixed The result of the method invocation - */ - private function handleRequest(Attributable $instance, ReflectionMethod $method, WP_REST_Request $request): mixed - { - $args = []; - - foreach ($method->getParameters() as $param) { - // A WP_REST_Request type hint gets the request itself. Looking its - // name up among the route parameters found nothing — no route - // declares one called "request" — so the handler was invoked with - // null and a controller declaring the type fataled before running. - if ($this->expectsTheRequest($param)) { - $args[] = $request; - - continue; - } - - $args[] = $request->get_param($param->getName()); - } - - // Get the real instance if available, otherwise use the provided instance - $realInstance = method_exists($instance, 'getRealInstance') ? $instance->getRealInstance() : $instance; - - return $method->invoke($realInstance, ...$args); - } - - /** - * Whether a parameter asks for the request object rather than a route value. - */ - private function expectsTheRequest(\ReflectionParameter $param): bool - { - $type = $param->getType(); - - if (! $type instanceof \ReflectionNamedType || $type->isBuiltin()) { - return false; - } - - $name = $type->getName(); - - // The name comparison stands on its own: ::class resolves whether or - // not WordPress is loaded, so this holds outside a WordPress runtime. - return $name === WP_REST_Request::class - || is_a($name, WP_REST_Request::class, true); - } - - /** - * Extracts dynamic arguments from a WordPress route. - * - * @param string $route The route pattern - * @return array The extracted arguments - */ - private function extractArgsFromRoute(string $route): array - { - preg_match_all('/\(\?P<(\w+)>/', $route, $matches); - - return array_fill_keys($matches[1], [ - 'validate_callback' => fn ($param): bool => is_string($param) || is_numeric($param), - ]); - } - - /** - * Resolves and executes the permission callback. - * - * @param class-string|Permission|null $permissionCallback The permission class or instance to use - * @return callable The permission function - */ - private function resolvePermissionCallback(string|Permission|null $permissionCallback): callable - { - if ($permissionCallback === null) { - return '__return_true'; - } - - if (is_string($permissionCallback) && (! class_exists($permissionCallback) || ! is_subclass_of($permissionCallback, Permission::class))) { - return fn (): WP_Error => new WP_Error('rest_forbidden', __('Invalid permission handler.'), ['status' => 403]); - } - - return WpGlobals::wrap(function (WP_REST_Request $request) use ($permissionCallback): bool|WP_Error { - $permissionInstance = is_string($permissionCallback) ? new $permissionCallback : $permissionCallback; - - return $permissionInstance->allow($request); - }); - } } diff --git a/src/PostType/Infrastructure/Services/PostTypeConfiguration.php b/src/PostType/Infrastructure/Services/PostTypeConfiguration.php index 27ddefd8..3b7e2f15 100644 --- a/src/PostType/Infrastructure/Services/PostTypeConfiguration.php +++ b/src/PostType/Infrastructure/Services/PostTypeConfiguration.php @@ -79,6 +79,16 @@ public function getArg(string $key, mixed $default = null): mixed return $this->attributeArgs[$key] ?? $default; } + /** + * Replace every attribute argument. + * + * @param array $args The arguments to keep + */ + public function replaceArgs(array $args): void + { + $this->attributeArgs = $args; + } + /** * Merge additional arguments into the configuration. * diff --git a/src/PostType/Infrastructure/Services/PostTypeDiscovery.php b/src/PostType/Infrastructure/Services/PostTypeDiscovery.php index 0095dd91..de149d40 100644 --- a/src/PostType/Infrastructure/Services/PostTypeDiscovery.php +++ b/src/PostType/Infrastructure/Services/PostTypeDiscovery.php @@ -5,6 +5,9 @@ namespace Pollora\PostType\Infrastructure\Services; use Illuminate\Support\Str; +use Pollora\Attributes\Contracts\ConfiguresArguments; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; +use Pollora\Attributes\Contracts\HandlesAttributes; use Pollora\Attributes\PostType; use Pollora\Discovery\Domain\Contracts\ConfigurableDiscoveryInterface; use Pollora\Discovery\Domain\Contracts\DiscoveryInterface; @@ -302,8 +305,13 @@ private function processClassAttribute(ReflectionClass $reflectionClass, \Reflec { $attributeInstance = $attribute->newInstance(); - // Check if the attribute has a handle method and call it - if (method_exists($attributeInstance, 'handle')) { + if ($attributeInstance instanceof ConfiguresArguments) { + $config->replaceArgs($attributeInstance->configureArguments($config->withArgs())); + + return; + } + + if ($attributeInstance instanceof HandlesAttributes) { $attributeInstance->handle(app(), $config, $reflectionClass, $attributeInstance); } } @@ -325,8 +333,13 @@ private function processMethodAttribute( ): void { $attributeInstance = $attribute->newInstance(); - // Check if the attribute has a handle method and call it - if (method_exists($attributeInstance, 'handle')) { + if ($attributeInstance instanceof ConfiguresArgumentsWithMethod) { + $config->replaceArgs($attributeInstance->configureArguments($config->withArgs(), [new $method->class, $method->getName()])); + + return; + } + + if ($attributeInstance instanceof HandlesAttributes) { $attributeInstance->handle(app(), $config, $method, $attributeInstance); } } diff --git a/src/Support/Slug.php b/src/Support/Slug.php index 7d0ae61a..94a1c9a9 100644 --- a/src/Support/Slug.php +++ b/src/Support/Slug.php @@ -4,6 +4,8 @@ namespace Pollora\Support; +use Pollora\Attributes\Support\Naming; + /** * Utility class for slug generation. * @@ -25,15 +27,7 @@ class Slug */ public static function fromClassName(string $className): string { - // Extract the base class name (remove namespace) - $baseName = basename(str_replace('\\', '/', $className)); - - // Remove "Command" suffix if present - if (self::endsWith($baseName, 'Command')) { - $baseName = substr($baseName, 0, -7); - } - - return self::toKebabCase($baseName); + return Naming::commandFromClassName($className); } /** @@ -50,7 +44,7 @@ public static function fromClassName(string $className): string */ public static function fromMethodName(string $methodName): string { - return self::toKebabCase($methodName); + return Naming::slug($methodName); } /** @@ -61,35 +55,6 @@ public static function fromMethodName(string $methodName): string */ public static function toKebabCase(string $string): string { - // Insert a hyphen before any uppercase letter that follows a lowercase letter or number - $string = preg_replace('/([a-z0-9])([A-Z])/', '$1-$2', $string); - - // Convert to lowercase - $string = strtolower((string) $string); - - // Replace multiple consecutive hyphens with a single hyphen - $string = preg_replace('/-+/', '-', $string); - - // Trim hyphens from the beginning and end - $string = trim((string) $string, '-'); - - return $string; - } - - /** - * Check if a string ends with a specific suffix. - * - * @param string $haystack The string to check - * @param string $needle The suffix to look for - * @return bool True if the string ends with the suffix - */ - private static function endsWith(string $haystack, string $needle): bool - { - $length = strlen($needle); - if ($length === 0) { - return true; - } - - return substr($haystack, -$length) === $needle; + return Naming::slug($string); } } diff --git a/src/Taxonomy/Infrastructure/Services/TaxonomyConfiguration.php b/src/Taxonomy/Infrastructure/Services/TaxonomyConfiguration.php index c6acae9b..0a289bc8 100644 --- a/src/Taxonomy/Infrastructure/Services/TaxonomyConfiguration.php +++ b/src/Taxonomy/Infrastructure/Services/TaxonomyConfiguration.php @@ -96,6 +96,16 @@ public function getArg(string $key, mixed $default = null): mixed return $this->attributeArgs[$key] ?? $default; } + /** + * Replace every attribute argument. + * + * @param array $args The arguments to keep + */ + public function replaceArgs(array $args): void + { + $this->attributeArgs = $args; + } + /** * Merge additional arguments into the configuration. * diff --git a/src/Taxonomy/Infrastructure/Services/TaxonomyDiscovery.php b/src/Taxonomy/Infrastructure/Services/TaxonomyDiscovery.php index 2cb6ca82..c5f4880e 100644 --- a/src/Taxonomy/Infrastructure/Services/TaxonomyDiscovery.php +++ b/src/Taxonomy/Infrastructure/Services/TaxonomyDiscovery.php @@ -5,6 +5,9 @@ namespace Pollora\Taxonomy\Infrastructure\Services; use Illuminate\Support\Str; +use Pollora\Attributes\Contracts\ConfiguresArguments; +use Pollora\Attributes\Contracts\ConfiguresArgumentsWithMethod; +use Pollora\Attributes\Contracts\HandlesAttributes; use Pollora\Attributes\Taxonomy; use Pollora\Discovery\Domain\Contracts\ConfigurableDiscoveryInterface; use Pollora\Discovery\Domain\Contracts\DiscoveryInterface; @@ -307,8 +310,13 @@ private function processClassAttribute(ReflectionClass $reflectionClass, \Reflec { $attributeInstance = $attribute->newInstance(); - // Check if the attribute has a handle method and call it - if (method_exists($attributeInstance, 'handle')) { + if ($attributeInstance instanceof ConfiguresArguments) { + $config->replaceArgs($attributeInstance->configureArguments($config->withArgs())); + + return; + } + + if ($attributeInstance instanceof HandlesAttributes) { $attributeInstance->handle(app(), $config, $reflectionClass, $attributeInstance); } } @@ -330,8 +338,13 @@ private function processMethodAttribute( ): void { $attributeInstance = $attribute->newInstance(); - // Check if the attribute has a handle method and call it - if (method_exists($attributeInstance, 'handle')) { + if ($attributeInstance instanceof ConfiguresArgumentsWithMethod) { + $config->replaceArgs($attributeInstance->configureArguments($config->withArgs(), [new $method->class, $method->getName()])); + + return; + } + + if ($attributeInstance instanceof HandlesAttributes) { $attributeInstance->handle(app(), $config, $method, $attributeInstance); } } diff --git a/src/WpRest/Infrastructure/Services/WpRestDiscovery.php b/src/WpRest/Infrastructure/Services/WpRestDiscovery.php index 62e89c78..f8781370 100644 --- a/src/WpRest/Infrastructure/Services/WpRestDiscovery.php +++ b/src/WpRest/Infrastructure/Services/WpRestDiscovery.php @@ -4,7 +4,9 @@ namespace Pollora\WpRest\Infrastructure\Services; +use Pollora\Attributes\Contracts\HandlesAttributes; use Pollora\Attributes\WpRestRoute; +use Pollora\Attributes\WpRestRoute\Method; use Pollora\Discovery\Domain\Contracts\DiscoveryInterface; use Pollora\Discovery\Domain\Contracts\DiscoveryLocationInterface; use Pollora\Discovery\Domain\Contracts\ReflectionCacheInterface; @@ -33,7 +35,8 @@ final class WpRestDiscovery implements DiscoveryInterface private array $wrapperCache = []; public function __construct( - private readonly ?LoggerInterface $logger = null + private readonly ?LoggerInterface $logger = null, + private readonly WpRestRouteRegistrar $registrar = new WpRestRouteRegistrar, ) {} /** @@ -205,15 +208,19 @@ private function processMethodAttribute( try { $attributeInstance = $attribute->newInstance(); - // Check if the attribute has a handle method and call it - if (! method_exists($attributeInstance, 'handle')) { + if ($attributeInstance instanceof Method) { + add_action('rest_api_init', function () use ($attributeInstance, $attributableWrapper, $method): void { + $this->registrar->register($attributableWrapper, $method, $attributeInstance); + }); + return; } - // Let the attribute handle the registration - add_action('rest_api_init', function () use ($attributeInstance, $attributableWrapper, $method): void { - $attributeInstance->handle(app(), $attributableWrapper, $method, $attributeInstance); - }); + if ($attributeInstance instanceof HandlesAttributes) { + add_action('rest_api_init', function () use ($attributeInstance, $attributableWrapper, $method): void { + $attributeInstance->handle(app(), $attributableWrapper, $method, $attributeInstance); + }); + } } catch (\Throwable $throwable) { $className = $method->getDeclaringClass()->getName(); $this->logger?->error(sprintf('Failed to process method attribute for %s::%s: ', $className, $method->getName()).$throwable->getMessage()); diff --git a/src/WpRest/Infrastructure/Services/WpRestRouteRegistrar.php b/src/WpRest/Infrastructure/Services/WpRestRouteRegistrar.php new file mode 100644 index 00000000..ef519021 --- /dev/null +++ b/src/WpRest/Infrastructure/Services/WpRestRouteRegistrar.php @@ -0,0 +1,133 @@ +permissionCallback; + $permissionCallback = $methodPermission ?? $instance->classPermission; + + register_rest_route( + $instance->namespace, + $instance->route, + [ + 'methods' => $attribute->getMethods(), + 'callback' => WpGlobals::wrap( + fn (WP_REST_Request $request): mixed => $this->handleRequest($instance, $context, $request) + ), + 'args' => $this->extractArgsFromRoute($instance->route), + 'permission_callback' => $this->resolvePermissionCallback($permissionCallback), + ] + ); + } + + /** + * Executes the class method associated with the REST request. + * + * @param WpRestAttributableWrapper $instance The route class wrapper + * @param ReflectionMethod $method The method to invoke + * @param WP_REST_Request $request The REST request instance + * @return mixed The result of the method invocation + */ + private function handleRequest(WpRestAttributableWrapper $instance, ReflectionMethod $method, WP_REST_Request $request): mixed + { + $args = []; + + foreach ($method->getParameters() as $param) { + // A WP_REST_Request type hint gets the request itself. Looking its + // name up among the route parameters found nothing — no route + // declares one called "request" — so the handler was invoked with + // null and a controller declaring the type fataled before running. + if ($this->expectsTheRequest($param)) { + $args[] = $request; + + continue; + } + + $args[] = $request->get_param($param->getName()); + } + + return $method->invoke($instance->getRealInstance(), ...$args); + } + + /** + * Whether a parameter asks for the request object rather than a route value. + */ + private function expectsTheRequest(\ReflectionParameter $param): bool + { + $type = $param->getType(); + + if (! $type instanceof \ReflectionNamedType || $type->isBuiltin()) { + return false; + } + + $name = $type->getName(); + + // The name comparison stands on its own: ::class resolves whether or + // not WordPress is loaded, so this holds outside a WordPress runtime. + return $name === WP_REST_Request::class + || is_a($name, WP_REST_Request::class, true); + } + + /** + * Extracts dynamic arguments from a WordPress route. + * + * @param string $route The route pattern + * @return array The extracted arguments + */ + private function extractArgsFromRoute(string $route): array + { + preg_match_all('/\(\?P<(\w+)>/', $route, $matches); + + return array_fill_keys($matches[1], [ + 'validate_callback' => fn ($param): bool => is_string($param) || is_numeric($param), + ]); + } + + /** + * Resolves and executes the permission callback. + * + * @param class-string|Permission|null $permissionCallback The permission class or instance to use + * @return callable The permission function + */ + private function resolvePermissionCallback(string|Permission|null $permissionCallback): callable + { + if ($permissionCallback === null) { + return '__return_true'; + } + + if (is_string($permissionCallback) && (! class_exists($permissionCallback) || ! is_subclass_of($permissionCallback, Permission::class))) { + return fn (): WP_Error => new WP_Error('rest_forbidden', __('Invalid permission handler.'), ['status' => 403]); + } + + return WpGlobals::wrap(function (WP_REST_Request $request) use ($permissionCallback): bool|WP_Error { + $permissionInstance = is_string($permissionCallback) ? new $permissionCallback : $permissionCallback; + + return $permissionInstance->allow($request); + }); + } +} diff --git a/tests/Feature/Hook/Async/AsyncAttributeTest.php b/tests/Feature/Hook/Async/AsyncAttributeTest.php index 8506b5bb..96b402da 100644 --- a/tests/Feature/Hook/Async/AsyncAttributeTest.php +++ b/tests/Feature/Hook/Async/AsyncAttributeTest.php @@ -11,7 +11,6 @@ use Pollora\Hook\Async\Async; use Pollora\Hook\Async\AsyncPayload; use Pollora\Hook\Async\QueuedHandler; -use Pollora\Hook\Domain\Contract\Action as ActionContract; use Pollora\Hook\Infrastructure\Services\AsyncAttributeRegistrar; use Pollora\Hook\Infrastructure\Services\HookDiscovery; use Psr\Log\AbstractLogger; @@ -149,42 +148,3 @@ function registeredCallback(Action $actions, string $hook): mixed ->and($this->logger->errors)->toContain(sprintf('#[Async] on %s::orphan() is ignored: the method has no #[Action] to make asynchronous.', AsyncAttributeHooks::class)); }); }); - -describe('Action::handle()', function (): void { - it('registers through the registrar, asynchronously when #[Async] says so', function (): void { - $locator = new readonly class($this->actions, $this->logger) - { - public function __construct(private ActionContract $actions, private AbstractLogger $logger) {} - - public function get(string $id): mixed - { - return $id === ActionContract::class ? $this->actions : $this->logger; - } - }; - $method = new ReflectionMethod(AsyncAttributeHooks::class, 'notify'); - $attribute = new ActionAttribute('transition_post_status'); - - $attribute->handle($locator, new AsyncAttributeHooks, $method, $attribute); - - expect(registeredCallback($this->actions, 'transition_post_status'))->toBeInstanceOf(QueuedHandler::class); - }); - - it('works without a logger in the service locator, and ignores a class context', function (): void { - $locator = new readonly class($this->actions) - { - public function __construct(private ActionContract $actions) {} - - public function get(string $id): mixed - { - return $id === ActionContract::class ? $this->actions : throw new RuntimeException('Not bound'); - } - }; - $attribute = new ActionAttribute('save_post'); - - $attribute->handle($locator, new AsyncAttributeInvalidHooks, new ReflectionMethod(AsyncAttributeInvalidHooks::class, 'typo'), $attribute); - $attribute->handle($locator, new AsyncAttributeHooks, new ReflectionClass(AsyncAttributeHooks::class), new ActionAttribute('init')); - - expect(registeredCallback($this->actions, 'save_post'))->toBeArray() - ->and($this->actions->callbacks('init'))->toBeNull(); - }); -}); diff --git a/tests/Feature/Hook/HookDiscoveryTest.php b/tests/Feature/Hook/HookDiscoveryTest.php new file mode 100644 index 00000000..15c40a00 --- /dev/null +++ b/tests/Feature/Hook/HookDiscoveryTest.php @@ -0,0 +1,94 @@ + */ + public array $calls = []; + + #[ActionAttribute('init')] + public function boot(): void + { + $this->calls[] = 'boot'; + } + + #[ActionAttribute('save_post', priority: 99)] + #[ActionAttribute('edit_post', priority: 20)] + public function syncPost(int $postId, object $post): void + { + $this->calls[] = 'syncPost'; + } + + #[FilterAttribute('the_title')] + public function title(string $title): string + { + return 'modified_'.$title; + } + + #[FilterAttribute('the_content', priority: 5)] + public function content(string $content): string + { + return $content; + } + + public function notAHook(): void + { + $this->calls[] = 'notAHook'; + } +} + +beforeEach(function (): void { + $this->actions = new Action; + $this->filters = new Filter; + $discovery = new HookDiscovery($this->actions, $this->filters); + $discovery->discover(new DiscoveryLocation('', __DIR__), DiscoveredClass::fromReflection(new ReflectionClass(DiscoveredHooks::class)), new ReflectionCache); + $discovery->apply(); +}); + +/** + * The registration made on a hook: its method, priority and accepted arguments. + * + * @return array{method: string, priority: int, args: int} + */ +function hookRegistration(Action|Filter $hooks, string $hook): array +{ + $registration = $hooks->callbacks($hook)[0]; + + return ['method' => $registration['callback'][1], 'priority' => $registration['priority'], 'args' => $registration['args']]; +} + +it('registers each #[Action] with its priority, 10 by default', function (): void { + expect(hookRegistration($this->actions, 'init'))->toBe(['method' => 'boot', 'priority' => 10, 'args' => 0]) + ->and(hookRegistration($this->actions, 'save_post'))->toBe(['method' => 'syncPost', 'priority' => 99, 'args' => 2]) + ->and(hookRegistration($this->actions, 'edit_post'))->toBe(['method' => 'syncPost', 'priority' => 20, 'args' => 2]); +}); + +it('registers each #[Filter] with its priority, 10 by default', function (): void { + expect(hookRegistration($this->filters, 'the_title'))->toBe(['method' => 'title', 'priority' => 10, 'args' => 1]) + ->and(hookRegistration($this->filters, 'the_content'))->toBe(['method' => 'content', 'priority' => 5, 'args' => 1]); +}); + +it('calls the method of an instance of the declaring class', function (): void { + $callback = $this->filters->callbacks('the_title')[0]['callback']; + + expect($callback[0])->toBeInstanceOf(DiscoveredHooks::class) + ->and($callback('Hello'))->toBe('modified_Hello'); +}); + +it('registers nothing for a method without hook attribute', function (): void { + $registrations = array_merge(...array_values($this->actions->all()), ...array_values($this->filters->all())); + + expect(array_map(fn (array $registration): string => $registration['callback'][1], $registrations)) + ->toHaveCount(5) + ->not->toContain('notAHook'); +}); diff --git a/tests/Unit/Attributes/ActionTest.php b/tests/Unit/Attributes/ActionTest.php deleted file mode 100644 index 4cd33586..00000000 --- a/tests/Unit/Attributes/ActionTest.php +++ /dev/null @@ -1,187 +0,0 @@ -mockAction = Mockery::mock(ActionService::class); - - // Create a fake service locator - $this->mockServiceLocator = new class($this->mockAction) - { - public function __construct(private $actionService) {} - - public function get($serviceClass) - { - if ($serviceClass === ActionService::class) { - return $this->actionService; - } - - return null; - } - }; -}); - -class SingleActionClass -{ - #[Action('test_action', priority: 10)] - public function actionMethod($param = null): string - { - // Test method - return $param ? 'processed_'.$param : 'processed'; - } -} - -class MultipleActionClass -{ - #[Action('test_action', priority: 10)] - public function actionMethod($param = null): string - { - // Test method - return $param ? 'processed_'.$param : 'processed'; - } - - #[Action('another_action', priority: 20)] - public function anotherActionMethod(): string - { - // Another test method - return 'another_processed'; - } -} - -class DefaultPriorityActionClass -{ - #[Action('test_action')] - public function actionMethod($param = null): string - { - // Test method with default priority - return $param ? 'processed_'.$param : 'processed'; - } -} - -class CustomPriorityActionClass -{ - #[Action('test_action', priority: 42)] - public function actionMethod($param = null): string - { - // Test method with custom priority - return $param ? 'processed_'.$param : 'processed'; - } -} - -it('registers an action hook correctly', function (): void { - // Set up expectations - $this->mockAction->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_action' - && is_array($callback) - && $callback[0] instanceof SingleActionClass - && $callback[1] === 'actionMethod' - && $priority === 10 - && $acceptedArgs === 1); - - // Test the action attribute directly using handle method - $testClass = new SingleActionClass; - $actionAttribute = new Action('test_action', 10); - $methodReflection = new ReflectionMethod($testClass, 'actionMethod'); - - $actionAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $actionAttribute); -}); - -it('registers multiple action hooks with different priorities', function (): void { - $testClass = new MultipleActionClass; - - // Test first action - $this->mockAction->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_action' - && is_array($callback) - && $callback[0] instanceof MultipleActionClass - && $callback[1] === 'actionMethod' - && $priority === 10); - - $actionAttribute1 = new Action('test_action', 10); - $methodReflection1 = new ReflectionMethod($testClass, 'actionMethod'); - $actionAttribute1->handle($this->mockServiceLocator, $testClass, $methodReflection1, $actionAttribute1); - - // Test second action - $this->mockAction->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'another_action' - && is_array($callback) - && $callback[0] instanceof MultipleActionClass - && $callback[1] === 'anotherActionMethod' - && $priority === 20); - - $actionAttribute2 = new Action('another_action', 20); - $methodReflection2 = new ReflectionMethod($testClass, 'anotherActionMethod'); - $actionAttribute2->handle($this->mockServiceLocator, $testClass, $methodReflection2, $actionAttribute2); -}); - -it('registers an action hook with default priority (10)', function (): void { - // Set up expectations - $this->mockAction->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_action' - && is_array($callback) - && $callback[0] instanceof DefaultPriorityActionClass - && $callback[1] === 'actionMethod' - && $priority === 10 // Default priority should be 10 - && $acceptedArgs === 1); - - // Test with default priority - $testClass = new DefaultPriorityActionClass; - $actionAttribute = new Action('test_action'); // No priority specified, should default to 10 - $methodReflection = new ReflectionMethod($testClass, 'actionMethod'); - - $actionAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $actionAttribute); -}); - -it('registers an action hook with custom priority', function (): void { - // Set up expectations - $this->mockAction->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_action' - && is_array($callback) - && $callback[0] instanceof CustomPriorityActionClass - && $callback[1] === 'actionMethod' - && $priority === 42 // Custom priority - && $acceptedArgs === 1); - - // Test with custom priority - $testClass = new CustomPriorityActionClass; - $actionAttribute = new Action('test_action', 42); - $methodReflection = new ReflectionMethod($testClass, 'actionMethod'); - - $actionAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $actionAttribute); -}); - -it('handles null service locator resolution gracefully', function (): void { - // Create a service locator that returns null for the service - $mockServiceLocator = new class - { - public function get($serviceClass): null - { - return null; - } - }; - - $testClass = new SingleActionClass; - $actionAttribute = new Action('test_action', 10); - $methodReflection = new ReflectionMethod($testClass, 'actionMethod'); - - // This should not throw an exception - $actionAttribute->handle($mockServiceLocator, $testClass, $methodReflection, $actionAttribute); - - // No assertions needed - we're just checking that it doesn't throw - expect(true)->toBeTrue(); -}); - -afterEach(function (): void { - Mockery::close(); - Facade::clearResolvedInstances(); -}); diff --git a/tests/Unit/Attributes/ArchitectureTest.php b/tests/Unit/Attributes/ArchitectureTest.php new file mode 100644 index 00000000..c3e01bfe --- /dev/null +++ b/tests/Unit/Attributes/ArchitectureTest.php @@ -0,0 +1,31 @@ +expect('Pollora\Attributes') + ->toOnlyUse([ + 'Pollora\Attributes', + \Pollora\Ajax\Domain\Model\AjaxAccess::class, + \Pollora\Abilities\Domain\Model\Behaviour::class, + \Pollora\BlockBinding\Domain\Enums\BindingFieldType::class, + \Pollora\Meta\Domain\Enums\Control::class, + \Pollora\Role\Domain\Enums\Access::class, + \Pollora\Schedule\Every::class, + \Pollora\Schedule\Interval::class, + ]) + // Permission::allow() names WordPress's request and error types in its + // signature only, so the attributes never load them. + ->ignoring([PostTypeAttribute::class, TaxonomyAttribute::class, 'WP_REST_Request', 'WP_Error']); diff --git a/tests/Unit/Attributes/FilterTest.php b/tests/Unit/Attributes/FilterTest.php deleted file mode 100644 index abf6cd87..00000000 --- a/tests/Unit/Attributes/FilterTest.php +++ /dev/null @@ -1,209 +0,0 @@ -mockFilter = Mockery::mock(FilterService::class); - - // Create a fake service locator - $this->mockServiceLocator = new class($this->mockFilter) - { - public function __construct(private $filterService) {} - - public function get($serviceClass) - { - if ($serviceClass === FilterService::class) { - return $this->filterService; - } - - return null; - } - }; -}); - -class SingleFilterClass -{ - #[Filter('test_filter', priority: 10)] - public function filterMethod(string $value): string - { - return 'modified_'.$value; - } -} - -class MultipleFilterClass -{ - #[Filter('test_filter', priority: 10)] - public function filterMethod(string $value): string - { - return 'modified_'.$value; - } - - #[Filter('another_filter', priority: 20)] - public function anotherFilterMethod(array $data): array - { - $data['modified'] = true; - - return $data; - } -} - -class DefaultPriorityFilterClass -{ - #[Filter('test_filter')] - public function filterMethod(string $value): string - { - // Test method with default priority - return 'modified_'.$value; - } -} - -class CustomPriorityFilterClass -{ - #[Filter('test_filter', priority: 99)] - public function filterMethod(string $value): string - { - // Test method with custom priority - return 'modified_'.$value; - } -} - -it('registers a filter hook correctly', function (): void { - // Set up expectations - $this->mockFilter->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_filter' - && is_array($callback) - && $callback[0] instanceof SingleFilterClass - && $callback[1] === 'filterMethod' - && $priority === 10 - && $acceptedArgs === 1); - - // Test the filter attribute directly using handle method - $testClass = new SingleFilterClass; - $filterAttribute = new Filter('test_filter', 10); - $methodReflection = new ReflectionMethod($testClass, 'filterMethod'); - - $filterAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $filterAttribute); -}); - -it('registers multiple filter hooks with different priorities', function (): void { - $testClass = new MultipleFilterClass; - - // Test first filter - $this->mockFilter->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_filter' - && is_array($callback) - && $callback[0] instanceof MultipleFilterClass - && $callback[1] === 'filterMethod' - && $priority === 10); - - $filterAttribute1 = new Filter('test_filter', 10); - $methodReflection1 = new ReflectionMethod($testClass, 'filterMethod'); - $filterAttribute1->handle($this->mockServiceLocator, $testClass, $methodReflection1, $filterAttribute1); - - // Test second filter - $this->mockFilter->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'another_filter' - && is_array($callback) - && $callback[0] instanceof MultipleFilterClass - && $callback[1] === 'anotherFilterMethod' - && $priority === 20); - - $filterAttribute2 = new Filter('another_filter', 20); - $methodReflection2 = new ReflectionMethod($testClass, 'anotherFilterMethod'); - $filterAttribute2->handle($this->mockServiceLocator, $testClass, $methodReflection2, $filterAttribute2); -}); - -it('registers a filter hook with default priority (10)', function (): void { - // Set up expectations - $this->mockFilter->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_filter' - && is_array($callback) - && $callback[0] instanceof DefaultPriorityFilterClass - && $callback[1] === 'filterMethod' - && $priority === 10 // Default priority should be 10 - && $acceptedArgs === 1); - - // Test with default priority - $testClass = new DefaultPriorityFilterClass; - $filterAttribute = new Filter('test_filter'); // No priority specified, should default to 10 - $methodReflection = new ReflectionMethod($testClass, 'filterMethod'); - - $filterAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $filterAttribute); -}); - -it('registers a filter hook with custom priority', function (): void { - // Set up expectations - $this->mockFilter->shouldReceive('add') - ->once() - ->withArgs(fn ($hook, $callback, $priority, $acceptedArgs): bool => $hook === 'test_filter' - && is_array($callback) - && $callback[0] instanceof CustomPriorityFilterClass - && $callback[1] === 'filterMethod' - && $priority === 99 // Custom priority - && $acceptedArgs === 1); - - // Test with custom priority - $testClass = new CustomPriorityFilterClass; - $filterAttribute = new Filter('test_filter', 99); - $methodReflection = new ReflectionMethod($testClass, 'filterMethod'); - - $filterAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $filterAttribute); -}); - -it('executes filter and returns modified value', function (): void { - // Set up expectations for the add method - $this->mockFilter->shouldReceive('add') - ->once() - ->withAnyArgs(); - - // Set up expectations for the apply method - $this->mockFilter->shouldReceive('apply') - ->once() - ->with('test_filter', 'original') - ->andReturn('modified_original'); - - // Test filter attribute directly - $testClass = new SingleFilterClass; - $filterAttribute = new Filter('test_filter', 10); - $methodReflection = new ReflectionMethod($testClass, 'filterMethod'); - $filterAttribute->handle($this->mockServiceLocator, $testClass, $methodReflection, $filterAttribute); - - // Test the apply method - $result = $this->mockFilter->apply('test_filter', 'original'); - expect($result)->toBe('modified_original'); -}); - -it('handles null service locator resolution gracefully', function (): void { - // Create a service locator that returns null for the service - $mockServiceLocator = new class - { - public function get($serviceClass): null - { - return null; - } - }; - - $testClass = new SingleFilterClass; - $filterAttribute = new Filter('test_filter', 10); - $methodReflection = new ReflectionMethod($testClass, 'filterMethod'); - - // This should not throw an exception - $filterAttribute->handle($mockServiceLocator, $testClass, $methodReflection, $filterAttribute); - - // No assertions needed - we're just checking that it doesn't throw - expect(true)->toBeTrue(); -}); - -afterEach(function (): void { - Mockery::close(); - Facade::clearResolvedInstances(); -}); diff --git a/tests/Unit/Attributes/HookTest.php b/tests/Unit/Attributes/HookTest.php index 72b02c9c..c153b323 100644 --- a/tests/Unit/Attributes/HookTest.php +++ b/tests/Unit/Attributes/HookTest.php @@ -12,17 +12,7 @@ */ // Create a concrete implementation of the abstract Hook class for testing -class ConcreteHook extends Hook -{ - public function handle( - $serviceLocator, - object $instance, - ReflectionClass|ReflectionMethod $context, - object $attribute - ): void { - // Implementation for testing - } -} +class ConcreteHook extends Hook {} it('initializes with default priority', function (): void { $hook = new ConcreteHook('test_hook'); diff --git a/tests/Unit/Attributes/LabelsAttributeTest.php b/tests/Unit/Attributes/LabelsAttributeTest.php index 84bde720..2f6b4af1 100644 --- a/tests/Unit/Attributes/LabelsAttributeTest.php +++ b/tests/Unit/Attributes/LabelsAttributeTest.php @@ -56,9 +56,7 @@ class GenreWithLabels {} $reflection = new ReflectionClass(ProjectWithLabels::class); $attr = $reflection->getAttributes(PostTypeLabels::class)[0]->newInstance(); - $attr->handle(null, $config, $reflection, $attr); - - $labels = $config->attributeArgs['labels']; + $labels = $attr->configureArguments($config->attributeArgs)['labels']; // Overridden by #[Labels] expect($labels['all_items'])->toBe('All Projects'); @@ -88,10 +86,7 @@ class GenreWithLabels {} ); $config = new PostTypeConfiguration('item', 'Item', 'Items'); - $reflection = new ReflectionClass(ArticleWithoutLabels::class); - $labels->handle(null, $config, $reflection, $labels); - - $result = $config->attributeArgs['labels']; + $result = $labels->configureArguments($config->attributeArgs)['labels']; expect($result)->toBe([ 'name' => 'My Items', @@ -126,9 +121,7 @@ class GenreWithLabels {} $reflection = new ReflectionClass(GenreWithLabels::class); $attr = $reflection->getAttributes(TaxonomyLabels::class)[0]->newInstance(); - $attr->handle(null, $config, $reflection, $attr); - - $labels = $config->attributeArgs['labels']; + $labels = $attr->configureArguments($config->attributeArgs)['labels']; // Overridden expect($labels['all_items'])->toBe('All Genres'); diff --git a/tests/Unit/Attributes/NamingTest.php b/tests/Unit/Attributes/NamingTest.php new file mode 100644 index 00000000..c0d9c143 --- /dev/null +++ b/tests/Unit/Attributes/NamingTest.php @@ -0,0 +1,49 @@ + 'SyntheseDePresse', + 'single word' => 'Book', + 'already lower' => 'book', + 'camelCase property' => 'eventDate', + 'acronym' => 'HTMLParser', + 'digits' => 'Top10Books', + 'underscore' => 'event_date', + 'spaces' => 'event date time', + 'accented capital' => 'ÉvénementPublic', + 'trailing capital' => 'PostA', +]); + +it('writes snake case as Str::snake() does', function (string $name): void { + expect(Naming::snake($name))->toBe(Str::snake($name)); +})->with('names'); + +it('writes kebab case as Str::kebab() does', function (string $name): void { + expect(Naming::kebab($name))->toBe(Str::kebab($name)); +})->with('names'); + +it('strips the namespace as class_basename() does', function (): void { + expect(Naming::classBasename('App\\Cms\\PostTypes\\Book'))->toBe(class_basename('App\\Cms\\PostTypes\\Book')) + ->and(Naming::classBasename('Book'))->toBe('Book'); +}); + +it('derives command slugs, the Command suffix dropped', function (): void { + expect(Naming::commandFromClassName('App\\Cli\\UserManagementCommand'))->toBe('user-management') + ->and(Naming::commandFromClassName('Cache'))->toBe('cache') + ->and(Naming::slug('deleteById'))->toBe('delete-by-id') + ->and(Naming::slug('HTMLParser'))->toBe('htmlparser') + ->and(Slug::fromClassName('App\\Cli\\UserManagementCommand'))->toBe('user-management') + ->and(Slug::fromMethodName('listItems'))->toBe('list-items'); +}); diff --git a/tests/Unit/Attributes/TaxonomyAttributeTest.php b/tests/Unit/Attributes/TaxonomyAttributeTest.php index 66edb2fb..52a346d5 100644 --- a/tests/Unit/Attributes/TaxonomyAttributeTest.php +++ b/tests/Unit/Attributes/TaxonomyAttributeTest.php @@ -5,6 +5,7 @@ use Illuminate\Container\Container; use Illuminate\Support\Facades\Facade; use Mockery as m; +use Pollora\Attributes\Contracts\ConfiguresArguments; use Pollora\Attributes\Taxonomy; use Pollora\Attributes\Taxonomy\AllowHierarchy; use Pollora\Attributes\Taxonomy\Args; @@ -161,8 +162,8 @@ function testBooleanAttribute(string $attributeName, string $argName): void $reflectionClass = new ReflectionClass($taxonomy); foreach ($reflectionClass->getAttributes() as $attribute) { $attributeInstance = $attribute->newInstance(); - if (method_exists($attributeInstance, 'handle')) { - $attributeInstance->handle(app(), $taxonomy, $reflectionClass, $attributeInstance); + if ($attributeInstance instanceof ConfiguresArguments) { + $taxonomy->attributeArgs = $attributeInstance->configureArguments($taxonomy->attributeArgs); } } @@ -180,8 +181,8 @@ function testValueAttribute(string $attributeName, string $argName, mixed $expec $reflectionClass = new ReflectionClass($taxonomy); foreach ($reflectionClass->getAttributes() as $attribute) { $attributeInstance = $attribute->newInstance(); - if (method_exists($attributeInstance, 'handle')) { - $attributeInstance->handle(app(), $taxonomy, $reflectionClass, $attributeInstance); + if ($attributeInstance instanceof ConfiguresArguments) { + $taxonomy->attributeArgs = $attributeInstance->configureArguments($taxonomy->attributeArgs); } } @@ -206,7 +207,7 @@ function testMethodAttribute(string $attributeName, string $argName, string $met $attributes = $method->getAttributes($attributeClass); foreach ($attributes as $attribute) { $attributeInstance = $attribute->newInstance(); - $attributeInstance->handle(null, $taxonomy, $method, $attributeInstance); + $taxonomy->attributeArgs = $attributeInstance->configureArguments($taxonomy->attributeArgs, [$taxonomy, $method->getName()]); } } @@ -259,8 +260,8 @@ function testMethodAttribute(string $attributeName, string $argName, string $met $reflectionClass = new ReflectionClass($taxonomy); foreach ($reflectionClass->getAttributes() as $attribute) { $attributeInstance = $attribute->newInstance(); - if (method_exists($attributeInstance, 'handle')) { - $attributeInstance->handle(app(), $taxonomy, $reflectionClass, $attributeInstance); + if ($attributeInstance instanceof ConfiguresArguments) { + $taxonomy->attributeArgs = $attributeInstance->configureArguments($taxonomy->attributeArgs); } } diff --git a/tests/Unit/PostType/PostTypeDiscoveryTest.php b/tests/Unit/PostType/PostTypeDiscoveryTest.php new file mode 100644 index 00000000..be45aed2 --- /dev/null +++ b/tests/Unit/PostType/PostTypeDiscoveryTest.php @@ -0,0 +1,114 @@ + */ + public array $calls = []; + + #[AdminCol('isbn', 'ISBN', sortable: true)] + public function isbnColumn(): string + { + return '978'; + } + + #[RegisterMetaBoxCb] + public function metaBoxes(): void + { + $this->calls[] = 'metaBoxes'; + } + + #[Action('init')] + public function onInit(): void + { + $this->calls[] = 'onInit'; + } +} + +/** + * Run the discovery over the given classes and return what reached the post type service. + * + * @return array{slug: string, singular: string, plural: string, args: array, priority: int} + */ +function registeredPostType(string $class): array +{ + $registered = []; + $service = Mockery::mock(PostTypeServiceInterface::class); + $service->shouldReceive('register')->once()->andReturnUsing( + function (string $slug, string $singular, string $plural, array $args, int $priority) use (&$registered): object { + $registered = ['slug' => $slug, 'singular' => $singular, 'plural' => $plural, 'args' => $args, 'priority' => $priority]; + + return new stdClass; + } + ); + + $discovery = new PostTypeDiscovery($service); + $discovery->discover(new DiscoveryLocation('Tests\\', __DIR__), DiscoveredClass::fromReflection(new ReflectionClass($class)), new ReflectionCache); + $discovery->apply(); + + return $registered; +} + +it('registers the arguments its attributes declare', function (): void { + $registered = registeredPostType(DiscoveredBook::class); + + expect($registered['slug'])->toBe('fixture_book') + ->and($registered['priority'])->toBe(7) + ->and($registered['args'])->toMatchArray([ + 'has_archive' => 'library', + 'supports' => ['title', 'excerpt'], + 'orderby' => 'date', + 'order' => 'DESC', + 'text_domain' => 'pollora', + ]) + ->and($registered['args'])->not->toHaveKey('priority'); +}); + +it('merges declared labels into the generated ones', function (): void { + $labels = registeredPostType(DiscoveredBook::class)['args']['labels']; + + expect($labels['menu_name'])->toBe('Library') + ->and($labels['singular_name'])->toBe('Book'); +}); + +it('turns method attributes into callbacks on the declaring class', function (): void { + $args = registeredPostType(DiscoveredBook::class)['args']; + + expect($args['admin_cols']['isbn'])->toMatchArray(['title' => 'ISBN', 'sortable' => true]) + ->and($args['admin_cols']['isbn']['function'][0])->toBeInstanceOf(DiscoveredBook::class) + ->and($args['admin_cols']['isbn']['function'][1])->toBe('isbnColumn') + ->and($args['register_meta_box_cb'][0])->toBeInstanceOf(DiscoveredBook::class) + ->and($args['register_meta_box_cb'][1])->toBe('metaBoxes'); +}); + +it('leaves the actions of a post type class to the hook discovery', function (): void { + $actions = Mockery::mock(ActionService::class); + $actions->shouldNotReceive('add'); + + app()->instance(ActionService::class, $actions); + + registeredPostType(DiscoveredBook::class); +}); diff --git a/tests/Unit/Taxonomy/TaxonomyDiscoveryTest.php b/tests/Unit/Taxonomy/TaxonomyDiscoveryTest.php new file mode 100644 index 00000000..c025d307 --- /dev/null +++ b/tests/Unit/Taxonomy/TaxonomyDiscoveryTest.php @@ -0,0 +1,86 @@ + */ + public array $calls = []; + + #[MetaBoxCb] + public function metaBox(): void + { + $this->calls[] = 'metaBox'; + } + + #[Action('init')] + public function onInit(): void + { + $this->calls[] = 'onInit'; + } +} + +/** + * Run the discovery over the class and return the arguments it registered. + * + * @return array + */ +function registeredTaxonomyArgs(string $class): array +{ + $registered = []; + $service = Mockery::mock(TaxonomyServiceInterface::class); + $service->shouldReceive('register')->once()->andReturnUsing( + function (string $slug, string|array $objectType, string $singular, string $plural, array $args) use (&$registered): object { + $registered = $args; + + return new stdClass; + } + ); + + $discovery = new TaxonomyDiscovery($service); + $discovery->discover(new DiscoveryLocation('Tests\\', __DIR__), DiscoveredClass::fromReflection(new ReflectionClass($class)), new ReflectionCache); + $discovery->apply(); + + return $registered; +} + +it('registers the arguments its attributes declare, labels merged', function (): void { + $args = registeredTaxonomyArgs(DiscoveredGenre::class); + + expect($args)->toMatchArray(['hierarchical' => true, 'show_in_rest' => true]) + ->and($args['labels']['menu_name'])->toBe('Shelves') + ->and($args['labels']['singular_name'])->toBe('Genre'); +}); + +it('turns a method attribute into a callback on the declaring class', function (): void { + $callback = registeredTaxonomyArgs(DiscoveredGenre::class)['meta_box_cb']; + + expect($callback[0])->toBeInstanceOf(DiscoveredGenre::class) + ->and($callback[1])->toBe('metaBox'); +}); + +it('leaves the actions of a taxonomy class to the hook discovery', function (): void { + $actions = Mockery::mock(ActionService::class); + $actions->shouldNotReceive('add'); + + app()->instance(ActionService::class, $actions); + + registeredTaxonomyArgs(DiscoveredGenre::class); +}); diff --git a/tests/Unit/WpRest/CanPermissionTest.php b/tests/Unit/WpRest/CanPermissionTest.php index e2c2b1e9..d977c375 100644 --- a/tests/Unit/WpRest/CanPermissionTest.php +++ b/tests/Unit/WpRest/CanPermissionTest.php @@ -3,7 +3,7 @@ declare(strict_types=1); use Brain\Monkey\Functions; -use Pollora\Attributes\WpRestRoute\Method; +use Pollora\WpRest\Infrastructure\Services\WpRestRouteRegistrar; use Pollora\WpRest\Permissions\Can; use Tests\Unit\Role\Fixtures\EventCap; @@ -37,9 +37,9 @@ it('is accepted as an instance by #[Method] and #[WpRestRoute]', function (): void { Functions\when('current_user_can')->justReturn(true); - $resolve = new ReflectionMethod(Method::class, 'resolvePermissionCallback'); + $resolve = new ReflectionMethod(WpRestRouteRegistrar::class, 'resolvePermissionCallback'); - $callback = $resolve->invoke(new Method('GET', permissionCallback: new Can('edit_posts')), new Can('edit_posts')); + $callback = $resolve->invoke(new WpRestRouteRegistrar, new Can('edit_posts')); expect($callback(Mockery::mock(WP_REST_Request::class)))->toBeTrue(); }); diff --git a/tests/Unit/WpRest/RestRequestInjectionTest.php b/tests/Unit/WpRest/RestRequestInjectionTest.php index d69922c1..56684741 100644 --- a/tests/Unit/WpRest/RestRequestInjectionTest.php +++ b/tests/Unit/WpRest/RestRequestInjectionTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use Pollora\Attributes\WpRestRoute\Method; +use Pollora\WpRest\Infrastructure\Services\WpRestRouteRegistrar; /** * Which arguments a REST handler is invoked with. @@ -27,12 +27,12 @@ public function withBuiltin(int $page): void {} $param = (new ReflectionMethod($probe, $signatureMethod))->getParameters()[0]; - $method = (new ReflectionClass(Method::class))->getMethod('expectsTheRequest'); + $method = (new ReflectionClass(WpRestRouteRegistrar::class))->getMethod('expectsTheRequest'); - return $method->invoke(new Method('GET'), $param); + return $method->invoke(new WpRestRouteRegistrar, $param); } -describe('Method::expectsTheRequest()', function (): void { +describe('WpRestRouteRegistrar::expectsTheRequest()', function (): void { it('gives the request to a parameter that asks for it by type', function (): void { expect(expectsRequest('withRequest'))->toBeTrue(); }); From d857a9b847125857a591c901187c928566af0f15 Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 12 Oct 2026 14:57:48 +0200 Subject: [PATCH 2/3] style: import the enumerations the architecture test allows --- tests/Unit/Attributes/ArchitectureTest.php | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/Unit/Attributes/ArchitectureTest.php b/tests/Unit/Attributes/ArchitectureTest.php index c3e01bfe..2cb2cff2 100644 --- a/tests/Unit/Attributes/ArchitectureTest.php +++ b/tests/Unit/Attributes/ArchitectureTest.php @@ -2,8 +2,15 @@ declare(strict_types=1); +use Pollora\Abilities\Domain\Model\Behaviour; +use Pollora\Ajax\Domain\Model\AjaxAccess; use Pollora\Attributes\PostType\PostTypeAttribute; use Pollora\Attributes\Taxonomy\TaxonomyAttribute; +use Pollora\BlockBinding\Domain\Enums\BindingFieldType; +use Pollora\Meta\Domain\Enums\Control; +use Pollora\Role\Domain\Enums\Access; +use Pollora\Schedule\Every; +use Pollora\Schedule\Interval; /** * Attributes are declarations: a plugin writes them without the framework, an @@ -18,13 +25,13 @@ ->expect('Pollora\Attributes') ->toOnlyUse([ 'Pollora\Attributes', - \Pollora\Ajax\Domain\Model\AjaxAccess::class, - \Pollora\Abilities\Domain\Model\Behaviour::class, - \Pollora\BlockBinding\Domain\Enums\BindingFieldType::class, - \Pollora\Meta\Domain\Enums\Control::class, - \Pollora\Role\Domain\Enums\Access::class, - \Pollora\Schedule\Every::class, - \Pollora\Schedule\Interval::class, + AjaxAccess::class, + Behaviour::class, + BindingFieldType::class, + Control::class, + Access::class, + Every::class, + Interval::class, ]) // Permission::allow() names WordPress's request and error types in its // signature only, so the attributes never load them. From d4e7a8567e4f4bb7f121448d9fad1e9bc14b9f3a Mon Sep 17 00:00:00 2001 From: Olivier Gorzalka Date: Mon, 12 Oct 2026 15:12:21 +0200 Subject: [PATCH 3/3] test: use the parameters of the hook fixture so Rector keeps them --- tests/Feature/Hook/HookDiscoveryTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Feature/Hook/HookDiscoveryTest.php b/tests/Feature/Hook/HookDiscoveryTest.php index 15c40a00..487f9a15 100644 --- a/tests/Feature/Hook/HookDiscoveryTest.php +++ b/tests/Feature/Hook/HookDiscoveryTest.php @@ -26,7 +26,7 @@ public function boot(): void #[ActionAttribute('edit_post', priority: 20)] public function syncPost(int $postId, object $post): void { - $this->calls[] = 'syncPost'; + $this->calls[] = sprintf('syncPost(%d, %s)', $postId, $post::class); } #[FilterAttribute('the_title')]