Passed
Push — 0.8.x ( f4c27e...d54548 )
by Alexander
06:06 queued 03:07
created
src/components/Debug/Exceptions/Handlers/PleasingPageHandler.php 1 patch
Indentation   +462 added lines, -462 removed lines patch added patch discarded remove patch
@@ -39,485 +39,485 @@
 block discarded – undo
39 39
  */
40 40
 class PleasingPageHandler extends Handler
41 41
 {
42
-	/**
43
-	 * The brand main of handler.
44
-	 * 
45
-	 * @var string $brand
46
-	 */
47
-	protected $brand = 'Lenevor Debug';
48
-
49
-	/**
50
-	 * A string identifier for a known IDE/text editor, or a closure
51
-	 * that resolves a string that can be used to open a given file
52
-	 * in an editor.
53
-	 * 
54
-	 * @var mixed $editor
55
-	 */
56
-	protected $editor;
57
-
58
-	/**
59
-	 * A list of known editor strings.
60
-	 * 
61
-	 * @var array $editors
62
-	 */
63
-	protected $editors = [
64
-		"vscode"   => "vscode://file/%file:%line",
65
-		"sublime"  => "subl://open?url=file://%file&line=%line",
66
-		"phpstorm" => "phpstorm://open?file://%file&line=%line",
67
-		"textmate" => "txmt://open?url=file://%file&line=%line",
68
-		"atom"     => "atom://core/open/file?filename=%file&line=%line",
69
-	];
42
+    /**
43
+     * The brand main of handler.
44
+     * 
45
+     * @var string $brand
46
+     */
47
+    protected $brand = 'Lenevor Debug';
48
+
49
+    /**
50
+     * A string identifier for a known IDE/text editor, or a closure
51
+     * that resolves a string that can be used to open a given file
52
+     * in an editor.
53
+     * 
54
+     * @var mixed $editor
55
+     */
56
+    protected $editor;
57
+
58
+    /**
59
+     * A list of known editor strings.
60
+     * 
61
+     * @var array $editors
62
+     */
63
+    protected $editors = [
64
+        "vscode"   => "vscode://file/%file:%line",
65
+        "sublime"  => "subl://open?url=file://%file&line=%line",
66
+        "phpstorm" => "phpstorm://open?file://%file&line=%line",
67
+        "textmate" => "txmt://open?url=file://%file&line=%line",
68
+        "atom"     => "atom://core/open/file?filename=%file&line=%line",
69
+    ];
70 70
 	
71
-	/**
72
-	 * The page title main of handler.
73
-	 * 
74
-	 * @var string $pageTitle
75
-	 */
76
-	protected $pageTitle = 'Lenevor Debug! There was an error';
71
+    /**
72
+     * The page title main of handler.
73
+     * 
74
+     * @var string $pageTitle
75
+     */
76
+    protected $pageTitle = 'Lenevor Debug! There was an error';
77 77
 	
78
-	/**
79
-	 * Fast lookup cache for known resource locations.
80
-	 * 
81
-	 * @var array $resourceCache
82
-	 */
83
-	protected $resourceCache = [];
78
+    /**
79
+     * Fast lookup cache for known resource locations.
80
+     * 
81
+     * @var array $resourceCache
82
+     */
83
+    protected $resourceCache = [];
84 84
 	
85
-	/**
86
-	 * The path to the directory containing the html error template directories.
87
-	 * 
88
-	 * @var array $searchPaths
89
-	 */
90
-	protected $searchPaths = [];
91
-
92
-	/**
93
-	 * Gets the table of data.
94
-	 * 
95
-	 * @var array $tables
96
-	 */
97
-	protected $tables = [];
85
+    /**
86
+     * The path to the directory containing the html error template directories.
87
+     * 
88
+     * @var array $searchPaths
89
+     */
90
+    protected $searchPaths = [];
91
+
92
+    /**
93
+     * Gets the table of data.
94
+     * 
95
+     * @var array $tables
96
+     */
97
+    protected $tables = [];
98 98
 	
99
-	/**
100
-	 * The template handler system.
101
-	 * 
102
-	 * @var string|object $template
103
-	 */
104
-	protected $template;	
99
+    /**
100
+     * The template handler system.
101
+     * 
102
+     * @var string|object $template
103
+     */
104
+    protected $template;	
105 105
 	
106
-	/**
107
-	 * Constructor. The PleasingPageHandler class.
108
-	 * 
109
-	 * @return void
110
-	 */
111
-	public function __construct()
112
-	{
113
-		$this->template      = new TemplateHandler;
114
-		$this->searchPaths[] = dirname(__DIR__).DIRECTORY_SEPARATOR.'Resources';
115
-	}
116
-
117
-	/**
118
-	 * Adds an editor resolver, identified by a string name, and that may be a 
119
-	 * string path, or a callable resolver.
120
-	 * 
121
-	 * @param  string            $identifier
122
-	 * @param  string|\Callable  $resolver
123
-	 * 
124
-	 * @return void
125
-	 */
126
-	public function addEditor($identifier, $resolver): void
127
-	{
128
-		$this->editors[$identifier] = $resolver;
129
-	}
130
-
131
-	/**
132
-	 * Adds an entry to the list of tables displayed in the template.
133
-	 * The expected data is a simple associative array. Any nested arrays
134
-	 * will be flattened with print_r.
135
-	 * 
136
-	 * @param  \Syscodes\Components\Contracts\Debug\Table  $table
137
-	 * 
138
-	 * @return void
139
-	 */
140
-	public function addTables(Table $table): void
141
-	{
142
-		$this->tables[] = $table;
143
-	}
106
+    /**
107
+     * Constructor. The PleasingPageHandler class.
108
+     * 
109
+     * @return void
110
+     */
111
+    public function __construct()
112
+    {
113
+        $this->template      = new TemplateHandler;
114
+        $this->searchPaths[] = dirname(__DIR__).DIRECTORY_SEPARATOR.'Resources';
115
+    }
116
+
117
+    /**
118
+     * Adds an editor resolver, identified by a string name, and that may be a 
119
+     * string path, or a callable resolver.
120
+     * 
121
+     * @param  string            $identifier
122
+     * @param  string|\Callable  $resolver
123
+     * 
124
+     * @return void
125
+     */
126
+    public function addEditor($identifier, $resolver): void
127
+    {
128
+        $this->editors[$identifier] = $resolver;
129
+    }
130
+
131
+    /**
132
+     * Adds an entry to the list of tables displayed in the template.
133
+     * The expected data is a simple associative array. Any nested arrays
134
+     * will be flattened with print_r.
135
+     * 
136
+     * @param  \Syscodes\Components\Contracts\Debug\Table  $table
137
+     * 
138
+     * @return void
139
+     */
140
+    public function addTables(Table $table): void
141
+    {
142
+        $this->tables[] = $table;
143
+    }
144 144
 	
145
-	/**
146
-	 * Gathers the variables that will be made available to the view.
147
-	 * 
148
-	 * @return  array
149
-	 */
150
-	protected function collectionVars(): array
151
-	{
152
-		$supervisor = $this->getSupervisor();
153
-		$style      = file_get_contents($this->getResource('css/debug.base.css'));
154
-		$jscript    = file_get_contents($this->getResource('js/debug.base.js'));
155
-		$servers    = array_merge($this->getDefaultServers(), $this->tables);
156
-		$routing    = array_merge($this->getDefaultRouting(), $this->tables);
157
-		$context    = array_merge($this->getDefaultContext(), $this->tables);
145
+    /**
146
+     * Gathers the variables that will be made available to the view.
147
+     * 
148
+     * @return  array
149
+     */
150
+    protected function collectionVars(): array
151
+    {
152
+        $supervisor = $this->getSupervisor();
153
+        $style      = file_get_contents($this->getResource('css/debug.base.css'));
154
+        $jscript    = file_get_contents($this->getResource('js/debug.base.js'));
155
+        $servers    = array_merge($this->getDefaultServers(), $this->tables);
156
+        $routing    = array_merge($this->getDefaultRouting(), $this->tables);
157
+        $context    = array_merge($this->getDefaultContext(), $this->tables);
158 158
 		
159
-		return [ 
160
-			'class' => explode('\\', $supervisor->getExceptionName()),
161
-			'stylesheet' => preg_replace('#[\r\n\t ]+#', ' ', $style),
162
-			'javascript' => preg_replace('#[\r\n\t ]+#', ' ', $jscript),
163
-			'header' => $this->getResource('views/partials/updown/header.php'),
164
-			'footer' => $this->getResource('views/partials/updown/footer.php'),
165
-			'info_exception' => $this->getResource('views/partials/info/info_exception.php'),
166
-			'section_stack_exception' => $this->getResource('views/partials/section_stack_exception.php'),
167
-			'section_frame' => $this->getResource('views/partials/section_frame.php'),
168
-			'frame_description' => $this->getResource('views/partials/frames/frame_description.php'),
169
-			'frame_list' => $this->getResource('views/partials/frames//frame_list.php'),
170
-			'section_code' => $this->getResource('views/partials/section_code.php'),
171
-			'code_source' => $this->getResource('views/partials/codes/code_source.php'),
172
-			'request_info' => $this->getResource('views/partials/request_info.php'),
173
-			'navigation' => $this->getResource('views/partials/details/navigation.php'),
174
-			'section_detail_context' => $this->getResource('views/partials/details/section_detail_context.php'),
175
-			'plain_exception' => Formatter::formatExceptionAsPlainText($this->getSupervisor()),
176
-			'handler' => $this,
177
-			'handlers' => $this->getDebug()->getHandlers(),
178
-			'debug' => $this->getDebug(),
179
-			'code' => $this->getExceptionCode(),
180
-			'message' => $supervisor->getExceptionMessage(),
181
-			'frames' => $this->getExceptionFrames(),
182
-			'servers' => $this->getProcessTables($servers),
183
-			'routes' => $this->getProcessTables($routing),
184
-			'contexts' => $this->getProcessTables($context),
185
-		];
186
-	}
159
+        return [ 
160
+            'class' => explode('\\', $supervisor->getExceptionName()),
161
+            'stylesheet' => preg_replace('#[\r\n\t ]+#', ' ', $style),
162
+            'javascript' => preg_replace('#[\r\n\t ]+#', ' ', $jscript),
163
+            'header' => $this->getResource('views/partials/updown/header.php'),
164
+            'footer' => $this->getResource('views/partials/updown/footer.php'),
165
+            'info_exception' => $this->getResource('views/partials/info/info_exception.php'),
166
+            'section_stack_exception' => $this->getResource('views/partials/section_stack_exception.php'),
167
+            'section_frame' => $this->getResource('views/partials/section_frame.php'),
168
+            'frame_description' => $this->getResource('views/partials/frames/frame_description.php'),
169
+            'frame_list' => $this->getResource('views/partials/frames//frame_list.php'),
170
+            'section_code' => $this->getResource('views/partials/section_code.php'),
171
+            'code_source' => $this->getResource('views/partials/codes/code_source.php'),
172
+            'request_info' => $this->getResource('views/partials/request_info.php'),
173
+            'navigation' => $this->getResource('views/partials/details/navigation.php'),
174
+            'section_detail_context' => $this->getResource('views/partials/details/section_detail_context.php'),
175
+            'plain_exception' => Formatter::formatExceptionAsPlainText($this->getSupervisor()),
176
+            'handler' => $this,
177
+            'handlers' => $this->getDebug()->getHandlers(),
178
+            'debug' => $this->getDebug(),
179
+            'code' => $this->getExceptionCode(),
180
+            'message' => $supervisor->getExceptionMessage(),
181
+            'frames' => $this->getExceptionFrames(),
182
+            'servers' => $this->getProcessTables($servers),
183
+            'routes' => $this->getProcessTables($routing),
184
+            'contexts' => $this->getProcessTables($context),
185
+        ];
186
+    }
187 187
 	
188
-	/**
189
-	 * The way in which the data sender (usually the server) can tell the recipient
190
-	 * (the browser, in general) what type of data is being sent in this case, html format tagged.
191
-	 * 
192
-	 * @return string
193
-	 */
194
-	public function contentType(): string
195
-	{
196
-		return 'text/html;charset=UTF-8';
197
-	}
198
-
199
-	/**
200
-	 * Gets the brand of project.
201
-	 * 
202
-	 * @return string
203
-	 */
204
-	public function getBrand(): string
205
-	{
206
-		return $this->brand;
207
-	}
208
-
209
-	/**
210
-	 * Returns the default servers.
211
-	 * 
212
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
213
-	 */
214
-	protected function getDefaultServers()
215
-	{
216
-		$server = [
217
-			'host' => $_SERVER['HTTP_HOST'], 
218
-			'user-agent' => $_SERVER['HTTP_USER_AGENT'], 
219
-			'accept' => $_SERVER['HTTP_ACCEPT'], 
220
-			'accept-language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
221
-			'accept-encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'],
222
-			'connection' => $_SERVER['HTTP_CONNECTION'],
223
-			'upgrade-insecure-requests' => $_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'], 
224
-			'sec-fetch-dest' => $_SERVER['HTTP_SEC_FETCH_DEST'],
225
-			'sec-fetch-mode' => $_SERVER['HTTP_SEC_FETCH_MODE'],
226
-			'sec-fetch-site' => $_SERVER['HTTP_SEC_FETCH_SITE'],
227
-			'sec-fetch-user' => $_SERVER['HTTP_SEC_FETCH_USER'],
228
-		];
229
-
230
-		return [new ArrayTable($server)];
231
-	}
232
-
233
-	/**
234
-	 * Returns the default routing.
235
-	 * 
236
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
237
-	 */
238
-	protected function getDefaultRouting()
239
-	{
240
-		$action = app('request')->route()->isControllerAction() 
241
-		          ? app('request')->route()->parseControllerCallback()[0] 
242
-		          : 'Closure';
243
-
244
-		$index = match (true) {
245
-			array_key_exists('web', app('router')->getMiddlewareGroups()) => 0,
246
-			array_key_exists('api', app('router')->getMiddlewareGroups()) => 1,
247
-		};
248
-
249
-		$routing = [
250
-			'Controller' => $action,
251
-			'Middleware' => array_keys(app('router')->getMiddlewareGroups())[$index],
252
-		];
253
-
254
-		return [new ArrayTable($routing)];
255
-	}
256
-
257
-	/**
258
-	 * Returns the default context data.
259
-	 * 
260
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
261
-	 */
262
-	protected function getDefaultContext()
263
-	{
264
-		$context = [
265
-			'Php Version' => PHP_VERSION,
266
-			'Lenevor Version' => app()->version(),
267
-			'Lenevor Locale' => config('app.locale'),
268
-			'App Debug' => (1 == env('APP_DEBUG') ? 'true' : 'false'),
269
-			'App Env' => env('APP_ENV'),
270
-		];
271
-
272
-		return [new ArrayTable($context)];
273
-	}
274
-
275
-	/**
276
-	 * Get the code of the exception that is currently being handled.
277
-	 * 
278
-	 * @return string
279
-	 */
280
-	protected function getExceptionCode()
281
-	{
282
-		$exception = $this->getException();
283
-		$code      = $exception->getCode();
284
-
285
-		if ($exception instanceof ErrorException) {
286
-			$code = Misc::translateErrorCode($exception->getSeverity());
287
-		}
288
-
289
-		return (string) $code;
290
-	}
291
-
292
-	/**
293
-	 * Get the stack trace frames of the exception that is currently being handled.
294
-	 * 
295
-	 * @return \Syscodes\Components\Debug\Engine\Supervisor;
296
-	 */
297
-	protected function getExceptionFrames()
298
-	{
299
-		$frames = $this->getSupervisor()->getFrames();
188
+    /**
189
+     * The way in which the data sender (usually the server) can tell the recipient
190
+     * (the browser, in general) what type of data is being sent in this case, html format tagged.
191
+     * 
192
+     * @return string
193
+     */
194
+    public function contentType(): string
195
+    {
196
+        return 'text/html;charset=UTF-8';
197
+    }
198
+
199
+    /**
200
+     * Gets the brand of project.
201
+     * 
202
+     * @return string
203
+     */
204
+    public function getBrand(): string
205
+    {
206
+        return $this->brand;
207
+    }
208
+
209
+    /**
210
+     * Returns the default servers.
211
+     * 
212
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
213
+     */
214
+    protected function getDefaultServers()
215
+    {
216
+        $server = [
217
+            'host' => $_SERVER['HTTP_HOST'], 
218
+            'user-agent' => $_SERVER['HTTP_USER_AGENT'], 
219
+            'accept' => $_SERVER['HTTP_ACCEPT'], 
220
+            'accept-language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
221
+            'accept-encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'],
222
+            'connection' => $_SERVER['HTTP_CONNECTION'],
223
+            'upgrade-insecure-requests' => $_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'], 
224
+            'sec-fetch-dest' => $_SERVER['HTTP_SEC_FETCH_DEST'],
225
+            'sec-fetch-mode' => $_SERVER['HTTP_SEC_FETCH_MODE'],
226
+            'sec-fetch-site' => $_SERVER['HTTP_SEC_FETCH_SITE'],
227
+            'sec-fetch-user' => $_SERVER['HTTP_SEC_FETCH_USER'],
228
+        ];
229
+
230
+        return [new ArrayTable($server)];
231
+    }
232
+
233
+    /**
234
+     * Returns the default routing.
235
+     * 
236
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
237
+     */
238
+    protected function getDefaultRouting()
239
+    {
240
+        $action = app('request')->route()->isControllerAction() 
241
+                  ? app('request')->route()->parseControllerCallback()[0] 
242
+                  : 'Closure';
243
+
244
+        $index = match (true) {
245
+            array_key_exists('web', app('router')->getMiddlewareGroups()) => 0,
246
+            array_key_exists('api', app('router')->getMiddlewareGroups()) => 1,
247
+        };
248
+
249
+        $routing = [
250
+            'Controller' => $action,
251
+            'Middleware' => array_keys(app('router')->getMiddlewareGroups())[$index],
252
+        ];
253
+
254
+        return [new ArrayTable($routing)];
255
+    }
256
+
257
+    /**
258
+     * Returns the default context data.
259
+     * 
260
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
261
+     */
262
+    protected function getDefaultContext()
263
+    {
264
+        $context = [
265
+            'Php Version' => PHP_VERSION,
266
+            'Lenevor Version' => app()->version(),
267
+            'Lenevor Locale' => config('app.locale'),
268
+            'App Debug' => (1 == env('APP_DEBUG') ? 'true' : 'false'),
269
+            'App Env' => env('APP_ENV'),
270
+        ];
271
+
272
+        return [new ArrayTable($context)];
273
+    }
274
+
275
+    /**
276
+     * Get the code of the exception that is currently being handled.
277
+     * 
278
+     * @return string
279
+     */
280
+    protected function getExceptionCode()
281
+    {
282
+        $exception = $this->getException();
283
+        $code      = $exception->getCode();
284
+
285
+        if ($exception instanceof ErrorException) {
286
+            $code = Misc::translateErrorCode($exception->getSeverity());
287
+        }
288
+
289
+        return (string) $code;
290
+    }
291
+
292
+    /**
293
+     * Get the stack trace frames of the exception that is currently being handled.
294
+     * 
295
+     * @return \Syscodes\Components\Debug\Engine\Supervisor;
296
+     */
297
+    protected function getExceptionFrames()
298
+    {
299
+        $frames = $this->getSupervisor()->getFrames();
300 300
 		
301
-		return $frames;
302
-	}
301
+        return $frames;
302
+    }
303 303
 	
