/** * This method binds the concern to the advice. * * @access public * @param callable $concern the concern to be bound * @param boolean $enabled whether the advice is applied * @return mixed the returned result of the concern */ public function bind($concern, $enabled = true) { $joinPoint =& $this->joinPoint; if ($enabled) { $pointcuts =& $this->pointcuts; $closure = function () use(&$concern, &$pointcuts, &$joinPoint) { $joinPoint->setAroundClosure(null); if (isset($pointcuts['Before'])) { foreach ($pointcuts['Before'] as $pointcut) { $joinPoint->setAdviceType(AOP\AdviceType::before()); $joinPoint->setPointcut($pointcut); $method = $pointcut['method']; $method($joinPoint); } } try { $joinPoint->setReturnedValue(call_user_func_array($concern, $joinPoint->getArguments())); if (isset($pointcuts['AfterReturning'])) { foreach ($pointcuts['AfterReturning'] as $pointcut) { $joinPoint->setAdviceType(AOP\AdviceType::afterReturning()); $joinPoint->setPointcut($pointcut); $method = $pointcut['method']; $method($joinPoint); } } } catch (\Exception $exception) { $joinPoint->setException($exception); if (isset($pointcuts['AfterThrowing'])) { foreach ($pointcuts['AfterThrowing'] as $pointcut) { $joinPoint->setAdviceType(AOP\AdviceType::afterThrowing()); $joinPoint->setPointcut($pointcut); $method = $pointcut['method']; $method($joinPoint); } } } //finally { if (isset($pointcuts['After'])) { foreach ($pointcuts['After'] as $pointcut) { $joinPoint->setAdviceType(AOP\AdviceType::after()); $joinPoint->setPointcut($pointcut); $method = $pointcut['method']; $method($joinPoint); } } //} $exception = $joinPoint->getException(); if ($exception instanceof \Exception) { throw $exception; } }; if (isset($pointcuts['Around'])) { foreach ($pointcuts['Around'] as $pointcut) { $joinPoint->setAdviceType(AOP\AdviceType::around()); $joinPoint->setAroundClosure($closure); $joinPoint->setPointcut($pointcut); $method = $pointcut['method']; $method($joinPoint); } } else { $closure(); } return $joinPoint->getReturnedValue(); } return call_user_func_array($concern, $joinPoint->getArguments()); }
/** * This method is meant to be used by "around" advice to allow for the direct * calling of the concern's logic. This method should only be called when inside * a pointcut that is administrating "around" advice. * * @access public * @return mixed the returned value by the concern */ public function proceed() { if (AOP\AdviceType::around()->__equals($this->adviceType)) { $closure = $this->closure; if ($closure !== null) { return $closure(); } } return null; }