DataSourceManager::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
crap 1
1
<?php
2
/*
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2015 zepi
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 *
25
 */
26
27
/**
28
 * The DataSourceManager manages and delivers the available
29
 * data sources.
30
 * 
31
 * @package Zepi\Turbo\Manager
32
 * @author Matthias Zobrist <[email protected]>
33
 * @copyright Copyright (c) 2015 zepi
34
 */
35
36
namespace Zepi\Turbo\Manager;
37
38
use \Zepi\Turbo\Framework;
39
use \Zepi\Turbo\Exception;
40
use \Zepi\Turbo\Backend\ObjectBackendAbstract;
41
42
/**
43
 * The DataSourceManager manages and delivers the available
44
 * data sources.
45
 * 
46
 * @author Matthias Zobrist <[email protected]>
47
 * @copyright Copyright (c) 2015 zepi
48
 */
49
class DataSourceManager
50
{
51
    /**
52
     * @access protected
53
     * @var Framework
54
     */
55
    protected $framework;
56
    
57
    /**
58
     * @access protected
59
     * @var \Zepi\Turbo\Backend\ObjectBackendAbstract
60
     */
61
    protected $dataSourceObjectBackend;
62
    
63
    /**
64
     * @access protected
65
     * @var array
66
     */
67
    protected $dataSources = array();
68
    
69
    /**
70
     * @access protected
71
     * @var array
72
     */
73
    protected $definitions = array();
74
    
75
    /**
76
     * Constructs the object
77
     * 
78
     * @access public
79
     * @param \Zepi\Turbo\Framework $framework
80
     * @param \Zepi\Turbo\Backend\ObjectBackendAbstract $dataSourceObjectBackend
81
     */
82 17
    public function __construct(
83
        Framework $framework, 
84
        ObjectBackendAbstract $dataSourceObjectBackend
85
    ) {
86 17
        $this->framework = $framework;
87 17
        $this->dataSourceObjectBackend = $dataSourceObjectBackend;
88 17
    }
89
    
90
    /**
91
     * Initializes the data source manager. The function loads all saved
92
     * events from the object backend.
93
     *
94
     * @access public
95
     */
96 17
    public function initializeDataSourceManager()
97
    {
98 17
        $dataSources = $this->dataSourceObjectBackend->loadObject();
99 17
        if (!is_array($dataSources)) {
100 17
            $dataSources = array();
101
        }
102
    
103 17
        $this->dataSources = $dataSources;
104 17
    }
105
    
106
    /**
107
     * Adds a data source to the repository
108
     * 
109
     * @access public 
110
     * @param string $interfaceName
111
     * @param string $driver
112
     * @param string $className
113
     */
114
    public function addDataSource($interfaceName, $driver, $className)
115
    {
116
        if (!isset($this->dataSources[$interfaceName]) || !is_array($this->dataSources[$interfaceName])) {
117
            $this->dataSources[$interfaceName] = array();
118
        }
119
        
120
        $this->dataSources[$interfaceName][$driver] = $className;
121
        $this->saveDataSources();
122
        
123
        return true;
124
    }
125
    
126
    /**
127
     * Removes a data source from the repository
128
     * 
129
     * @access public
130
     * @param stirng $interfaceName
131
     * @param string $driver
132
     * @param string $className
133
     * @return boolean
134
     */
135
    public function removeDataSource($interfaceName, $driver, $className)
136
    {
137
        if (!isset($this->dataSources[$interfaceName][$driver])) {
138
            return false;
139
        }
140
        
141
        unset($this->dataSources[$interfaceName][$driver]);
142
        $this->saveDataSources();
143
        
144
        return true;
145
    }
146
    
147
    /**
148
     * Saves the registred data sources in the object backend.
149
     *
150
     * @access protected
151
     */
152
    protected function saveDataSources()
153
    {
154
        $this->dataSourceObjectBackend->saveObject($this->dataSources);
155
    }
156
    
157
    /**
158
     * Adds a definition
159
     * 
160
     * @access public
161
     * @param string $selector
162
     * @param string $driver
163
     */
164
    public function addDefinition($selector, $driver)
165
    {
166
        $this->definitions[$selector] = $driver;
167
    }
168
    
169
    /**
170
     * Removes a definition
171
     * 
172
     * @access public
173
     * @param string $selector
174
     * @return boolean
175
     */
176
    public function removeDefinition($selector)
177
    {
178
        if (!isset($this->definitions[$selector])) {
179
            return false;
180
        }
181
        
182
        unset($this->definitions[$selector]);
183
        return true;
184
    }
185
    
186
    /**
187
     * Returns the data source for the given type class.
188
     * 
189
     * @access public
190
     * @param string $typeClass
191
     * @return mixed
192
     * 
193
     * @throws \Zepi\Turbo\Exception Cannot find a driver for the given type class.
194
     * @throws \Zepi\Turbo\Exception Cannot find a data source for the given type class.
195
     */
196
    public function getDataSource($typeClass)
197
    {
198
        $driver = $this->getDriver($typeClass);
199
        
200
        // If there is no driver for the given type class throw an exception
201
        if ($driver === false) {
202
            throw new Exception('Cannot find a driver for the given type class "' . $typeClass . '".');
203
        }
204
        
205
        $dataSourceClass = $this->searchDataSourceClass($typeClass, $driver);
206
207
        // If there is no data source class for the given type class throw an exception
208
        if ($dataSourceClass === false) {
209
            throw new Exception('Cannot find a data source for the given type class "' . $typeClass . '" (selected driver: "' . $driver . '").');
210
        }
211
        
212
        return $this->framework->getInstance($dataSourceClass);
213
    }
214
    
215
    /**
216
     * Returns an array with all DataSource type classes
217
     * 
218
     * @access public
219
     * @return array
220
     */
221
    public function getDataSourceTypeClasses()
222
    {
223
        return array_keys($this->dataSources);
224
    }
225
    
226
    /**
227
     * Returns the driver for the given type class or false if no 
228
     * driver is available.
229
     * 
230
     * @access protected
231
     * @param string $typeClass
232
     * @return false|string
233
     */
234
    protected function getDriver($typeClass)
235
    {
236
        $bestDriver = false;
237
        $numberOfParts = 0;
238
        
239
        foreach ($this->definitions as $selector => $driver) {
240
            if ($selector === '*' || $selector === $typeClass) {
241
                $bestDriver = $driver;
242
                $numberOfParts = $this->countNumberOfParts($selector);
243
            } else if (substr($selector, -1) === '*') {
244
                $selectorWithoutWildcard = substr($selector, 0, -1);
245
                
246
                if (strpos($selector, $selectorWithoutWildcard) === 0 || $numberOfParts < $this->countNumberOfParts($selector)) {
247
                    $bestDriver = $driver;
248
                    $numberOfParts = $this->countNumberOfParts($selector);
249
                }
250
            }
251
        }
252
        
253
        return $bestDriver;
254
    }
255
    
256
    /**
257
     * Returns the number of parts
258
     * 
259
     * @access protected
260
     * @param string $selector
261
     * @return integer
262
     */
263
    protected function countNumberOfParts($selector)
264
    {
265
        $selector = trim($selector, '*\\');
266
        
267
        if ($selector === '') {
268
            return 0;
269
        }
270
        
271
        return substr_count($selector, '\\');
272
    }
273
    
274
    /**
275
     * Returns the DataSource class for the given type class and driver
276
     * @param string $typeClass
277
     * @param string $driver
278
     * @return false|string
279
     */
280
    protected function searchDataSourceClass($typeClass, $driver)
281
    {
282
        if (isset($this->dataSources[$typeClass][$driver])) {
283
            return $this->dataSources[$typeClass][$driver];
284
        }
285
        
286
        return false;
287
    }
288
}
289