304
-	/**
305
-	 * Gets the page title web.
306
-	 * 
307
-	 * @return string
308
-	 */
309
-	public function getPageTitle(): string
310
-	{
311
-		return $this->pageTitle;
312
-	}
313
-
314
-	/**
315
-	 * Processes an array of tables making sure everything is all right.
316
-	 * 
317
-	 * @param  \Syscodes\Components\Contracts\Debug\Table[]  $tables
318
-	 * 
319
-	 * @return array
320
-	 */
321
-	protected function getProcessTables(array $tables): array
322
-	{
323
-		$processTables = [];
324
-
325
-		foreach ($tables as $table) {
326
-			if ( ! $table instanceof Table) {
327
-				continue;
328
-			}
304
+    /**
305
+     * Gets the page title web.
306
+     * 
307
+     * @return string
308
+     */
309
+    public function getPageTitle(): string
310
+    {
311
+        return $this->pageTitle;
312
+    }
313
+
314
+    /**
315
+     * Processes an array of tables making sure everything is all right.
316
+     * 
317
+     * @param  \Syscodes\Components\Contracts\Debug\Table[]  $tables
318
+     * 
319
+     * @return array
320
+     */
321
+    protected function getProcessTables(array $tables): array
322
+    {
323
+        $processTables = [];
324
+
325
+        foreach ($tables as $table) {
326
+            if ( ! $table instanceof Table) {
327
+                continue;
328
+            }
329 329
 			
330
-			$label = $table->getLabel();
331
-
332
-			try {
333
-				$data = (array) $table->getData();
334
-
335
-				if ( ! (is_array($data) || $data instanceof Traversable)) {
336
-					$data = [];
337
-				}
338
-			} catch (Exception $e) {
339
-				$data = [];
340
-			}
341
-
342
-			$processTables[$label] = $data;
343
-		}
344
-
345
-		return $processTables;
346
-	}
347
-
348
-	/**
349
-	 * Finds a resource, by its relative path, in all available search paths.
350
-	 *
351
-	 * @param  string  $resource
352
-	 * 
353
-	 * @return string
354
-	 * 
355
-	 * @throws \RuntimeException
356
-	 */
357
-	protected function getResource($resource)
358
-	{
359
-		if (isset($this->resourceCache[$resource])) {
360
-			return $this->resourceCache[$resource];
361
-		}
362
-
363
-		foreach ($this->searchPaths as $path) {
364
-			$fullPath = $path.DIRECTORY_SEPARATOR.$resource;
365
-
366
-			if (is_file($fullPath)) {
367
-				// Cache:
368
-				$this->resourceCache[$resource] = $fullPath;
369
-
370
-				return $fullPath;
371
-			}
372
-		}
373
-
374
-		throw new RuntimeException( 
375
-				"Could not find resource '{$resource}' in any resource paths.". 
376
-				"(searched: ".join(", ", $this->searchPaths).")");
377
-	}
330
+            $label = $table->getLabel();
331
+
332
+            try {
333
+                $data = (array) $table->getData();
334
+
335
+                if ( ! (is_array($data) || $data instanceof Traversable)) {
336
+                    $data = [];
337
+                }
338
+            } catch (Exception $e) {
339
+                $data = [];
340
+            }
341
+
342
+            $processTables[$label] = $data;
343
+        }
344
+
345
+        return $processTables;
346
+    }
347
+
348
+    /**
349
+     * Finds a resource, by its relative path, in all available search paths.
350
+     *
351
+     * @param  string  $resource
352
+     * 
353
+     * @return string
354
+     * 
355
+     * @throws \RuntimeException
356
+     */
357
+    protected function getResource($resource)
358
+    {
359
+        if (isset($this->resourceCache[$resource])) {
360
+            return $this->resourceCache[$resource];
361
+        }
362
+
363
+        foreach ($this->searchPaths as $path) {
364
+            $fullPath = $path.DIRECTORY_SEPARATOR.$resource;
365
+
366
+            if (is_file($fullPath)) {
367
+                // Cache:
368
+                $this->resourceCache[$resource] = $fullPath;
369
+
370
+                return $fullPath;
371
+            }
372
+        }
373
+
374
+        throw new RuntimeException( 
375
+                "Could not find resource '{$resource}' in any resource paths.". 
376
+                "(searched: ".join(", ", $this->searchPaths).")");
377
+    }
378 378
 	
