Completed
Pull Request — master (#13)
by
unknown
01:55
created

Whoops_Run_Composite   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 4
dl 0
loc 123
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A register() 0 10 1
A unregister() 0 4 1
A pushHandler() 0 3 1
A skipAllNoticesAndWarnings() 0 3 1
A watchSpecificPlugins() 0 3 1
A watchSpecificThemes() 0 3 1
C handleError() 0 52 11
1
<?php
2
namespace Rarst\wps;
3
4
use Whoops\Exception\ErrorException;
5
use Whoops\Exception\Inspector;
6
use Whoops\Run;
7
use Whoops\Util\SystemFacade;
8
9
/**
10
 * This class will show Errors and Warnings only if they are coming from
11
 * Specific Plugin
12
 */
13
class Whoops_Run_Composite {
14
15
    /**
16
     * @var SystemFacade
17
     */
18
    private $system;
19
    
20
    /**
21
     * @var Run
22
     */
23
    private $run;
24
    
25
    private $skipAllNoticesAndWarnings = false;
26
27
    private $watchSpecificPlugins = [];
28
29
    private $watchSpecificThemes = [];
30
31
    public function __construct(SystemFacade $system = null)
32
    {
33
        $this->system = $system ?: new SystemFacade;
34
        $this->run = new Run($this->system);
35
    }
36
37
    public function register() {
38
        class_exists("\\Whoops\\Exception\\ErrorException");
39
        class_exists("\\Whoops\\Exception\\FrameCollection");
40
        class_exists("\\Whoops\\Exception\\Frame");
41
        class_exists("\\Whoops\\Exception\\Inspector");
42
43
        $this->system->setErrorHandler([$this, Run::ERROR_HANDLER]);
44
        $this->system->setExceptionHandler([$this->run, Run::EXCEPTION_HANDLER]);
45
        $this->system->registerShutdownFunction([$this->run, Run::SHUTDOWN_HANDLER]);
46
    }
47
48
    public function unregister() {
49
        $this->system->restoreExceptionHandler();
50
        $this->system->restoreErrorHandler();
51
    }
52
53
    public function pushHandler($handler) {
54
        $this->run->pushHandler($handler);
55
    }
56
57
    public function skipAllNoticesAndWarnings() {
58
        $this->skipAllNoticesAndWarnings = true;
59
    }
60
61
    public function watchSpecificPlugins($plugins) {
62
        $this->watchSpecificPlugins = $plugins;
63
    }
64
65
    public function watchSpecificThemes($themes) {
66
        $this->watchSpecificThemes = $themes;
67
    }
68
69
    /**
70
     * Converts generic PHP errors to \ErrorException
71
     * instances, before passing them off to be handled.
72
     *
73
     * This method MUST be compatible with set_error_handler.
74
     *
75
     * @param int    $level
76
     * @param string $message
77
     * @param string $file
78
     * @param int    $line
79
     *
80
     * @return bool
81
     * @throws ErrorException
82
     */
83
    public function handleError($level, $message, $file = null, $line = null) {
84
85
        // Handle all fatals, exceptions etc.
86
        if(in_array(
87
            $level, 
88
            [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR]
89
        )) {
90
            $this->run->handleError($level, $message, $file, $line);
91
            return false;
92
        }
93
94
        // If All Notices and Warnings should be skipped, then short-circuit
95
        // error handler.
96
        if($this->skipAllNoticesAndWarnings) {
97
            return false;
98
        }
99
100
        // Watch for all plugins and Themes
101
        if( empty($this->watchSpecificPlugins) && empty($this->watchSpecificThemes ) ) {
102
            $this->run->handleError($level, $message, $file, $line);
103
            return false;
104
        }
105
106
        $watchablePlugins = empty($this->watchSpecificPlugins) ? [] : array_map(function($pluginBaseFolder){
107
            return 'plugins/' . $pluginBaseFolder;
108
        }, $this->watchSpecificPlugins);
109
110
        $watchableThemes = empty($this->watchSpecificThemes) ? [] : array_map(function($themeBaseFolder){
111
            return 'themes/' . $themeBaseFolder;
112
        }, $this->watchSpecificThemes);
113
114
        $directoriesToWatchFor = array_merge($watchablePlugins, $watchableThemes);
115
        $errorBelongsToWatchCriteria = false;
116
        
117
        // We are creating an exception object because Inspector Class needs it.
118
        $exception = new ErrorException($message, /*code*/ $level, /*severity*/ $level, $file, $line);
119
        $frames = (new Inspector($exception))->getFrames();
0 ignored issues
show
Documentation introduced by
$exception is of type object<Whoops\Exception\ErrorException>, but the function expects a object<Throwable>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
120
        foreach( $frames as $frame ) {
121
            foreach($directoriesToWatchFor as $directory) {
122
                if (strpos($frame->getFile(), $directory) !== false) {
123
                    $errorBelongsToWatchCriteria = true;
124
                    break 2;
125
                }
126
            }
127
        }
128
129
        if($errorBelongsToWatchCriteria) {
130
            $this->run->handleError($level, $message, $file, $line);
131
        }
132
133
        return false;
134
    }
135
}