-
Notifications
You must be signed in to change notification settings - Fork 1
WIP: WordPress aware Container conrtact and Adapter #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
35 commits
Select commit
Hold shift + click to select a range
fcde7d5
feat: introduce WP aware container contract and adapter
dpanta94 a7afb10
fix: pass $actions to array_map
dpanta94 53d37fc
fix: use same closure across all actions so we can reliably remove it
dpanta94 09f3e49
chore: pint issues
dpanta94 d209ff8
docs: add actions docblocks
dpanta94 98042ae
docs: add package readme file
dpanta94 1f6bfbd
chore: pint issues
dpanta94 3a99408
revert: change to container contract @param hinting
dpanta94 907b55a
chore: fix pint issue
dpanta94 0e73f8a
feat: added wordpress-stubs
dpanta94 d947f4f
chore: static analysis
dpanta94 f2e9383
refactor: amend CR comments
dpanta94 f9b9785
tweak: make a callback static
dpanta94 c91e577
refactor: rename method get_container to getContainer
dpanta94 986ba7a
Revert "tweak: make a callback static"
dpanta94 2384e22
tweak: fix some typos
dpanta94 685e81d
fix: added missed semicolon
dpanta94 964ef77
tweak: rename default hook prefix
dpanta94 72b86a6
fix: require 1.1 of the foundation container
dpanta94 5631536
chore: pint issue
dpanta94 0863587
feat: bump di52 to 4.1
dpanta94 6accd50
feat: added mergeArrayVar method
dpanta94 a6d2dd9
chore: pint issue
dpanta94 ade2a4d
docs: fix binding
dpanta94 864a271
docs: amend change in method names
dpanta94 46e8806
chore: pint issue
dpanta94 ce6901c
tests: adding integration coverage
dpanta94 b97b473
tests: add unit coverage for the WP container
dpanta94 5801531
tests: mergeArrayVar method coverage added
dpanta94 b16295b
tests: fix counting issue
dpanta94 f67bc15
chore: pint fixes
dpanta94 b369a63
Fix README.md
defunctl a23eca6
Ignore dead catches in tests
defunctl ee85172
Fix README.md example
defunctl e71fe90
normalize $prefix, do a more strict identifier check, validate action…
defunctl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Path-based git attributes | ||
| # https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html | ||
|
|
||
| # Ignore paths when git creates an archive of this package | ||
| .gitattributes export-ignore | ||
| .gitignore export-ignore | ||
| .github export-ignore |
13 changes: 13 additions & 0 deletions
13
src/ContainerWordPress/.github/workflows/close-pull-request.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| name: Close Pull Request | ||
|
|
||
| on: | ||
| pull_request_target: | ||
| types: [opened] | ||
|
|
||
| jobs: | ||
| run: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: superbrothers/close-pull-request@v3 | ||
| with: | ||
| comment: "This is a read-only repository. Please submit your PR on the https://github.com/stellarwp/foundation repository.<br><br>Thanks!" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| vendor/ | ||
| composer.lock |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,258 @@ | ||
| <?php declare(strict_types=1); | ||
|
|
||
| namespace StellarWP\Foundation\ContainerWordPress; | ||
|
|
||
| use Closure; | ||
| use InvalidArgumentException; | ||
| use lucatume\DI52\Container as DI52Container; | ||
| use lucatume\DI52\ContainerException; | ||
| use StellarWP\Foundation\Container\ContainerAdapter as FoundationContainerAdapter; | ||
| use StellarWP\Foundation\Container\Contracts\Providable; | ||
| use StellarWP\Foundation\ContainerWordPress\Contracts\Container; | ||
|
|
||
| /** | ||
| * WordPress-aware container adapter. | ||
| * | ||
| * Wraps the Foundation container so WordPress projects keep the full base | ||
| * container API and gain WordPress-specific helpers. Add WordPress-specific | ||
| * methods here alongside the matching signatures on {@see Container}. | ||
| * | ||
| * @method mixed make(string $id) | ||
| * @method mixed getVar(string $key, mixed|null $default = null) | ||
| * @method void singletonDecorators($id, array<string> $decorators, ?array<string> $afterBuildMethods = null) | ||
| * @method void bindDecorators($id, array<string> $decorators, ?array<string> $afterBuildMethods = null) | ||
| */ | ||
| final readonly class ContainerAdapter implements Container | ||
| { | ||
| private FoundationContainerAdapter $container; | ||
|
|
||
| private string $prefix; | ||
|
|
||
| public function __construct( | ||
| FoundationContainerAdapter $container, | ||
| string $prefix = 'nexcess/foundation/container/wp/', | ||
| ) { | ||
| $this->container = $container; | ||
| $this->prefix = $prefix === '' ? '' : rtrim($prefix, '/') . '/'; | ||
| } | ||
|
|
||
| /** | ||
| * Build the "registered" WordPress action name for a service provider or alias. | ||
| * | ||
| * @param string $identifier The service provider class or alias slug. | ||
| * | ||
| * @throws InvalidArgumentException When the provided $identifier is empty. | ||
| * | ||
| * @return non-empty-string | ||
| */ | ||
| private function registeredAction(string $identifier): string { | ||
| if ($identifier === '') { | ||
| throw new InvalidArgumentException('You need to provide an identifier!'); | ||
| } | ||
|
|
||
| return $this->prefix . $identifier . '/registered'; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function register(string $serviceProviderClass, ...$alias): void { | ||
| $this->registeredAction($serviceProviderClass); | ||
|
|
||
| foreach ($alias as $slug) { | ||
| $this->registeredAction($slug); | ||
| } | ||
|
|
||
| $this->container->register($serviceProviderClass, ...$alias); | ||
|
|
||
| /** | ||
| * Fires after a service provider has been registered in the container. | ||
| * | ||
| * The dynamic portion of the hook name, `$serviceProviderClass`, refers to the | ||
| * fully-qualified class name of the registered service provider. | ||
| * | ||
| * @param class-string<Providable> $serviceProviderClass The registered service provider class. | ||
| * @param string[] $alias The aliases the provider was registered under. | ||
| */ | ||
| do_action($this->registeredAction($serviceProviderClass), $serviceProviderClass, $alias); | ||
|
|
||
| foreach ($alias as $slug) { | ||
| /** | ||
| * Fires after a service provider has been registered, once per alias. | ||
| * | ||
| * The dynamic portion of the hook name, `$slug`, refers to an alias the | ||
| * service provider was registered under. | ||
| * | ||
| * @param class-string<Providable> $serviceProviderClass The registered service provider class. | ||
| * @param string[] $alias The aliases the provider was registered under. | ||
| */ | ||
| do_action($this->registeredAction($slug), $serviceProviderClass, $alias); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function registerAfterAllActions(array $actions, string $serviceProviderClass, ...$alias): void { | ||
| $pending = array_values(array_filter($actions, static fn (string $action): bool => ! did_action($action))); | ||
|
|
||
| if ($pending === []) { | ||
| // All the actions have already fired, register the provider immediately. | ||
| $this->register($serviceProviderClass, ...$alias); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| // A single closure is hooked onto every pending action. Whichever action fires | ||
| // last finds all actions done, registers once, and detaches from the rest. | ||
| $register_when_ready = function () use ($actions, $pending, $serviceProviderClass, $alias, &$register_when_ready): void { | ||
| foreach ($actions as $action) { | ||
| if (! did_action($action)) { | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| // Detach from every pending action so the provider is only registered once. | ||
| foreach ($pending as $action) { | ||
| remove_action($action, $register_when_ready); | ||
| } | ||
|
|
||
| $this->register($serviceProviderClass, ...$alias); | ||
| }; | ||
|
|
||
| foreach ($pending as $action) { | ||
| add_action($action, $register_when_ready); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function registerOnAction(string $action, string $serviceProviderClass, ...$alias): void { | ||
| if (did_action($action)) { | ||
| // If the action has already fired, register the provider immediately. | ||
| $this->register($serviceProviderClass, ...$alias); | ||
|
|
||
| return; | ||
| } | ||
|
|
||
| // If the action has not fired yet, register the provider when/if it does. | ||
| $registration_closure = function () use ($action, $serviceProviderClass, $alias, &$registration_closure) { | ||
| // Remove the closure from the action to avoid calling it again. | ||
| remove_action($action, $registration_closure); | ||
| $this->register($serviceProviderClass, ...$alias); | ||
| }; | ||
|
|
||
| add_action($action, $registration_closure); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function registerOnProvider( | ||
| string $baseProviderClass, | ||
| string $dependentProviderClass, | ||
| ...$alias | ||
| ): void { | ||
| $this->registerOnAction($this->registeredAction($baseProviderClass), $dependentProviderClass, ...$alias); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function when(string $class): Container { | ||
| $this->container->when($class); | ||
|
|
||
| return $this; | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function needs(string $id): Container { | ||
| $this->container->needs($id); | ||
|
|
||
| return $this; | ||
| } | ||
|
|
||
| /** | ||
| * @param string[]|null $afterBuildMethods | ||
| * | ||
| * @throws \lucatume\DI52\ContainerException | ||
| */ | ||
| public function bind(string $id, mixed $implementation = null, ?array $afterBuildMethods = null): void { | ||
| $this->container->bind($id, $implementation, $afterBuildMethods); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| */ | ||
| public function get(string $id): mixed { | ||
| return $this->container->get($id); | ||
| } | ||
|
|
||
| /** | ||
| * @codeCoverageIgnore | ||
| */ | ||
| public function getContainer(): DI52Container { | ||
| return $this->container->getContainer(); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| * | ||
| * @codeCoverageIgnore | ||
| */ | ||
| public function has(string $id): bool { | ||
| return $this->container->has($id); | ||
| } | ||
|
|
||
| /** | ||
| * @param string[]|null $afterBuildMethods | ||
| * | ||
| * @throws \lucatume\DI52\ContainerException | ||
| */ | ||
| public function singleton(string $id, mixed $implementation = null, ?array $afterBuildMethods = null): void { | ||
| $this->container->singleton($id, $implementation, $afterBuildMethods); | ||
| } | ||
|
|
||
| public function give(mixed $implementation): void { | ||
| $this->container->give($implementation); | ||
| } | ||
|
|
||
| /** | ||
| * {@inheritDoc} | ||
| * | ||
| * @throws ContainerException | ||
| */ | ||
| public function mergeArrayVar(string $id, mixed $implementation): void { | ||
| $this->container->mergeArrayVar($id, $implementation); | ||
| } | ||
|
|
||
| /** | ||
| * @param array<mixed> $buildArgs | ||
| * @param string[]|null $afterBuildMethods | ||
| */ | ||
| public function instance(mixed $id, array $buildArgs = [], ?array $afterBuildMethods = null): Closure { | ||
| return $this->container->instance($id, $buildArgs, $afterBuildMethods); | ||
| } | ||
|
|
||
| /** | ||
| * @param class-string|string|object $id | ||
| * | ||
| * @throws ContainerException | ||
| */ | ||
| public function callback(object|string $id, string $method): callable { | ||
| return $this->container->callback($id, $method); | ||
| } | ||
|
|
||
| /** | ||
| * Defer all other calls to the wrapped Foundation container adapter. | ||
| * | ||
| * @param string $name The method name. | ||
| * @param mixed[] $args Method arguments. | ||
| */ | ||
| public function __call(string $name, array $args): mixed { | ||
|
defunctl marked this conversation as resolved.
|
||
| return $this->container->{$name}(...$args); | ||
| } | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.