379
-	/**
380
-	 * Given an exception and status code will display the error to the client.
381
-	 * 
382
-	 * @return int|null
383
-	 */
384
-	public function handle()
385
-	{	
386
-		$templatePath = $this->getResource('views/debug.layout.php');
387
-
388
-		$vars = $this->collectionVars();
379
+    /**
380
+     * Given an exception and status code will display the error to the client.
381
+     * 
382
+     * @return int|null
383
+     */
384
+    public function handle()
385
+    {	
386
+        $templatePath = $this->getResource('views/debug.layout.php');
387
+
388
+        $vars = $this->collectionVars();
389 389
 		
390
-		if (empty($vars['message'])) $vars['message'] = __('exception.noMessage');
390
+        if (empty($vars['message'])) $vars['message'] = __('exception.noMessage');
391 391
 		
392
-		$this->template->setVariables($vars);
393
-		$this->template->render($templatePath);
392
+        $this->template->setVariables($vars);
393
+        $this->template->render($templatePath);
394 394
 		
395
-		return Handler::QUIT;
396
-	}
397
-
398
-	/**
399
-	 * Set the editor to use to open referenced files, by a string identifier or callable
400
-	 * that will be executed for every file reference. Should return a string.
401
-	 * 
402
-	 * @example  $debug->setEditor(function($file, $line) { return "file:///{$file}"; });
403
-	 * @example  $debug->setEditor('vscode');
404
-	 * 
405
-	 * @param  string  $editor
406
-	 * 
407
-	 * @return void
408
-	 * 
409
-	 * @throws \InvalidArgumentException
410
-	 */
411
-	public function setEditor($editor)
412
-	{
413
-		if ( ! is_callable($editor) && ! isset($this->editors[$editor])) {
414
-			throw new InvalidArgumentException("Unknown editor identifier: [{$editor}]. Known editors: " .
415
-				implode(', ', array_keys($this->editors))
416
-			);
417
-		}
418
-
419
-		$this->editor = $editor;
420
-	}
421
-
422
-	/**
423
-	 * Given a string file path, and an integer file line,
424
-	 * executes the editor resolver and returns.
425
-	 * 
426
-	 * @param  string  $file
427
-	 * @param  int	   $line
428
-	 * 
429
-	 * @return string|bool
430
-	 * 
431
-	 * @throws \UnexpectedValueException
432
-	 */
433
-	public function getEditorAtHref($file, $line)
434
-	{
435
-		$editor = $this->getEditor($file, $line);
436
-
437
-		if (empty($editor))	{
438
-			return false;
439
-		}
440
-
441
-		if ( ! isset($editor['url']) || ! is_string($editor['url'])) {
442
-			throw new UnexpectedValueException(__METHOD__.'should always resolve to a string or a valid editor array');
443
-		}
444
-
445
-		$editor['url'] = str_replace("%file", rawurldecode($file), $editor['url']);
446
-		$editor['url'] = str_replace("%line", rawurldecode($line), $editor['url']);
447
-
448
-		return $editor['url'];
449
-	}
450
-
451
-	/**
452
-	 * The editor must be a valid callable function/closure.
453
-	 * 
454
-	 * @param  string  $file
455
-	 * @param  int	   $line
456
-	 * 
457
-	 * @return array
458
-	 */
459
-	protected function getEditor($file, $line): array
460
-	{
461
-		if ( ! $this->editor || ( ! is_string($this->editor) && ! is_callable($this->editor))) {
462
-			return [];
463
-		}
464
-
465
-		if (is_string($this->editor) && isset($this->editors[$this->editor]) && ! is_callable($this->editors[$this->editor])) {
466
-			return ['url' => $this->editors[$this->editor]];
467
-		}
468
-
469
-		if (is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor]))) {
470
-			if (is_callable($this->editor)) {
471
-				$callback = call_user_func($this->editor, $file, $line);
472
-			} else {
473
-				$callback = call_user_func($this->editors[$this->editor], $file, $line);
474
-			}
475
-
476
-			if (empty($callback)) {
477
-				return [];
478
-			}
479
-
480
-			if (is_string($callback)) {
481
-				return ['url' => $callback];
482
-			}
395
+        return Handler::QUIT;
396
+    }
397
+
398
+    /**
399
+     * Set the editor to use to open referenced files, by a string identifier or callable
400
+     * that will be executed for every file reference. Should return a string.
401
+     * 
402
+     * @example  $debug->setEditor(function($file, $line) { return "file:///{$file}"; });
403
+     * @example  $debug->setEditor('vscode');
404
+     * 
405
+     * @param  string  $editor
406
+     * 
407
+     * @return void
408
+     * 
409
+     * @throws \InvalidArgumentException
410
+     */
411
+    public function setEditor($editor)
412
+    {
413
+        if ( ! is_callable($editor) && ! isset($this->editors[$editor])) {
414
+            throw new InvalidArgumentException("Unknown editor identifier: [{$editor}]. Known editors: " .
415
+                implode(', ', array_keys($this->editors))
416
+            );
417
+        }
418
+
419
+        $this->editor = $editor;
420
+    }
421
+
422
+    /**
423
+     * Given a string file path, and an integer file line,
424
+     * executes the editor resolver and returns.
425
+     * 
426
+     * @param  string  $file
427
+     * @param  int	   $line
428
+     * 
429
+     * @return string|bool
430
+     * 
431
+     * @throws \UnexpectedValueException
432
+     */
433
+    public function getEditorAtHref($file, $line)
434
+    {
435
+        $editor = $this->getEditor($file, $line);
436
+
437
+        if (empty($editor))	{
438
+            return false;
439
+        }
440
+
441
+        if ( ! isset($editor['url']) || ! is_string($editor['url'])) {
442
+            throw new UnexpectedValueException(__METHOD__.'should always resolve to a string or a valid editor array');
443
+        }
444
+
445
+        $editor['url'] = str_replace("%file", rawurldecode($file), $editor['url']);
446
+        $editor['url'] = str_replace("%line", rawurldecode($line), $editor['url']);
447
+
448
+        return $editor['url'];
449
+    }
450
+
451
+    /**
452
+     * The editor must be a valid callable function/closure.
453
+     * 
454
+     * @param  string  $file
455
+     * @param  int	   $line
456
+     * 
457
+     * @return array
458
+     */
459
+    protected function getEditor($file, $line): array
460
+    {
461
+        if ( ! $this->editor || ( ! is_string($this->editor) && ! is_callable($this->editor))) {
462
+            return [];
463
+        }
464
+
465
+        if (is_string($this->editor) && isset($this->editors[$this->editor]) && ! is_callable($this->editors[$this->editor])) {
466
+            return ['url' => $this->editors[$this->editor]];
467
+        }
468
+
469
+        if (is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor]))) {
470
+            if (is_callable($this->editor)) {
471
+                $callback = call_user_func($this->editor, $file, $line);
472
+            } else {
473
+                $callback = call_user_func($this->editors[$this->editor], $file, $line);
474
+            }
475
+
476
+            if (empty($callback)) {
477
+                return [];
478
+            }
479
+
480
+            if (is_string($callback)) {
481
+                return ['url' => $callback];
482
+            }
483 483
 			
484
-			return ['url' => isset($callback['url']) ? $callback['url'] : $callback];
485
-		}
484
+            return ['url' => isset($callback['url']) ? $callback['url'] : $callback];
485
+        }
486 486
 		
