Installation
composer require chamber-orchestra/metadata-bundle
Add to config/bundles.php in Symfony:
return [
// ...
ChamberOrchestra\MetadataBundle\MetadataBundle::class => ['all' => true],
];
First Use Case: Annotate an Entity
use ChamberOrchestra\MetadataBundle\Annotation\Metadata;
#[ORM\Entity]
#[Metadata('cacheable' => true, 'driver' => 'doctrine')]
class Product
{
// ...
}
Access Metadata via Reader
$reader = $container->get('metadata.reader');
$metadata = $reader->loadMetadata(Product::class);
// Returns array: ['cacheable' => true, 'driver' => 'doctrine']
Attribute-Driven Metadata
#[Metadata] on entities/classes to define cacheable, driver-specific, or embedded metadata.#[Metadata('embedded' => true, 'driver' => 'custom')]
class Address {}
Cacheable Mapping
#[Metadata('cacheable' => true)] to optimize repeated metadata reads.config/packages/metadata.yaml:
chamber_orchestra_metadata:
cache_driver: apcu
Event-Driven Extensions
MetadataEvents (e.g., MetadataLoadedEvent) to modify metadata dynamically:
use ChamberOrchestra\MetadataBundle\Event\MetadataLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CustomMetadataSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
MetadataLoadedEvent::class => 'onMetadataLoaded',
];
}
public function onMetadataLoaded(MetadataLoadedEvent $event): void
{
$metadata = $event->getMetadata();
$metadata['custom_field'] = 'value'; // Extend metadata
}
}
Driver Integration
services.yaml:
services:
ChamberOrchestra\MetadataBundle\Driver\DriverInterface $custom_driver:
class: App\Driver\CustomDriver
tags: ['metadata.driver']
Cache Invalidation
php bin/console cache:clear
#[Metadata('cacheable' => false)] for volatile metadata.Driver Priority
priority in services.yaml:
tags: ['metadata.driver', { name: 'metadata.driver', priority: 100 }]
Annotation vs. Attribute
#[Metadata] (PHP 8+) and @Metadata (legacy). Prefer attributes for new projects.Circular Dependencies
Product referencing Address which references Product).Enable Debug Mode
Set APP_DEBUG=true in .env to log metadata events:
// config/packages/dev/metadata.yaml
chamber_orchestra_metadata:
debug: true
Inspect Loaded Metadata Use the debug command:
php bin/console debug:metadata App\Entity\Product
Custom Metadata Keys
Extend the MetadataReader to support additional keys:
$reader->addSupportedKey('custom_key');
Metadata Validation
Implement MetadataValidatorInterface to enforce rules:
use ChamberOrchestra\MetadataBundle\Validator\MetadataValidatorInterface;
class RequiredDriverValidator implements MetadataValidatorInterface
{
public function validate(array $metadata): void
{
if (!isset($metadata['driver'])) {
throw new \InvalidArgumentException('Driver is required.');
}
}
}
Embedded Entity Handling
Use #[Metadata('embedded' => true)] for lightweight entities. Override the EmbeddedMetadataDriver for custom logic:
services:
ChamberOrchestra\MetadataBundle\Driver\EmbeddedMetadataDriver:
class: App\Driver\CustomEmbeddedDriver
How can I help you explore Laravel packages today?