Completed
Push — master ( 299ff6...6578e4 )
by Sandro
18s queued 12s
created

ClientOptions::offsetSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 2
1
<?php
2
/**
3
 * Sandro Keil (https://sandro-keil.de)
4
 *
5
 * @link      http://github.com/sandrokeil/arangodb-php-client for the canonical source repository
6
 * @copyright Copyright (c) 2018-2020 Sandro Keil
7
 * @license   http://github.com/sandrokeil/arangodb-php-client/blob/master/LICENSE.md New BSD License
8
 */
9
10
namespace ArangoDb\Http;
11
12
use ArangoDb\Exception\LogicException;
13
use ArrayAccess;
14
15
/**
16
 * Immutable client options array container
17
 *
18
 * @implements ArrayAccess<string, mixed>
19
 */
20
final class ClientOptions implements ArrayAccess
21
{
22
    // connection options
23
    public const OPTION_ENDPOINT = 'endpoint';
24
    public const OPTION_DATABASE = 'database';
25
    public const OPTION_TIMEOUT = 'timeout';
26
    public const OPTION_CONNECTION = 'Connection';
27
    public const OPTION_RECONNECT = 'Reconnect';
28
29
    // connection default options
30
    public const DEFAULT_CONNECTION = 'Keep-Alive';
31
    public const DEFAULT_TIMEOUT = 30;
32
33
    // auth options
34
    public const OPTION_AUTH_USER = 'AuthUser';
35
    public const OPTION_AUTH_PASSWD = 'AuthPasswd';
36
    public const OPTION_AUTH_TYPE = 'AuthType';
37
38
    // auth default options
39
    public const DEFAULT_AUTH_TYPE = 'Basic';
40
41
    // ssl options
42
    public const OPTION_VERIFY_CERT = 'verifyCert';
43
    public const OPTION_VERIFY_CERT_NAME = 'verifyCertName';
44
    public const OPTION_ALLOW_SELF_SIGNED = 'allowSelfSigned';
45
    public const OPTION_CIPHERS = 'ciphers';
46
47
    // ssl default options
48
    public const DEFAULT_VERIFY_CERT = false;
49
    public const DEFAULT_VERIFY_CERT_NAME = false;
50
    public const DEFAULT_ALLOW_SELF_SIGNED = true;
51
    public const DEFAULT_CIPHERS = 'DEFAULT';
52
53
    /**
54
     * The current options
55
     *
56
     * @var array
57
     */
58
    private $options;
59
60 42
    public function __construct(array $options)
61
    {
62 42
        $this->options = array_merge(self::getDefaults(), $options);
63 42
        $this->validate();
64 42
    }
65
66
    public function toArray(): array
67
    {
68
        return $this->options;
69
    }
70
71
    /**
72
     * Returns supported authorization types
73
     *
74
     * @return string[]
75
     */
76
    private static function getSupportedAuthTypes(): array
77
    {
78
        return ['Basic'];
79
    }
80
81
    /**
82
     * Returns supported connection types
83
     *
84
     * @return string[]
85
     */
86 42
    private static function getSupportedConnectionTypes(): array
87
    {
88 42
        return ['Close', 'Keep-Alive'];
89
    }
90
91 42
    private static function getDefaults(): array
92
    {
93
        return [
94 42
            self::OPTION_ENDPOINT                => '',
95 42
            self::OPTION_TIMEOUT                 => self::DEFAULT_TIMEOUT,
96 42
            self::OPTION_CONNECTION              => self::DEFAULT_CONNECTION,
97 42
            self::OPTION_VERIFY_CERT             => self::DEFAULT_VERIFY_CERT,
98 42
            self::OPTION_VERIFY_CERT_NAME        => self::DEFAULT_VERIFY_CERT_NAME,
99 42
            self::OPTION_ALLOW_SELF_SIGNED       => self::DEFAULT_ALLOW_SELF_SIGNED,
100 42
            self::OPTION_CIPHERS                 => self::DEFAULT_CIPHERS,
101 42
            self::OPTION_RECONNECT               => false,
102 42
            self::OPTION_DATABASE                => '_system',
103
        ];
104
    }
105
106 42
    private function validate(): void
107
    {
108 42
        $this->options[self::OPTION_ENDPOINT] = preg_replace(
109 42
            ['/^http:/', '/^https:/'],
110 42
            ['tcp:', 'ssl:'],
111 42
            $this->options[self::OPTION_ENDPOINT]
112
        );
113
114 42
        if (! isset($this->options[self::OPTION_ENDPOINT])) {
115
            throw new LogicException('Endpoint not specified');
116
        }
117
118 42
        if (isset($this->options[self::OPTION_AUTH_TYPE])
119 42
            && ! in_array($this->options[self::OPTION_AUTH_TYPE], self::getSupportedAuthTypes(), true)
120
        ) {
121
            throw new LogicException('Unsupported authorization method: ' . $this->options[self::OPTION_AUTH_TYPE]);
122
        }
123
124 42
        if (isset($this->options[self::OPTION_CONNECTION])
125 42
            && ! in_array($this->options[self::OPTION_CONNECTION], self::getSupportedConnectionTypes(), true)
126
        ) {
127
            throw new LogicException('Unsupported connection value: ' . $this->options[self::OPTION_CONNECTION]);
128
        }
129 42
    }
130
131
    /**
132
     * @param mixed $offset
133
     * @param mixed $value
134
     */
135
    public function offsetSet($offset, $value): void
136
    {
137
        throw new LogicException('Immutable object. Value for "' . $offset . '" not set.');
138
    }
139
140
    /**
141
     * @param mixed $offset
142
     * @return bool
143
     */
144 42
    public function offsetExists($offset): bool
145
    {
146 42
        return isset($this->options[$offset]);
147
    }
148
149
    /**
150
     * @param mixed $offset
151
     */
152
    public function offsetUnset($offset): void
153
    {
154
        throw new LogicException('Immutable object. Value for "' . $offset . '" not unset.');
155
    }
156
157
    /**
158
     * @param mixed $offset
159
     * @return mixed
160
     */
161 42
    public function offsetGet($offset)
162
    {
163 42
        if (! array_key_exists($offset, $this->options)) {
164
            throw new LogicException('Invalid option ' . $offset);
165
        }
166
167 42
        return $this->options[$offset];
168
    }
169
}
170