1 | <?php |
||
44 | class InMemoryRepository extends AbstractEditableRepository |
||
45 | { |
||
46 | /** |
||
47 | * @var PuliResource[] |
||
48 | */ |
||
49 | private $resources = array(); |
||
50 | |||
51 | /** |
||
52 | * Create the repository. |
||
53 | * |
||
54 | * @param ChangeStream|null $changeStream If provided, the repository will log |
||
55 | * resources changes in this change stream. |
||
56 | */ |
||
57 | 140 | public function __construct(ChangeStream $changeStream = null) |
|
58 | { |
||
59 | 140 | parent::__construct($changeStream); |
|
60 | |||
61 | 140 | $this->clear(); |
|
62 | 140 | } |
|
63 | |||
64 | /** |
||
65 | * {@inheritdoc} |
||
66 | */ |
||
67 | 57 | public function get($path) |
|
68 | { |
||
69 | 57 | $path = $this->sanitizePath($path); |
|
70 | |||
71 | 48 | if (!isset($this->resources[$path])) { |
|
72 | 4 | throw ResourceNotFoundException::forPath($path); |
|
73 | } |
||
74 | |||
75 | 44 | return $this->resources[$path]; |
|
76 | } |
||
77 | |||
78 | /** |
||
79 | * {@inheritdoc} |
||
80 | */ |
||
81 | 27 | public function find($query, $language = 'glob') |
|
82 | { |
||
83 | 27 | $this->failUnlessGlob($language); |
|
84 | |||
85 | 25 | $query = $this->sanitizePath($query); |
|
86 | 19 | $resources = array(); |
|
87 | |||
88 | 19 | if (Glob::isDynamic($query)) { |
|
89 | 7 | $resources = $this->getGlobIterator($query); |
|
90 | 12 | } elseif (isset($this->resources[$query])) { |
|
91 | 12 | $resources = array($this->resources[$query]); |
|
92 | } |
||
93 | |||
94 | 19 | return new ArrayResourceCollection($resources); |
|
|
|||
95 | } |
||
96 | |||
97 | /** |
||
98 | * {@inheritdoc} |
||
99 | */ |
||
100 | 16 | public function contains($query, $language = 'glob') |
|
101 | { |
||
102 | 16 | $this->failUnlessGlob($language); |
|
103 | |||
104 | 15 | $query = $this->sanitizePath($query); |
|
105 | |||
106 | 12 | if (Glob::isDynamic($query)) { |
|
107 | 1 | $iterator = $this->getGlobIterator($query); |
|
108 | 1 | $iterator->rewind(); |
|
109 | |||
110 | 1 | return $iterator->valid(); |
|
111 | } |
||
112 | |||
113 | 11 | return isset($this->resources[$query]); |
|
114 | } |
||
115 | |||
116 | /** |
||
117 | * {@inheritdoc} |
||
118 | */ |
||
119 | 90 | public function add($path, $resource) |
|
120 | { |
||
121 | 90 | $path = $this->sanitizePath($path); |
|
122 | |||
123 | 87 | if ($resource instanceof ResourceCollection) { |
|
124 | 1 | $this->ensureDirectoryExists($path); |
|
125 | 1 | foreach ($resource as $child) { |
|
126 | 1 | $this->addResource($path.'/'.$child->getName(), $child); |
|
127 | } |
||
128 | |||
129 | // Keep the resources sorted by file name |
||
130 | 1 | ksort($this->resources); |
|
131 | |||
132 | 1 | return; |
|
133 | } |
||
134 | |||
135 | 86 | if ($resource instanceof PuliResource) { |
|
136 | 85 | $this->ensureDirectoryExists(Path::getDirectory($path)); |
|
137 | 85 | $this->addResource($path, $resource); |
|
138 | |||
139 | 85 | ksort($this->resources); |
|
140 | |||
141 | 85 | return; |
|
142 | } |
||
143 | |||
144 | 1 | throw new UnsupportedResourceException(sprintf( |
|
145 | 1 | 'The passed resource must be a PuliResource or ResourceCollection. Got: %s', |
|
146 | 1 | is_object($resource) ? get_class($resource) : gettype($resource) |
|
147 | )); |
||
148 | } |
||
149 | |||
150 | /** |
||
151 | * {@inheritdoc} |
||
152 | */ |
||
153 | 16 | public function remove($query, $language = 'glob') |
|
167 | |||
168 | /** |
||
169 | * {@inheritdoc} |
||
170 | */ |
||
171 | 140 | public function clear() |
|
186 | |||
187 | /** |
||
188 | * {@inheritdoc} |
||
189 | */ |
||
190 | 12 | public function listChildren($path) |
|
196 | |||
197 | /** |
||
198 | * {@inheritdoc} |
||
199 | */ |
||
200 | 6 | public function hasChildren($path) |
|
207 | |||
208 | /** |
||
209 | * Recursively creates a directory for a path. |
||
210 | * |
||
211 | * @param string $path A directory path. |
||
212 | */ |
||
213 | 86 | private function ensureDirectoryExists($path) |
|
227 | |||
228 | 86 | private function addResource($path, PuliResource $resource) |
|
248 | |||
249 | 10 | private function removeResource(PuliResource $resource) |
|
250 | { |
||
251 | 10 | $path = $resource->getPath(); |
|
252 | |||
253 | 10 | $this->removeVersions($path); |
|
254 | |||
255 | // Ignore non-existing resources |
||
256 | 10 | if (!isset($this->resources[$path])) { |
|
257 | return; |
||
258 | } |
||
259 | |||
260 | // Recursively remove directory contents |
||
261 | 10 | foreach ($this->getChildIterator($resource) as $child) { |
|
262 | 6 | $this->removeResource($child); |
|
263 | } |
||
264 | |||
265 | 10 | unset($this->resources[$path]); |
|
266 | |||
267 | // Detach from locator |
||
268 | 10 | $resource->detach(); |
|
269 | 10 | } |
|
270 | |||
271 | /** |
||
272 | * Returns an iterator for the children of a resource. |
||
273 | * |
||
274 | * @param PuliResource $resource The resource. |
||
275 | * |
||
276 | * @return RegexFilterIterator The iterator. |
||
277 | */ |
||
278 | 19 | private function getChildIterator(PuliResource $resource) |
|
290 | |||
291 | /** |
||
292 | * Returns an iterator for a glob. |
||
293 | * |
||
294 | * @param string $glob The glob. |
||
295 | * |
||
296 | * @return GlobFilterIterator The iterator. |
||
297 | */ |
||
298 | 8 | protected function getGlobIterator($glob) |
|
306 | } |
||
307 |
If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.