Passed
Push — 0.8.x ( 6e510b...88282a )
by Alexander
08:59 queued 05:20
created
src/components/Debug/Exceptions/Handlers/PleasingPageHandler.php 1 patch
Indentation   +513 added lines, -513 removed lines patch added patch discarded remove patch
@@ -39,537 +39,537 @@
 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
-		"netbeans" => "netbeans://open/?f=%file:%line",
66
-		"idea"     => "idea://open?file=%file&line=%line",
67
-		"sublime"  => "subl://open?url=file://%file&line=%line",
68
-		"phpstorm" => "phpstorm://open?file://%file&line=%line",
69
-		"textmate" => "txmt://open?url=file://%file&line=%line",
70
-		"emacs"    => "emacs://open?url=file://%file&line=%line",
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
+        "netbeans" => "netbeans://open/?f=%file:%line",
66
+        "idea"     => "idea://open?file=%file&line=%line",
67
+        "sublime"  => "subl://open?url=file://%file&line=%line",
68
+        "phpstorm" => "phpstorm://open?file://%file&line=%line",
69
+        "textmate" => "txmt://open?url=file://%file&line=%line",
70
+        "emacs"    => "emacs://open?url=file://%file&line=%line",
71 71
         "macvim"   => "mvim://open/?url=file://%file&line=%line",
72
-		"atom"     => "atom://core/open/file?filename=%file&line=%line",
73
-	];
72
+        "atom"     => "atom://core/open/file?filename=%file&line=%line",
73
+    ];
74 74
 	
75
-	/**
76
-	 * The page title main of handler.
77
-	 * 
78
-	 * @var string $pageTitle
79
-	 */
80
-	protected $pageTitle = 'Lenevor Debug! There was an error';
75
+    /**
76
+     * The page title main of handler.
77
+     * 
78
+     * @var string $pageTitle
79
+     */
80
+    protected $pageTitle = 'Lenevor Debug! There was an error';
81 81
 	
82
-	/**
83
-	 * Fast lookup cache for known resource locations.
84
-	 * 
85
-	 * @var array $resourceCache
86
-	 */
87
-	protected $resourceCache = [];
82
+    /**
83
+     * Fast lookup cache for known resource locations.
84
+     * 
85
+     * @var array $resourceCache
86
+     */
87
+    protected $resourceCache = [];
88 88
 	
89
-	/**
90
-	 * The path to the directory containing the html error template directories.
91
-	 * 
92
-	 * @var array $searchPaths
93
-	 */
94
-	protected $searchPaths = [];
95
-
96
-	/**
97
-	 * Gets the table of data.
98
-	 * 
99
-	 * @var array $tables
100
-	 */
101
-	protected $tables = [];
102
-
103
-	/**
104
-	 * Gets the theme default.
105
-	 * 
106
-	 * @var string $theme
107
-	 */
108
-	protected $theme;
89
+    /**
90
+     * The path to the directory containing the html error template directories.
91
+     * 
92
+     * @var array $searchPaths
93
+     */
94
+    protected $searchPaths = [];
95
+
96
+    /**
97
+     * Gets the table of data.
98
+     * 
99
+     * @var array $tables
100
+     */
101
+    protected $tables = [];
102
+
103
+    /**
104
+     * Gets the theme default.
105
+     * 
106
+     * @var string $theme
107
+     */
108
+    protected $theme;
109 109
 	
110
-	/**
111
-	 * The template handler system.
112
-	 * 
113
-	 * @var string|object $template
114
-	 */
115
-	protected $template;	
110
+    /**
111
+     * The template handler system.
112
+     * 
113
+     * @var string|object $template
114
+     */
115
+    protected $template;	
116 116
 	
117
-	/**
118
-	 * Constructor. The PleasingPageHandler class.
119
-	 * 
120
-	 * @return void
121
-	 */
122
-	public function __construct()
123
-	{
124
-		$this->template      = new TemplateHandler;
125
-		$this->searchPaths[] = dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR.'Resources';
126
-	}
127
-
128
-	/**
129
-	 * Adds an editor resolver, identified by a string name, and that may be a 
130
-	 * string path, or a callable resolver.
131
-	 * 
132
-	 * @param  string            $identifier
133
-	 * @param  string|\Callable  $resolver
134
-	 * 
135
-	 * @return void
136
-	 */
137
-	public function addEditor($identifier, $resolver): void
138
-	{
139
-		$this->editors[$identifier] = $resolver;
140
-	}
141
-
142
-	/**
143
-	 * Adds an entry to the list of tables displayed in the template.
144
-	 * The expected data is a simple associative array. Any nested arrays
145
-	 * will be flattened with print_r.
146
-	 * 
147
-	 * @param  \Syscodes\Components\Contracts\Debug\Table  $table
148
-	 * 
149
-	 * @return void
150
-	 */
151
-	public function addTables(Table $table): void
152
-	{
153
-		$this->tables[] = $table;
154
-	}
117
+    /**
118
+     * Constructor. The PleasingPageHandler class.
119
+     * 
120
+     * @return void
121
+     */
122
+    public function __construct()
123
+    {
124
+        $this->template      = new TemplateHandler;
125
+        $this->searchPaths[] = dirname(dirname(__DIR__)).DIRECTORY_SEPARATOR.'Resources';
126
+    }
127
+
128
+    /**
129
+     * Adds an editor resolver, identified by a string name, and that may be a 
130
+     * string path, or a callable resolver.
131
+     * 
132
+     * @param  string            $identifier
133
+     * @param  string|\Callable  $resolver
134
+     * 
135
+     * @return void
136
+     */
137
+    public function addEditor($identifier, $resolver): void
138
+    {
139
+        $this->editors[$identifier] = $resolver;
140
+    }
141
+
142
+    /**
143
+     * Adds an entry to the list of tables displayed in the template.
144
+     * The expected data is a simple associative array. Any nested arrays
145
+     * will be flattened with print_r.
146
+     * 
147
+     * @param  \Syscodes\Components\Contracts\Debug\Table  $table
148
+     * 
149
+     * @return void
150
+     */
151
+    public function addTables(Table $table): void
152
+    {
153
+        $this->tables[] = $table;
154
+    }
155 155
 	
156
-	/**
157
-	 * Gathers the variables that will be made available to the view.
158
-	 * 
159
-	 * @return  array
160
-	 */
161
-	protected function collectionVars(): array
162
-	{
163
-		$supervisor = $this->getSupervisor();
164
-		$style      = file_get_contents($this->getResource('compiled/css/debug.base.css'));
165
-		$jscript    = file_get_contents($this->getResource('compiled/js/debug.base.js'));
166
-		$servers    = array_merge($this->getDefaultServers(), $this->tables);
167
-		$routing    = array_merge($this->getDefaultRouting(), $this->tables);
168
-		$databases  = array_merge($this->getDefaultDatabase(), $this->tables);
169
-		$context    = array_merge($this->getDefaultContext(), $this->tables);
156
+    /**
157
+     * Gathers the variables that will be made available to the view.
158
+     * 
159
+     * @return  array
160
+     */
161
+    protected function collectionVars(): array
162
+    {
163
+        $supervisor = $this->getSupervisor();
164
+        $style      = file_get_contents($this->getResource('compiled/css/debug.base.css'));
165
+        $jscript    = file_get_contents($this->getResource('compiled/js/debug.base.js'));
166
+        $servers    = array_merge($this->getDefaultServers(), $this->tables);
167
+        $routing    = array_merge($this->getDefaultRouting(), $this->tables);
168
+        $databases  = array_merge($this->getDefaultDatabase(), $this->tables);
169
+        $context    = array_merge($this->getDefaultContext(), $this->tables);
170 170
 		
171
-		return [ 
172
-			'class' => explode('\\', $supervisor->getExceptionName()),
173
-			'stylesheet' => preg_replace('#[\r\n\t ]+#', ' ', $style),
174
-			'javascript' => preg_replace('#[\r\n\t ]+#', ' ', $jscript),
175
-			'header' => $this->getResource('views/partials/updown/header.php'),
176
-			'footer' => $this->getResource('views/partials/updown/footer.php'),
177
-			'info_exception' => $this->getResource('views/partials/info/info_exception.php'),
178
-			'section_stack_exception' => $this->getResource('views/partials/section_stack_exception.php'),
179
-			'section_frame' => $this->getResource('views/partials/section_frame.php'),
180
-			'frame_description' => $this->getResource('views/partials/frames/frame_description.php'),
181
-			'frame_list' => $this->getResource('views/partials/frames/frame_list.php'),
182
-			'section_code' => $this->getResource('views/partials/section_code.php'),
183
-			'code_source' => $this->getResource('views/partials/codes/code_source.php'),
184
-			'request_info' => $this->getResource('views/partials/request_info.php'),
185
-			'navigation' => $this->getResource('views/components/navBar.php'),
186
-			'settings' => $this->getResource('views/components/settingsDropdown.php'),
187
-			'section_detail_context' => $this->getResource('views/partials/details/section_detail_context.php'),
188
-			'plain_exception' => Formatter::formatExceptionAsPlainText($this->getSupervisor()),
189
-			'handler' => $this,
190
-			'handlers' => $this->getDebug()->getHandlers(),
191
-			'debug' => $this->getDebug(),
192
-			'code' => $this->getExceptionCode(),
193
-			'message' => $supervisor->getExceptionMessage(),
194
-			'frames' => $this->getExceptionFrames(),
195
-			'servers' => $this->getProcessTables($servers),
196
-			'routes' => $this->getProcessTables($routing),
197
-			'databases' => $this->getProcessTables($databases),
198
-			'contexts' => $this->getProcessTables($context),
199
-		];
200
-	}
171
+        return [ 
172
+            'class' => explode('\\', $supervisor->getExceptionName()),
173
+            'stylesheet' => preg_replace('#[\r\n\t ]+#', ' ', $style),
174
+            'javascript' => preg_replace('#[\r\n\t ]+#', ' ', $jscript),
175
+            'header' => $this->getResource('views/partials/updown/header.php'),
176
+            'footer' => $this->getResource('views/partials/updown/footer.php'),
177
+            'info_exception' => $this->getResource('views/partials/info/info_exception.php'),
178
+            'section_stack_exception' => $this->getResource('views/partials/section_stack_exception.php'),
179
+            'section_frame' => $this->getResource('views/partials/section_frame.php'),
180
+            'frame_description' => $this->getResource('views/partials/frames/frame_description.php'),
181
+            'frame_list' => $this->getResource('views/partials/frames/frame_list.php'),
182
+            'section_code' => $this->getResource('views/partials/section_code.php'),
183
+            'code_source' => $this->getResource('views/partials/codes/code_source.php'),
184
+            'request_info' => $this->getResource('views/partials/request_info.php'),
185
+            'navigation' => $this->getResource('views/components/navBar.php'),
186
+            'settings' => $this->getResource('views/components/settingsDropdown.php'),
187
+            'section_detail_context' => $this->getResource('views/partials/details/section_detail_context.php'),
188
+            'plain_exception' => Formatter::formatExceptionAsPlainText($this->getSupervisor()),
189
+            'handler' => $this,
190
+            'handlers' => $this->getDebug()->getHandlers(),
191
+            'debug' => $this->getDebug(),
192
+            'code' => $this->getExceptionCode(),
193
+            'message' => $supervisor->getExceptionMessage(),
194
+            'frames' => $this->getExceptionFrames(),
195
+            'servers' => $this->getProcessTables($servers),
196
+            'routes' => $this->getProcessTables($routing),
197
+            'databases' => $this->getProcessTables($databases),
198
+            'contexts' => $this->getProcessTables($context),
199
+        ];
200
+    }
201 201
 	
