Completed
Push — 2.0 ( 143803...4e64fa )
by grégoire
08:42 queued 04:22
created

Pomm   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 420
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 12
Bugs 2 Features 5
Metric Value
wmc 37
lcom 1
cbo 3
dl 0
loc 420
c 12
b 2
f 5
rs 8.6

21 Methods

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