These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the puli/repository package. |
||
5 | * |
||
6 | * (c) Bernhard Schussek <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Puli\Repository; |
||
13 | |||
14 | use Psr\Log\LoggerAwareInterface; |
||
15 | use Psr\Log\LoggerInterface; |
||
16 | use Psr\Log\LogLevel; |
||
17 | use Puli\Repository\Api\ChangeStream\ChangeStream; |
||
18 | use Puli\Repository\Api\Resource\FilesystemResource; |
||
19 | use Puli\Repository\Api\Resource\PuliResource; |
||
20 | use Puli\Repository\Api\ResourceCollection; |
||
21 | use Puli\Repository\Api\ResourceNotFoundException; |
||
22 | use Puli\Repository\Api\UnsupportedResourceException; |
||
23 | use Puli\Repository\Resource\Collection\ArrayResourceCollection; |
||
24 | use Puli\Repository\Resource\DirectoryResource; |
||
25 | use Puli\Repository\Resource\FileResource; |
||
26 | use Puli\Repository\Resource\GenericResource; |
||
27 | use Puli\Repository\Resource\LinkResource; |
||
28 | use RuntimeException; |
||
29 | use Webmozart\Assert\Assert; |
||
30 | use Webmozart\Json\JsonDecoder; |
||
31 | use Webmozart\Json\JsonEncoder; |
||
32 | use Webmozart\PathUtil\Path; |
||
33 | |||
34 | /** |
||
35 | * Base class for repositories backed by a JSON file. |
||
36 | * |
||
37 | * The generated JSON file is described by res/schema/repository-schema-1.0.json. |
||
38 | * |
||
39 | * @since 1.0 |
||
40 | * |
||
41 | * @author Bernhard Schussek <[email protected]> |
||
42 | * @author Titouan Galopin <[email protected]> |
||
43 | */ |
||
44 | abstract class AbstractJsonRepository extends AbstractEditableRepository implements LoggerAwareInterface |
||
45 | { |
||
46 | /** |
||
47 | * Flag: Whether to stop after the first result. |
||
48 | * |
||
49 | * @internal |
||
50 | */ |
||
51 | const STOP_ON_FIRST = 1; |
||
52 | |||
53 | /** |
||
54 | * @var array |
||
55 | */ |
||
56 | protected $json; |
||
57 | |||
58 | /** |
||
59 | * @var string |
||
60 | */ |
||
61 | protected $baseDirectory; |
||
62 | |||
63 | /** |
||
64 | * @var string |
||
65 | */ |
||
66 | private $path; |
||
67 | |||
68 | /** |
||
69 | * @var string |
||
70 | */ |
||
71 | private $schemaPath; |
||
72 | |||
73 | /** |
||
74 | * @var JsonEncoder |
||
75 | */ |
||
76 | private $encoder; |
||
77 | |||
78 | /** |
||
79 | * @var LoggerInterface |
||
80 | */ |
||
81 | private $logger; |
||
82 | |||
83 | /** |
||
84 | * Creates a new repository. |
||
85 | * |
||
86 | * @param string $path The path to the JSON file. If |
||
87 | * relative, it must be relative to |
||
88 | * the base directory. |
||
89 | * @param string $baseDirectory The base directory of the store. |
||
90 | * Paths inside that directory are |
||
91 | * stored as relative paths. Paths |
||
92 | * outside that directory are stored |
||
93 | * as absolute paths. |
||
94 | * @param bool $validateJson Whether to validate the JSON file |
||
95 | * against the schema. Slow but |
||
96 | * spots problems. |
||
97 | * @param ChangeStream|null $changeStream If provided, the repository will |
||
98 | * append resource changes to this |
||
99 | * change stream. |
||
100 | */ |
||
101 | 392 | public function __construct($path, $baseDirectory, $validateJson = false, ChangeStream $changeStream = null) |
|
102 | { |
||
103 | 392 | parent::__construct($changeStream); |
|
104 | |||
105 | 392 | $this->baseDirectory = $baseDirectory; |
|
106 | 392 | $this->path = Path::makeAbsolute($path, $baseDirectory); |
|
107 | 392 | $this->encoder = new JsonEncoder(); |
|
108 | |||
109 | 392 | if ($validateJson) { |
|
110 | 392 | $this->schemaPath = realpath(__DIR__.'/../res/schema/path-mappings-schema-1.0.json'); |
|
111 | } |
||
112 | 392 | } |
|
113 | |||
114 | /** |
||
115 | * {@inheritdoc} |
||
116 | */ |
||
117 | 22 | public function setLogger(LoggerInterface $logger = null) |
|
118 | { |
||
119 | 22 | $this->logger = $logger; |
|
120 | 22 | } |
|
121 | |||
122 | /** |
||
123 | * {@inheritdoc} |
||
124 | */ |
||
125 | 352 | public function add($path, $resource) |
|
126 | { |
||
127 | 352 | if (null === $this->json) { |
|
128 | 352 | $this->load(); |
|
129 | } |
||
130 | |||
131 | 352 | $path = $this->sanitizePath($path); |
|
132 | |||
133 | 340 | View Code Duplication | if ($resource instanceof ResourceCollection) { |
134 | 4 | $this->ensureDirectoryExists($path); |
|
135 | |||
136 | 4 | foreach ($resource as $child) { |
|
137 | 4 | $this->addResource($path.'/'.$child->getName(), $child); |
|
138 | } |
||
139 | |||
140 | 4 | $this->flush(); |
|
141 | |||
142 | 4 | return; |
|
143 | } |
||
144 | |||
145 | 336 | $this->ensureDirectoryExists(Path::getDirectory($path)); |
|
146 | |||
147 | 336 | $this->addResource($path, $resource); |
|
0 ignored issues
–
show
|
|||
148 | |||
149 | 332 | $this->flush(); |
|
150 | 332 | } |
|
151 | |||
152 | /** |
||
153 | * {@inheritdoc} |
||
154 | */ |
||
155 | 156 | public function get($path) |
|
156 | { |
||
157 | 156 | if (null === $this->json) { |
|
158 | 24 | $this->load(); |
|
159 | } |
||
160 | |||
161 | 156 | $path = $this->sanitizePath($path); |
|
162 | 144 | $references = $this->getReferencesForPath($path); |
|
163 | |||
164 | // Might be null, don't use isset() |
||
165 | 144 | if (array_key_exists($path, $references)) { |
|
166 | 134 | return $this->createResource($path, $references[$path]); |
|
167 | } |
||
168 | |||
169 | 10 | throw ResourceNotFoundException::forPath($path); |
|
170 | } |
||
171 | |||
172 | /** |
||
173 | * {@inheritdoc} |
||
174 | */ |
||
175 | 48 | public function find($query, $language = 'glob') |
|
176 | { |
||
177 | 48 | if (null === $this->json) { |
|
178 | 6 | $this->load(); |
|
179 | } |
||
180 | |||
181 | 48 | $this->failUnlessGlob($language); |
|
182 | 44 | $query = $this->sanitizePath($query); |
|
183 | 32 | $results = $this->createResources($this->getReferencesForGlob($query)); |
|
184 | |||
185 | 32 | ksort($results); |
|
186 | |||
187 | 32 | return new ArrayResourceCollection(array_values($results)); |
|
188 | } |
||
189 | |||
190 | /** |
||
191 | * {@inheritdoc} |
||
192 | */ |
||
193 | 68 | public function contains($query, $language = 'glob') |
|
194 | { |
||
195 | 68 | if (null === $this->json) { |
|
196 | 22 | $this->load(); |
|
197 | } |
||
198 | |||
199 | 68 | $this->failUnlessGlob($language); |
|
200 | 64 | $query = $this->sanitizePath($query); |
|
201 | |||
202 | 52 | $results = $this->getReferencesForGlob($query, self::STOP_ON_FIRST); |
|
203 | |||
204 | 52 | return !empty($results); |
|
205 | } |
||
206 | |||
207 | /** |
||
208 | * {@inheritdoc} |
||
209 | */ |
||
210 | 66 | public function remove($query, $language = 'glob') |
|
211 | { |
||
212 | 66 | if (null === $this->json) { |
|
213 | 24 | $this->load(); |
|
214 | } |
||
215 | |||
216 | 66 | $this->failUnlessGlob($language); |
|
217 | 62 | $query = $this->sanitizePath($query); |
|
218 | |||
219 | 50 | Assert::notEmpty(trim($query, '/'), 'The root directory cannot be removed.'); |
|
220 | |||
221 | 42 | $removed = $this->removeReferences($query); |
|
222 | |||
223 | 40 | $this->flush(); |
|
224 | |||
225 | 40 | return $removed; |
|
226 | } |
||
227 | |||
228 | /** |
||
229 | * {@inheritdoc} |
||
230 | */ |
||
231 | 6 | public function clear() |
|
232 | { |
||
233 | 6 | if (null === $this->json) { |
|
234 | 2 | $this->load(); |
|
235 | } |
||
236 | |||
237 | // Subtract root which is not deleted |
||
238 | 6 | $removed = count($this->getReferencesForRegex('/', '~.~')) - 1; |
|
239 | |||
240 | 6 | $this->json = array(); |
|
241 | |||
242 | 6 | $this->flush(); |
|
243 | |||
244 | 6 | return $removed; |
|
245 | } |
||
246 | |||
247 | /** |
||
248 | * {@inheritdoc} |
||
249 | */ |
||
250 | 48 | public function listChildren($path) |
|
251 | { |
||
252 | 48 | if (null === $this->json) { |
|
253 | 2 | $this->load(); |
|
254 | } |
||
255 | |||
256 | 48 | $path = $this->sanitizePath($path); |
|
257 | 36 | $results = $this->createResources($this->getReferencesInDirectory($path)); |
|
258 | |||
259 | 36 | if (empty($results)) { |
|
260 | 16 | $pathResults = $this->getReferencesForPath($path); |
|
261 | |||
262 | 16 | if (empty($pathResults)) { |
|
263 | 4 | throw ResourceNotFoundException::forPath($path); |
|
264 | } |
||
265 | } |
||
266 | |||
267 | 32 | ksort($results); |
|
268 | |||
269 | 32 | return new ArrayResourceCollection(array_values($results)); |
|
270 | } |
||
271 | |||
272 | /** |
||
273 | * {@inheritdoc} |
||
274 | */ |
||
275 | 32 | public function hasChildren($path) |
|
276 | { |
||
277 | 32 | if (null === $this->json) { |
|
278 | 2 | $this->load(); |
|
279 | } |
||
280 | |||
281 | 32 | $path = $this->sanitizePath($path); |
|
282 | |||
283 | 20 | $results = $this->getReferencesInDirectory($path, self::STOP_ON_FIRST); |
|
284 | |||
285 | 20 | if (empty($results)) { |
|
286 | 12 | $pathResults = $this->getReferencesForPath($path); |
|
287 | |||
288 | 12 | if (empty($pathResults)) { |
|
289 | 4 | throw ResourceNotFoundException::forPath($path); |
|
290 | } |
||
291 | |||
292 | 8 | return false; |
|
293 | } |
||
294 | |||
295 | 12 | return true; |
|
296 | } |
||
297 | |||
298 | /** |
||
299 | * Inserts a path reference into the JSON file. |
||
300 | * |
||
301 | * The path reference can be: |
||
302 | * |
||
303 | * * a link starting with `@` |
||
304 | * * an absolute filesystem path |
||
305 | * |
||
306 | * @param string $path The Puli path. |
||
307 | * @param string|null $reference The path reference. |
||
308 | */ |
||
309 | abstract protected function insertReference($path, $reference); |
||
1 ignored issue
–
show
For interfaces and abstract methods it is generally a good practice to add a
@return annotation even if it is just @return void or @return null , so that implementors know what to do in the overridden method.
For interface and abstract methods, it is impossible to infer the return type
from the immediate code. In these cases, it is generally advisible to explicitly
annotate these methods with a
Loading history...
|
|||
310 | |||
311 | /** |
||
312 | * Removes all path references matching the given glob from the JSON file. |
||
313 | * |
||
314 | * @param string $glob The glob for a list of Puli paths. |
||
315 | */ |
||
316 | abstract protected function removeReferences($glob); |
||
1 ignored issue
–
show
For interfaces and abstract methods it is generally a good practice to add a
@return annotation even if it is just @return void or @return null , so that implementors know what to do in the overridden method.
For interface and abstract methods, it is impossible to infer the return type
from the immediate code. In these cases, it is generally advisible to explicitly
annotate these methods with a
Loading history...
|
|||
317 | |||
318 | /** |
||
319 | * Returns the references for a given Puli path. |
||
320 | * |
||
321 | * Each reference returned by this method can be: |
||
322 | * |
||
323 | * * `null` |
||
324 | * * a link starting with `@` |
||
325 | * * an absolute filesystem path |
||
326 | * |
||
327 | * The result has either one entry or none, if no path was found. The key |
||
328 | * of the single entry is the path passed to this method. |
||
329 | * |
||
330 | * @param string $path The Puli path. |
||
331 | * |
||
332 | * @return string[]|null[] A one-level array of references with Puli paths |
||
333 | * as keys. The array has at most one entry. |
||
334 | */ |
||
335 | abstract protected function getReferencesForPath($path); |
||
336 | |||
337 | /** |
||
338 | * Returns the references matching a given Puli path glob. |
||
339 | * |
||
340 | * Each reference returned by this method can be: |
||
341 | * |
||
342 | * * `null` |
||
343 | * * a link starting with `@` |
||
344 | * * an absolute filesystem path |
||
345 | * |
||
346 | * The keys of the returned array are Puli paths. Their order is undefined. |
||
347 | * |
||
348 | * @param string $glob The glob. |
||
349 | * @param int $flags A bitwise combination of the flag constants in this |
||
350 | * class. |
||
351 | * |
||
352 | * @return string[]|null[] A one-level array of references with Puli paths |
||
353 | * as keys. |
||
354 | */ |
||
355 | abstract protected function getReferencesForGlob($glob, $flags = 0); |
||
356 | |||
357 | /** |
||
358 | * Returns the references matching a given Puli path regular expression. |
||
359 | * |
||
360 | * Each reference returned by this method can be: |
||
361 | * |
||
362 | * * `null` |
||
363 | * * a link starting with `@` |
||
364 | * * an absolute filesystem path |
||
365 | * |
||
366 | * The keys of the returned array are Puli paths. Their order is undefined. |
||
367 | * |
||
368 | * @param string $staticPrefix The static prefix of all Puli paths matching |
||
369 | * the regular expression. |
||
370 | * @param string $regex The regular expression. |
||
371 | * @param int $flags A bitwise combination of the flag constants |
||
372 | * in this class. |
||
373 | * |
||
374 | * @return string[]|null[] A one-level array of references with Puli paths |
||
375 | * as keys. |
||
376 | */ |
||
377 | abstract protected function getReferencesForRegex($staticPrefix, $regex, $flags = 0); |
||
378 | |||
379 | /** |
||
380 | * Returns the references in a given Puli path. |
||
381 | * |
||
382 | * Each reference returned by this method can be: |
||
383 | * |
||
384 | * * `null` |
||
385 | * * a link starting with `@` |
||
386 | * * an absolute filesystem path |
||
387 | * |
||
388 | * The keys of the returned array are Puli paths. Their order is undefined. |
||
389 | * |
||
390 | * @param string $path The Puli path. |
||
391 | * @param int $flags A bitwise combination of the flag constants in this |
||
392 | * class. |
||
393 | * |
||
394 | * @return string[]|null[] A one-level array of references with Puli paths |
||
395 | * as keys. |
||
396 | */ |
||
397 | abstract protected function getReferencesInDirectory($path, $flags = 0); |
||
398 | |||
399 | /** |
||
400 | * Logs a message. |
||
401 | * |
||
402 | * @param mixed $level One of the level constants in {@link LogLevel}. |
||
403 | * @param string $message The message. |
||
404 | */ |
||
405 | 22 | protected function log($level, $message) |
|
406 | { |
||
407 | 22 | if (null !== $this->logger) { |
|
408 | 22 | $this->logger->log($level, $message); |
|
409 | } |
||
410 | 22 | } |
|
411 | |||
412 | /** |
||
413 | * Logs a warning that a reference could not be found. |
||
414 | * |
||
415 | * @param string $path The Puli path of a path mapping. |
||
416 | * @param string $reference The reference that was not found. |
||
417 | * @param string $absoluteReference The absolute filesystem path of the |
||
418 | * reference. |
||
419 | */ |
||
420 | 22 | protected function logReferenceNotFound($path, $reference, $absoluteReference) |
|
421 | { |
||
422 | 22 | $this->log(LogLevel::WARNING, sprintf( |
|
423 | 22 | 'The reference "%s"%s mapped by the path %s could not be found.', |
|
424 | $reference, |
||
425 | 22 | $reference !== $absoluteReference ? ' ('.$absoluteReference.')' : '', |
|
426 | $path |
||
427 | )); |
||
428 | 22 | } |
|
429 | |||
430 | /** |
||
431 | * Adds a filesystem resource to the JSON file. |
||
432 | * |
||
433 | * @param string $path The Puli path. |
||
434 | * @param FilesystemResource $resource The resource to add. |
||
435 | */ |
||
436 | 336 | protected function addFilesystemResource($path, FilesystemResource $resource) |
|
437 | { |
||
438 | 336 | $resource->attachTo($this, $path); |
|
439 | |||
440 | 336 | $relativePath = Path::makeRelative($resource->getFilesystemPath(), $this->baseDirectory); |
|
441 | |||
442 | 336 | $this->insertReference($path, $relativePath); |
|
443 | |||
444 | 336 | $this->storeVersion($resource); |
|
445 | 336 | } |
|
446 | |||
447 | /** |
||
448 | * Loads the JSON file. |
||
449 | */ |
||
450 | 392 | protected function load() |
|
451 | { |
||
452 | 392 | $decoder = new JsonDecoder(); |
|
453 | |||
454 | 392 | $this->json = file_exists($this->path) |
|
455 | 65 | ? (array) $decoder->decodeFile($this->path, $this->schemaPath) |
|
456 | 392 | : array(); |
|
457 | |||
458 | 392 | if (isset($this->json['_order'])) { |
|
459 | 5 | $this->json['_order'] = (array) $this->json['_order']; |
|
460 | |||
461 | 5 | foreach ($this->json['_order'] as $path => $entries) { |
|
462 | 5 | foreach ($entries as $key => $entry) { |
|
463 | 5 | $this->json['_order'][$path][$key] = (array) $entry; |
|
464 | } |
||
465 | } |
||
466 | } |
||
467 | |||
468 | // The root node always exists |
||
469 | 392 | if (!isset($this->json['/'])) { |
|
470 | 392 | $this->json['/'] = null; |
|
471 | } |
||
472 | |||
473 | // Make sure the JSON is sorted in reverse order |
||
474 | 392 | krsort($this->json); |
|
475 | 392 | } |
|
476 | |||
477 | /** |
||
478 | * Writes the JSON file. |
||
479 | */ |
||
480 | 340 | protected function flush() |
|
481 | { |
||
482 | // The root node always exists |
||
483 | 340 | if (!isset($this->json['/'])) { |
|
484 | 144 | $this->json['/'] = null; |
|
485 | } |
||
486 | |||
487 | // Always save in reverse order |
||
488 | 340 | krsort($this->json); |
|
489 | |||
490 | // Comply to schema |
||
491 | 340 | $json = (object) $this->json; |
|
492 | |||
493 | 340 | if (isset($json->{'_order'})) { |
|
494 | 10 | $order = $json->{'_order'}; |
|
495 | |||
496 | 10 | foreach ($order as $path => $entries) { |
|
497 | 10 | foreach ($entries as $key => $entry) { |
|
498 | 10 | $order[$path][$key] = (object) $entry; |
|
499 | } |
||
500 | } |
||
501 | |||
502 | 10 | $json->{'_order'} = (object) $order; |
|
503 | } |
||
504 | |||
505 | 340 | $this->encoder->encodeFile($json, $this->path, $this->schemaPath); |
|
506 | 340 | } |
|
507 | |||
508 | /** |
||
509 | * Returns whether a reference contains a link. |
||
510 | * |
||
511 | * @param string $reference The reference. |
||
512 | * |
||
513 | * @return bool Whether the reference contains a link. |
||
514 | */ |
||
515 | 280 | protected function isLinkReference($reference) |
|
516 | { |
||
517 | 280 | return isset($reference{0}) && '@' === $reference{0}; |
|
518 | } |
||
519 | |||
520 | /** |
||
521 | * Returns whether a reference contains an absolute or relative filesystem |
||
522 | * path. |
||
523 | * |
||
524 | * @param string $reference The reference. |
||
525 | * |
||
526 | * @return bool Whether the reference contains a filesystem path. |
||
527 | */ |
||
528 | 286 | protected function isFilesystemReference($reference) |
|
529 | { |
||
530 | 286 | return null !== $reference && !$this->isLinkReference($reference); |
|
531 | } |
||
532 | |||
533 | /** |
||
534 | * Turns a reference into a resource. |
||
535 | * |
||
536 | * @param string $path The Puli path. |
||
537 | * @param string|null $reference The reference. |
||
538 | * |
||
539 | * @return PuliResource The resource. |
||
0 ignored issues
–
show
|
|||
540 | */ |
||
541 | 152 | protected function createResource($path, $reference) |
|
542 | { |
||
543 | 152 | if (null === $reference) { |
|
544 | 12 | $resource = new GenericResource(); |
|
545 | 140 | } elseif (isset($reference{0}) && '@' === $reference{0}) { |
|
546 | 8 | $resource = new LinkResource(substr($reference, 1)); |
|
547 | 140 | } elseif (is_dir($reference)) { |
|
548 | 76 | $resource = new DirectoryResource($reference); |
|
549 | 92 | } elseif (is_file($reference)) { |
|
550 | 92 | $resource = new FileResource($reference); |
|
551 | } else { |
||
552 | throw new RuntimeException(sprintf( |
||
553 | 'Trying to create a FilesystemResource on a non-existing file or directory "%s"', |
||
554 | $reference |
||
555 | )); |
||
556 | } |
||
557 | |||
558 | 152 | $resource->attachTo($this, $path); |
|
559 | |||
560 | 152 | return $resource; |
|
561 | } |
||
562 | |||
563 | /** |
||
564 | * Turns a list of references into a list of resources. |
||
565 | * |
||
566 | * The references are expected to be in the format returned by |
||
567 | * {@link getReferencesForPath()}, {@link getReferencesForGlob()} and |
||
568 | * {@link getReferencesInDirectory()}. |
||
569 | * |
||
570 | * The result contains Puli paths as keys and {@link PuliResource} |
||
571 | * implementations as values. The order of the results is undefined. |
||
572 | * |
||
573 | * @param string[]|null[] $references The references indexed by Puli paths. |
||
574 | * |
||
575 | * @return array |
||
0 ignored issues
–
show
|
|||
576 | */ |
||
577 | 68 | private function createResources(array $references) |
|
578 | { |
||
579 | 68 | foreach ($references as $path => $reference) { |
|
580 | 44 | $references[$path] = $this->createResource($path, $reference); |
|
581 | } |
||
582 | |||
583 | 68 | return $references; |
|
584 | } |
||
585 | |||
586 | /** |
||
587 | * Adds all ancestor directories of a path to the repository. |
||
588 | * |
||
589 | * @param string $path A Puli path. |
||
590 | */ |
||
591 | 340 | private function ensureDirectoryExists($path) |
|
592 | { |
||
593 | 340 | if (array_key_exists($path, $this->json)) { |
|
594 | 340 | return; |
|
595 | } |
||
596 | |||
597 | // Recursively initialize parent directories |
||
598 | 112 | if ('/' !== $path) { |
|
599 | 112 | $this->ensureDirectoryExists(Path::getDirectory($path)); |
|
600 | } |
||
601 | |||
602 | 112 | $this->json[$path] = null; |
|
603 | 112 | } |
|
604 | |||
605 | /** |
||
606 | * Adds a resource to the repository. |
||
607 | * |
||
608 | * @param string $path The Puli path to add the |
||
609 | * resource at. |
||
610 | * @param FilesystemResource|LinkResource $resource The resource to add. |
||
611 | */ |
||
612 | 340 | private function addResource($path, $resource) |
|
613 | { |
||
614 | 340 | if (!$resource instanceof FilesystemResource && !$resource instanceof LinkResource) { |
|
615 | 4 | throw new UnsupportedResourceException(sprintf( |
|
616 | 'The %s only supports adding FilesystemResource and '. |
||
617 | 4 | 'LinkedResource instances. Got: %s', |
|
618 | // Get the short class name |
||
619 | 4 | $this->getShortClassName(get_class($this)), |
|
620 | 4 | $this->getShortClassName(get_class($resource)) |
|
621 | )); |
||
622 | } |
||
623 | |||
624 | // Don't modify resources attached to other repositories |
||
625 | 336 | if ($resource->isAttached()) { |
|
626 | 4 | $resource = clone $resource; |
|
627 | } |
||
628 | |||
629 | 336 | if ($resource instanceof LinkResource) { |
|
630 | 8 | $resource->attachTo($this, $path); |
|
631 | |||
632 | 8 | $this->insertReference($path, '@'.$resource->getTargetPath()); |
|
633 | |||
634 | 8 | $this->storeVersion($resource); |
|
635 | } else { |
||
636 | // Extension point for the optimized repository |
||
637 | 336 | $this->addFilesystemResource($path, $resource); |
|
638 | } |
||
639 | 336 | } |
|
640 | |||
641 | /** |
||
642 | * Returns the short name of a fully-qualified class name. |
||
643 | * |
||
644 | * @param string $className The fully-qualified class name. |
||
645 | * |
||
646 | * @return string The short class name. |
||
647 | */ |
||
648 | 4 | private function getShortClassName($className) |
|
649 | { |
||
650 | 4 | if (false !== ($pos = strrpos($className, '\\'))) { |
|
651 | 4 | return substr($className, $pos + 1); |
|
652 | } |
||
653 | |||
654 | 4 | return $className; |
|
655 | } |
||
656 | } |
||
657 |
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: