1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Copyright (c) 2011-present Mediasift Ltd |
5
|
|
|
* All rights reserved. |
6
|
|
|
* |
7
|
|
|
* Redistribution and use in source and binary forms, with or without |
8
|
|
|
* modification, are permitted provided that the following conditions |
9
|
|
|
* are met: |
10
|
|
|
* |
11
|
|
|
* * Redistributions of source code must retain the above copyright |
12
|
|
|
* notice, this list of conditions and the following disclaimer. |
13
|
|
|
* |
14
|
|
|
* * Redistributions in binary form must reproduce the above copyright |
15
|
|
|
* notice, this list of conditions and the following disclaimer in |
16
|
|
|
* the documentation and/or other materials provided with the |
17
|
|
|
* distribution. |
18
|
|
|
* |
19
|
|
|
* * Neither the names of the copyright holders nor the names of his |
20
|
|
|
* contributors may be used to endorse or promote products derived |
21
|
|
|
* from this software without specific prior written permission. |
22
|
|
|
* |
23
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
24
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
25
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
26
|
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
27
|
|
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
28
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
29
|
|
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
30
|
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
31
|
|
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
32
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
33
|
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
34
|
|
|
* POSSIBILITY OF SUCH DAMAGE. |
35
|
|
|
* |
36
|
|
|
* @category Libraries |
37
|
|
|
* @package Storyplayer/OutputLib |
38
|
|
|
* @author Stuart Herbert <[email protected]> |
39
|
|
|
* @copyright 2011-present Mediasift Ltd www.datasift.com |
40
|
|
|
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
41
|
|
|
* @link http://datasift.github.io/storyplayer |
42
|
|
|
*/ |
43
|
|
|
|
44
|
|
|
namespace DataSift\Storyplayer; |
45
|
|
|
|
46
|
|
|
use Exception; |
47
|
|
|
use DataSift\Storyplayer\Phases\Phase; |
48
|
|
|
use DataSift\Storyplayer\PlayerLib\Phase_Result; |
49
|
|
|
use DataSift\Storyplayer\PlayerLib\PhaseGroup_Result; |
50
|
|
|
use DataSift\Storyplayer\PlayerLib\Story_Result; |
51
|
|
|
use DataSift\Storyplayer\OutputLib\OutputPlugin; |
52
|
|
|
use DataSift\Storyplayer\Console\DefaultConsole; |
53
|
|
|
use DataSift\Storyplayer\Console\Console; |
54
|
|
|
|
55
|
|
|
use Phix_Project\ContractLib2\Contract; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* all output goes through here |
59
|
|
|
* |
60
|
|
|
* @category Libraries |
61
|
|
|
* @package Storyplayer/OutputLib |
62
|
|
|
* @author Stuart Herbert <[email protected]> |
63
|
|
|
* @copyright 2011-present Mediasift Ltd www.datasift.com |
64
|
|
|
* @license http://www.opensource.org/licenses/bsd-license.php BSD License |
65
|
|
|
* @link http://datasift.github.io/storyplayer |
66
|
|
|
*/ |
67
|
|
|
class Output extends OutputPlugin |
68
|
|
|
{ |
69
|
|
|
/** |
70
|
|
|
* a list of the plugins that are currently active |
71
|
|
|
* |
72
|
|
|
* @var array |
73
|
|
|
*/ |
74
|
|
|
protected $plugins = []; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* a list of the log messages that we have been asked to output |
78
|
|
|
* |
79
|
|
|
* this is used for producing detailed error reports when something |
80
|
|
|
* has gone badly wrong |
81
|
|
|
* |
82
|
|
|
* @var array |
83
|
|
|
*/ |
84
|
|
|
protected $activityLog = []; |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* constructor |
88
|
|
|
* |
89
|
|
|
* ensures we have a default console that is connected to stdout |
90
|
|
|
*/ |
91
|
|
|
public function __construct() |
92
|
|
|
{ |
93
|
|
|
// we need a default output for the console |
94
|
|
|
$console = new DefaultConsole(); |
95
|
|
|
$console->addOutputToStdout(); |
96
|
|
|
|
97
|
|
|
$this->usePluginAsConsole($console); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* make a plugin the one that we use when writing to the user's |
102
|
|
|
* console |
103
|
|
|
* |
104
|
|
|
* @param Console $plugin |
105
|
|
|
* the plugin that we want |
106
|
|
|
* |
107
|
|
|
* @return void |
108
|
|
|
*/ |
109
|
|
|
public function usePluginAsConsole(Console $plugin) |
110
|
|
|
{ |
111
|
|
|
$this->plugins['console'] = $plugin; |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* set the plugin for a named output slot |
116
|
|
|
* |
117
|
|
|
* @param OutputPlugin $plugin |
118
|
|
|
* the plugin to use in the slot |
119
|
|
|
* @param string $slotName |
120
|
|
|
* the name of the slot to use for this plugin |
121
|
|
|
*/ |
122
|
|
|
public function usePluginInSlot(OutputPlugin $plugin, $slotName) |
123
|
|
|
{ |
124
|
|
|
// enforce our inputs |
125
|
|
|
Contract::RequiresValue($slotName, is_string($slotName)); |
126
|
|
|
|
127
|
|
|
// put the plugin in the required slot |
128
|
|
|
$this->plugins[$slotName] = $plugin; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* get the array of all plugins |
133
|
|
|
* |
134
|
|
|
* @return array |
135
|
|
|
*/ |
136
|
|
|
public function getPlugins() |
137
|
|
|
{ |
138
|
|
|
return $this->plugins; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* return the active plugin in the 'console' slot |
143
|
|
|
* |
144
|
|
|
* @return Console|null |
145
|
|
|
*/ |
146
|
|
|
public function getActiveConsolePlugin() |
147
|
|
|
{ |
148
|
|
|
// we ALWAYS have a console plugin :) |
149
|
|
|
return $this->plugins['console']; |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* return the active plugin in the named slot |
154
|
|
|
* |
155
|
|
|
* @param string $slotName |
156
|
|
|
* @return OutputPlugin|null |
157
|
|
|
*/ |
158
|
|
|
public function getActivePluginInSlot($slotName) |
159
|
|
|
{ |
160
|
|
|
// enforce our inputs |
161
|
|
|
Contract::RequiresValue($slotName, is_string($slotName)); |
162
|
|
|
|
163
|
|
|
// do we have a plugin in this slot? |
164
|
|
|
if (isset($this->plugins[$slotName])) { |
165
|
|
|
return $this->plugins[$slotName]; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
// no, we do not |
169
|
|
|
return null; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* disable 'silent' mode |
174
|
|
|
* |
175
|
|
|
* NOTE: it is up to each plugin in turn whether or not to support |
176
|
|
|
* 'silent' mode at all |
177
|
|
|
* |
178
|
|
|
* @return void |
179
|
|
|
*/ |
180
|
|
|
public function resetSilentMode() |
181
|
|
|
{ |
182
|
|
|
foreach ($this->plugins as $plugin) |
183
|
|
|
{ |
184
|
|
|
$plugin->resetSilentMode(); |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* switches 'silent' mode on |
190
|
|
|
* |
191
|
|
|
* in 'silent' mode, we do not write log activity to the output writer |
192
|
|
|
* at all. HOWEVER, the plugin may still add the log activity to any |
193
|
|
|
* internal cache it has (can be useful for error reports etc) |
194
|
|
|
* |
195
|
|
|
* @return void |
196
|
|
|
*/ |
197
|
|
|
public function setSilentMode() |
198
|
|
|
{ |
199
|
|
|
foreach ($this->plugins as $plugin) |
200
|
|
|
{ |
201
|
|
|
$plugin->setSilentMode(); |
202
|
|
|
} |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* switches 'verbose' mode on or off |
207
|
|
|
* |
208
|
|
|
* in 'non-verbose' mode, each output plugin is free to supress some of |
209
|
|
|
* the output, for the sake of asthetics |
210
|
|
|
* |
211
|
|
|
* @param boolean $isVerbose |
212
|
|
|
* do we want verbose mode or not? |
213
|
|
|
*/ |
214
|
|
|
public function setIsVerbose($isVerbose) |
215
|
|
|
{ |
216
|
|
|
foreach ($this->plugins as $plugin) |
217
|
|
|
{ |
218
|
|
|
$plugin->setIsVerbose($isVerbose); |
219
|
|
|
} |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
/** |
223
|
|
|
* disables any colour output |
224
|
|
|
* |
225
|
|
|
* @return void |
226
|
|
|
*/ |
227
|
|
|
public function disableColourSupport() |
228
|
|
|
{ |
229
|
|
|
foreach ($this->plugins as $plugin) |
230
|
|
|
{ |
231
|
|
|
$plugin->disableColourSupport(); |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* forces switching on colour support |
237
|
|
|
* |
238
|
|
|
* @return void |
239
|
|
|
*/ |
240
|
|
|
public function enforceColourSupport() |
241
|
|
|
{ |
242
|
|
|
foreach ($this->plugins as $plugin) |
243
|
|
|
{ |
244
|
|
|
$plugin->enforceColourSupport(); |
245
|
|
|
} |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* asks each active plugin to switch on colour support if possible |
250
|
|
|
* |
251
|
|
|
* a plugin may still choose to not output colour. one example of this |
252
|
|
|
* are consoles. they're happy to output colour if talking to a terminal, |
253
|
|
|
* but choose not to output colour if they're only writing to log files |
254
|
|
|
* or to a pipe into another UNIX process. |
255
|
|
|
* |
256
|
|
|
* @return void |
257
|
|
|
*/ |
258
|
|
|
public function enableColourSupport() |
259
|
|
|
{ |
260
|
|
|
foreach ($this->plugins as $plugin) |
261
|
|
|
{ |
262
|
|
|
$plugin->enableColourSupport(); |
263
|
|
|
} |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* called when storyplayer starts |
268
|
|
|
* |
269
|
|
|
* @param string $version |
270
|
|
|
* @param string $url |
271
|
|
|
* @param string $copyright |
272
|
|
|
* @param string $license |
273
|
|
|
* @return void |
274
|
|
|
*/ |
275
|
|
|
public function startStoryplayer($version, $url, $copyright, $license) |
276
|
|
|
{ |
277
|
|
|
// enforce our inputs |
278
|
|
|
Contract::RequiresValue($version, is_string($version)); |
279
|
|
|
Contract::RequiresValue($url, is_string($url)); |
280
|
|
|
Contract::RequiresValue($copyright, is_string($copyright)); |
281
|
|
|
Contract::RequiresValue($license, is_string($license)); |
282
|
|
|
|
283
|
|
|
// call all of our plugins |
284
|
|
|
foreach ($this->plugins as $plugin) |
285
|
|
|
{ |
286
|
|
|
$plugin->startStoryplayer($version, $url, $copyright, $license); |
287
|
|
|
} |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
/** |
291
|
|
|
* called when Storyplayer exits |
292
|
|
|
* |
293
|
|
|
* @param float $duration |
294
|
|
|
* how long did storyplayer take to run (in seconds)? |
295
|
|
|
* @return int |
296
|
|
|
*/ |
297
|
|
|
public function endStoryplayer($duration) |
298
|
|
|
{ |
299
|
|
|
$retval = 0; |
300
|
|
|
|
301
|
|
|
foreach ($this->plugins as $plugin) |
302
|
|
|
{ |
303
|
|
|
$retval = max($retval, $plugin->endStoryplayer($duration)); |
304
|
|
|
} |
305
|
|
|
|
306
|
|
|
return $retval; |
307
|
|
|
} |
308
|
|
|
|
309
|
|
|
/** |
310
|
|
|
* called when we start playing a new PhaseGroup |
311
|
|
|
* |
312
|
|
|
* @param string $activity |
313
|
|
|
* what are we doing? (e.g. 'creating', 'running') |
314
|
|
|
* @param string $name |
315
|
|
|
* the name of the phase group |
316
|
|
|
* @param array|null $details |
317
|
|
|
* optional explanation of what this PhaseGroup is trying |
318
|
|
|
* to achieve |
319
|
|
|
* @return void |
320
|
|
|
*/ |
321
|
|
|
public function startPhaseGroup($activity, $name, $details = null) |
322
|
|
|
{ |
323
|
|
|
// ensure our inputs! |
324
|
|
|
Contract::RequiresValue($activity, is_string($activity)); |
325
|
|
|
Contract::RequiresValue($name, is_string($name)); |
326
|
|
|
|
327
|
|
|
// call our plugins |
328
|
|
|
foreach ($this->plugins as $plugin) |
329
|
|
|
{ |
330
|
|
|
$plugin->startPhaseGroup($activity, $name, $details); |
331
|
|
|
} |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* called when we have finished playing a PhaseGroup |
336
|
|
|
* |
337
|
|
|
* NOTE: we cannot use a type-hint for $result here. we may pass in |
338
|
|
|
* a class that inherits from PhaseGroup_Result, and (annoyingly) |
339
|
|
|
* this isn't allowed if we use a type-hint (grrrr) |
340
|
|
|
* |
341
|
|
|
* @param PhaseGroup_Result $result |
342
|
|
|
* @return void |
343
|
|
|
*/ |
344
|
|
|
public function endPhaseGroup($result) |
345
|
|
|
{ |
346
|
|
|
// enforce our input type |
347
|
|
|
Contract::Requires($result instanceof PhaseGroup_Result); |
348
|
|
|
|
349
|
|
|
// call our plugins |
350
|
|
|
foreach ($this->plugins as $plugin) |
351
|
|
|
{ |
352
|
|
|
$plugin->endPhaseGroup($result); |
353
|
|
|
} |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* called when a story starts a new phase |
358
|
|
|
* |
359
|
|
|
* $param Phase $phase |
360
|
|
|
* the phase that we are executing |
361
|
|
|
* @return void |
362
|
|
|
*/ |
363
|
|
|
public function startPhase($phase) |
364
|
|
|
{ |
365
|
|
|
// enforce our input type |
366
|
|
|
Contract::Requires($phase instanceof Phase); |
367
|
|
|
|
368
|
|
|
foreach ($this->plugins as $plugin) |
369
|
|
|
{ |
370
|
|
|
$plugin->startPhase($phase); |
371
|
|
|
} |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
/** |
375
|
|
|
* called when a story ends a phase |
376
|
|
|
* |
377
|
|
|
* @param Phase $phase |
378
|
|
|
* the phase that has finished |
379
|
|
|
* @param Phase_Result $phaseResult |
380
|
|
|
* the result of running $phase |
381
|
|
|
* @return void |
382
|
|
|
*/ |
383
|
|
|
public function endPhase($phase, $phaseResult) |
384
|
|
|
{ |
385
|
|
|
// enforce our input type |
386
|
|
|
Contract::Requires($phase instanceof Phase); |
387
|
|
|
Contract::Requires($phaseResult instanceof Phase_Result); |
388
|
|
|
|
389
|
|
|
// inject the captured activity into the phase |
390
|
|
|
$phaseResult->activityLog = $this->activityLog; |
391
|
|
|
$this->activityLog=[]; |
392
|
|
|
|
393
|
|
|
// pass the phase on |
394
|
|
|
foreach ($this->plugins as $plugin) |
395
|
|
|
{ |
396
|
|
|
$plugin->endPhase($phase, $phaseResult); |
397
|
|
|
} |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* called when a story logs an action |
402
|
|
|
* |
403
|
|
|
* @param string $msg |
404
|
|
|
* the message to write to the logs / console |
405
|
|
|
* @param array|null $codeLine |
406
|
|
|
* information about the line of code that is executing |
407
|
|
|
* @return void |
408
|
|
|
*/ |
409
|
|
View Code Duplication |
public function logPhaseActivity($msg, $codeLine = null) |
410
|
|
|
{ |
411
|
|
|
// enforce our input type |
412
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
413
|
|
|
if ($codeLine) { |
414
|
|
|
Contract::RequiresValue($codeLine, is_array($codeLine)); |
415
|
|
|
} |
416
|
|
|
|
417
|
|
|
// keep track of what was attempted, in case we need to show |
418
|
|
|
// the user what was attempted |
419
|
|
|
$this->activityLog[] = [ |
420
|
|
|
'ts' => time(), |
421
|
|
|
'text' => $msg, |
422
|
|
|
'codeLine' => $codeLine, |
423
|
|
|
'isOutput' => false, |
424
|
|
|
]; |
425
|
|
|
|
426
|
|
|
// call all of our plugins |
427
|
|
|
foreach ($this->plugins as $plugin) |
428
|
|
|
{ |
429
|
|
|
$plugin->logPhaseActivity($msg, $codeLine); |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
/** |
434
|
|
|
* called when a story logs the (possibly partial) output from |
435
|
|
|
* running a subprocess |
436
|
|
|
* |
437
|
|
|
* @param string $msg the output to log |
438
|
|
|
* @return void |
439
|
|
|
*/ |
440
|
|
|
public function logPhaseSubprocessOutput($msg) |
441
|
|
|
{ |
442
|
|
|
// enforce our input type |
443
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
444
|
|
|
|
445
|
|
|
// keep track of what was attempted, in case we need to show |
446
|
|
|
// the user what was attempted |
447
|
|
|
$this->activityLog[] = [ |
448
|
|
|
'ts' => time(), |
449
|
|
|
'text' => $msg, |
450
|
|
|
'codeLine' => null, |
451
|
|
|
'isOutput' => true, |
452
|
|
|
]; |
453
|
|
|
|
454
|
|
|
// call all of our plugins |
455
|
|
|
foreach ($this->plugins as $plugin) |
456
|
|
|
{ |
457
|
|
|
$plugin->logPhaseSubprocessOutput($msg); |
458
|
|
|
} |
459
|
|
|
} |
460
|
|
|
|
461
|
|
|
/** |
462
|
|
|
* called when a story logs an error |
463
|
|
|
* |
464
|
|
|
* @param string $phaseName |
465
|
|
|
* the name of the phase where the error occurred |
466
|
|
|
* @param string $msg |
467
|
|
|
* an error message to send to console|logfile |
468
|
|
|
* @return void |
469
|
|
|
*/ |
470
|
|
View Code Duplication |
public function logPhaseError($phaseName, $msg) |
471
|
|
|
{ |
472
|
|
|
// enforce our inputs |
473
|
|
|
Contract::RequiresValue($phaseName, is_string($phaseName)); |
474
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
475
|
|
|
|
476
|
|
|
// keep track of what was attempted, in case we need to show |
477
|
|
|
// the user what was attempted |
478
|
|
|
$this->activityLog[] = [ |
479
|
|
|
'ts' => time(), |
480
|
|
|
'text' => $msg, |
481
|
|
|
'codeLine' => null, |
482
|
|
|
]; |
483
|
|
|
|
484
|
|
|
// call all of our plugins |
485
|
|
|
foreach ($this->plugins as $plugin) |
486
|
|
|
{ |
487
|
|
|
$plugin->logPhaseError($phaseName, $msg); |
488
|
|
|
} |
489
|
|
|
} |
490
|
|
|
|
491
|
|
|
/** |
492
|
|
|
* called when a story is skipped |
493
|
|
|
* |
494
|
|
|
* @param string $phaseName |
495
|
|
|
* the name of the phase where the error occurred |
496
|
|
|
* @param string $msg |
497
|
|
|
* an informational message to send to console|logfile |
498
|
|
|
* @return void |
499
|
|
|
*/ |
500
|
|
View Code Duplication |
public function logPhaseSkipped($phaseName, $msg) |
501
|
|
|
{ |
502
|
|
|
// enforce our inputs |
503
|
|
|
Contract::RequiresValue($phaseName, is_string($phaseName)); |
504
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
505
|
|
|
|
506
|
|
|
// keep track of what was attempted, in case we need to show |
507
|
|
|
// the user what was attempted |
508
|
|
|
$this->activityLog[] = [ |
509
|
|
|
'ts' => time(), |
510
|
|
|
'text' => $msg, |
511
|
|
|
'codeLine' => null, |
512
|
|
|
]; |
513
|
|
|
|
514
|
|
|
// call all of our plugins |
515
|
|
|
foreach ($this->plugins as $plugin) |
516
|
|
|
{ |
517
|
|
|
$plugin->logPhaseSkipped($phaseName, $msg); |
518
|
|
|
} |
519
|
|
|
} |
520
|
|
|
|
521
|
|
|
/** |
522
|
|
|
* called when we want to record which line of code in a phase is |
523
|
|
|
* currently executing |
524
|
|
|
* |
525
|
|
|
* @param array $codeLine |
526
|
|
|
* details about the line of code that is executing |
527
|
|
|
* @return void |
528
|
|
|
*/ |
529
|
|
|
public function logPhaseCodeLine($codeLine) |
530
|
|
|
{ |
531
|
|
|
// enforce our inputs |
532
|
|
|
Contract::RequiresValue($codeLine, is_array($codeLine)); |
533
|
|
|
|
534
|
|
|
// pass it on to all of our plugins |
535
|
|
|
foreach ($this->plugins as $plugin) |
536
|
|
|
{ |
537
|
|
|
$plugin->logPhaseCodeLine($codeLine); |
538
|
|
|
} |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* called when the outer CLI shell encounters a fatal error |
543
|
|
|
* |
544
|
|
|
* @param string $msg |
545
|
|
|
* the error message to show the user |
546
|
|
|
* |
547
|
|
|
* @return void |
548
|
|
|
*/ |
549
|
|
|
public function logCliError($msg) |
550
|
|
|
{ |
551
|
|
|
// enforce our inputs |
552
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
553
|
|
|
|
554
|
|
|
// pass it on to our plugins |
555
|
|
|
foreach ($this->plugins as $plugin) |
556
|
|
|
{ |
557
|
|
|
$plugin->logCliError($msg); |
558
|
|
|
} |
559
|
|
|
} |
560
|
|
|
|
561
|
|
|
/** |
562
|
|
|
* called when the outer CLI shell encounters a fatal error |
563
|
|
|
* |
564
|
|
|
* @param string $msg |
565
|
|
|
* the error message to show the user |
566
|
|
|
* @param \Exception $e |
567
|
|
|
* the exception that caused the error |
568
|
|
|
* @return void |
569
|
|
|
*/ |
570
|
|
|
public function logCliErrorWithException($msg, $e) |
571
|
|
|
{ |
572
|
|
|
// enforce our inputs |
573
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
574
|
|
|
Contract::RequiresValue($e, $e instanceof Exception); |
575
|
|
|
|
576
|
|
|
// pass this on to our plugins |
577
|
|
|
foreach ($this->plugins as $plugin) |
578
|
|
|
{ |
579
|
|
|
$plugin->logCliErrorWithException($msg, $e); |
580
|
|
|
} |
581
|
|
|
} |
582
|
|
|
|
583
|
|
|
/** |
584
|
|
|
* called when the outer CLI shell needs to publish a warning |
585
|
|
|
* |
586
|
|
|
* @param string $msg |
587
|
|
|
* the warning message to show the user |
588
|
|
|
* |
589
|
|
|
* @return void |
590
|
|
|
*/ |
591
|
|
|
public function logCliWarning($msg) |
592
|
|
|
{ |
593
|
|
|
// enforce our inputs |
594
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
595
|
|
|
|
596
|
|
|
// pass this on to our plugins |
597
|
|
|
foreach ($this->plugins as $plugin) |
598
|
|
|
{ |
599
|
|
|
$plugin->logCliWarning($msg); |
600
|
|
|
} |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* called when the outer CLI shell needs to tell the user something |
605
|
|
|
* |
606
|
|
|
* @param string $msg |
607
|
|
|
* the message to show the user |
608
|
|
|
* |
609
|
|
|
* @return void |
610
|
|
|
*/ |
611
|
|
|
public function logCliInfo($msg) |
612
|
|
|
{ |
613
|
|
|
// enforce our inputs |
614
|
|
|
Contract::RequiresValue($msg, is_string($msg)); |
615
|
|
|
|
616
|
|
|
// pass this on to our plugins |
617
|
|
|
foreach ($this->plugins as $plugin) |
618
|
|
|
{ |
619
|
|
|
$plugin->logCliInfo($msg); |
620
|
|
|
} |
621
|
|
|
} |
622
|
|
|
|
623
|
|
|
/** |
624
|
|
|
* an alternative to using PHP's built-in var_dump() |
625
|
|
|
* |
626
|
|
|
* @param string $name |
627
|
|
|
* a human-readable name to describe $var |
628
|
|
|
* |
629
|
|
|
* @param mixed $var |
630
|
|
|
* the variable to dump |
631
|
|
|
* |
632
|
|
|
* @return void |
633
|
|
|
*/ |
634
|
|
|
public function logVardump($name, $var) |
635
|
|
|
{ |
636
|
|
|
// enforce our inputs |
637
|
|
|
Contract::RequiresValue($name, is_string($name)); |
638
|
|
|
// $var can be anything, so there is no contract to enforce |
639
|
|
|
|
640
|
|
|
// pass this on to our plugins |
641
|
|
|
foreach ($this->plugins as $plugin) |
642
|
|
|
{ |
643
|
|
|
$plugin->logVardump($name, $var); |
644
|
|
|
} |
645
|
|
|
} |
646
|
|
|
} |
647
|
|
|
|