Completed
Push — master ( afce1d...f8221d )
by Vladimir
09:37
created

Kernel::dispatch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 6
ccs 4
cts 4
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace FondBot\Foundation;
6
7
use FondBot\Drivers\Driver;
8
use FondBot\Drivers\Command;
9
use FondBot\Channels\Channel;
10
use Illuminate\Bus\Dispatcher;
11
use FondBot\Conversation\Context;
12
use FondBot\Conversation\Session;
13
use FondBot\Conversation\ContextManager;
14
use FondBot\Conversation\SessionManager;
15
use Illuminate\Contracts\Container\Container;
16
17
class Kernel
18
{
19
    public const VERSION = '2.0';
20
21
    /** @var Kernel */
22
    private static $instance;
23
24
    private $container;
25
    private $terminable;
26
27
    private $driver;
28
    private $channel;
29
    private $session;
30
    private $context;
31
32 119
    private function __construct(Container $container, bool $terminable = true)
33
    {
34 119
        $this->container = $container;
35 119
        $this->terminable = $terminable;
36 119
    }
37
38 4
    public function __destruct()
39
    {
40 4
        $this->terminate();
41 4
    }
42
43 22
    public static function getInstance(): Kernel
44
    {
45 22
        return static::$instance;
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
46
    }
47
48 119
    public static function createInstance(Container $container, bool $terminable = true): Kernel
49
    {
50 119
        return static::$instance = new static($container, $terminable);
0 ignored issues
show
Bug introduced by
Since $instance is declared private, accessing it with static will lead to errors in possible sub-classes; consider using self, or increasing the visibility of $instance to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return static::$someVariable;
    }
}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass { }

YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class SomeClass
{
    private static $someVariable;

    public static function getSomeVariable()
    {
        return self::$someVariable; // self works fine with private.
    }
}
Loading history...
51
    }
52
53
    /**
54
     * Boot kernel.
55
     *
56
     * @param Channel $channel
57
     * @param Driver  $driver
58
     */
59 1
    public function boot(Channel $channel, Driver $driver): void
60
    {
61 1
        $this->session = $this->sessionManager()->load($channel, $driver);
62 1
        $this->context = $this->contextManager()->load($channel, $driver);
63 1
    }
64
65
    /**
66
     * Perform shutdown tasks.
67
     */
68 6
    public function terminate(): void
69
    {
70 6
        if (!$this->terminable) {
71 1
            return;
72
        }
73
74
        // Save session if exists
75 5
        if ($this->session !== null) {
76 2
            $this->sessionManager()->save($this->session);
77
        }
78
79
        // Save context if exists
80 5
        if ($this->context !== null) {
81 2
            $this->contextManager()->save($this->context);
82
        }
83 5
    }
84
85
    /**
86
     * Get current channel.
87
     *
88
     * @return Channel|null
89
     */
90 1
    public function getChannel(): ?Channel
91
    {
92 1
        return $this->channel;
93
    }
94
95
    /**
96
     * Set channel.
97
     *
98
     * @param Channel $channel
99
     */
100 7
    public function setChannel(Channel $channel): void
101
    {
102 7
        $this->channel = $channel;
103 7
    }
104
105
    /**
106
     * Get current driver.
107
     *
108
     * @return Driver|null
109
     */
110 1
    public function getDriver(): ?Driver
111
    {
112 1
        return $this->driver;
113
    }
114
115
    /**
116
     * Set driver.
117
     *
118
     * @param Driver $driver
119
     */
120 7
    public function setDriver(Driver $driver): void
121
    {
122 7
        $this->driver = $driver;
123 7
    }
124
125
    /**
126
     * Get session.
127
     *
128
     * @return Session|null
129
     */
130 14
    public function getSession(): ?Session
131
    {
132 14
        return $this->session;
133
    }
134
135
    /**
136
     * Set session.
137
     *
138
     * @param Session $session
139
     */
140 14
    public function setSession(Session $session): void
141
    {
142 14
        $this->session = $session;
143 14
    }
144
145
    /**
146
     * Close session.
147
     */
148 3
    public function closeSession(): void
149
    {
150 3
        if ($this->session !== null) {
151 3
            $this->sessionManager()->close($this->session);
152 3
            $this->session = null;
153
        }
154 3
    }
155
156
    /**
157
     * Get context.
158
     *
159
     * @return Context|null
160
     */
161 3
    public function getContext(): ?Context
162
    {
163 3
        return $this->context;
164
    }
165
166
    /**
167
     * Set context.
168
     *
169
     * @param Context $context
170
     */
171 6
    public function setContext(Context $context): void
172
    {
173 6
        $this->context = $context;
174 6
    }
175
176
    /**
177
     * Clear context.
178
     */
179 3
    public function clearContext(): void
180
    {
181 3
        if ($this->context !== null) {
182 1
            $this->contextManager()->clear($this->context);
183 1
            $this->context = null;
184
        }
185 3
    }
186
187
    /**
188
     * Resolve an alias from container.
189
     *
190
     * @param string $alias
191
     *
192
     * @return mixed
193
     */
194 18
    public function resolve(string $alias)
195
    {
196 18
        return $this->container->make($alias);
197
    }
198
199
    /**
200
     * Dispatch command to driver.
201
     *
202
     * @param Command $command
203
     */
204 6
    public function dispatch(Command $command): void
205
    {
206 6
        $dispatcher = $this->resolve(Dispatcher::class);
207
208 6
        $dispatcher->dispatch($command);
209 6
    }
210
211
    /**
212
     * Get session manager.
213
     *
214
     * @return SessionManager
215
     */
216 6
    private function sessionManager(): SessionManager
217
    {
218 6
        return $this->resolve(SessionManager::class);
219
    }
220
221
    /**
222
     * Get context manager.
223
     *
224
     * @return ContextManager
225
     */
226 4
    private function contextManager(): ContextManager
227
    {
228 4
        return $this->resolve(ContextManager::class);
229
    }
230
}
231