Connections   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 82
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
c 1
b 0
f 0
dl 0
loc 82
rs 10
wmc 12

3 Methods

Rating   Name   Duplication   Size   Complexity  
A close() 0 18 4
A get() 0 11 3
A add() 0 10 5
1
<?php
2
3
namespace alkemann\h2l;
4
5
use alkemann\h2l\exceptions\ConfigMissing;
6
use Closure;
7
use InvalidArgumentException;
8
use UnderflowException;
9
10
/**
11
 * Class Connections
12
 *
13
 * @TODO tie close into a destruct to ensure connection closure?
14
 * @package alkemann\h2l
15
 */
16
class Connections
17
{
18
    /**
19
     * @var array<string, mixed>
20
     */
21
    private static array $connections = [];
22
    /**
23
     * @var array<string, callable|Closure>
24
     */
25
    private static array $open = [];
26
    /**
27
     * @var array<string, callable|Closure>
28
     */
29
    private static array $close = [];
30
31
    /**
32
     * Add a new connection by giving a name and a closure that is callable to open and return it
33
     *
34
     * A close Closure may also be supplied for connection that requires/supports closing
35
     *
36
     * @param string $name name of of connection
37
     * @param callable $open an anonymous function that takes no arguments and returns an open connection
38
     * @param callable|null $close an optional anonymous function that takes the connection as arguments and closes it
39
     * @throws InvalidArgumentException if connection $name already exists
40
     */
41
    public static function add(string $name, callable $open, ?callable $close = null): void
42
    {
43
        if (isset(self::$open[$name])) {
44
            throw new InvalidArgumentException("Connection $name already exists");
45
        }
46
        self::$open[$name] = ($open instanceof Closure) ? $open : Closure::fromCallable($open);
47
        if ($close) {
48
            self::$close[$name] = ($close instanceof Closure) ? $close : Closure::fromCallable($close);
49
        }
50
        self::$connections[$name] = false;
51
    }
52
53
    /**
54
     * Grab the opened connection, if it isnt open already, it will be opened.
55
     *
56
     * @param string $name name of of connection
57
     * @return mixed an instanced and open connection
58
     * @throws ConfigMissing
59
     */
60
    public static function get(string $name)
61
    {
62
        if (!isset(self::$open[$name])) {
63
            throw new ConfigMissing("Connection $name is not configured", ConfigMissing::MISSING_CONNECTION);
64
        }
65
66
        if (self::$connections[$name] === false) {
67
            $open = self::$open[$name];
68
            self::$connections[$name] = $open();
69
        }
70
        return self::$connections[$name];
71
    }
72
73
    /**
74
     * Close the named connection
75
     *
76
     * @param string $name name of of connection
77
     * @throws UnderflowException when connection is already closed
78
     * @throws InvalidArgumentException if connection does not exist
79
     */
80
    public static function close(string $name): void
81
    {
82
        if (!isset(self::$open[$name])) {
83
            throw new InvalidArgumentException("Connection $name does not exists");
84
        }
85
86
        if (self::$connections[$name] === false) {
87
            throw new UnderflowException("Already closed");
88
        }
89
90
        if (!isset(self::$close[$name])) {
91
            return; // Closing is optional, no error
92
        }
93
94
        $close = self::$close[$name];
95
        $close(self::$connections[$name]);
96
97
        self::$connections[$name] = false;
98
    }
99
}
100