Completed
Push — master ( 96cfdd...488d47 )
by Paul
02:23
created

CoreTrait::getAllTraits()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
4
declare(strict_types=1);
5
6
namespace Mcneely\Core\Traits;
7
8
use Mcneely\Core\CoreObject;
9
10
trait CoreTrait
11
{
12
    /** @var CoreObject */
13
    private $CoreTrait_CoreObject = null;
14
15
    /** @var bool $CoreTrait_hasSetUp */
16
    private $CoreTrait_hasSetUp = false;
17
18
    /** @var array $CoreTrait_events */
19
    private $CoreTrait_events = [];
20
21
    /**
22
     * @return CoreObject
23
     */
24 8
    protected function CoreTrait_getCoreObject(): CoreObject
25
    {
26 8
        $this->CoreTrait_fireEvents($this, __CLASS__, __METHOD__, __TRAIT__);
27
28 8
        return $this->CoreTrait_CoreObject;
29
    }
30
31
    /**
32
     * @param object $eventClassObject    -- object as function type not introduced until 7.2
33
     * @param string $eventImmediateClass
34
     * @param string $eventMethod
35
     * @param string $eventTrait
36
     *
37
     * @return self
38
     */
39 11
    protected function CoreTrait_fireEvents(
40
        /* @noinspection PhpUnusedParameterInspection */
41
        $eventClassObject,
42
        ?string $eventImmediateClass = '',
43
        ?string $eventMethod = '',
44
        ?string $eventTrait = ''
45
    ): self {
46 11
        if (!$this->CoreTrait_hasSetUp) {
47 11
            $this->CoreTrait_fireStartup($eventClassObject, $eventImmediateClass);
48
        }
49
50 11
        $eventMethodArray = !empty($eventMethod) ? explode('::', $eventMethod) : [];
51 11
        $eventMethodShort = array_pop($eventMethodArray);
52 11
        $beforeMethod     = '__fireBefore_'.$eventMethodShort;
53 11
        $triggers         = [];
54
55 11
        if (method_exists($eventClassObject, $beforeMethod)) {
56 1
            $triggers[] = [
57 1
                'method'  => $beforeMethod,
58
                'exclude' => [],
59
            ];
60
        }
61
62 11
        $functionTriggers = array_key_exists(
63 11
            $eventMethodShort,
64 11
            $this->CoreTrait_events
65 11
        ) ? $this->CoreTrait_events[$eventMethodShort] : [];
66 11
        $wildCardTriggers = array_key_exists('*', $this->CoreTrait_events) ? $this->CoreTrait_events['*'] : [];
67 11
        $triggers         = array_merge($triggers, $functionTriggers, $wildCardTriggers);
68
69 11
        foreach ($triggers as $trigger) {
70 2
            if (!in_array($eventMethodShort, $trigger['exclude'])) {
71 2
                $method = $trigger['method'];
72 2
                if ($method instanceof \Closure) {
73 1
                    $closure = \Closure::bind($method, $eventClassObject);
74 1
                    $closure();
75
                } else {
76 2
                    $eventClassObject->$method();
77
                }
78
            }
79
        }
80
81 11
        return $this;
82
    }
83
84
    /**
85
     * @param object $eventClassObject
86
     * @param string $eventImmediateClass
87
     */
88 11
    private function CoreTrait_fireStartup($eventClassObject, $eventImmediateClass): void
89
    {
90 11
        $this->CoreTrait_hasSetUp = true;
91 11
        $traits                   = array_merge(class_uses($eventImmediateClass), class_uses($eventClassObject));
92 11
        $traits                   = $this->cleanTraits($traits);
93
94 11
        $methods = preg_grep('/^__setUp_/', get_class_methods(get_class($eventClassObject)));
95
96 11
        foreach ($methods as $method) {
97 1
            if (in_array(substr($method, 8), $traits)) {
98 1
                $eventClassObject->$method();
99
            }
100
        }
101 11
    }
102
103 11
    protected function cleanTraits(array $traits): array
104
    {
105 11
        foreach ($traits as $key => $trait) {
106 11
            $traits[$key] = basename(str_replace('\\', '/', $trait));
107
        }
108
109 11
        return $traits;
110
    }
111
112
    /**
113
     * @param mixed $object
114
     *
115
     * @return self
116
     */
117 11
    protected function CoreTrait_setCoreObject($object = null): self
118
    {
119 11
        $this->CoreTrait_hasSetUp   = false;
120 11
        $this->CoreTrait_events     = [];
121 11
        $this->CoreTrait_CoreObject = ($object instanceof CoreObject) ? $object : new CoreObject($object);
122 11
        $this->CoreTrait_fireEvents($this, __CLASS__, __METHOD__, __TRAIT__);
123
124 11
        return $this;
125
    }
126
127 3
    protected function CoreTrait_registerEvent($onFunction, $triggerMethod, array $exclude = []): self
128
    {
129 3
        $this->CoreTrait_events[$onFunction][] = [
130 3
            'method'  => $triggerMethod,
131 3
            'exclude' => ('*' === $onFunction) ? $exclude : [],
132
        ];
133
134 3
        return $this;
135
    }
136
137
    /**
138
     * @param array $traits
139
     * @param       $currentTrait
140
     *
141
     * @throws \Exception
142
     */
143 1
    protected function CoreTrait_require(array $traits, $currentTrait)
144
    {
145 1
        $classTraits = $this->getAllTraits($this);
146
147 1
        foreach ($traits as $trait) {
148 1
            if (!in_array($trait, $classTraits)) {
149 1
                throw new \Exception("{$currentTrait} requires trait {$trait}");
150
            }
151
        }
152 1
    }
153
154 1
    protected function getAllTraits($object) {
155 1
        $objects = array_merge([$object], class_parents($object));
156 1
        $traits = [];
157 1
        foreach ($objects as $object) {
0 ignored issues
show
introduced by
$object is overwriting one of the parameters of this function.
Loading history...
158 1
            $traits = array_merge(class_uses($object), $traits);
159
        }
160
161 1
        return array_unique($traits);
162
    }
163
}
164