Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Class Meta Laravel Package

ashleydawson/class-meta

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require ashleydawson/class-meta
    

    Add to composer.json autoload if not auto-discovered:

    "autoload": {
        "files": ["vendor/ashleydawson/class-meta/Annotation/AnnotationRegistry.php"]
    }
    

    Run composer dump-autoload.

  2. First Use Case: Annotate a class/constant with metadata (see README example) and retrieve it via the manager:

    $manager = new \AshleyDawson\ClassMeta\ClassMetaManager();
    $meta = $manager->getClassMeta(\Acme\Enum\InvoiceStatus::class);
    
  3. Key Files:

    • Annotation/Meta.php (annotation definition)
    • ClassMetaManager.php (core retrieval logic)
    • AnnotationRegistry.php (annotation autoloader)

Implementation Patterns

Common Workflows

  1. Enum/Constant Metadata:

    // Define
    class UserRole {
        /** @Meta(data={"permission": ["create", "read"]}) */
        const ADMIN = 'admin';
    }
    
    // Use
    $roleMeta = $manager->getConstantMeta(UserRole::ADMIN);
    $permissions = $roleMeta->getData()['permission'];
    
  2. Dynamic Lookups:

    // Cache metadata in a service provider
    public function boot() {
        $this->app->singleton('role.metadata', function() {
            return collect([
                UserRole::ADMIN => $manager->getConstantMeta(UserRole::ADMIN),
                // ...
            ]);
        });
    }
    
  3. Validation Integration:

    // Validate against metadata
    $validPermissions = $manager->getConstantMeta(UserRole::ADMIN)->getData()['permission'];
    if (!in_array('create', $validPermissions)) {
        abort(403);
    }
    
  4. API Responses:

    // Serialize metadata for API
    return response()->json([
        'statuses' => array_map(function($constant) {
            return [
                'value' => $constant,
                'label' => $manager->getConstantMeta($constant)->getData()['name']
            ];
        }, InvoiceStatus::getConstants())
    ]);
    

Integration Tips

  • Laravel Service Provider: Bind the manager to the container for dependency injection:

    $this->app->singleton(ClassMetaManager::class);
    
  • Annotation Parsing: Use AnnotationRegistry::registerLoader() to customize annotation parsing (e.g., for PHPDoc parsing libraries like phpDocumentor).

  • Caching: Cache metadata in a service provider or use Laravel’s cache:

    $meta = Cache::remember("meta.{$class}", now()->addHours(1), function() use ($manager, $class) {
        return $manager->getClassMeta($class);
    });
    

Gotchas and Tips

Pitfalls

  1. Annotation Parsing:

    • Issue: Annotations may not parse if PHPDoc format is non-standard (e.g., missing @ or incorrect spacing).
    • Fix: Use AnnotationRegistry::registerLoader() with a custom loader or validate annotations with a regex:
      if (!preg_match('/@Meta\(data={"([^"]*)"}\)/', $docComment)) {
          throw new \InvalidArgumentException("Invalid Meta annotation");
      }
      
  2. Performance:

    • Issue: Parsing annotations on every request can be slow for large codebases.
    • Fix: Cache metadata aggressively or pre-load during boot:
      // In a service provider
      $manager->getClassMeta(\Acme\Enum\InvoiceStatus::class); // Pre-load
      
  3. Namespace Sensitivity:

    • Issue: Metadata retrieval fails if the class isn’t autoloaded or the namespace is incorrect.
    • Fix: Use fully qualified class names (e.g., \Acme\Enum\InvoiceStatus instead of InvoiceStatus).
  4. Data Serialization:

    • Issue: data attribute is stored as a string (e.g., {"key":"value"}), requiring manual JSON decoding:
      $data = json_decode($meta->getData(), true);
      
    • Tip: Extend the Meta annotation to support typed data (e.g., arrays directly).

Debugging

  • Verify Annotations: Use ClassMetaManager::getClassMeta() with a non-existent class to check for parsing errors:

    try {
        $manager->getClassMeta(\NonExistentClass::class);
    } catch (\Exception $e) {
        // Debug annotation parsing
    }
    
  • Check Autoloading: Ensure AnnotationRegistry.php is autoloaded. Run:

    composer dump-autoload --optimize
    

Extension Points

  1. Custom Metadata Storage: Extend ClassMetaManager to store metadata in a database or Redis:

    class DatabaseMetaManager extends ClassMetaManager {
        public function getClassMeta($class) {
            $cached = Cache::get("meta.{$class}");
            if (!$cached) {
                $cached = parent::getClassMeta($class);
                Cache::put("meta.{$class}", $cached);
            }
            return $cached;
        }
    }
    
  2. Annotation Validation: Add validation rules to the Meta annotation:

    use AshleyDawson\ClassMeta\Annotation\Meta;
    
    /**
     * @Meta(data={"required": ["name"], "type": "object"})
     */
    class ValidatedEnum { ... }
    
  3. Laravel Blade Directives: Create a Blade directive to output metadata in views:

    Blade::directive('meta', function($expression) {
        $class = $expression;
        return "<?php echo \$manager->getClassMeta({$class})->getData()['name'] ?? ''; ?>";
    });
    

    Usage:

    @meta(\Acme\Enum\InvoiceStatus::class)
    
  4. Testing: Mock the ClassMetaManager in tests:

    $manager = Mockery::mock(ClassMetaManager::class);
    $manager->shouldReceive('getClassMeta')
            ->with(\Acme\Enum\InvoiceStatus::class)
            ->andReturn((object) ['data' => json_encode(['name' => 'Test'])]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle