MongoDBServiceProvider::__construct()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 2
1
<?php
2
/**
3
 * This file is part of the Silex MongoDB Service Provider package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Corllete\SilexMongoDB\Provider;
10
11
use MongoDB\Client;
12
use Pimple\ServiceProviderInterface;
13
use Pimple\Container;
14
15
/**
16
 * Integrate MongoDB via MongoDB PHP Library as Silex services
17
 *
18
 * @link   https://github.com/mongodb/mongo-php-library
19
 *
20
 * @author Miroslav Yovchev <[email protected]>
21
 */
22
class MongoDBServiceProvider implements ServiceProviderInterface
23
{
24
    const VERSION = '1.1.0';
25
    
26
    private $namespace;
27
    private $multiNamespace;
28
29
    /**
30
     * Client options documentation:
31
     *
32
     * @link http://mongodb.github.io/mongo-php-library/classes/client/
33
     *
34
     * Connection string
35
     * @link https://docs.mongodb.com/manual/reference/connection-string/
36
     *
37
     * Default 'typeMap' driver options
38
     * @link https://github.com/mongodb/mongo-php-library/blob/master/src/Client.php#L14-L18
39
     */
40
    public static $defaultOptions = [
41
        'uri'            => null,
42
        'host'           => 'localhost',
43
        'port'           => 27017,
44
        'database'       => null,
45
        'username'       => null,
46
        'password'       => null,
47
        'uri_options'    => [],
48
        'driver_options' => [
49
            'type_map' => [],
50
        ],
51
    ];
52
53
    /**
54
     * Namespace for single and multi-connection mode
55
     *
56
     * @param string $namespace
57
     * @param string $multiNamespace
58
     * @throws \InvalidArgumentException
59
     */
60
    public function __construct($namespace = 'mongodb', $multiNamespace = 'mongodbs')
61
    {
62
        if (empty($namespace)) {
63
            throw new \InvalidArgumentException("Namespace can not be empty");
64
        }
65
66
        if (empty($multiNamespace)) {
67
            throw new \InvalidArgumentException("Namespace for connections collection can not be empty");
68
        }
69
70
        $this->namespace      = $namespace;
71
        $this->multiNamespace = $multiNamespace;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function register(Container $app)
78
    {
79
        $ns  = $this->namespace;
80
        $mns = $this->multiNamespace;
81
82
        $app[$ns.'.default_options'] = isset($app[$ns.'.default_options']) ? $app[$ns.'.default_options'] : [];
83
        $app[$ns.'.default_options'] += self::$defaultOptions;
84
85
        $app[$ns.'.factory'] = $app->protect(
86
            function (array $options = []) use ($app, $ns) {
87
                $options += $app[$ns.'.default_options'];
88
                $options += self::$defaultOptions;
89
90
                if (empty($options['uri']) && !empty($options['host'])) {
91
92
                    $options['uri'] = $this->assembleUri(
93
                        $options['host'],
94
                        $options['port'],
95
                        $options['database'],
96
                        $options['username'],
97
                        $options['password']
98
                    );
99
                }
100
101
                return new Client($options['uri'], $options['uri_options'], $options['driver_options']);
102
            }
103
        );
104
105
        $app[$mns.'.options.init'] = $app->protect(
106
            function () use ($app, $ns, $mns) {
107
                static $done = false;
108
109
                if ($done) {
110
                    return;
111
                }
112
                $done = true;
113
114
                if (isset($app[$ns.'.options']) && isset($app[$mns.'.options'])) {
115
                    throw new \LogicException("Illegal configuration - choose either single or multi connection setup", 1);
116
                    
117
                }
118
119
                if (!isset($app[$mns.'.options'])) {
120
                    $singleOptions = isset($app[$ns.'.options']) ? $app[$ns.'.options'] : [];
121
                    $singleOptions += $app[$ns.'.default_options'];
122
123
                    $app[$mns.'.options'] = [
124
                        'default' => $singleOptions,
125
                    ];
126
                }
127
128
                if (isset($app[$mns.'.options']['default'])) {
129
                    $app[$mns.'.default'] = 'default';
130
                } elseif (!isset($app[$mns.'.default'])) {
131
                    $tmp = $app[$mns.'.options'];
132
                    reset($tmp);
133
                    $app[$mns.'.default'] = key($tmp);
134
                }
135
            }
136
        );
137
138
        $app[$mns] = function ($app) use ($ns, $mns) {
139
            $app[$mns.'.options.init']();
140
141
            $mongos = new Container();
142
            foreach ($app[$mns.'.options'] as $name => $options) {
143
                $mongos[$name] = function () use ($app, $options, $ns) {
144
                    return $app[$ns.'.factory']($options);
145
                };
146
            }
147
148
            if (!isset($mongos['default'])) {
149
                $mongos['default'] = $mongos[$app[$mns.'.default']];
150
            }
151
152
            return $mongos;
153
        };
154
155
        $app[$ns] = function ($app) use ($mns) {
156
            $dbs = $app[$mns];
157
158
            return $dbs[$app[$mns.'.default']];
159
        };
160
    }
161
162
    /**
163
     * @link http://php.net/manual/en/mongodb-driver-manager.construct.php
164
     *
165
     * @param string      $host
166
     * @param string      $port
167
     * @param string|null $db
168
     * @param string|null $username
169
     * @param string|null $password
170
     * @return string
171
     */
172
    private function assembleUri($host, $port, $db = null, $username = null, $password = null)
173
    {
174
        if (!empty($db)) {
175
            $db = '/'.$db;
176
        }
177
178
        $cred = '';
179
        if ($username !== null && $password !== null) {
180
            $cred = sprintf('%s:%s@', rawurlencode($username), rawurlencode($password));
181
        }
182
183
        return sprintf('mongodb://%s%s:%s%s', $cred, $host, $port, $db.'');
184
    }
185
}
186