Completed
Push — master ( 0c61e0...13e76d )
by Malte
01:53
created

ClientManager   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
wmc 39
eloc 65
c 2
b 0
f 1
dl 0
loc 239
rs 9.28

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 2 1
A __call() 0 4 1
A get() 0 20 6
B setConfig() 0 33 9
A account() 0 11 3
A getDefaultAccount() 0 2 1
A setDefaultAccount() 0 2 1
A getClientConfig() 0 6 3
A make() 0 2 1
C array_merge_recursive_distinct() 0 31 12
A resolve() 0 4 1
1
<?php
2
/*
3
* File:     ClientManager.php
4
* Category: -
5
* Author:   M. Goldenbaum
6
* Created:  19.01.17 22:21
7
* Updated:  -
8
*
9
* Description:
10
*  -
11
*/
12
13
namespace Webklex\PHPIMAP;
14
15
/**
16
 * Class ClientManager
17
 *
18
 * @package Webklex\IMAP
19
 *
20
 * @mixin Client
21
 */
22
class ClientManager {
23
24
    /**
25
     * All library config
26
     *
27
     * @var array $config
28
     */
29
    public static $config = [];
30
31
    /**
32
     * @var array $accounts
33
     */
34
    protected $accounts = [];
35
36
    /**
37
     * ClientManager constructor.
38
     * @param array|string $config
39
     */
40
    public function __construct($config = []) {
41
        $this->setConfig($config);
42
    }
43
44
    /**
45
     * Dynamically pass calls to the default account.
46
     * @param  string  $method
47
     * @param  array   $parameters
48
     *
49
     * @return mixed
50
     * @throws Exceptions\MaskNotFoundException
51
     */
52
    public function __call($method, $parameters) {
53
        $callable = [$this->account(), $method];
54
55
        return call_user_func_array($callable, $parameters);
56
    }
57
58
    /**
59
     * Safely create a new client instance which is not listed in accounts
60
     * @param array $config
61
     *
62
     * @return Client
63
     * @throws Exceptions\MaskNotFoundException
64
     */
65
    public function make($config) {
66
        return new Client($config);
67
    }
68
69
    /**
70
     * Get a dotted config parameter
71
     * @param string $key
72
     * @param null   $default
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $default is correct as it would always require null to be passed?
Loading history...
73
     *
74
     * @return mixed|null
75
     */
76
    public static function get($key, $default = null) {
77
        $parts = explode('.', $key);
78
        $value = null;
79
        foreach($parts as $part) {
80
            if($value === null) {
81
                if(isset(self::$config[$part])) {
82
                    $value = self::$config[$part];
83
                }else{
84
                    break;
85
                }
86
            }else{
87
                if(isset($value[$part])) {
88
                    $value = $value[$part];
89
                }else{
90
                    break;
91
                }
92
            }
93
        }
94
95
        return $value === null ? $default : $value;
96
    }
97
98
    /**
99
     * Resolve a account instance.
100
     * @param  string  $name
101
     *
102
     * @return Client
103
     * @throws Exceptions\MaskNotFoundException
104
     */
105
    public function account($name = null) {
106
        $name = $name ?: $this->getDefaultAccount();
107
108
        // If the connection has not been resolved yet we will resolve it now as all
109
        // of the connections are resolved when they are actually needed so we do
110
        // not make any unnecessary connection to the various queue end-points.
111
        if (!isset($this->accounts[$name])) {
112
            $this->accounts[$name] = $this->resolve($name);
113
        }
114
115
        return $this->accounts[$name];
116
    }
117
118
    /**
119
     * Resolve a account.
120
     *
121
     * @param  string  $name
122
     *
123
     * @return Client
124
     * @throws Exceptions\MaskNotFoundException
125
     */
126
    protected function resolve($name) {
127
        $config = $this->getClientConfig($name);
128
129
        return new Client($config);
130
    }
131
132
    /**
133
     * Get the account configuration.
134
     * @param  string  $name
135
     *
136
     * @return array
137
     */
138
    protected function getClientConfig($name) {
139
        if ($name === null || $name === 'null') {
140
            return ['driver' => 'null'];
141
        }
142
143
        return self::$config["accounts"][$name];
144
    }
145
146
    /**
147
     * Get the name of the default account.
148
     *
149
     * @return string
150
     */
151
    public function getDefaultAccount() {
152
        return self::$config['default'];
153
    }
154
155
    /**
156
     * Set the name of the default account.
157
     * @param  string  $name
158
     *
159
     * @return void
160
     */
161
    public function setDefaultAccount($name) {
162
        self::$config['default'] = $name;
163
    }
164
165
166
    /**
167
     * Merge the vendor settings with the local config
168
     *
169
     * The default account identifier will be used as default for any missing account parameters.
170
     * If however the default account is missing a parameter the package default account parameter will be used.
171
     * This can be disabled by setting imap.default in your config file to 'false'
172
     *
173
     * @param array|string $config
174
     *
175
     * @return $this
176
     */
177
    public function setConfig($config) {
178
179
        if(is_array($config) === false) {
180
            $config = require $config;
181
        }
182
183
        $config_key = 'imap';
184
        $path = __DIR__.'/config/'.$config_key.'.php';
185
186
        $vendor_config = require $path;
187
        $config = $this->array_merge_recursive_distinct($vendor_config, $config);
188
189
        if(is_array($config)){
0 ignored issues
show
introduced by
The condition is_array($config) is always true.
Loading history...
190
            if(isset($config['default'])){
191
                if(isset($config['accounts']) && $config['default'] != false){
192
193
                    $default_config = $vendor_config['accounts']['default'];
194
                    if(isset($config['accounts'][$config['default']])){
195
                        $default_config = array_merge($default_config, $config['accounts'][$config['default']]);
196
                    }
197
198
                    if(is_array($config['accounts'])){
199
                        foreach($config['accounts'] as $account_key => $account){
200
                            $config['accounts'][$account_key] = array_merge($default_config, $account);
201
                        }
202
                    }
203
                }
204
            }
205
        }
206
207
        self::$config = $config;
208
209
        return $this;
210
    }
211
212
    /**
213
     * Marge arrays recursively and distinct
214
     *
215
     * Merges any number of arrays / parameters recursively, replacing
216
     * entries with string keys with values from latter arrays.
217
     * If the entry or the next value to be assigned is an array, then it
218
     * automatically treats both arguments as an array.
219
     * Numeric entries are appended, not replaced, but only if they are
220
     * unique
221
     *
222
     * @param  array $array1 Initial array to merge.
223
     * @param  array ...     Variable list of arrays to recursively merge.
224
     *
225
     * @return array|mixed
226
     *
227
     * @link   http://www.php.net/manual/en/function.array-merge-recursive.php#96201
228
     * @author Mark Roduner <[email protected]>
229
     */
230
    private function array_merge_recursive_distinct() {
231
232
        $arrays = func_get_args();
233
        $base = array_shift($arrays);
234
235
        if(!is_array($base)) $base = empty($base) ? array() : array($base);
236
237
        foreach($arrays as $append) {
238
239
            if(!is_array($append)) $append = array($append);
240
241
            foreach($append as $key => $value) {
242
243
                if(!array_key_exists($key, $base) and !is_numeric($key)) {
244
                    $base[$key] = $append[$key];
245
                    continue;
246
                }
247
248
                if(is_array($value) or is_array($base[$key])) {
249
                    $base[$key] = $this->array_merge_recursive_distinct($base[$key], $append[$key]);
250
                } else if(is_numeric($key)) {
251
                    if(!in_array($value, $base)) $base[] = $value;
252
                } else {
253
                    $base[$key] = $value;
254
                }
255
256
            }
257
258
        }
259
260
        return $base;
261
    }
262
}