Skip to content

Commit

Permalink
Merge pull request #225 from koriym/refactor-bindings
Browse files Browse the repository at this point in the history
Binding multiple interceptors with multiple bindings in PECL AOP
  • Loading branch information
koriym authored Nov 6, 2024
2 parents 24f3cb8 + 2d5f44f commit 4536d0e
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 10 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ $aspect->bind(

$billing = $aspect->newInstance(RealBillingService::class);
try {
echo $billing->chargeOrder();
echo $billing->chargeOrder(); // Interceptors applied
} catch (\RuntimeException $e) {
echo $e->getMessage() . "\n";
exit(1);
Expand All @@ -103,7 +103,11 @@ $aspect->bind(
(new Matcher())->annotatedWith(NotOnWeekends::class),
[new WeekendBlocker()]
);
$aspect->weave(__DIR__ . '/src'); // Weave the aspects to all classes in the directory that match the matcher.
// Weave aspects into all matching classes in the source directory
$aspect->weave('/path/to/src');

// Or weave into specific target directory
$aspect->weave('/path/to/target');

$billing = new RealBillingService();
echo $billing->chargeOrder(); // Interceptors applied
Expand Down
27 changes: 19 additions & 8 deletions src/AspectPecl.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use RuntimeException;

use function array_keys;
use function array_merge;
use function assert;
use function class_exists;
use function extension_loaded;
Expand All @@ -35,20 +36,24 @@ public function __construct()
* Weave aspects into classes in the specified directory
*
* @param non-empty-string $classDir Target class directory
* @param MatcherConfigList $mathcers List of matchers and interceptors
* @param MatcherConfigList $matchers List of matchers and interceptors
*
* @throws RuntimeException When Ray.Aop extension is not loaded.
*/
public function weave(string $classDir, array $mathcers): void
public function weave(string $classDir, array $matchers): void
{
foreach (new ClassList($classDir) as $className) {
$boundInterceptors = $this->getBoundInterceptors($className, $mathcers);
$this->apply($boundInterceptors);
$boundInterceptors = $this->getBoundInterceptors($className, $matchers);
if ($boundInterceptors === []) {
continue;
}

$this->interceptMethods($boundInterceptors);
}
}

/**
* Process class for interception
* Get interceptors bound to class methods based on matchers
*
* @param class-string $className
* @param MatcherConfigList $matchers
Expand All @@ -73,19 +78,25 @@ private function getBoundInterceptors(string $className, array $matchers): array
continue;
}

$bound[$className][$method->getName()] = $matcher['interceptors'];
$methodName = $method->getName();
if (isset($bound[$className][$methodName])) {
$bound[$className][$methodName] = array_merge($bound[$className][$methodName], $matcher['interceptors']);
continue;
}

$bound[$className][$methodName] = $matcher['interceptors'];
}
}

return $bound;
}

/**
* Apply interceptors to bound methods
* Intercept methods with bounded interceptors using PECL extension
*
* @param ClassBoundInterceptors $boundInterceptors
*/
private function apply(array $boundInterceptors): void
private function interceptMethods(array $boundInterceptors): void
{
$dispatcher = new PeclDispatcher($boundInterceptors);
assert(function_exists('\method_intercept')); // PECL Ray.Aop extension
Expand Down

0 comments on commit 4536d0e

Please sign in to comment.