/** * Create a callback which bind the advice in the weaver. * * @param int $kind The kind. * * @param \Aop\Pointcut\PointcutInterface $pointcut The pointcut instance containing * the selector. * * @param \Aop\Advice\AdviceInterface $advice The callback to invoke * if pointcut is triggered. * * @param array $options An array of options for the advice. * * @return \Closure The callback (advice) for the weaver. * * @throws \Aop\Exception\PointcutException If the pointcut does not contain the selector. */ protected function createBinder($kind, PointcutInterface $pointcut, AdviceInterface $advice, array $options = []) { // assign the index of this $this->lastIndex++; $index = $this->lastIndex; // if options for the advice if (!empty($options['advice'])) { $advice->addOptions($options['advice']); } if (!$pointcut->getSelector()) { throw new PointcutException('The instance of the pointcut must contain the selector.'); } // add the advice in the queue self::$context[$index] = ['advice' => $advice, 'pointcut' => $pointcut, 'binder' => null, 'called' => false, 'enabled' => true, 'args' => null, 'exception' => null, 'kind' => $kind]; // create the reference of the context to add to Patchwork $context =& self::$context; // add the advice in the binder (container of callback) and bind the advice $this->doBindAdvice($index); return function () use($index, &$context) { // change the status $context[$index]['called'] = true; // arguments passed to the intercepted function $context[$index]['args'] = Stack\top('args'); // Resolve to JoinPoint // and execute the registered callback // for this pointcut (the advice or the original code) return $context[$index]['binder']($this->resolveJoinPoint($index)); }; }
/** * Add a `Pointcut` in the `PointcutCollection`. * * @param \Aop\Pointcut\PointcutInterface $pointcut * @return PointcutCollection The current instance. */ public function add(PointcutInterface $pointcut) { $this->container[$pointcut->getName()] = $pointcut; return $this; }