202
-	/**
203
-	 * The way in which the data sender (usually the server) can tell the recipient
204
-	 * (the browser, in general) what type of data is being sent in this case, html format tagged.
205
-	 * 
206
-	 * @return string
207
-	 */
208
-	public function contentType(): string
209
-	{
210
-		return 'text/html;charset=UTF-8';
211
-	}
212
-
213
-	/**
214
-	 * Gets the brand of project.
215
-	 * 
216
-	 * @return string
217
-	 */
218
-	public function getBrand(): string
219
-	{
220
-		return $this->brand;
221
-	}
222
-
223
-	/**
224
-	 * Returns the default servers.
225
-	 * 
226
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
227
-	 */
228
-	protected function getDefaultServers()
229
-	{
230
-		$server = [
231
-			'host' => $_SERVER['HTTP_HOST'], 
232
-			'user-agent' => $_SERVER['HTTP_USER_AGENT'], 
233
-			'accept' => $_SERVER['HTTP_ACCEPT'], 
234
-			'accept-language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
235
-			'accept-encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'],
236
-			'connection' => $_SERVER['HTTP_CONNECTION'],
237
-			'upgrade-insecure-requests' => $_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'], 
238
-			'sec-fetch-dest' => $_SERVER['HTTP_SEC_FETCH_DEST'],
239
-			'sec-fetch-mode' => $_SERVER['HTTP_SEC_FETCH_MODE'],
240
-			'sec-fetch-site' => $_SERVER['HTTP_SEC_FETCH_SITE'],
241
-			'sec-fetch-user' => $_SERVER['HTTP_SEC_FETCH_USER'],
242
-		];
243
-
244
-		return [new ArrayTable($server)];
245
-	}
246
-
247
-	/**
248
-	 * Returns the default routing.
249
-	 * 
250
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
251
-	 */
252
-	protected function getDefaultRouting()
253
-	{
254
-		$action = app('request')->route()->isControllerAction() 
255
-		          ? app('request')->route()->parseControllerCallback()[0] 
256
-		          : 'Closure';
257
-
258
-		$index = match (true) {
259
-			array_key_exists('web', app('router')->getMiddlewareGroups()) => 0,
260
-			array_key_exists('api', app('router')->getMiddlewareGroups()) => 1,
261
-		};
262
-
263
-		$routing = [
264
-			'Controller' => $action,
265
-			'Middleware' => array_keys(app('router')->getMiddlewareGroups())[$index],
266
-		];
267
-
268
-		return [new ArrayTable($routing)];
269
-	}
270
-
271
-	/**
272
-	 * Returns the default database.
273
-	 * 
274
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
275
-	 */
276
-	protected function getDefaultDatabase()
277
-	{
278
-		$query = [
279
-			'Sql' => null,
280
-			'Time' => null,
281
-			'Connection name' => null,
282
-		];
283
-
284
-		return [new ArrayTable($query)];
285
-	}
286
-
287
-	/**
288
-	 * Returns the default context data.
289
-	 * 
290
-	 * @return \Syscodes\Components\Contracts\Debug\Table[]
291
-	 */
292
-	protected function getDefaultContext()
293
-	{
294
-		$context = [
295
-			'Php Version' => PHP_VERSION,
296
-			'Lenevor Version' => app()->version(),
297
-			'Lenevor Locale' => config('app.locale'),
298
-			'App Debug' => (1 == env('APP_DEBUG') ? 'true' : 'false'),
299
-			'App Env' => env('APP_ENV'),
300
-		];
301
-
302
-		return [new ArrayTable($context)];
303
-	}
304
-
305
-	/**
306
-	 * Get the code of the exception that is currently being handled.
307
-	 * 
308
-	 * @return string
309
-	 */
310
-	protected function getExceptionCode()
311
-	{
312
-		$exception = $this->getException();
313
-		$code      = $exception->getCode();
314
-
315
-		if ($exception instanceof ErrorException) {
316
-			$code = Misc::translateErrorCode($exception->getSeverity());
317
-		}
318
-
319
-		return (string) $code;
320
-	}
321
-
322
-	/**
323
-	 * Get the stack trace frames of the exception that is currently being handled.
324
-	 * 
325
-	 * @return \Syscodes\Components\Debug\Engine\Supervisor;
326
-	 */
327
-	protected function getExceptionFrames()
328
-	{
329
-		$frames = $this->getSupervisor()->getFrames();
202
+    /**
203
+     * The way in which the data sender (usually the server) can tell the recipient
204
+     * (the browser, in general) what type of data is being sent in this case, html format tagged.
205
+     * 
206
+     * @return string
207
+     */
208
+    public function contentType(): string
209
+    {
210
+        return 'text/html;charset=UTF-8';
211
+    }
212
+
213
+    /**
214
+     * Gets the brand of project.
215
+     * 
216
+     * @return string
217
+     */
218
+    public function getBrand(): string
219
+    {
220
+        return $this->brand;
221
+    }
222
+
223
+    /**
224
+     * Returns the default servers.
225
+     * 
226
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
227
+     */
228
+    protected function getDefaultServers()
229
+    {
230
+        $server = [
231
+            'host' => $_SERVER['HTTP_HOST'], 
232
+            'user-agent' => $_SERVER['HTTP_USER_AGENT'], 
233
+            'accept' => $_SERVER['HTTP_ACCEPT'], 
234
+            'accept-language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
235
+            'accept-encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'],
236
+            'connection' => $_SERVER['HTTP_CONNECTION'],
237
+            'upgrade-insecure-requests' => $_SERVER['HTTP_UPGRADE_INSECURE_REQUESTS'], 
238
+            'sec-fetch-dest' => $_SERVER['HTTP_SEC_FETCH_DEST'],
239
+            'sec-fetch-mode' => $_SERVER['HTTP_SEC_FETCH_MODE'],
240
+            'sec-fetch-site' => $_SERVER['HTTP_SEC_FETCH_SITE'],
241
+            'sec-fetch-user' => $_SERVER['HTTP_SEC_FETCH_USER'],
242
+        ];
243
+
244
+        return [new ArrayTable($server)];
245
+    }
246
+
247
+    /**
248
+     * Returns the default routing.
249
+     * 
250
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
251
+     */
252
+    protected function getDefaultRouting()
253
+    {
254
+        $action = app('request')->route()->isControllerAction() 
255
+                  ? app('request')->route()->parseControllerCallback()[0] 
256
+                  : 'Closure';
257
+
258
+        $index = match (true) {
259
+            array_key_exists('web', app('router')->getMiddlewareGroups()) => 0,
260
+            array_key_exists('api', app('router')->getMiddlewareGroups()) => 1,
261
+        };
262
+
263
+        $routing = [
264
+            'Controller' => $action,
265
+            'Middleware' => array_keys(app('router')->getMiddlewareGroups())[$index],
266
+        ];
267
+
268
+        return [new ArrayTable($routing)];
269
+    }
270
+
271
+    /**
272
+     * Returns the default database.
273
+     * 
274
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
275
+     */
276
+    protected function getDefaultDatabase()
277
+    {
278
+        $query = [
279
+            'Sql' => null,
280
+            'Time' => null,
281
+            'Connection name' => null,
282
+        ];
283
+
284
+        return [new ArrayTable($query)];
285
+    }
286
+
287
+    /**
288
+     * Returns the default context data.
289
+     * 
290
+     * @return \Syscodes\Components\Contracts\Debug\Table[]
291
+     */
292
+    protected function getDefaultContext()
293
+    {
294
+        $context = [
295
+            'Php Version' => PHP_VERSION,
296
+            'Lenevor Version' => app()->version(),
297
+            'Lenevor Locale' => config('app.locale'),
298
+            'App Debug' => (1 == env('APP_DEBUG') ? 'true' : 'false'),
299
+            'App Env' => env('APP_ENV'),
300
+        ];
301
+
302
+        return [new ArrayTable($context)];
303
+    }
304
+
305
+    /**
306
+     * Get the code of the exception that is currently being handled.
307
+     * 
308
+     * @return string
309
+     */
310
+    protected function getExceptionCode()
311
+    {
312
+        $exception = $this->getException();
313
+        $code      = $exception->getCode();
314
+
315
+        if ($exception instanceof ErrorException) {
316
+            $code = Misc::translateErrorCode($exception->getSeverity());
317
+        }
318
+
319
+        return (string) $code;
320
+    }
321
+
322
+    /**
323
+     * Get the stack trace frames of the exception that is currently being handled.
324
+     * 
325
+     * @return \Syscodes\Components\Debug\Engine\Supervisor;
326
+     */
327
+    protected function getExceptionFrames()
328
+    {
329
+        $frames = $this->getSupervisor()->getFrames();
330 330
 		
331
-		return $frames;
332
-	}
331
+        return $frames;
332
+    }
333 333
 	
