StorageProxy::rewindAdapterPool()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * Copyright (c) 2011-2015, Celestino Diaz <[email protected]>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
25
namespace Brickoo\Component\Storage;
26
27
use Brickoo\Component\Storage\Adapter\Adapter;
28
use Brickoo\Component\Storage\Adapter\AdapterPoolIterator;
29
use Brickoo\Component\Storage\Exception\AdapterNotFoundException;
30
use Brickoo\Component\Common\Assert;
31
32
/**
33
 * StorageProxy
34
 *
35
 * Implements a storage proxy using an adapter pool.
36
 * @author Celestino Diaz <[email protected]>
37
 */
38
class StorageProxy {
39
40
    /** @var string */
41
    const BREAK_ITERATION_CALLBACK = "BIC";
42
43
    /** @var \Brickoo\Component\Storage\Adapter\Adapter */
44
    private $adapter;
45
46
    /** @var \Brickoo\Component\Storage\Adapter\AdapterPoolIterator */
47
    private $adapterPoolIterator;
48
49
    /**
50
     * Class constructor.
51
     * @param \Brickoo\Component\Storage\Adapter\AdapterPoolIterator $adapterPoolIterator
52
     */
53 1
    public function __construct(AdapterPoolIterator $adapterPoolIterator) {
54 1
        $this->adapter = null;
55 1
        $this->adapterPoolIterator = $adapterPoolIterator;
56 1
    }
57
58
    /**
59
     * Returns a stored content or if the stored content is not available,
60
     * it will be retrieved by the provided callback and stored back into the storage.
61
     * @param string $identifier the identifier to retrieve/store the content from/to
62
     * @param callable $callback the callback to call if the content is not stored
63
     * @param array $callbackArguments the arguments to pass forward to the callback
64
     * @param integer $lifetime the lifetime of the stored content in seconds
65
     * @throws \InvalidArgumentException if an argument is not valid
66
     * @throws \Brickoo\Component\Storage\Exception\AdapterNotFoundException
67
     * @return mixed the stored content
68
     */
69 3
    public function getByCallback($identifier, callable $callback, array $callbackArguments, $lifetime) {
70 3
        Assert::isString($identifier);
71 2
        Assert::isInteger($lifetime);
72
73 1
        if ((!($content = $this->get($identifier)))
74 1
            && ($content = call_user_func_array($callback, $callbackArguments))) {
75 1
                $this->set($identifier, $content, $lifetime);
76 1
        }
77 1
        return $content;
78
    }
79
80
    /**
81
     * Returns the stored content hold by the identifier.
82
     * @param string $identifier the identifier to retrieve the content
83
     * @throws \InvalidArgumentException if an argument is not valid
84
     * @throws \Brickoo\Component\Storage\Exception\AdapterNotFoundException
85
     * @return mixed the stored content
86
     */
87 4
    public function get($identifier) {
88 4
        Assert::isString($identifier);
89 3
        return $this->getAdapter()->get($identifier);
90
    }
91
92
    /**
93
     * Sets the content hold by the given identifier.
94
     * If the identifier already exists the content will be replaced.
95
     * @param string $identifier the identifier which holds the content
96
     * @param mixed $content the content to store
97
     * @param integer $lifetime the lifetime of the stored content
98
     * @throws \InvalidArgumentException if an argument is not valid
99
     * @throws \Brickoo\Component\Storage\Exception\AdapterNotFoundException
100
     * @return \Brickoo\Component\Storage\StorageProxy
101
     */
102 3
    public function set($identifier, $content, $lifetime) {
103 3
        Assert::isString($identifier);
104 2
        Assert::isInteger($lifetime);
105 1
        $this->getAdapter()->set($identifier, $content, $lifetime);
106 1
        return $this;
107
    }
108
109
    /**
110
     * Deletes the stored content which is hold by the identifier.
111
     * Removes the local stored content.
112
     * @param string $identifier the identifier which holds the content
113
     * @throws \InvalidArgumentException if an argument is not valid
114
     * @return \Brickoo\Component\Storage\StorageProxy
115
     */
116 2
    public function delete($identifier) {
117 2
        Assert::isString($identifier);
118 1
        $this->executeIterationCallback(
119
            function(Adapter $readyAdapter) use ($identifier) {
120 1
                $readyAdapter->delete($identifier);
121 1
                return null;
122
            }
123 1
        );
124 1
        return $this;
125
    }
126
127
    /**
128
     * Flushes the storage of all ready adapters.
129
     * @return \Brickoo\Component\Storage\StorageProxy
130
     */
131 1
    public function flush() {
132 1
        $this->executeIterationCallback(
133
            function(Adapter $readyAdapter) {
134 1
                $readyAdapter->flush();
135 1
                return null;
136
            }
137 1
        );
138 1
        return $this;
139
    }
140
141
    /**
142
     * Returns a ready adapter entry from the adapter pool.
143
     * @throws \Brickoo\Component\Storage\Exception\AdapterNotFoundException
144
     * @return \Brickoo\Component\Storage\Adapter\Adapter
145
     */
146 5
    private function getAdapter() {
147 5
        if ($this->adapter === null) {
148 5
            $this->adapter = $this->getReadyAdapter();
149 4
        }
150 4
        return $this->adapter;
151
    }
152
153
    /**
154
     * Returns an adapter which is ready to use.
155
     * @throws \Brickoo\Component\Storage\Exception\AdapterNotFoundException
156
     * @return \Brickoo\Component\Storage\Adapter\Adapter
157
     */
158 5
    private function getReadyAdapter() {
159 5
        $adapter = null;
160
161 5
        $this->executeIterationCallback(
162 4
            function(Adapter $readyAdapter) use (&$adapter) {
163 4
                $adapter = $readyAdapter;
164 4
                return StorageProxy::BREAK_ITERATION_CALLBACK;
165
            }
166 5
        );
167
168 5
        if (!$adapter instanceof Adapter) {
169 1
            throw new AdapterNotFoundException();
170
        }
171 4
        return $adapter;
172
    }
173
174
    /**
175
     * Execute a callback on every ready adapter.
176
     * @param \Closure $callbackFunction
177
     * @return \Brickoo\Component\Storage\StorageProxy
178
     */
179 5
    private function executeIterationCallback(\Closure $callbackFunction) {
180 5
        $this->rewindAdapterPool();
181
182 5
        $callbackValue = null;
183
        while ($callbackValue !== self::BREAK_ITERATION_CALLBACK
184 5
            && $this->adapterPoolIterator->valid()
185 5
            && $this->adapterPoolIterator->isCurrentReady()) {
186 5
                $callbackValue = $callbackFunction($this->adapterPoolIterator->current());
187 5
                $this->adapterPoolIterator->next();
188 5
        }
189 5
        return $this;
190
    }
191
192
    /**
193
     * Rewind the adapter pool.
194
     * @return \Brickoo\Component\Storage\StorageProxy
195
     */
196 4
    private function rewindAdapterPool() {
197 4
        $this->adapterPoolIterator->rewind();
198 4
        return $this;
199
    }
200
201
}
202