Pomm::removeSession()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
/*
3
 * This file is part of the PommProject/Foundation package.
4
 *
5
 * (c) 2014 - 2017 Grégoire HUBERT <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace PommProject\Foundation;
11
12
use PommProject\Foundation\Exception\FoundationException;
13
use PommProject\Foundation\Session\SessionBuilder as VanillaSessionBuilder;
14
use PommProject\Foundation\Session\Session as BaseSession;
15
use Psr\Log\LoggerAwareInterface;
16
use Psr\Log\LoggerAwareTrait;
17
18
/**
19
 * Pomm
20
 *
21
 * The Pomm service manager.
22
 *
23
 * @package     Foundation
24
 * @copyright   2014 - 2017 Grégoire HUBERT
25
 * @author      Grégoire HUBERT
26
 * @license     X11 {@link http://opensource.org/licenses/mit-license.php}
27
 */
28
class Pomm implements \ArrayAccess, LoggerAwareInterface
29
{
30
    protected $builders = [];
31
    protected $post_configurations = [];
32
    protected $sessions = [];
33
    protected $default;
34
35
    use LoggerAwareTrait;
36
37
    /**
38
     * __construct
39
     *
40
     * Instantiate a new Pomm Service class. It takes an array of
41
     * configurations as parameter. Following configuration settings are
42
     * supported by this service for each configuration:
43
     *
44
     * class_name   name of the DatabaseConfiguration class to instantiate.
45
     *
46
     * @param   array $configurations
47
     */
48
    public function __construct(array $configurations = [])
49
    {
50
        foreach ($configurations as $name => $configuration) {
51
            $builder_class = '\PommProject\Foundation\SessionBuilder';
52
            if (isset($configuration['class:session_builder'])) {
53
                $builder_class = $this->checkSessionBuilderClass($configuration['class:session_builder']);
54
            }
55
56
            $this->addBuilder($name, new $builder_class($configuration));
57
58
            if (isset($configuration['pomm:default']) && $configuration['pomm:default'] === true) {
59
                $this->setDefaultBuilder($name);
60
            }
61
        }
62
    }
63
64
    /**
65
     * checkSessionBuilderClass
66
     *
67
     * Check if the given builder class is valid.
68
     *
69
     * @param   string              $builder_class
70
     * @throws  FoundationException if not valid
71
     * @return  string              $builder_class
72
     */
73
    private function checkSessionBuilderClass($builder_class)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
74
    {
75
        try {
76
            $reflection = new \ReflectionClass($builder_class);
77
78
            if (!$reflection->isSubclassOf('\PommProject\Foundation\Session\SessionBuilder')) {
79
                throw new FoundationException(
80
                    sprintf(
81
                        "Class '%s' is not a subclass of \PommProject\Foundation\Session\SessionBuilder.",
82
                        $builder_class
83
                    )
84
                );
85
            }
86
        } catch (\ReflectionException $e) {
87
            throw new FoundationException(
88
                sprintf(
89
                    "Could not instantiate class '%s'.",
90
                    $builder_class
91
                ),
92
                null,
93
                $e
94
            );
95
        }
96
97
        return $builder_class;
98
    }
99
100
    /**
101
     * setDefaultBuilder
102
     *
103
     * Set the name for the default session builder.
104
     *
105
     * @param   string  $name
106
     * @return  Pomm    $this
107
     * @throws FoundationException
108
     */
109
    public function setDefaultBuilder($name)
110
    {
111
        if (!$this->hasBuilder($name)) {
112
            throw new FoundationException(
113
                sprintf(
114
                    "No such builder '%s'.",
115
                    $name
116
                )
117
            );
118
        }
119
120
        $this->default = $name;
121
122
        return $this;
123
    }
124
125
    /**
126
     * getDefaultSession
127
     *
128
     * Return a session built by the default session builder.
129
     *
130
     * @return  BaseSession
131
     * @throws FoundationException
132
     */
133
    public function getDefaultSession()
134
    {
135
        if ($this->default === null) {
136
            throw new FoundationException(
137
                "No default session builder set."
138
            )
139
            ;
140
        }
141
142
        return $this->getSession($this->default);
143
    }
144
145
    /**
146
     * isDefaultSession
147
     *
148
     * Check if $name is a default session builder
149
     *
150
     * @param   string $name
151
     * @return  bool
152
     */
153
    public function isDefaultSession($name)
154
    {
155
        return (bool) ($this->default == $name);
156
    }
157
158
    /**
159
     * addBuilder
160
     *
161
     * Add a new session builder. Override any previously existing builder with
162
     * the same name.
163
     *
164
     * @param   string                   $builder_name
165
     * @param   VanillaSessionBuilder    $builder
166
     * @return  Pomm                     $this
167
     */
168
    public function addBuilder($builder_name, VanillaSessionBuilder $builder)
169
    {
170
        $this->builders[$builder_name] = $builder;
171
        $this->post_configurations[$builder_name] = [];
172
173
        if ($this->default === null) {
174
            $this->setDefaultBuilder($builder_name);
175
        }
176
177
        return $this;
178
    }
179
180
    /**
181
     * addPostConfiguration
182
     *
183
     * Add a environment dependent post configuration callable that will be run
184
     * once after the session creation.
185
     *
186
     * @param   string   $name
187
     * @param   callable $callable
188
     * @return  Pomm     $this
189
     */
190
    public function addPostConfiguration($name, callable $callable)
191
    {
192
        $this
193
            ->builderMustExist($name)
194
            ->post_configurations[$name][] = $callable
195
            ;
196
197
        return $this;
198
    }
199
200
    /**
201
     * hasBuilder
202
     *
203
     * Return if true or false the given builder exists.
204
     *
205
     * @param   string $name
206
     * @return  bool
207
     */
208
    public function hasBuilder($name)
209
    {
210
        return (bool) (isset($this->builders[$name]));
211
    }
212
213
    /**
214
     * removeBuilder
215
     *
216
     * Remove the builder with the given name.
217
     *
218
     * @param   string   $name
219
     * @throws  FoundationException if name does not exist.
220
     * @return  Pomm     $this
221
     */
222
    public function removeBuilder($name)
223
    {
224
        unset(
225
            $this->builderMustExist($name)->builders[$name],
226
            $this->post_configurations[$name]
227
        );
228
229
        return $this;
230
    }
231
232
    /**
233
     * getBuilder
234
     *
235
     * Return the given builder.
236
     *
237
     * @param   string $name
238
     * @return  VanillaSessionBuilder
239
     */
240
    public function getBuilder($name)
241
    {
242
        return $this->builderMustExist($name)->builders[$name];
243
    }
244
245
    /**
246
     * getSession
247
     *
248
     * Return a session from the pool. If no session exists, an attempt is made
249
     * to create one.
250
     *
251
     * @param   string  $name
252
     * @return  BaseSession
253
     */
254
    public function getSession($name)
255
    {
256
        if (!$this->hasSession($name)) {
257
            $this->createSession($name);
258
        }
259
260
        return $this->sessions[$name];
261
    }
262
263
    /**
264
     * createSession
265
     *
266
     * Create a new session using a session_builder and set it to the pool. Any
267
     * previous session for this name is overrided.
268
     *
269
     * @param   string  $name
270
     * @throws  FoundationException if builder does not exist.
271
     * @return  BaseSession
272
     */
273
    public function createSession($name)
274
    {
275
        $this->sessions[$name] = $this
276
            ->builderMustExist($name)
277
            ->builders[$name]
278
            ->buildSession($name)
279
            ;
280
281
        $session = $this->sessions[$name];
282
283
        foreach ($this->post_configurations[$name] as $callable) {
284
            call_user_func($callable, $session);
285
        }
286
287
        if ($this->logger !== null) {
288
            $session->setLogger($this->logger);
289
        }
290
291
        return $session;
292
    }
293
294
    /**
295
     * hasSession
296
     *
297
     * Does a given session exist in the pool ?
298
     *
299
     * @param   string $name
300
     * @return  bool
301
     */
302
    public function hasSession($name)
303
    {
304
        return (bool) isset($this->sessions[$name]);
305
    }
306
307
    /**
308
     * removeSession
309
     *
310
     * Remove a session from the pool if it exists.
311
     *
312
     * @param   string              $name
313
     * @throws  FoundationException if no builders with that name exist
314
     * @return  Pomm                $this
315
     */
316
    public function removeSession($name)
317
    {
318
        if ($this->builderMustExist($name)->hasSession($name)) {
319
            unset($this->sessions[$name]);
320
        }
321
322
        return $this;
323
    }
324
325
    /**
326
     * getSessionBuilders
327
     *
328
     * Return the builders. This is mainly done for testing
329
     * purposes.
330
     *
331
     * @return  array
332
     */
333
    public function getSessionBuilders()
334
    {
335
        return $this->builders;
336
    }
337
338
    /**
339
     * @see ArrayAccess
340
     */
341
    public function offsetGet($offset)
342
    {
343
        return $this->getSession($offset);
344
    }
345
346
    /**
347
     * @see ArrayAccess
348
     */
349
    public function offsetSet($offset, $value)
350
    {
351
        $this->addBuilder($offset, $value);
352
    }
353
354
    /**
355
     * @see ArrayAccess
356
     */
357
    public function offsetUnset($offset)
358
    {
359
        $this->removeBuilder($offset);
360
    }
361
362
    /**
363
     * @see ArrayAccess
364
     */
365
    public function offsetExists($offset)
366
    {
367
        return $this->hasBuilder($offset);
368
    }
369
370
    /**
371
     * shutdown
372
     *
373
     * Shutdown and remove sessions from the service. If no arguments are
374
     * given, all the instantiated sessions are shutdown. Otherwise, only given
375
     * sessions are shutdown.
376
     *
377
     * @param  array $session_names
378
     * @return Pomm  $this
379
     */
380
    public function shutdown(array $session_names = [])
381
    {
382
        if (empty($session_names)) {
383
            $sessions = array_keys($this->sessions);
384
        } else {
385
            array_map([ $this, 'builderMustExist' ], $session_names);
386
            $sessions = array_intersect(
387
                array_keys($this->sessions),
388
                $session_names
389
            );
390
        }
391
392
        foreach ($sessions as $session_name) {
393
            $this->getSession($session_name)->shutdown();
394
            $this->removeSession($session_name);
395
        }
396
397
        return $this;
398
    }
399
400
    /**
401
     * builderMustExist
402
     *
403
     * Throw a FoundationException if the given builder does not exist.
404
     *
405
     * @param   string   $name
406
     * @throws  FoundationException
407
     * @return  Pomm      $this
408
     */
409
    private function builderMustExist($name)
410
    {
411
        if (!$this->hasBuilder($name)) {
412
            throw new FoundationException(
413
                sprintf(
414
                    "No such builder '%s'. Available builders are {%s}.",
415
                    $name,
416
                    join(
417
                        ', ',
418
                        array_map(
419
                            function ($val) {
420
                                return sprintf("'%s'", $val);
421
                            },
422
                            array_keys($this->getSessionBuilders())
423
                        )
424
                    )
425
                )
426
            );
427
        }
428
429
        return $this;
430
    }
431
}
432