334
-	/**
335
-	 * Gets the page title web.
336
-	 * 
337
-	 * @return string
338
-	 */
339
-	public function getPageTitle(): string
340
-	{
341
-		return $this->pageTitle;
342
-	}
343
-
344
-	/**
345
-	 * Processes an array of tables making sure everything is all right.
346
-	 * 
347
-	 * @param  \Syscodes\Components\Contracts\Debug\Table[]  $tables
348
-	 * 
349
-	 * @return array
350
-	 */
351
-	protected function getProcessTables(array $tables): array
352
-	{
353
-		$processTables = [];
354
-
355
-		foreach ($tables as $table) {
356
-			if ( ! $table instanceof Table) {
357
-				continue;
358
-			}
334
+    /**
335
+     * Gets the page title web.
336
+     * 
337
+     * @return string
338
+     */
339
+    public function getPageTitle(): string
340
+    {
341
+        return $this->pageTitle;
342
+    }
343
+
344
+    /**
345
+     * Processes an array of tables making sure everything is all right.
346
+     * 
347
+     * @param  \Syscodes\Components\Contracts\Debug\Table[]  $tables
348
+     * 
349
+     * @return array
350
+     */
351
+    protected function getProcessTables(array $tables): array
352
+    {
353
+        $processTables = [];
354
+
355
+        foreach ($tables as $table) {
356
+            if ( ! $table instanceof Table) {
357
+                continue;
358
+            }
359 359
 			
360
-			$label = $table->getLabel();
361
-
362
-			try {
363
-				$data = (array) $table->getData();
364
-
365
-				if ( ! (is_array($data) || $data instanceof Traversable)) {
366
-					$data = [];
367
-				}
368
-			} catch (Exception $e) {
369
-				$data = [];
370
-			}
371
-
372
-			$processTables[$label] = $data;
373
-		}
374
-
375
-		return $processTables;
376
-	}
377
-
378
-	/**
379
-	 * Finds a resource, by its relative path, in all available search paths.
380
-	 *
381
-	 * @param  string  $resource
382
-	 * 
383
-	 * @return string
384
-	 * 
385
-	 * @throws \RuntimeException
386
-	 */
387
-	protected function getResource($resource)
388
-	{
389
-		if (isset($this->resourceCache[$resource])) {
390
-			return $this->resourceCache[$resource];
391
-		}
392
-
393
-		foreach ($this->searchPaths as $path) {
394
-			$fullPath = $path.DIRECTORY_SEPARATOR.$resource;
395
-
396
-			if (is_file($fullPath)) {
397
-				// Cache:
398
-				$this->resourceCache[$resource] = $fullPath;
399
-
400
-				return $fullPath;
401
-			}
402
-		}
403
-
404
-		throw new RuntimeException( 
405
-				"Could not find resource '{$resource}' in any resource paths.". 
406
-				"(searched: ".join(", ", $this->searchPaths).")");
407
-	}
360
+            $label = $table->getLabel();
361
+
362
+            try {
363
+                $data = (array) $table->getData();
364
+
365
+                if ( ! (is_array($data) || $data instanceof Traversable)) {
366
+                    $data = [];
367
+                }
368
+            } catch (Exception $e) {
369
+                $data = [];
370
+            }
371
+
372
+            $processTables[$label] = $data;
373
+        }
374
+
375
+        return $processTables;
376
+    }
377
+
378
+    /**
379
+     * Finds a resource, by its relative path, in all available search paths.
380
+     *
381
+     * @param  string  $resource
382
+     * 
383
+     * @return string
384
+     * 
385
+     * @throws \RuntimeException
386
+     */
387
+    protected function getResource($resource)
388
+    {
389
+        if (isset($this->resourceCache[$resource])) {
390
+            return $this->resourceCache[$resource];
391
+        }
392
+
393
+        foreach ($this->searchPaths as $path) {
394
+            $fullPath = $path.DIRECTORY_SEPARATOR.$resource;
395
+
396
+            if (is_file($fullPath)) {
397
+                // Cache:
398
+                $this->resourceCache[$resource] = $fullPath;
399
+
400
+                return $fullPath;
401
+            }
402
+        }
403
+
404
+        throw new RuntimeException( 
405
+                "Could not find resource '{$resource}' in any resource paths.". 
406
+                "(searched: ".join(", ", $this->searchPaths).")");
407
+    }
408 408
 	
