Completed
Push — master ( 3eed6d...7635b2 )
by Sebastian
04:09 queued 01:07
created

PrinterCli::onCleanupEnd()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
crap 2
1
<?php
2
namespace phpbu\App\Result;
3
4
use InvalidArgumentException;
5
use phpbu\App\Event;
6
use phpbu\App\Listener;
7
use phpbu\App\Result;
8
use phpbu\App\Util;
9
use phpbu\App\Version;
10
use PHP_Timer;
11
use SebastianBergmann\Environment\Console;
12
use SebastianBergmann\Environment\Runtime;
13
14
/**
15
 * Default app output.
16
 *
17
 * Heavily 'inspired' by Sebastian Bergmann's phpunit PHPUnit_TextUI_ResultPrinter.
18
 *
19
 * @package    phpbu
20
 * @subpackage Result
21
 * @author     Sebastian Feldmann <[email protected]>
22
 * @copyright  Sebastian Feldmann <[email protected]>
23
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
24
 * @link       http://phpbu.de/
25
 * @since      Class available since Release 1.0.0
26
 */
27
class PrinterCli implements Listener
28
{
29
    /**
30
     * Verbose output
31
     *
32
     * @var bool
33
     */
34
    protected $verbose = false;
35
36
    /**
37
     * Output with colors
38
     *
39
     * @var bool
40
     */
41
    protected $colors = false;
42
43
    /**
44
     * Is debug active
45
     *
46
     * @var bool
47
     */
48
    protected $debug = false;
49
50
    /**
51
     * Amount of executed backups
52
     *
53
     * @var integer
54
     */
55
    private $numBackups = 0;
56
57
    /**
58
     * Amount of executed checks
59
     *
60
     * @var integer
61
     */
62
    private $numChecks = 0;
63
64
    /**
65
     * Amount of executed crypts
66
     *
67
     * @var integer
68
     */
69
    private $numCrypts = 0;
70
71
    /**
72
     * Amount of executed Syncs
73
     *
74
     * @var integer
75
     */
76
    private $numSyncs = 0;
77
78
    /**
79
     * Amount of executed Cleanups
80
     *
81
     * @var integer
82
     */
83
    private $numCleanups = 0;
84
85
    /**
86
     * Console
87
     *
88
     * @var \SebastianBergmann\Environment\Console
89
     */
90
    private $console;
91
92
    /**
93
     * PHP Runtime
94
     *
95
     * @var \SebastianBergmann\Environment\Runtime
96
     */
97
    private $runtime;
98
99
    /**
100
     * Returns an array of event names this subscriber wants to listen to.
101
     *
102
     * The array keys are event names and the value can be:
103
     *
104
     *  * The method name to call (priority defaults to 0)
105
     *  * An array composed of the method name to call and the priority
106
     *  * An array of arrays composed of the method names to call and respective
107
     *    priorities, or 0 if unset
108
     *
109
     * @return array The event names to listen to
110
     */
111 2
    public static function getSubscribedEvents()
112
    {
113
        return [
114 2
            'phpbu.debug'           => 'onDebug',
115
            'phpbu.app_start'       => 'onPhpbuStart',
116
            'phpbu.backup_start'    => 'onBackupStart',
117
            'phpbu.backup_failed'   => 'onBackupFailed',
118
            'phpbu.backup_end'      => 'onBackupEnd',
119
            'phpbu.check_start'     => 'onCheckStart',
120
            'phpbu.check_failed'    => 'onCheckFailed',
121
            'phpbu.check_end'       => 'onCheckEnd',
122
            'phpbu.crypt_start'     => 'onCryptStart',
123
            'phpbu.crypt_skipped'   => 'onCryptSkipped',
124
            'phpbu.crypt_failed'    => 'onCryptFailed',
125
            'phpbu.crypt_end'       => 'onCryptEnd',
126
            'phpbu.sync_start'      => 'onSyncStart',
127
            'phpbu.sync_skipped'    => 'onSyncSkipped',
128
            'phpbu.sync_failed'     => 'onSyncFailed',
129
            'phpbu.sync_end'        => 'onSyncEnd',
130
            'phpbu.cleanup_start'   => 'onCleanupStart',
131
            'phpbu.cleanup_skipped' => 'onCleanupSkipped',
132
            'phpbu.cleanup_failed'  => 'onCleanupFailed',
133
            'phpbu.cleanup_end'     => 'onCleanupEnd',
134
            'phpbu.app_end'         => 'onPhpbuEnd',
135
        ];
136
    }
137
138
    /**
139
     * Constructor
140
     *
141
     * @param  bool $verbose
142
     * @param  bool $colors
143
     * @param  bool $debug
144
     * @throws \InvalidArgumentException
145
     */
146 28
    public function __construct(bool $verbose = false, bool $colors = false, bool $debug = false)
147
    {
148 28
        $this->console = new Console;
149 28
        $this->runtime = new Runtime;
150 28
        $this->debug   = $debug;
151 28
        $this->verbose = $verbose;
152 28
        $this->colors  = $colors && $this->console->hasColorSupport();
153 28
    }
154
155
    /**
156
     * phpbu start event.
157
     *
158
     * @param \phpbu\App\Event\App\Start $event
159
     */
160 2
    public function onPhpbuStart(Event\App\Start $event)
161
    {
162 2
        $configuration = $event->getConfiguration();
163 2
        if ($this->verbose) {
164 1
            $this->write(
165 1
                'Runtime:       ' . $this->runtime->getNameWithVersion() . PHP_EOL .
166 1
                'Configuration: ' . $configuration->getFilename() . PHP_EOL .
167 1
                PHP_EOL
168
            );
169
        }
170 2
    }
171
172
    /**
173
     * Backup start event.
174
     *
175
     * @param \phpbu\App\Event\Backup\Start $event
176
     */
177 3
    public function onBackupStart(Event\Backup\Start $event)
178
    {
179 3
        $this->numBackups++;
180 3
        if ($this->debug) {
181 2
            $backup = $event->getConfiguration();
182 2
            $this->writeWithAsterisk('backup: [' . $backup->getSource()->type . '] ');
183
        }
184 3
    }
185
186
    /**
187
     * Backup failed event.
188
     *
189
     * @param \phpbu\App\Event\Backup\Failed $event
190
     */
191 1
    public function onBackupFailed(Event\Backup\Failed $event)
192
    {
193 1
        if ($this->debug) {
194 1
            $this->writeWithColor('fg-white, bg-red, bold', 'failed' . PHP_EOL);
195
        }
196 1
    }
197
198
    /**
199
     * Backup end event.
200
     *
201
     * @param \phpbu\App\Event\Backup\End $event
202
     */
203 2
    public function onBackupEnd(Event\Backup\End $event)
204
    {
205 2
        if ($this->debug) {
206 1
            $this->writeWithColor('fg-black, bg-green', 'ok' . PHP_EOL);
207
        }
208 2
    }
209
210
    /**
211
     * Check start event.
212
     *
213
     * @param \phpbu\App\Event\Check\Start $event
214
     */
215 3
    public function onCheckStart(Event\Check\Start $event)
216
    {
217 3
        $this->numChecks++;
218 3
        if ($this->debug) {
219 2
            $check = $event->getConfiguration();
220 2
            $this->writeWithAsterisk('check: [' . $check->type . '] ');
221 2
            $this->write('checking: [' . $check->value . '] ');
222
        }
223 3
    }
224
225
    /**
226
     * Check failed event.
227
     *
228
     * @param \phpbu\App\Event\Check\Failed $event
229
     */
230 1
    public function onCheckFailed(Event\Check\Failed $event)
231
    {
232 1
        if ($this->debug) {
233 1
            $this->writeWithColor('fg-white, bg-red, bold', 'failed' . PHP_EOL);
234
        }
235 1
    }
236
237
    /**
238
     * Check end event.
239
     *
240
     * @param \phpbu\App\Event\Check\End $event
241
     */
242 2
    public function onCheckEnd(Event\Check\End $event)
243
    {
244 2
        if ($this->debug) {
245 1
            $this->writeWithColor('fg-black, bg-green', 'ok' . PHP_EOL);
246
        }
247 2
    }
248
249
    /**
250
     * Crypt start event.
251
     *
252
     * @param \phpbu\App\Event\Crypt\Start $event
253
     */
254 4
    public function onCryptStart(Event\Crypt\Start $event)
255
    {
256 4
        $this->numCrypts++;
257 4
        if ($this->debug) {
258 3
            $crypt = $event->getConfiguration();
259 3
            $this->writeWithAsterisk('crypt: [' . $crypt->type . '] ');
260
        }
261 4
    }
262
263
    /**
264
     * Crypt skipped event.
265
     *
266
     * @param \phpbu\App\Event\Crypt\Skipped $event
267
     */
268 1
    public function onCryptSkipped(Event\Crypt\Skipped $event)
269
    {
270 1
        if ($this->debug) {
271 1
            $this->writeWithColor('fg-black, bg-yellow', 'skipped' . PHP_EOL);
272
        }
273 1
    }
274
275
    /**
276
     * Crypt failed event.
277
     *
278
     * @param \phpbu\App\Event\Crypt\Failed $event
279
     */
280 1
    public function onCryptFailed(Event\Crypt\Failed $event)
281
    {
282 1
        if ($this->debug) {
283 1
            $this->writeWithColor('fg-white, bg-red, bold', 'failed' . PHP_EOL);
284
        }
285 1
    }
286
287
    /**
288
     * Crypt end event.
289
     *
290
     * @param \phpbu\App\Event\Crypt\End $event
291
     */
292 2
    public function onCryptEnd(Event\Crypt\End $event)
293
    {
294 2
        if ($this->debug) {
295 1
            $this->writeWithColor('fg-black, bg-green', 'ok' . PHP_EOL);
296
        }
297 2
    }
298
299
    /**
300
     * Sync start event.
301
     *
302
     * @param \phpbu\App\Event\Sync\Start $event
303
     */
304 4
    public function onSyncStart(Event\Sync\Start $event)
305
    {
306 4
        $this->numSyncs++;
307 4
        if ($this->debug) {
308 3
            $sync = $event->getConfiguration();
309 3
            $this->writeWithAsterisk('sync: [' . $sync->type . '] ');
310
        }
311 4
    }
312
313
    /**
314
     * Sync skipped event.
315
     *
316
     * @param \phpbu\App\Event\Sync\Skipped $event
317
     */
318 1
    public function onSyncSkipped(Event\Sync\Skipped $event)
319
    {
320 1
        if ($this->debug) {
321 1
            $this->writeWithColor('fg-black, bg-yellow', 'skipped' . PHP_EOL);
322
        }
323 1
    }
324
325
    /**
326
     * Sync failed event.
327
     *
328
     * @param \phpbu\App\Event\Sync\Failed $event
329
     */
330 1
    public function onSyncFailed(Event\Sync\Failed $event)
331
    {
332 1
        if ($this->debug) {
333 1
            $this->writeWithColor('fg-white, bg-red, bold', 'failed' . PHP_EOL);
334
        }
335 1
    }
336
337
    /**
338
     * Sync end event.
339
     *
340
     * @param \phpbu\App\Event\Sync\End $event
341
     */
342 2
    public function onSyncEnd(Event\Sync\End $event)
343
    {
344 2
        if ($this->debug) {
345 1
            $this->writeWithColor('fg-black, bg-green', 'ok' . PHP_EOL);
346
        }
347 2
    }
348
349
    /**
350
     * Cleanup start event.
351
     *
352
     * @param \phpbu\App\Event\Cleanup\Start $event
353
     */
354 4
    public function onCleanupStart(Event\Cleanup\Start $event)
355
    {
356 4
        $this->numCleanups++;
357 4
        if ($this->debug) {
358 3
            $cleanup = $event->getConfiguration();
359 3
            $this->writeWithAsterisk('cleanup: [' . $cleanup->type . '] ');
360
        }
361 4
    }
362
363
    /**
364
     * Cleanup skipped event.
365
     *
366
     * @param \phpbu\App\Event\Cleanup\Skipped $event
367
     */
368 1
    public function onCleanupSkipped(Event\Cleanup\Skipped $event)
369
    {
370 1
        if ($this->debug) {
371 1
            $this->writeWithColor('fg-black, bg-yellow', 'skipped' . PHP_EOL);
372
        }
373 1
    }
374
375
    /**
376
     * Cleanup failed event.
377
     *
378
     * @param \phpbu\App\Event\Cleanup\Failed $event
379
     */
380 1
    public function onCleanupFailed(Event\Cleanup\Failed $event)
381
    {
382 1
        if ($this->debug) {
383 1
            $this->writeWithColor('fg-white, bg-red, bold', 'failed' . PHP_EOL);
384
        }
385 1
    }
386
387
    /**
388
     * Cleanup end event.
389
     *
390
     * @param \phpbu\App\Event\Cleanup\End $event
391
     */
392 2
    public function onCleanupEnd(Event\Cleanup\End $event)
393
    {
394 2
        if ($this->debug) {
395 1
            $this->writeWithColor('fg-black, bg-green', 'ok' . PHP_EOL);
396
        }
397 2
    }
398
399
    /**
400
     * Debugging.
401
     *
402
     * @param \phpbu\App\Event\Debug $event
403
     */
404 1
    public function onDebug(Event\Debug $event)
405
    {
406 1
        if ($this->debug) {
407 1
            $this->write($event->getMessage() . PHP_EOL);
408
        }
409 1
    }
410
411
    /**
412
     * phpbu end event.
413
     *
414
     * @param \phpbu\App\Event\App\End $event
415
     */
416 1
    public function onPhpbuEnd(Event\App\End $event)
417
    {
418 1
        $result = $event->getResult();
419 1
        $this->printResult($result);
420 1
    }
421
422
    /**
423
     * Prints a result summary.
424
     *
425
     * @param \phpbu\App\Result $result
426
     */
427 5
    public function printResult(Result $result)
428
    {
429 5
        $this->printHeader();
430 5
        $this->printErrors($result);
431
432 5
        if ($this->verbose) {
433 3
            foreach ($result->getBackups() as $backup) {
434 3
                $this->printBackupVerbose($backup);
435
            }
436
        }
437 5
        $this->printFooter($result);
438 5
    }
439
440
    /**
441
     * Prints the result header with memory usage info.
442
     */
443 5
    protected function printHeader()
444
    {
445 5
        $this->write(PHP_Timer::resourceUsage() . PHP_EOL . PHP_EOL);
446 5
    }
447
448
    /**
449
     * Print error information.
450
     *
451
     * @param \phpbu\App\Result $result
452
     */
453 5
    protected function printErrors(Result $result)
454
    {
455
        /* @var $e \Exception */
456 5
        foreach ($result->getErrors() as $e) {
457 1
            $this->write(
458 1
                sprintf(
459 1
                    "Exception '%s' with message '%s'\nin %s:%d\n\n",
460 1
                    get_class($e),
461 1
                    $e->getMessage(),
462 1
                    $e->getFile(),
463 1
                    $e->getLine()
464
                )
465
            );
466
        }
467 5
    }
468
469
    /**
470
     * Prints verbose backup information.
471
     *
472
     * @param \phpbu\App\Result\Backup $backup
473
     */
474 3
    protected function printBackupVerbose(Result\Backup $backup)
475
    {
476 3
        $this->write(sprintf('backup %s: ', $backup->getName()));
477 3
        if ($backup->allOk()) {
478 1
            $this->writeWithColor(
479 1
                'fg-green',
480 1
                'OK'
481
            );
482 2
        } elseif ($backup->okButSkipsOrFails()) {
483 1
                $this->writeWithColor(
484 1
                    'fg-yellow',
485 1
                    'OK, but skipped or failed Crypts, Syncs or Cleanups!'
486
                );
487
        } else {
488 1
            $this->writeWithColor(
489 1
                'fg-red',
490 1
                'FAILED'
491
            );
492
        }
493 3
        $chExecuted = str_pad($backup->checkCount(), 8, ' ', STR_PAD_LEFT);
494 3
        $chFailed   = str_pad($backup->checkCountFailed(), 6, ' ', STR_PAD_LEFT);
495 3
        $crExecuted = str_pad($backup->cryptCount(), 8, ' ', STR_PAD_LEFT);
496 3
        $crSkipped  = str_pad($backup->cryptCountSkipped(), 7, ' ', STR_PAD_LEFT);
497 3
        $crFailed   = str_pad($backup->cryptCountFailed(), 6, ' ', STR_PAD_LEFT);
498 3
        $syExecuted = str_pad($backup->syncCount(), 8, ' ', STR_PAD_LEFT);
499 3
        $sySkipped  = str_pad($backup->syncCountSkipped(), 7, ' ', STR_PAD_LEFT);
500 3
        $syFailed   = str_pad($backup->syncCountFailed(), 6, ' ', STR_PAD_LEFT);
501 3
        $clExecuted = str_pad($backup->cleanupCount(), 8, ' ', STR_PAD_LEFT);
502 3
        $clSkipped  = str_pad($backup->cleanupCountSkipped(), 7, ' ', STR_PAD_LEFT);
503 3
        $clFailed   = str_pad($backup->cleanupCountFailed(), 6, ' ', STR_PAD_LEFT);
504
505 3
        $out = PHP_EOL . '          | executed | skipped | failed |' . PHP_EOL
506 3
            . '----------+----------+---------+--------+' . PHP_EOL
507 3
            . ' checks   | ' . $chExecuted . ' |         | ' . $chFailed . ' |' . PHP_EOL
508 3
            . ' crypts   | ' . $crExecuted . ' | ' . $crSkipped . ' | ' . $crFailed . ' |' . PHP_EOL
509 3
            . ' syncs    | ' . $syExecuted . ' | ' . $sySkipped . ' | ' . $syFailed . ' |' . PHP_EOL
510 3
            . ' cleanups | ' . $clExecuted . ' | ' . $clSkipped . ' | ' . $clFailed . ' |' . PHP_EOL
511 3
            . '----------+----------+---------+--------+' . PHP_EOL . PHP_EOL;
512
513 3
        $this->write($out);
514 3
    }
515
516
    /**
517
     * Prints 'OK' or 'FAILURE' footer.
518
     *
519
     * @param Result $result
520
     */
521 5
    protected function printFooter(Result $result)
522
    {
523 5
        if (count($result->getBackups()) === 0) {
524 2
            $this->writeWithColor(
525 2
                'fg-yellow',
526 2
                'No backups executed!'
527
            );
528 3
        } elseif ($result->allOk()) {
529 1
            $this->writeWithColor(
530 1
                'fg-green',
531 1
                sprintf(
532 1
                    'OK (%d %s, %d %s, %d %s, %d %s, %d %s)' . PHP_EOL,
533 1
                    count($result->getBackups()),
534 1
                    Util\Str::appendPluralS('backup', count($result->getBackups())),
535 1
                    $this->numChecks,
536 1
                    Util\Str::appendPluralS('check', $this->numChecks),
537 1
                    $this->numCrypts,
538 1
                    Util\Str::appendPluralS('crypt', $this->numCrypts),
539 1
                    $this->numSyncs,
540 1
                    Util\Str::appendPluralS('sync', $this->numSyncs),
541 1
                    $this->numCleanups,
542 1
                    Util\Str::appendPluralS('cleanup', $this->numCleanups)
543
                )
544
            );
545 2
        } elseif ($result->backupOkButSkipsOrFails()) {
546 1
            $this->writeWithColor(
547 1
                'fg-yellow',
548 1
                sprintf(
549 1
                    "WARNING, skipped|failed Crypts, Syncs or Cleanups!" . PHP_EOL .
550 1
                    'Backups: %d, Crypts: %d|%d, Syncs: %d|%d, Cleanups: %d|%d ' . PHP_EOL,
551 1
                    count($result->getBackups()),
552 1
                    $result->cryptsSkippedCount(),
553 1
                    $result->cryptsFailedCount(),
554 1
                    $result->syncsSkippedCount(),
555 1
                    $result->syncsFailedCount(),
556 1
                    $result->cleanupsSkippedCount(),
557 1
                    $result->cleanupsFailedCount()
558
                )
559
            );
560
        } else {
561 1
            $this->writeWithColor(
562 1
                'fg-red',
563 1
                sprintf(
564 1
                    "FAILURE!" . PHP_EOL .
565 1
                    'Backups: %d, failed Checks: %d, failed Crypts: %d, failed Syncs: %d, failed Cleanups: %d.' . PHP_EOL,
566 1
                    count($result->getBackups()),
567 1
                    $result->checksFailedCount(),
568 1
                    $result->cryptsFailedCount(),
569 1
                    $result->syncsFailedCount(),
570 1
                    $result->cleanupsFailedCount()
571
                )
572
            );
573
        }
574 5
    }
575
576
    /**
577
     * Writes a buffer out with a color sequence if colors are enabled.
578
     *
579
     * @author Sebastian Bergmann <[email protected]>
580
     * @param  string $color
581
     * @param  string $buffer
582
     */
583 18
    protected function writeWithColor($color, $buffer)
584
    {
585 18
        if ($this->colors) {
586 1
            $buffer = Util\Cli::formatWithColor($color, $buffer);
587
        }
588 18
        $this->write($buffer . PHP_EOL);
589 18
    }
590
591
    /**
592
     * Writes a buffer with Ansible like asterisk decoration.
593
     *
594
     * @param string $buffer
595
     */
596 13
    protected function writeWithAsterisk($buffer)
597
    {
598 13
        $this->write(Util\Cli::formatWithAsterisk($buffer));
599 13
    }
600
601
    /**
602
     * Writes a buffer.
603
     *
604
     * @param string $buffer
605
     */
606 20
    public function write($buffer)
607
    {
608 20
        if (PHP_SAPI != 'cli') {
609
            $buffer = htmlspecialchars($buffer);
610
        }
611 20
        echo $buffer;
612 20
    }
613
}
614