Completed
Push — master ( 6e8933...5ff1a9 )
by Brian
11s
created

AssertionException::traceLeoCall()   C

Complexity

Conditions 7
Paths 15

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 31
rs 6.7272
cc 7
eloc 17
nc 15
nop 1
1
<?php
2
namespace Peridot\Leo\Responder\Exception;
3
4
use Exception;
5
use ReflectionClass;
6
7
/**
8
 * Thrown by ExceptionResponder when an assertion fails.
9
 *
10
 * @package Peridot\Leo\Responder\Exception
11
 */
12
final class AssertionException extends Exception
13
{
14
    /**
15
     * Trim the supplied exception's stack trace to only include relevant
16
     * information.
17
     *
18
     * Also replaces the file path and line number.
19
     *
20
     * @param Exception $exception The exception.
21
     */
22
    public static function trim(Exception $exception)
23
    {
24
        $reflector = new ReflectionClass('Exception');
25
26
        $traceProperty = $reflector->getProperty('trace');
27
        $traceProperty->setAccessible(true);
28
        $fileProperty = $reflector->getProperty('file');
29
        $fileProperty->setAccessible(true);
30
        $lineProperty = $reflector->getProperty('line');
31
        $lineProperty->setAccessible(true);
32
33
        $call = static::traceLeoCall($traceProperty->getValue($exception));
34
35
        if ($call) {
36
            $traceProperty->setValue($exception, array($call));
37
            $fileProperty->setValue(
38
                $exception,
39
                isset($call['file']) ? $call['file'] : null
40
            );
41
            $lineProperty->setValue(
42
                $exception,
43
                isset($call['line']) ? $call['line'] : null
44
            );
45
        } else {
46
            $traceProperty->setValue($exception, array());
47
            $fileProperty->setValue($exception, null);
48
            $lineProperty->setValue($exception, null);
49
        }
50
    }
51
52
    /**
53
     * Find the Leo entry point call in a stack trace.
54
     *
55
     * @param array $trace The stack trace.
56
     *
57
     * @return array|null The call, or null if unable to determine the entry point.
58
     */
59
    public static function traceLeoCall(array $trace)
60
    {
61
        $prefix = 'Peridot\\Leo\\';
62
63
        $index = null;
64
        $broke = false;
65
66
        foreach ($trace as $index => $call) {
67
            if (isset($call['class'])) {
68
                if (0 !== strpos($call['class'], $prefix)) {
69
                    $broke = true;
70
71
                    break;
72
                }
73
            } elseif (0 !== strpos($call['function'], $prefix)) {
74
                $broke = true;
75
76
                break;
77
            }
78
        }
79
80
        if (null === $index) {
81
            return;
82
        }
83
84
        if (!$broke) {
85
            ++$index;
86
        }
87
88
        return $trace[$index - 1];
89
    }
90
91
    /**
92
     * Construct a new assertion exception.
93
     *
94
     * @param string $message The message.
95
     */
96
    public function __construct($message)
97
    {
98
        parent::__construct($message);
99
100
        static::trim($this);
101
    }
102
}
103