409
-	/**
410
-	 * Given an exception and status code will display the error to the client.
411
-	 * 
412
-	 * @return int|null
413
-	 */
414
-	public function handle()
415
-	{	
416
-		$templatePath = $this->getResource('views/debug.layout.php');
417
-
418
-		$vars = $this->collectionVars();
409
+    /**
410
+     * Given an exception and status code will display the error to the client.
411
+     * 
412
+     * @return int|null
413
+     */
414
+    public function handle()
415
+    {	
416
+        $templatePath = $this->getResource('views/debug.layout.php');
417
+
418
+        $vars = $this->collectionVars();
419 419
 		
420
-		if (empty($vars['message'])) $vars['message'] = __('exception.noMessage');
420
+        if (empty($vars['message'])) $vars['message'] = __('exception.noMessage');
421 421
 		
422
-		$this->template->setVariables($vars);
423
-		$this->template->render($templatePath);
422
+        $this->template->setVariables($vars);
423
+        $this->template->render($templatePath);
424 424
 		
425
-		return Handler::QUIT;
426
-	}
427
-
428
-	/**
429
-	 * Set the editor to use to open referenced files, by a string identifier or callable
430
-	 * that will be executed for every file reference. Should return a string.
431
-	 * 
432
-	 * @example  $debug->setEditor(function($file, $line) { return "file:///{$file}"; });
433
-	 * @example  $debug->setEditor('vscode');
434
-	 * 
435
-	 * @param  string  $editor
436
-	 * 
437
-	 * @return void
438
-	 * 
439
-	 * @throws \InvalidArgumentException
440
-	 */
441
-	public function setEditor($editor)
442
-	{
443
-		if ( ! is_callable($editor) && ! isset($this->editors[$editor])) {
444
-			throw new InvalidArgumentException("Unknown editor identifier: [{$editor}]. Known editors: " .
445
-				implode(', ', array_keys($this->editors))
446
-			);
447
-		}
448
-
449
-		$this->editor = $editor;
450
-	}
451
-
452
-	/**
453
-	 * Given a string file path, and an integer file line,
454
-	 * executes the editor resolver and returns.
455
-	 * 
456
-	 * @param  string  $file
457
-	 * @param  int	   $line
458
-	 * 
459
-	 * @return string|bool
460
-	 * 
461
-	 * @throws \UnexpectedValueException
462
-	 */
463
-	public function getEditorAtHref($file, $line)
464
-	{
465
-		$editor = $this->getEditor($file, $line);
466
-
467
-		if (empty($editor))	{
468
-			return false;
469
-		}
470
-
471
-		if ( ! isset($editor['url']) || ! is_string($editor['url'])) {
472
-			throw new UnexpectedValueException(__METHOD__.'should always resolve to a string or a valid editor array');
473
-		}
474
-
475
-		$editor['url'] = str_replace("%file", rawurldecode($file), $editor['url']);
476
-		$editor['url'] = str_replace("%line", rawurldecode($line), $editor['url']);
477
-
478
-		return $editor['url'];
479
-	}
480
-
481
-	/**
482
-	 * The editor must be a valid callable function/closure.
483
-	 * 
484
-	 * @param  string  $file
485
-	 * @param  int	   $line
486
-	 * 
487
-	 * @return array
488
-	 */
489
-	protected function getEditor($file, $line): array
490
-	{
491
-		if ( ! $this->editor || ( ! is_string($this->editor) && ! is_callable($this->editor))) {
492
-			return [];
493
-		}
494
-
495
-		if (is_string($this->editor) && isset($this->editors[$this->editor]) && ! is_callable($this->editors[$this->editor])) {
496
-			return ['url' => $this->editors[$this->editor]];
497
-		}
498
-
499
-		if (is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor]))) {
500
-			if (is_callable($this->editor)) {
501
-				$callback = call_user_func($this->editor, $file, $line);
502
-			} else {
503
-				$callback = call_user_func($this->editors[$this->editor], $file, $line);
504
-			}
505
-
506
-			if (empty($callback)) {
507
-				return [];
508
-			}
509
-
510
-			if (is_string($callback)) {
511
-				return ['url' => $callback];
512
-			}
425
+        return Handler::QUIT;
426
+    }
427
+
428
+    /**
429
+     * Set the editor to use to open referenced files, by a string identifier or callable
430
+     * that will be executed for every file reference. Should return a string.
431
+     * 
432
+     * @example  $debug->setEditor(function($file, $line) { return "file:///{$file}"; });
433
+     * @example  $debug->setEditor('vscode');
434
+     * 
435
+     * @param  string  $editor
436
+     * 
437
+     * @return void
438
+     * 
439
+     * @throws \InvalidArgumentException
440
+     */
441
+    public function setEditor($editor)
442
+    {
443
+        if ( ! is_callable($editor) && ! isset($this->editors[$editor])) {
444
+            throw new InvalidArgumentException("Unknown editor identifier: [{$editor}]. Known editors: " .
445
+                implode(', ', array_keys($this->editors))
446
+            );
447
+        }
448
+
449
+        $this->editor = $editor;
450
+    }
451
+
452
+    /**
453
+     * Given a string file path, and an integer file line,
454
+     * executes the editor resolver and returns.
455
+     * 
456
+     * @param  string  $file
457
+     * @param  int	   $line
458
+     * 
459
+     * @return string|bool
460
+     * 
461
+     * @throws \UnexpectedValueException
462
+     */
463
+    public function getEditorAtHref($file, $line)
464
+    {
465
+        $editor = $this->getEditor($file, $line);
466
+
467
+        if (empty($editor))	{
468
+            return false;
469
+        }
470
+
471
+        if ( ! isset($editor['url']) || ! is_string($editor['url'])) {
472
+            throw new UnexpectedValueException(__METHOD__.'should always resolve to a string or a valid editor array');
473
+        }
474
+
475
+        $editor['url'] = str_replace("%file", rawurldecode($file), $editor['url']);
476
+        $editor['url'] = str_replace("%line", rawurldecode($line), $editor['url']);
477
+
478
+        return $editor['url'];
479
+    }
480
+
481
+    /**
482
+     * The editor must be a valid callable function/closure.
483
+     * 
484
+     * @param  string  $file
485
+     * @param  int	   $line
486
+     * 
487
+     * @return array
488
+     */
489
+    protected function getEditor($file, $line): array
490
+    {
491
+        if ( ! $this->editor || ( ! is_string($this->editor) && ! is_callable($this->editor))) {
492
+            return [];
493
+        }
494
+
495
+        if (is_string($this->editor) && isset($this->editors[$this->editor]) && ! is_callable($this->editors[$this->editor])) {
496
+            return ['url' => $this->editors[$this->editor]];
497
+        }
498
+
499
+        if (is_callable($this->editor) || (isset($this->editors[$this->editor]) && is_callable($this->editors[$this->editor]))) {
500
+            if (is_callable($this->editor)) {
501
+                $callback = call_user_func($this->editor, $file, $line);
502
+            } else {
503
+                $callback = call_user_func($this->editors[$this->editor], $file, $line);
504
+            }
505
+
506
+            if (empty($callback)) {
507
+                return [];
508
+            }
509
+
510
+            if (is_string($callback)) {
511
+                return ['url' => $callback];
512
+            }
513 513
 			
514
-			return ['url' => isset($callback['url']) ? $callback['url'] : $callback];
515
-		}
514
+            return ['url' => isset($callback['url']) ? $callback['url'] : $callback];
515
+        }
516 516
 		
