zenstruck / class-metadata
Add human readable class aliases & metadata with efficient lookups.
Fund package maintenance!
kbond
Installs: 661
Dependents: 1
Suggesters: 0
Security: 0
Stars: 5
Watchers: 3
Forks: 1
Open Issues: 1
Type:composer-plugin
Requires
- php: >=8.0
- composer-plugin-api: ^2.0
Requires (Dev)
- composer/composer: ^2.4
- doctrine/persistence: ^1.0|^2.0|^3.0
- phpstan/phpstan: ^1.4
- phpunit/phpunit: ^9.5
- symfony/phpunit-bridge: ^6.0
Suggests
- doctrine/persistence: To use the AliasManagerRegistry decorator
Conflicts
- composer: <2.4
README
Add human-readable class aliases and scalar metadata to your classes with an efficient runtime lookup. These can be added via attributes or composer.json configuration.
- Alias: short name for a class (could be used as an alternative to storing a FQCN in the database).
- Metadata: key-value map of scalar values specific to a class (could be used to mark a class as trackable in an auditing system).
This library provides a Composer plugin that hooks into Composer's dump-autoload event to generate a lookup map for use at runtime.
Installation
Note: This package requires composer 2.4+.
composer require zenstruck/class-metadata
- When asked to enable the Composer plugin, choose
y
(yes).
Configuration
Metadata and aliases can be added to class' via attributes or
composer.json
config.
- Aliases must be a non-empty string.
- Only 1 alias allowed per class.
- Multiple classes cannot have the same alias.
- Metadata keys must be strings.
- Metadata values must be scalar (
bool|float|int|string
).
Note: During development, when adding/changing/removing aliases and metadata, you need to run
composer dump-autoload
for the changes to take effect.
Attributes
When creating the autoload configuration for your application, the composer
plugin scans your PSR-4 autoload
path(s) (defined in your composer.json
)
to look for classes with the Alias
& Metadata
attributes. These are
parsed and a mapping file is generated.
namespace App\Entity; use Zenstruck\Alias; use Zenstruck\Metadata; #[Alias('user')] #[Metadata('track', true)] #[Metadata('identifier', 'getId')] class User { // ... }
Customize Paths
If you have a large code-base, scanning all the files could be time-consuming.
You can configure specific paths to scan in your composer.json
:
{ "extra": { "class-metadata": { "paths": [ "src/Domain/*/Entity" ] } } }
You can disable path scanning entirely and only configure via your
composer.json
:
{ "extra": { "class-metadata": { "paths": false } } }
composer.json
Metadata and aliases can also be configured in your composer.json
. This allows
adding aliases and metadata to 3rd party classes:
{ "extra": { "class-metadata": { "map": { "Vendor\\Code\\Class1": "class1", "Vendor\\Code\\Class2": { "alias": "class2", "key1": "value", "key2": 7 } } } } }
For the mapping, a string is a shortcut for an alias (class1
in the example
above). An array will be used as the metadata except the special alias
key.
This value will be used as the alias (class2
in the example above).
Runtime API
Since the alias/metadata maps are created when Composer creates the autoload files, runtime lookups are fast - just fetching from generated PHP constant array's.
The following examples use the user class shown above.
Alias Lookup
use Zenstruck\Alias; // alias for class lookup: Alias::for(User::class); // "user" (string|null - the alias for User or null if none) Alias::for(new User()); // "user" (alternatively, you can pass the object directly) // class for alias lookup: Alias::classFor('user'); // "App\Entity\User" (class-string|null - the FQCN whose alias is "user")
Metadata Lookup
use Zenstruck\Metadata; // metadata for a class Metadata::for(User::class); // ['track' => true, 'identifier' => 'getId'] (array<string,scalar> - metadata array for User or empty array if none) Metadata::for(new User()); // ['track' => true, 'identifier' => 'getId'] (alternatively, you can pass the object directly) Metadata::for('user'); // ['track' => true, 'identifier' => 'getId'] (alternatively, fetch metadata by a class' alias) // metadata value for key Metadata::get(User::class, 'track'); // true (scalar|null - the metadata value for "key" or null if none) Metadata::get(new User(), 'track'); // true (alternatively, you can pass the object directly) Metadata::get('user', 'track'); // true (alternatively, fetch metadata by a class' alias) // "first" metadata value for list of keys Metadata::first(User::class, 'audit_id', 'identifier', 'id'); // "getId" (scalar|null - first metadata value found for" keys" (left to right) or null if none) Metadata::first(new User(), 'audit_id', 'identifier', 'id'); // "getId" (alternatively, you can pass the object directly) Metadata::first('user', 'audit_id', 'identifier', 'id'); // "getId" (alternatively, fetch metadata by a class' alias) // all classes with metadata key Metadata::classesWith('identifier'); // ["App\Entity\User"] (class-string[] - FQCN's that have metadata with key "identifier")
list-class-metadata
Command
A custom Composer command is provided to debug/list all classes that have metadata/aliases configured:
composer list-class-metadata
Using the User example above, the following would be output:
----------------- ------- -------------------------------------
Class Alias Metadata
----------------- ------- -------------------------------------
App\Entity\User user {"track":true,"identifier":"getId"}
----------------- ------- -------------------------------------
Doctrine Bridge
AliasManagerRegistry
This is a decorated ManagerRegistry
that allows using aliases for the
getRepository()
and getManagerForClass()
methods:
use Zenstruck\Metadata\Bridge\Doctrine\AliasManagerRegistry; /** @var \Doctrine\Persistence\ManagerRegistry $inner */ $registry = new AliasManagerRegistry($inner); $registry->getRepository('user'); // converts "user" alias to FQCN $registry->getRepository(User::class); // can still use FQCN $registry->getManagerForClass('user'); // converts "user" alias to FQCN $registry->getManagerForClass(User::class); // can still use FQCN