EventObserver   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 17
eloc 45
c 1
b 0
f 0
dl 0
loc 120
ccs 46
cts 46
cp 1
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A update() 0 4 2
A __construct() 0 6 1
A validate() 0 14 5
A getResults() 0 3 1
B handleEvent() 0 32 8
1
<?php
2
3
namespace App;
4
5
use SplSubject;
6
use SplObserver;
7
use Symfony\Component\Process\Process;
8
9
/**
10
 * Event observer class
11
 *
12
 * @see https://www.php.net/manual/zh/class.splobserver.php
13
 */
14
class EventObserver implements SplObserver
15
{
16
    /**
17
     * Event handler config
18
     *
19
     * @var array
20
     */
21
    private $_config;
22
23
    /**
24
     * Event handler results
25
     *
26
     * @var array
27
     */
28
    private $_results = [];
29
30
    /**
31
     * Construct a new event observer
32
     *
33
     * @param array $config Event handler config
34
     */
35 3
    public function __construct(array $config)
36
    {
37 3
        $this->_config = $config + [
38 3
            'type' => '*',
39
            'conditions' => [],
40
            'commands' => []
41
        ];
42 3
    }
43
44
    /**
45
     * Receive update from subject
46
     *
47
     * @param \SplSubject $subject Event subject
48
     *
49
     * @return void
50
     */
51 2
    public function update(SplSubject $subject): void
52
    {
53 2
        if ($subject instanceof EventSubject) {
54 2
            $this->handleEvent($subject);
55
        }
56 2
    }
57
58
    /**
59
     * Handle event.
60
     *
61
     * @param \App\EventSubject $subject Event subject
62
     *
63
     * @return void
64
     */
65 2
    private function handleEvent(EventSubject $subject): void
66
    {
67 2
        $this->_results = [];
68 2
        $this->_config['conditions']['object_kind'] = $this->_config['type'];
69 2
        foreach ($this->_config['conditions'] as $key => $expected) {
70 2
            if (strpos($key, '.') !== false) {
71 1
                list($attr, $subkey) = explode('.', $key);
72 1
                $value = $subject[$attr][$subkey];
73
            } else {
74 1
                $value = $subject[$key];
75
            }
76 2
            if (self::validate($value, $expected) === false) {
77 1
                $this->_results[] = ['debug', '{event} event ignored, expected: {expected}, actual: {actual}.', [
78 1
                    'event' => $this->_config['name'],
79 1
                    'expected' => (is_array($expected) ? json_encode($expected) : $expected),
80 1
                    'actual' => $value,
81
                ]];
82 2
                return;
83
            }
84
        }
85 1
        foreach ($this->_config['commands'] as $command) {
86 1
            $process = new Process($command, null, $subject->getEnv());
87 1
            $process->run();
88 1
            $output = $process->getOutput();
89 1
            $this->_results[] = [
90 1
                ($process->isSuccessful() ? 'notice' : 'error'),
91 1
                '{event}: {command} (return:{code}){output}',
92
                [
93 1
                    'event' => $this->_config['name'],
94 1
                    'command' => implode(' ', $command),
95 1
                    'code' => $process->getExitCode(),
96 1
                    'output' => ($output ? PHP_EOL . $output : '')
97
                ]
98
            ];
99
        }
100 1
    }
101
102
    /**
103
     * Get results
104
     *
105
     * @return array
106
     */
107 2
    public function getResults(): array
108
    {
109 2
        return $this->_results;
110
    }
111
112
    /**
113
     * Validate
114
     *
115
     * @param mixed $actual   Actual value
116
     * @param mixed $expected Expected value
117
     *
118
     * @return bool
119
     */
120 4
    public static function validate($actual, $expected): bool
121
    {
122 4
        if (is_array($expected)) {
123 1
            $result = false;
124 1
            foreach ($expected as $item) {
125 1
                if ($result = self::validate($actual, $item)) {
126 1
                    break;
127
                }
128
            }
129 1
            return $result;
130 4
        } elseif (strpos($expected, '*') !== false) {
131 1
            return preg_match('#^' . str_replace('*', '.*', $expected) . '$#', $actual) > 0;
132
        } else {
133 3
            return $actual == $expected;
134
        }
135
    }
136
}
137