517
-		return [];
518
-	}
519
-
520
-	/**
521
-	 * Registered the editor.
522
-	 * 
523
-	 * @return string
524
-	 */
525
-	public function getEditorcode(): string
526
-	{
527
-		return $this->editor;
528
-	}
529
-
530
-	/**
531
-	 * Get the theme default.
532
-	 * 
533
-	 * @return string
534
-	 */
535
-	public function getTheme(): string
536
-	{
537
-		return $this->theme = config('gdebug.theme');
538
-	}
517
+        return [];
518
+    }
519
+
520
+    /**
521
+     * Registered the editor.
522
+     * 
523
+     * @return string
524
+     */
525
+    public function getEditorcode(): string
526
+    {
527
+        return $this->editor;
528
+    }
529
+
530
+    /**
531
+     * Get the theme default.
532
+     * 
533
+     * @return string
534
+     */
535
+    public function getTheme(): string
536
+    {
537
+        return $this->theme = config('gdebug.theme');
538
+    }
539 539
 	
540
-	/**
541
-	 * Sets the brand of project.
542
-	 * 
543
-	 * @param  string  $brand
544
-	 * 
545
-	 * @return void
546
-	 */
547
-	public function setBrand(string $brand): void
548
-	{
549
-		$this->brand = (string) $brand;
550
-	}
540
+    /**
541
+     * Sets the brand of project.
542
+     * 
543
+     * @param  string  $brand
544
+     * 
545
+     * @return void
546
+     */
547
+    public function setBrand(string $brand): void
548
+    {
549
+        $this->brand = (string) $brand;
550
+    }
551 551
 	
552
-	/**
553
-	 * Sets the page title web.
554
-	 * 
555
-	 * @param  string  $title
556
-	 * 
557
-	 * @return void
558
-	 */
559
-	public function setPageTitle(string $title): void
560
-	{
561
-		$this->pageTitle = (string) $title;
562
-	}
563
-
564
-	/**
565
-	 * Set the theme manually.
566
-	 * 
567
-	 * @param  string  $theme
568
-	 * 
569
-	 * @return void
570
-	 */
571
-	public function setTheme(string $theme): void
572
-	{
573
-		$this->theme = (string) $theme;
574
-	}
552
+    /**
553
+     * Sets the page title web.
554
+     * 
555
+     * @param  string  $title
556
+     * 
557
+     * @return void
558
+     */
559
+    public function setPageTitle(string $title): void
560
+    {
561
+        $this->pageTitle = (string) $title;
562
+    }
563
+
564
+    /**
565
+     * Set the theme manually.
566
+     * 
567
+     * @param  string  $theme
568
+     * 
569
+     * @return void
570
+     */
571
+    public function setTheme(string $theme): void
572
+    {
573
+        $this->theme = (string) $theme;
574
+    }
575 575
 }
576 576
\ No newline at end of file
Please login to merge, or discard this patch.