nucleardog / discovery
Dynamically discover PHP objects
Requires
- php: ^8.2
- illuminate/collections: ^11.0
- illuminate/support: ^11.0
This package is auto-updated.
Last update: 2024-12-24 23:46:19 UTC
README
Provide dynamic discovery of PHP objects.
Usage
[!note] Laravel
This documentation focuses on use of this package within Laravel. While it should work outside of Laravel, you will be responsible for setting up all the scaffolding currently managed by the included Laravel service provider.
This package provides a system for declaring interfaces, attributes, and other things which you are interested in and dynamically discovery all classes that are annotated with the attribute, implement the interface, etc.
Register Things to Discover
You can either register things directly in your configuration or at runtime.
Config
Publish the default configuration:
$ artisan vendor:publish --provider='Nucleardog\Discovery\Laravel\Providers\DiscoveryServiceProvider'
Edit the new config/discovery.php
class to list any interfaces or attributes
you want discovered. For example:
<?php
declare(strict_types=1);
return [
'discover' => [
// For any interface listed here, all classes implementing this interface
// will be discovered and available through the discovery class.
'interfaces' => [
\App\Contracts\ProvidesFoo::class,
],
// For any attributes listed here, all classes tagged with this attribute
// will be discovered and available through the discovery class.
'attributes' => [
//
],
],
// List the namespaces you want the discovery package to look in to find
// implementations.
'namespaces' => [
'App',
],
];
Runtime
In a service provider's register()
method, extend the Discovery class and
register any additional interfaces, attributes, or namespaces you are interested
in:
<?php
use Nucleardog\Discovery\Discovery;
class MyServiceProvider
{
public function register(): void
{
$this->app->extend(
Discovery::class,
function(Discovery $discovery) {
$discovery->addNamespace('My\\Module');
$discovery->addAttribute(\My\Module\Frobulates::class);
},
);
}
}
Fetched Discovered Things
At runtime, you can fetch things that have been discovered:
<?php
$discovery = app()->make(Discovery::class);
// Fetch all classes that implement an interface
$classes = $discovery->classes(\App\Contracts\ProvidesFoo::class);
foreach ($classes as $class) {
// $class is the class path (string) for the class implementing the interface
$instance = new $class();
$instance->getFoo();
}
// Fetch all classes that have an attribute attached
$attributes = $discovery->attributes(\My\Module\Frobulates::class);
foreach ($attributes as $class => $attribute) {
// $class is the class path (string) for the class with the attribute attached
// to it
// $attribute is an instantiated instance of the attribute class
}
// Fetch all classes that have an attribute attached, and fetch all instances
// of that attribute that are attached (if the attribute is declared more than
// once).
$attributes = $discovery->attributes(\My\Module\Frobulates::class, all: true);
foreach ($attributes as $class => $attributes) {
// $class is the class path (string) for the class with the attribute attached
// to it
// $attributes is an array of instantiated attribute classes.
}
Artisan Commands
This package register a few artisan commands:
discovery:list
Syntax:
artisan discovery:list
Lists all registered interfaces and attributes and the implementing classes that have been discovered.
discovery:cache
Syntax:
artisan discovery:cache
Caches all discovered classes in bootstrap/cache/discovery.php
so discovery
doesn't have to happen on every request.
discovery:clear
Syntax:
artisan discovery:clear
Clears the discovery cache.
Tests
Phpunit is included in a separate composer file and must be explicitly installed:
$ cd tools/phpunit/
$ composer install
Once installed, the tests can be run from the root package folder with:
$ composer test
Notes
The discovery process currently uses the composer class map to find all classes
in your project. During development, as files are added or removed from your
project, you may need to re-run composer dump-autoload
to regenerate the
class map for the discovery system to detect the changes.
Legal
Copyright 2024 Adam Pippin hello@adampippin.ca
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this project except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.