487
-		return [];
488
-	}
489
-
490
-	/**
491
-	 * Registered the editor.
492
-	 * 
493
-	 * @return string
494
-	 */
495
-	public function getEditorcode(): string
496
-	{
497
-		return $this->editor;
498
-	}
487
+        return [];
488
+    }
489
+
490
+    /**
491
+     * Registered the editor.
492
+     * 
493
+     * @return string
494
+     */
495
+    public function getEditorcode(): string
496
+    {
497
+        return $this->editor;
498
+    }
499 499
 	
500
-	/**
501
-	 * Sets the brand of project.
502
-	 * 
503
-	 * @param  string  $brand
504
-	 * 
505
-	 * @return void
506
-	 */
507
-	public function setBrand($brand): void
508
-	{
509
-		$this->brand = (string) $brand;
510
-	}
500
+    /**
501
+     * Sets the brand of project.
502
+     * 
503
+     * @param  string  $brand
504
+     * 
505
+     * @return void
506
+     */
507
+    public function setBrand($brand): void
508
+    {
509
+        $this->brand = (string) $brand;
510
+    }
511 511
 	
512
-	/**
513
-	 * Sets the page title web.
514
-	 * 
515
-	 * @param  string  $title
516
-	 * 
517
-	 * @return void
518
-	 */
519
-	public function setPageTitle($title): void
520
-	{
521
-		$this->pageTitle = (string) $title;
522
-	}
512
+    /**
513
+     * Sets the page title web.
514
+     * 
515
+     * @param  string  $title
516
+     * 
517
+     * @return void
518
+     */
519
+    public function setPageTitle($title): void
520
+    {
521
+        $this->pageTitle = (string) $title;
522
+    }
523 523
 }
