* @package tao */ class ExceptionInterpreterService extends ConfigurableService { const SERVICE_ID = 'tao/ExceptionInterpreterService'; const OPTION_INTERPRETERS = 'interpreters'; /** * @param \Exception $e * @return ExceptionInterpretor */ public function getExceptionInterpreter(\Exception $e) { $interpreters = $this->hasOption(self::OPTION_INTERPRETERS) ? $this->getOption(self::OPTION_INTERPRETERS) : []; $exceptionClassesHierarchy = $this->getClassesHierarchy($e); $foundInterpreters = []; foreach ($interpreters as $configuredExceptionClass => $configuredInterpreterClass) { $configuredExceptionClass = trim($configuredExceptionClass, '\\'); if (isset($exceptionClassesHierarchy[$configuredExceptionClass])) { $foundInterpreters[$exceptionClassesHierarchy[$configuredExceptionClass]] = $configuredInterpreterClass; } } $interpreterClass = $foundInterpreters[min(array_keys($foundInterpreters))]; $result = new $interpreterClass(); $result->setException($e); $result->setServiceLocator($this->getServiceManager()); return $result; } /** * Function calculates exception classes hierarchy * * Example: * * Given hierarchy: * class B extends A {} * class A extends Exception {} * //B => A => Exception * * $this->getClassesHierarchy(new B) * * Result: * [ * 'B' => 0, * 'A' => 1, * 'Exception' => 2, * ] * * * @param \Exception $e * @return array where key is class name and value is index in the hierarchy */ protected function getClassesHierarchy(\Exception $e) { $exceptionClass = get_class($e); $exceptionClassesHierarchy = array_values(class_parents($exceptionClass)); array_unshift($exceptionClassesHierarchy, $exceptionClass); $exceptionClassesHierarchy = array_flip($exceptionClassesHierarchy); return $exceptionClassesHierarchy; } }