Weave 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

Aop Bundle Laravel Package

dmp/aop-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require dmp/aop-bundle
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        DMP\AopBundle\DmpAopBundle::class => ['all' => true],
    ];
    
  2. Configure Cache: Update config/packages/dmp_aop.yaml:

    jms_aop:
        cache_dir: '%kernel.cache_dir%/aop'
    
  3. First Use Case: Create a pointcut to match methods (e.g., logging delete methods) and an interceptor to execute logic.


Where to Look First

  • README: Focus on the Usage section for pointcut/interceptor structure.
  • Examples: Study the Logging example under Examples for a practical starting point.
  • Configuration: Verify cache_dir is writable and matches your Symfony cache setup.

Implementation Patterns

Core Workflow

  1. Define Pointcuts: Use annotations or class/method patterns to match targets (e.g., @Pointcut("execution(* delete*(..))")). Example:

    use DMP\AopBundle\Pointcut\PointcutInterface;
    
    class DeleteMethodPointcut implements PointcutInterface {
        public function matches(MethodReflection $method): bool {
            return str_contains($method->getName(), 'delete');
        }
    }
    
  2. Create Interceptors: Implement InterceptorInterface to define pre/post logic or method replacement. Example (logging interceptor):

    use DMP\AopBundle\Interceptor\InterceptorInterface;
    use Psr\Log\LoggerInterface;
    
    class LoggingInterceptor implements InterceptorInterface {
        private LoggerInterface $logger;
    
        public function __construct(LoggerInterface $logger) {
            $this->logger = $logger;
        }
    
        public function invoke(MethodInvocation $invocation) {
            $this->logger->info(sprintf(
                'Calling %s with args: %s',
                $invocation->getMethod()->getName(),
                json_encode($invocation->getArguments())
            ));
            return $invocation->proceed(); // Proceeds to original method
        }
    }
    
  3. Bind Pointcuts to Interceptors: Register bindings in a service configuration (e.g., services.yaml):

    services:
        DMP\AopBundle\Pointcut\DeleteMethodPointcut:
            tags: ['dmp_aop.pointcut']
        DMP\AopBundle\Interceptor\LoggingInterceptor:
            tags: ['dmp_aop.interceptor']
            arguments: ['@logger']
    
  4. Apply to Services: Use @Around or @Before annotations on target methods/services:

    use DMP\AopBundle\Annotation\Around;
    
    class ProductService {
        /**
         * @Around("execution(* delete*(..))")
         */
        public function deleteProduct() { ... }
    }
    

Integration Tips

  • Dependency Injection: Interceptors can leverage Symfony’s DI container (e.g., inject LoggerInterface).
  • Dynamic Logic: Use MethodInvocation to inspect arguments/method context before proceeding.
  • Performance: Cache pointcut/interceptor mappings in cache_dir to avoid runtime reflection overhead.
  • Testing: Mock MethodInvocation in unit tests to verify interceptor behavior.

Gotchas and Tips

Pitfalls

  1. Cache Invalidation: Clear the cache (php bin/console cache:clear) after adding/removing pointcuts/interceptors.

    php bin/console dmp:aop:clear-cache
    

    Tip: Use cache_dir outside var/ for shared environments.

  2. Method Matching Precision: Overly broad pointcuts (e.g., execution(* *(..))) may degrade performance. Tip: Use specific patterns like execution(* Service\* delete*(..)).

  3. Circular Dependencies: Interceptors depending on services that are also intercepted can cause deadlocks. Tip: Use @Before instead of @Around for one-way dependencies.

  4. Annotation Parsing: Annotations like @Around must be parsed by Symfony’s annotation reader. Tip: Ensure annotation_reader is configured in framework.yaml:

    framework:
        annotation_reader: 'annotation_reader'
    

Debugging

  1. Enable Logging: Add debug logs for interceptor invocation:

    monolog:
        handlers:
            main:
                level: debug
                channels: ['dmp_aop']
    

    Tip: Check logs for MethodInvocation details during debugging.

  2. Verify Pointcut Matches: Use var_dump() in PointcutInterface::matches() to confirm method signatures are matched correctly.

  3. Interceptor Order: Interceptors are applied in registration order. Use tags with priorities:

    tags: ['dmp_aop.interceptor', { priority: 100 }]
    

Extension Points

  1. Custom Matchers: Extend PointcutInterface to support complex logic (e.g., role-based access). Example:

    class RolePointcut implements PointcutInterface {
        public function matches(MethodReflection $method): bool {
            return $method->hasAnnotation(new Role('ROLE_ADMIN'));
        }
    }
    
  2. Aspect-Oriented Transactions: Use @Around to wrap methods in transactions:

    class TransactionInterceptor implements InterceptorInterface {
        public function invoke(MethodInvocation $invocation) {
            $entityManager = ...;
            $entityManager->beginTransaction();
            try {
                $result = $invocation->proceed();
                $entityManager->commit();
                return $result;
            } catch (\Exception $e) {
                $entityManager->rollback();
                throw $e;
            }
        }
    }
    
  3. Dynamic Interception: Register pointcuts/interceptors programmatically via DmpAopBundle events:

    use DMP\AopBundle\Event\PointcutEvent;
    
    $eventDispatcher->addListener(PointcutEvent::REGISTER, function (PointcutEvent $event) {
        $event->addPointcut(new DynamicPointcut());
    });
    

Config Quirks

  • Cache Directory Permissions: Ensure cache_dir is writable by the web server user. Fix: Run chmod -R 775 %kernel.cache_dir%/aop.

  • Symfony 6+ Compatibility: The bundle targets Symfony 5 but may work with 6+. Test with:

    composer require symfony/*:^6.0 --dev
    
  • Annotation Autoconfiguration: If annotations aren’t detected, enable auto_mapping in framework.yaml:

    framework:
        autowire: true
        auto_mapping: true
    
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.
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log
hsluv/hsluv
seampact/codegen