Completed
Push — 2.0 ( ada449...a2425b )
by Vermeulen
01:55
created

Observers::addMonologForObserver()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 4
nc 4
nop 1
1
<?php
2
3
namespace BfwSql\Runners;
4
5
use \Exception;
6
7
/**
8
 * Create and attach all observer declared in config file.
9
 * Create also monolog instance used by him.
10
 * It's a runner, so is called when the module is initialized.
11
 * 
12
 * @package bfw-sql
13
 * @author Vermeulen Maxime <[email protected]>
14
 * @version 2.0
15
 */
16
class Observers extends AbstractRunner
17
{
18
    /**
19
     * @const ERR_ADD_OBSERVER_MISSING_CLASSNAME Exception code if an observer
20
     * declared in config has no class name
21
     */
22
    const ERR_ADD_OBSERVER_MISSING_CLASSNAME = 2504001;
23
    
24
    /**
25
     * @const ERR_ADD_OBSERVER_UNKNOWN_CLASS Exception code if an observer
26
     * declared in config has an unknown class.
27
     */
28
    const ERR_ADD_OBSERVER_UNKNOWN_CLASS = 2504002;
29
    
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function run()
34
    {
35
        $app     = \BFW\Application::getInstance();
36
        $subject = new \BFW\Subject;
37
        $app->getSubjectList()->addSubject($subject, 'bfw-sql');
38
        
39
        $config        = $this->module->getConfig();
40
        $listObservers = $config->getValue('observers', 'observers.php');
41
        
42
        foreach ($listObservers as $observerInfos) {
43
            $this->addObserver($observerInfos, $subject);
44
        }
45
    }
46
    
47
    /**
48
     * Create the new observer and attach it to the bfw-sql subject
49
     * 
50
     * @param \stdClass $observerInfos Infos from config for the new observer
51
     * @param \BFW\Subject $subject The subject to attach the new observer
52
     * 
53
     * @return void
54
     */
55
    protected function addObserver($observerInfos, \BFW\Subject $subject)
56
    {
57
        $this->checkObserverClass($observerInfos);
58
        $this->checkObserverMonologHandlers($observerInfos);
59
        
60
        $monolog = $this->addMonologForObserver($observerInfos);
61
        
62
        $observerClassName = $observerInfos->className;
63
        $observer          = new $observerClassName($monolog);
64
        $subject->attach($observer);
65
    }
66
    
67
    /**
68
     * Check the observer class infos declared in config
69
     * 
70
     * @param \stdClass $observerInfos Infos from config for the new observer
71
     * 
72
     * @throws Exception If there are somes problems with the class to use
73
     * 
74
     * @return void
75
     */
76
    protected function checkObserverClass($observerInfos)
77
    {
78
        if (!property_exists($observerInfos, 'className')) {
79
            throw new Exception(
80
                'The property "className" should be declared for each observer.',
81
                self::ERR_ADD_OBSERVER_MISSING_CLASSNAME
82
            );
83
        }
84
        
85
        if (!class_exists($observerInfos->className)) {
86
            throw new Exception(
87
                'The class '.$observerInfos->className.' not exist.',
88
                self::ERR_ADD_OBSERVER_UNKNOWN_CLASS
89
            );
90
        }
91
    }
92
    
93
    /**
94
     * Check monolog handler declared in the config and add missing datas.
95
     * 
96
     * @param \stdClass $observerInfos Infos from config for the new observer
97
     * 
98
     * @return void
99
     */
100
    protected function checkObserverMonologHandlers($observerInfos)
101
    {
102
        if (!property_exists($observerInfos, 'monologHandlers')) {
103
            $observerInfos->monologHandlers = (object) [];
104
        }
105
        $handlersInfos = $observerInfos->monologHandlers;
106
        
107
        if (!property_exists($handlersInfos, 'useGlobal')) {
108
            $handlersInfos->useGlobal = false;
109
        }
110
        
111
        if (!is_bool($handlersInfos->useGlobal)) {
112
            $handlersInfos->useGlobal = (bool) $handlersInfos->useGlobal;
113
        }
114
        
115
        if (!property_exists($handlersInfos, 'others')) {
116
            $handlersInfos->others = [];
117
        }
118
        
119
        if (!is_array($handlersInfos->others)) {
120
            $handlersInfos->others = [];
121
        }
122
    }
123
    
124
    /**
125
     * Add monolog handlers for the new observer
126
     * 
127
     * @param \stdClass $observerInfos Infos from config for the new observer
128
     * 
129
     * @return \BFW\Monolog
130
     */
131
    protected function addMonologForObserver($observerInfos)
132
    {
133
        $handlersInfos = $observerInfos->monologHandlers;
134
        
135
        if ($handlersInfos->useGlobal === false) {
136
            $monolog = Monolog::createMonolog($this->module->getConfig());
137
        } else {
138
            //Clone because we want add new handlers only for this observer.
139
            $monolog = clone $this->module->monolog;
140
        }
141
        
142
        if ($handlersInfos->others !== []) {
143
            foreach ($handlersInfos->others as $handlerInfos) {
144
                $monolog->addNewHandler($handlerInfos);
145
            }
146
        }
147
        
148
        return $monolog;
149
    }
150
}
151