Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ExceptionInterpreterService
100.00% covered (success)
100.00%
18 / 18
100.00% covered (success)
100.00%
2 / 2
5
100.00% covered (success)
100.00%
1 / 1
 getExceptionInterpreter
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
4
 getClassesHierarchy
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; under version 2
7 * of the License (non-upgradable).
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17 *
18 * Copyright (c) 2017 (original work) Open Assessment Technologies SA (under the project TAO-PRODUCT);
19 *
20 *
21 */
22
23namespace oat\tao\model\mvc\error;
24
25use oat\oatbox\service\ConfigurableService;
26
27/**
28 * Registry for exception interpreter
29 *
30 * @access public
31 * @author Aleh Hutnikau, <hutnikau@1pt.com>
32 * @package tao
33 */
34class ExceptionInterpreterService extends ConfigurableService
35{
36    public const SERVICE_ID = 'tao/ExceptionInterpreterService';
37
38    public const OPTION_INTERPRETERS = 'interpreters';
39
40    /**
41     * @param \Exception $e
42     * @return ExceptionInterpretor
43     */
44    public function getExceptionInterpreter(\Exception $e)
45    {
46        $interpreters = $this->hasOption(self::OPTION_INTERPRETERS) ?
47            $this->getOption(self::OPTION_INTERPRETERS) : [];
48
49        $exceptionClassesHierarchy = $this->getClassesHierarchy($e);
50
51        $foundInterpreters = [];
52        foreach ($interpreters as $configuredExceptionClass => $configuredInterpreterClass) {
53            $configuredExceptionClass = trim($configuredExceptionClass, '\\');
54            if (isset($exceptionClassesHierarchy[$configuredExceptionClass])) {
55                $foundInterpreters[$exceptionClassesHierarchy[$configuredExceptionClass]] = $configuredInterpreterClass;
56            }
57        }
58
59        $interpreterClass = $foundInterpreters[min(array_keys($foundInterpreters))];
60        $result = new $interpreterClass();
61
62        $result->setException($e);
63        $result->setServiceLocator($this->getServiceManager());
64        return $result;
65    }
66
67    /**
68     * Function calculates exception classes hierarchy
69     *
70     * Example:
71     *
72     * Given hierarchy:
73     * class B extends A {}
74     * class A extends Exception {}
75     * //B => A => Exception
76     *
77     * $this->getClassesHierarchy(new B)
78     *
79     * Result:
80     * [
81     *   'B' => 0,
82     *   'A' => 1,
83     *   'Exception' => 2,
84     * ]
85     *
86     *
87     * @param \Exception $e
88     * @return array where key is class name and value is index in the hierarchy
89     */
90    protected function getClassesHierarchy(\Exception $e)
91    {
92        $exceptionClass = get_class($e);
93        $exceptionClassesHierarchy = array_values(class_parents($exceptionClass));
94        array_unshift($exceptionClassesHierarchy, $exceptionClass);
95        $exceptionClassesHierarchy = array_flip($exceptionClassesHierarchy);
96        return $exceptionClassesHierarchy;
97    }
98}