524 524
\ No newline at end of file
Please login to merge, or discard this patch.
src/components/Debug/GDebug.php 1 patch
Indentation   +393 added lines, -393 removed lines patch added patch discarded remove patch
@@ -39,413 +39,413 @@
 block discarded – undo
39 39
  */
40 40
 class GDebug implements DebugContract
41 41
 {
42
-	/**
43
-	 * Allow Handlers to force the script to quit.
44
-	 * 
45
-	 * @var bool $allowQuit
46
-	 */
47
-	protected $allowQuit = true;
42
+    /**
43
+     * Allow Handlers to force the script to quit.
44
+     * 
45
+     * @var bool $allowQuit
46
+     */
47
+    protected $allowQuit = true;
48 48
 	
49
-	/**
50
-	 * Benchmark instance.
51
-	 * 
52
-	 * @var string|object $benchmark
53
-	 */
54
-	protected $benchmark;
55
-
56
-	/**
57
-	 * The handler stack.
58
-	 * 
59
-	 * @var array $handlerStack
60
-	 */
61
-	protected $handlerStack = [];
62
-
63
-	/**
64
-	 * The send Http code by default: 500 Internal Server Error.
65
-	 * 
66
-	 * @var bool $sendHttpCode
67
-	 */
68
-	protected $sendHttpCode = 500;
69
-
70
-	/**
71
-	 * The send output.
72
-	 * 
73
-	 * @var bool $sendOutput
74
-	 */
75
-	protected $sendOutput = true;
76
-
77
-	/**
78
-	 * The functions of system what control errors and exceptions.
79
-	 * 
80
-	 * @var string|object $system
81
-	 */
82
-	protected $system;
83
-
84
-	/**
85
-	 * In certain scenarios, like in shutdown handler, we can not throw exceptions.
86
-	 * 
87
-	 * @var bool $throwExceptions
88
-	 */
89
-	protected $throwExceptions = true;
90
-
91
-	/**
92
-	 * Constructor. The Debug class instance.
93
-	 * 
94
-	 * @param  \Syscodes\Components\Debug\Util\System|null  $system
95
-	 * 
96
-	 * @return void
97
-	 */
98
-	public function __construct(System $system = null)
99
-	{
100
-		$this->system    = $system ?: new System;
101
-		$this->benchmark = new Benchmark;
102
-	}
103
-
104
-	/**
105
-	 * Catches any uncaught errors and exceptions, including most Fatal errors. Will log the 
106
-	 * error, display it if display_errors is on, and fire an event that allows custom actions 
107
-	 * to be taken at this point.
108
-	 *
109
-	 * @param  \Throwable  $exception
110
-	 *
111
-	 * @return string
112
-	 */
113
-	public function handleException(Throwable $exception): string
114
-	{	
115
-		// The start benchmark
116
-		$this->benchmark->start('total_execution', LENEVOR_START);
117
-
118
-		$supervisor = $this->getSupervisor($exception);
119
-
120
-		// Start buffer
121
-		$this->system->startOutputBuferring();
122
-
123
-		$handlerResponse    = null;
124
-		$handlerContentType = null;
49
+    /**
50
+     * Benchmark instance.
51
+     * 
52
+     * @var string|object $benchmark
53
+     */
54
+    protected $benchmark;
55
+
56
+    /**
57
+     * The handler stack.
58
+     * 
59
+     * @var array $handlerStack
60
+     */
61
+    protected $handlerStack = [];
62
+
63
+    /**
64
+     * The send Http code by default: 500 Internal Server Error.
65
+     * 
66
+     * @var bool $sendHttpCode
67
+     */
68
+    protected $sendHttpCode = 500;
69
+
70
+    /**
71
+     * The send output.
72
+     * 
73
+     * @var bool $sendOutput
74
+     */
75
+    protected $sendOutput = true;
76
+
77
+    /**
78
+     * The functions of system what control errors and exceptions.
79
+     * 
80
+     * @var string|object $system
81
+     */
82
+    protected $system;
83
+
84
+    /**
85
+     * In certain scenarios, like in shutdown handler, we can not throw exceptions.
86
+     * 
87
+     * @var bool $throwExceptions
88
+     */
89
+    protected $throwExceptions = true;
90
+
91
+    /**
92
+     * Constructor. The Debug class instance.
93
+     * 
94
+     * @param  \Syscodes\Components\Debug\Util\System|null  $system
95
+     * 
96
+     * @return void
97
+     */
98
+    public function __construct(System $system = null)
99
+    {
100
+        $this->system    = $system ?: new System;
101
+        $this->benchmark = new Benchmark;
102
+    }
103
+
104
+    /**
105
+     * Catches any uncaught errors and exceptions, including most Fatal errors. Will log the 
106
+     * error, display it if display_errors is on, and fire an event that allows custom actions 
107
+     * to be taken at this point.
108
+     *
109
+     * @param  \Throwable  $exception
110
+     *
111
+     * @return string
112
+     */
113
+    public function handleException(Throwable $exception): string
114
+    {	
115
+        // The start benchmark
116
+        $this->benchmark->start('total_execution', LENEVOR_START);
117
+
118
+        $supervisor = $this->getSupervisor($exception);
119
+
120
+        // Start buffer
121
+        $this->system->startOutputBuferring();
122
+
123
+        $handlerResponse    = null;
124
+        $handlerContentType = null;
125 125
 		
126
-		try {
127
-			foreach (array_reverse($this->handlerStack) as $handler) {			
128
-				$handler->setDebug($this);
129
-				$handler->setException($exception);
130
-				$handler->setSupervisor($supervisor);
126
+        try {
127
+            foreach (array_reverse($this->handlerStack) as $handler) {			
128
+                $handler->setDebug($this);
129
+                $handler->setException($exception);
130
+                $handler->setSupervisor($supervisor);
131 131
 				
132
-				$handlerResponse = $handler->handle();
132
+                $handlerResponse = $handler->handle();
133 133
 	
134
-				// Collect the content type for possible sending in the headers
135
-				$handlerContentType = method_exists($handler, 'contentType') ? $handler->contentType() : null;
134
+                // Collect the content type for possible sending in the headers
135
+                $handlerContentType = method_exists($handler, 'contentType') ? $handler->contentType() : null;
136 136
 	
137
-				if (in_array($handlerResponse, [Handler::LAST_HANDLER, Handler::QUIT])) {
138
-					break;
139
-				}
140
-			}
137
+                if (in_array($handlerResponse, [Handler::LAST_HANDLER, Handler::QUIT])) {
138
+                    break;
139
+                }
140
+            }
141 141
 	
142
-			$quit = $handlerResponse == Handler::QUIT && $this->allowQuit();
143
-		} finally {
144
-			// Returns the contents of the output buffer
145
-			$output = $this->system->CleanOutputBuffer();	
146
-		}
147
-
148
-		// Returns the contents of the output buffer for loading time of page
149
-		$totalTime = $this->benchmark->getElapsedTime('total_execution');
150
-		$output    = str_replace('{{ elapsed_time }}', $totalTime, $output);
151
-
152
-		if ($this->writeToOutput()) {
153
-			if ($quit) {
154
-				while ($this->system->getOutputBufferLevel() > 0) {
155
-					// Cleanes the output buffer
156
-					$this->system->endOutputBuffering();
157
-				}
158
-
159
-				if (Misc::sendHeaders() && $handlerContentType)	{
160
-					header("Content-Type: {$handlerContentType}");
161
-				}
162
-			}
163
-
164
-			$this->writeToOutputBuffer($output);
165
-		}
166
-
167
-		if ($quit) {
168
-			$this->system->flushOutputBuffer();
169
-			$this->system->stopException($this->sendHttpCode());
170
-		}
171
-
172
-		return $output;
173
-	}
174
-
175
-	/**
176
-	 * Allow Handlers to force the script to quit.
177
-	 * 
178
-	 * @param  bool|int|null  $exit
179
-	 * 
180
-	 * @return bool
181
-	 */
182
-	public function allowQuit($exit = null): bool
183
-	{
184
-		if (func_num_args() == 0) {
185
-			return $this->allowQuit;
186
-		}
187
-
188
-		return $this->allowQuit = (bool) $exit;
189
-	}
190
-
191
-	/**
192
-	 * Lenevor Exception push output directly to the client it the data  
193
-	 * if they are true, but if it is false, the output will be returned 
194
-	 * by exception.
195
-	 * 
196
-	 * @param  bool|int|null  $send
197
-	 *
198
-	 * @return bool
199
-	 */
200
-	public function writeToOutput($send = null): bool
201
-	{
202
-		if (func_num_args() == 0) {
203
-			return $this->sendOutput;
204
-		}
142
+            $quit = $handlerResponse == Handler::QUIT && $this->allowQuit();
143
+        } finally {
144
+            // Returns the contents of the output buffer
145
+            $output = $this->system->CleanOutputBuffer();	
146
+        }
147
+
148
+        // Returns the contents of the output buffer for loading time of page
149
+        $totalTime = $this->benchmark->getElapsedTime('total_execution');
150
+        $output    = str_replace('{{ elapsed_time }}', $totalTime, $output);
151
+
152
+        if ($this->writeToOutput()) {
153
+            if ($quit) {
154
+                while ($this->system->getOutputBufferLevel() > 0) {
155
+                    // Cleanes the output buffer
156
+                    $this->system->endOutputBuffering();
157
+                }
158
+
159
+                if (Misc::sendHeaders() && $handlerContentType)	{
160
+                    header("Content-Type: {$handlerContentType}");
161
+                }
162
+            }
163
+
164
+            $this->writeToOutputBuffer($output);
165
+        }
166
+
167
+        if ($quit) {
168
+            $this->system->flushOutputBuffer();
169
+            $this->system->stopException($this->sendHttpCode());
170
+        }
171
+
172
+        return $output;
173
+    }
174
+
175
+    /**
176
+     * Allow Handlers to force the script to quit.
177
+     * 
178
+     * @param  bool|int|null  $exit
179
+     * 
180
+     * @return bool
181
+     */
182
+    public function allowQuit($exit = null): bool
183
+    {
184
+        if (func_num_args() == 0) {
185
+            return $this->allowQuit;
186
+        }
187
+
188
+        return $this->allowQuit = (bool) $exit;
189
+    }
190
+
191
+    /**
192
+     * Lenevor Exception push output directly to the client it the data  
193
+     * if they are true, but if it is false, the output will be returned 
194
+     * by exception.
195
+     * 
196
+     * @param  bool|int|null  $send
197
+     *
198
+     * @return bool
199
+     */
200
+    public function writeToOutput($send = null): bool
201
+    {
202
+        if (func_num_args() == 0) {
203
+            return $this->sendOutput;
204
+        }
205 205
 		
206
-		return $this->sendOutput = (bool) $send;
207
-	}
206
+        return $this->sendOutput = (bool) $send;
207
+    }
208 208
 	
209
-	/**
210
-	 * Generate output to the browser.
211
-	 * 
212
-	 * @param  string  $output
213
-	 * 
214
-	 * @return static
215
-	 */
216
-	protected function writeToOutputBuffer($output): static
217
-	{
218
-		if ($this->sendHttpCode() && Misc::sendHeaders()) {
219
-			$this->system->setHttpResponseCode($this->sendHttpCode());
220
-		}
209
+    /**
210
+     * Generate output to the browser.
211
+     * 
212
+     * @param  string  $output
213
+     * 
214
+     * @return static
215
+     */
216
+    protected function writeToOutputBuffer($output): static
217
+    {
218
+        if ($this->sendHttpCode() && Misc::sendHeaders()) {
219
+            $this->system->setHttpResponseCode($this->sendHttpCode());
220
+        }
221 221
 		
222
-		echo $output;
222
+        echo $output;
223 223
 		
224
-		return $this;
225
-	}
226
-
227
-	/**
228
-	 * Error handler
229
-	 *
230
-	 * This will catch the php native error and treat it as a exception which will 
231
-	 * provide a full back trace on all errors.
232
-	 *
233
-	 * @param  int  $level
234
-	 * @param  string  $message
235
-	 * @param  string|null  $file
236
-	 * @param  int|null  $line
237
-	 * 
238
-	 * @return bool
239
-	 * 
240
-	 * @throws \ErrorException
241
-	 */
242
-	public function handleError(
243
-		int $level, 
244
-		string $message, 
245
-		string $file = null, 
246
-		int $line = null
247
-	): bool {
248
-		if ($level & $this->system->getErrorReportingLevel()) {
249
-			$exception = new ErrorException($message, $level, $level, $file, $line);
250
-
251
-			if ($this->throwExceptions) {
252
-				throw $exception;
253
-			} else {
254
-				$this->handleException($exception);
255
-			}
256
-
257
-			return true;
258
-		}
259
-
260
-		return false;
261
-	}
262
-
263
-	/**
264
-	 * Appends a handler to the end of the stack.
265
-	 * 
266
-	 * @param  \Callable|\Syscodes\Components\Contracts\Debug\Handler  $handler
267
-	 * 
268
-	 * @return static
269
-	 */
270
-	public function appendHandler($handler): static
271
-	{
272
-		array_unshift($this->handlerStack, $this->resolveHandler($handler));
273
-
274
-		return $this;
275
-	}
276
-
277
-	/**
278
-	 * Prepends a handler to the start of the stack.
279
-	 * 
280
-	 * @param  \Callable|\Syscodes\Components\Contracts\Debug\Handler  $handler
281
-	 * 
282
-	 * @return static
283
-	 */
284
-	public function prependHandler($handler): static
285
-	{
286
-		return $this->pushHandler($handler);
287
-	}
288
-
289
-	/**
290
-	 * Pushes a handler to the end of the stack.
291
-	 * 
292
-	 * @param  string|callable  $handler
293
-	 * 
294
-	 * @return static
295
-	 */
296
-	public function pushHandler($handler): static
297
-	{
298
-		$this->handlerStack[] = $this->resolveHandler($handler);
299
-
300
-		return $this;
301
-	}
302
-
303
-	/**
304
-	 * Create a CallbackHandler from callable and throw if handler is invalid.
305
-	 * 
306
-	 * @param  \Callable|\Syscodes\Components\Contracts\Debug\Handler  $handler
307
-	 * 
308
-	 * @return \Syscodes\Components\Contracts\Debug\Handler
309
-	 * 
310
-	 * @throws \InvalidArgumentException If argument is not callable or instance of \Syscodes\Components\Contracts\Debug\Handler
311
-	 */
312
-	protected function resolveHandler($handler)
313
-	{
314
-		if (is_callable($handler)) {
315
-			$handler = new CallbackHandler($handler);
316
-		}
317
-
318
-		if ( ! $handler instanceof MainHandler) {
319
-			throw new InvalidArgumentException(
320
-				"Argument to " . __METHOD__ . " must be a callable, or instance of ".
321
-				"Syscodes\Components\\Contracts\\Debug\\MainHandler"
322
-			);
323
-		}
324
-
325
-		return $handler;
326
-	}
327
-
328
-	/**
329
-	 * Returns an array with all handlers, in the order they were added to the stack.
330
-	 * 
331
-	 * @return array
332
-	 */
333
-	public function getHandlers(): array
334
-	{
335
-		return $this->handlerStack;
336
-	}
337
-
338
-	/**
339
-	 * Clears all handlers in the handlerStack, including the default PleasingPage handler.
340
-	 * 
341
-	 * @return static
342
-	 */
343
-	public function clearHandlers(): static
344
-	{
345
-		$this->handlerStack = [];
346
-
347
-		return $this;
348
-	}
349
-
350
-	/**
351
-	 * Removes the last handler in the stack and returns it.
352
-	 * 
353
-	 * @return array|null
354
-	 */
355
-	public function popHandler()
356
-	{
357
-		return array_pop($this->handlerStack);
358
-	}
359
-
360
-	/**
361
-	 * Gets supervisor already specified.
362
-	 * 
363
-	 * @param  \Throwable  $exception
364
-	 * 
365
-	 * @return \Syscodes\Components\Debug\Engine\Supervisor
366
-	 */
367
-	protected function getSupervisor(Throwable $exception)
368
-	{
369
-		return new Supervisor($exception);
370
-	}
371
-
372
-	/**
373
-	 * Unregisters all handlers registered by this Debug instance.
374
-	 * 
375
-	 * @return void
376
-	 */
377
-	public function off(): void
378
-	{
379
-		$this->system->restoreExceptionHandler();
380
-		$this->system->restoreErrorHandler();
381
-	}
224
+        return $this;
225
+    }
226
+
227
+    /**
228
+     * Error handler
229
+     *
230
+     * This will catch the php native error and treat it as a exception which will 
231
+     * provide a full back trace on all errors.
232
+     *
233
+     * @param  int  $level
234
+     * @param  string  $message
235
+     * @param  string|null  $file
236
+     * @param  int|null  $line
237
+     * 
238
+     * @return bool
239
+     * 
240
+     * @throws \ErrorException
241
+     */
242
+    public function handleError(
243
+        int $level, 
244
+        string $message, 
245
+        string $file = null, 
246
+        int $line = null
247
+    ): bool {
248
+        if ($level & $this->system->getErrorReportingLevel()) {
249
+            $exception = new ErrorException($message, $level, $level, $file, $line);
250
+
251
+            if ($this->throwExceptions) {
252
+                throw $exception;
253
+            } else {
254
+                $this->handleException($exception);
255
+            }
256
+
257
+            return true;
258
+        }
259
+
260
+        return false;
261
+    }
262
+
263
+    /**
264
+     * Appends a handler to the end of the stack.
265
+     * 
266
+     * @param  \Callable|\Syscodes\Components\Contracts\Debug\Handler  $handler
267
+     * 
268
+     * @return static
269
+     */
270
+    public function appendHandler($handler): static
271
+    {
272
+        array_unshift($this->handlerStack, $this->resolveHandler($handler));
273
+
274
+        return $this;
275
+    }
276
+
277
+    /**
278
+     * Prepends a handler to the start of the stack.
279
+     * 
280
+     * @param  \Callable|\Syscodes\Components\Contracts\Debug\Handler  $handler
281
+     * 
282
+     * @return static
283
+     */
284
+    public function prependHandler($handler): static
285
+    {
286
+        return $this->pushHandler($handler);
287
+    }
288
+
289
+    /**
290
+     * Pushes a handler to the end of the stack.
291
+     * 
292
+     * @param  string|callable  $handler
293
+     * 
294
+     * @return static
295
+     */
296
+    public function pushHandler($handler): static
297
+    {
298
+        $this->handlerStack[] = $this->resolveHandler($handler);
299
+
300
+        return $this;
301
+    }
302
+
303
+    /**
304
+     * Create a CallbackHandler from callable and throw if handler is invalid.
305
+     * 
306
+     * @param  \Callable|\Syscodes\Components\Contracts\Debug\Handler  $handler
307
+     * 
308
+     * @return \Syscodes\Components\Contracts\Debug\Handler
309
+     * 
310
+     * @throws \InvalidArgumentException If argument is not callable or instance of \Syscodes\Components\Contracts\Debug\Handler
311
+     */
312
+    protected function resolveHandler($handler)
313
+    {
314
+        if (is_callable($handler)) {
315
+            $handler = new CallbackHandler($handler);
316
+        }
317
+
318
+        if ( ! $handler instanceof MainHandler) {
319
+            throw new InvalidArgumentException(
320
+                "Argument to " . __METHOD__ . " must be a callable, or instance of ".
321
+                "Syscodes\Components\\Contracts\\Debug\\MainHandler"
322
+            );
323
+        }
324
+
325
+        return $handler;
326
+    }
327
+
328
+    /**
329
+     * Returns an array with all handlers, in the order they were added to the stack.
330
+     * 
331
+     * @return array
332
+     */
333
+    public function getHandlers(): array
334
+    {
335
+        return $this->handlerStack;
336
+    }
337
+
338
+    /**
339
+     * Clears all handlers in the handlerStack, including the default PleasingPage handler.
340
+     * 
341
+     * @return static
342
+     */
343
+    public function clearHandlers(): static
344
+    {
345
+        $this->handlerStack = [];
346
+
347
+        return $this;
348
+    }
349
+
350
+    /**
351
+     * Removes the last handler in the stack and returns it.
352
+     * 
353
+     * @return array|null
354
+     */
355
+    public function popHandler()
356
+    {
357
+        return array_pop($this->handlerStack);
358
+    }
359
+
360
+    /**
361
+     * Gets supervisor already specified.
362
+     * 
363
+     * @param  \Throwable  $exception
364
+     * 
365
+     * @return \Syscodes\Components\Debug\Engine\Supervisor
366
+     */
367
+    protected function getSupervisor(Throwable $exception)
368
+    {
369
+        return new Supervisor($exception);
370
+    }
371
+
372
+    /**
373
+     * Unregisters all handlers registered by this Debug instance.
374
+     * 
375
+     * @return void
376
+     */
377
+    public function off(): void
378
+    {
379
+        $this->system->restoreExceptionHandler();
380
+        $this->system->restoreErrorHandler();
381
+    }
382 382
 	
383
-	/**
384
-	 * Registers this instance as an error handler.
385
-	 * 
386
-	 * @return void
387
-	 */
388
-	public function on() : void
389
-	{
390
-		// Set the exception handler
391
-		$this->system->setExceptionHandler([$this, self::EXCEPTION_HANDLER]);
392
-		// Set the error handler
393
-		$this->system->setErrorHandler([$this, self::ERROR_HANDLER]);
394
-		// Set the handler for shutdown to catch Parse errors
395
-		$this->system->registerShutdownFunction([$this, self::SHUTDOWN_HANDLER]);
396
-	}
397
-
398
-	/**
399
-	 * Lenevor Exception will by default send HTTP code 500, but you may wish
400
-	 * to use 502, 503, or another 5xx family code.
401
-	 * 
402
-	 * @param  bool|int  $code
403
-	 * 
404
-	 * @return int|false
405
-	 * 
406
-	 * @throws \InvalidArgumentException
407
-	 */
408
-	public function sendHttpCode($code = null)
409
-	{
410
-		if (func_num_args() == 0) {
411
-			return $this->sendHttpCode;
412
-		}
383
+    /**
384
+     * Registers this instance as an error handler.
385
+     * 
386
+     * @return void
387
+     */
388
+    public function on() : void
389
+    {
390
+        // Set the exception handler
391
+        $this->system->setExceptionHandler([$this, self::EXCEPTION_HANDLER]);
392
+        // Set the error handler
393
+        $this->system->setErrorHandler([$this, self::ERROR_HANDLER]);
394
+        // Set the handler for shutdown to catch Parse errors
395
+        $this->system->registerShutdownFunction([$this, self::SHUTDOWN_HANDLER]);
396
+    }
397
+
398
+    /**
399
+     * Lenevor Exception will by default send HTTP code 500, but you may wish
400
+     * to use 502, 503, or another 5xx family code.
401
+     * 
402
+     * @param  bool|int  $code
403
+     * 
404
+     * @return int|false
405
+     * 
406
+     * @throws \InvalidArgumentException
407
+     */
408
+    public function sendHttpCode($code = null)
409
+    {
410
+        if (func_num_args() == 0) {
411
+            return $this->sendHttpCode;
412
+        }
413 413
 		
414
-		if ( ! $code) {
415
-			return $this->sendHttpCode = false;
416
-		}
414
+        if ( ! $code) {
415
+            return $this->sendHttpCode = false;
416
+        }
417 417
 		
418
-		if ($code === true) {
419
-			$code = 500;
420
-		}
418
+        if ($code === true) {
419
+            $code = 500;
420
+        }
421 421
 		
422
-		if ($code < 400 || 600 <= $code) {
423
-			throw new InvalidArgumentException("Invalid status code {$code}, must be 4xx or 5xx");
424
-		}
422
+        if ($code < 400 || 600 <= $code) {
423
+            throw new InvalidArgumentException("Invalid status code {$code}, must be 4xx or 5xx");
424
+        }
425 425
 		
426
-		return $this->sendHttpCode = $code;
427
-	}
428
-
429
-	/**
430
-	 * This will catch errors that are generated at the shutdown level of execution.
431
-	 *
432
-	 * @return void
433
-	 *
434
-	 * @throws \ErrorException
435
-	 */
436
-	public function handleShutdown()
437
-	{
438
-		$this->throwExceptions = false;
439
-
440
-		$error = $this->system->getLastError();
441
-
442
-		// If we've got an error that hasn't been displayed, then convert
443
-		// it to an Exception and use the Exception handler to display it
444
-		// to the user
445
-		if ($error && Misc::isFatalError($error['type'])) {
446
-			$this->allowQuit = false;
426
+        return $this->sendHttpCode = $code;
427
+    }
428
+
429
+    /**
430
+     * This will catch errors that are generated at the shutdown level of execution.
431
+     *
432
+     * @return void
433
+     *
434
+     * @throws \ErrorException
435
+     */
436
+    public function handleShutdown()
437
+    {
438
+        $this->throwExceptions = false;
439
+
440
+        $error = $this->system->getLastError();
441
+
442
+        // If we've got an error that hasn't been displayed, then convert
443
+        // it to an Exception and use the Exception handler to display it
444
+        // to the user
445
+        if ($error && Misc::isFatalError($error['type'])) {
446
+            $this->allowQuit = false;
447 447
 			
448
-			$this->handleError($error['type'], $error['message'], $error['file'], $error['line']);
449
-		}
450
-	}
448
+            $this->handleError($error['type'], $error['message'], $error['file'], $error['line']);
449
+        }
450
+    }
451 451
 }
452 452
\ No newline at end of file
Please login to merge, or discard this patch.