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

ConnectionConfigurator::getConnectionString()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 25
Code Lines 14

Duplication

Lines 9
Ratio 36 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 9
loc 25
rs 8.5806
cc 4
eloc 14
nc 8
nop 0
1
<?php
2
/*
3
 * This file is part of the Pomm's 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\Session;
11
12
use PommProject\Foundation\ParameterHolder;
13
use PommProject\Foundation\Exception\ConnectionException;
14
15
/**
16
 * ConnectionConfigurator
17
 *
18
 * This class is responsible of configuring the connection.
19
 * It has to extract information from the DSN and ensure required arguments
20
 * are present.
21
 *
22
 * @package     Foundation
23
 * @copyright   2014 - 2015 Grégoire HUBERT
24
 * @author      Grégoire HUBERT
25
 * @license     X11 {@link http://opensource.org/licenses/mit-license.php}
26
 */
27
class ConnectionConfigurator
28
{
29
    protected $configuration;
30
31
    /**
32
     * __construct
33
     *
34
     * Initialize configuration.
35
     *
36
     * @access public
37
     * @param  array $dsn
38
     */
39
    public function __construct($dsn)
40
    {
41
        $this->configuration = new ParameterHolder(
42
            [
43
                'dsn' => $dsn,
44
                'configuration' => $this->getDefaultConfiguration(),
45
            ]
46
        );
47
        $this->parseDsn();
48
    }
49
50
    /**
51
     * addConfiguration
52
     *
53
     * Add configuration settings. If settings exist, they are overridden.
54
     *
55
     * @access public
56
     * @param  array      $configuration
57
     * @return Connection $this
58
     */
59
    public function addConfiguration(array $configuration)
60
    {
61
        $this ->configuration->setParameter(
62
            'configuration',
63
            array_merge(
64
                $this->configuration->getParameter('configuration'),
65
                $configuration
66
            )
67
        );
68
69
        return $this;
70
    }
71
72
    /**
73
     * set
74
     *
75
     * Set a new configuration setting.
76
     *
77
     * @access public
78
     * @param  string $name
79
     * @param  mixed $value
80
     * @return ConnectionConfigurator $this
81
     */
82
    public function set($name, $value)
83
    {
84
        $configuration = $this->configuration->getParameter('configuration');
85
        $configuration[$name] = $value;
86
        $this
87
            ->configuration
88
            ->setParameter(
89
                'configuration',
90
                $configuration
91
            );
92
93
        return $this;
94
    }
95
96
97
    /**
98
     * parseDsn()
99
     *
100
     * Sets the different parameters from the DSN.
101
     *
102
     * @access private
103
     * @return Connection $this
104
     * @throws ConnectionException
105
     */
106
    private function parseDsn()
107
    {
108
        $dsn = $this->configuration->mustHave('dsn')->getParameter('dsn');
109
        if (!preg_match(
110
            '#([a-z]+)://([^:@]+)(?::([^@]*))?(?:@([\w\.-]+|!/.+[^/]!)(?::(\w+))?)?/(.+)#',
111
            $dsn,
112
            $matches
113
        )) {
114
            throw new ConnectionException(sprintf('Could not parse DSN "%s".', $dsn));
115
        }
116
117
        if ($matches[1] == null || $matches[1] !== 'pgsql') {
118
            throw new ConnectionException(
119
                sprintf(
120
                    "bad protocol information '%s' in dsn '%s'. Pomm does only support 'pgsql' for now.",
121
                    $matches[1],
122
                    $dsn
123
                )
124
            );
125
        }
126
127
        $adapter = $matches[1];
128
129
        if ($matches[2] === null) {
130
            throw new ConnectionException(
131
                sprintf(
132
                    "No user information in dsn '%s'.",
133
                    $dsn
134
                )
135
            );
136
        }
137
138
        $user = $matches[2];
139
        $pass = $matches[3];
140
141
        if (preg_match('/!(.*)!/', $matches[4], $host_matches)) {
142
            $host = $host_matches[1];
143
        } else {
144
            $host = $matches[4];
145
        }
146
147
        $port = $matches[5];
148
149
        if ($matches[6] === null) {
150
            throw new ConnectionException(
151
                sprintf(
152
                    "No database name in dsn '%s'.",
153
                    $dsn
154
                )
155
            );
156
        }
157
158
        $database = $matches[6];
159
        $this->configuration
160
            ->setParameter('adapter', $adapter)
161
            ->setParameter('user', $user)
162
            ->setParameter('pass', $pass)
163
            ->setParameter('host', $host)
164
            ->setParameter('port', $port)
165
            ->setParameter('database', $database)
166
            ->mustHave('user')
167
            ->mustHave('database')
168
            ;
169
170
        return $this;
171
    }
172
173
    /**
174
     * getConnectionString
175
     *
176
     * Return the connection string.
177
     *
178
     * @access public
179
     * @return string
180
     */
181
    public function getConnectionString()
182
    {
183
        $this->parseDsn();
184
        $connect_parameters = [
185
            sprintf(
186
                "user=%s dbname=%s",
187
                $this->configuration['user'],
188
                $this->configuration['database']
189
            )
190
        ];
191
192 View Code Duplication
        if ($this->configuration['host'] !== '') {
193
            $connect_parameters[] = sprintf('host=%s', $this->configuration['host']);
194
        }
195
196 View Code Duplication
        if ($this->configuration['port'] !== '') {
197
            $connect_parameters[] = sprintf('port=%s', $this->configuration['port']);
198
        }
199
200 View Code Duplication
        if ($this->configuration['pass'] !== '') {
201
            $connect_parameters[] = sprintf('password=%s', addslashes($this->configuration['pass']));
202
        }
203
204
        return join(' ', $connect_parameters);
205
    }
206
207
    /**
208
     * getDefaultConfiguration
209
     *
210
     * Standalone, default configuration.
211
     *
212
     * @access protected
213
     * @return array
214
     */
215
    protected function getDefaultConfiguration()
216
    {
217
        return [];
218
    }
219
220
    /**
221
     * getConfiguration
222
     *
223
     * Return current configuration settings.
224
     *
225
     * @access public
226
     * @return array
227
     * @throws ConnectionException
228
     */
229
    public function getConfiguration()
230
    {
231
        $configuration = $this->configuration->getParameter('configuration');
232
233
        if (!is_array($configuration)) {
234
            throw new ConnectionException(
235
                sprintf(
236
                    "Invalid configuration. It should be an array of settings, '%s' returned.",
237
                    gettype($configuration)
238
                )
239
            );
240
        }
241
242
        return $configuration;
243
    }
244
}
245