Skip to content

Commit be7cf4e

Browse files
authored
fix: streamline Metadata usage (#220)
1 parent 3854a65 commit be7cf4e

File tree

6 files changed

+60
-23
lines changed

6 files changed

+60
-23
lines changed

psalm.baseline.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,11 @@
668668
<code><![CDATA[__construct]]></code>
669669
</PossiblyUnusedMethod>
670670
</file>
671+
<file src="src/Metadata.php">
672+
<PossiblyUnusedProperty>
673+
<code><![CDATA[$id]]></code>
674+
</PossiblyUnusedProperty>
675+
</file>
671676
<file src="src/Permutator.php">
672677
<MixedArgument>
673678
<code><![CDATA[$parameters]]></code>

src/Bridge/Twig/Extension/ThumbnailExtension.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use Sigwin\YASSG\Asset\AssetFetch;
1717
use Sigwin\YASSG\AssetQueue;
18+
use Sigwin\YASSG\Metadata;
1819
use Symfony\Component\Asset\Packages;
1920
use Symfony\Component\HttpFoundation\RequestStack;
2021
use Twig\Extension\AbstractExtension;
@@ -34,21 +35,22 @@ public function getFunctions(): array
3435
if (str_starts_with($path, './')) {
3536
if (! isset($context['__path'])) {
3637
if (isset($options['self'])) {
37-
if (! \is_object($options['self']) || ! property_exists($options['self'], '__path')) {
38+
if (! \is_object($options['self']) || ! property_exists($options['self'], '__metadata')
39+
|| ! \is_object($options['self']->__metadata) || ! $options['self']->__metadata instanceof Metadata) {
3840
throw new \RuntimeException('Cannot use yassg_thumbnail() with {self: object} as the second argument, pass {self: object} as the second argument');
3941
}
40-
$context['__path'] = $options['self']->__path;
42+
$context['__path'] = $options['self']->__metadata->path;
4143
} else {
4244
$candidates = [];
4345
foreach ($context as $item) {
44-
if (\is_object($item) && property_exists($item, '__path')) {
45-
$candidates[] = $item;
46+
if (\is_object($item) && property_exists($item, '__metadata') && $item->__metadata instanceof Metadata) {
47+
$candidates[] = $item->__metadata;
4648
}
4749
}
4850
if (\count($candidates) !== 1) {
4951
throw new \RuntimeException('Cannot use yassg_thumbnail() without a single Locatable object in context, pass {self: object} as the second argument');
5052
}
51-
$context['__path'] = $candidates[0]->__path;
53+
$context['__path'] = $candidates[0]->path;
5254
}
5355
}
5456

src/Metadata.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Sigwin Yassg project.
7+
*
8+
* (c) sigwin.hr
9+
*
10+
* This source file is subject to the MIT license that is bundled
11+
* with this source code in the file LICENSE.
12+
*/
13+
14+
namespace Sigwin\YASSG;
15+
16+
final class Metadata
17+
{
18+
public function __construct(
19+
public readonly string $id,
20+
public readonly ?string $path = null,
21+
) {
22+
}
23+
}

src/Storage/DenormalizingStorage.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use Sigwin\YASSG\Context\LocaleContext;
1717
use Sigwin\YASSG\Exception\UnexpectedAttributeException;
18+
use Sigwin\YASSG\Metadata;
1819
use Sigwin\YASSG\Storage;
1920
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
2021
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
@@ -108,21 +109,18 @@ private function denormalize(string $id, array $data, array $context): object
108109
$metadata = [];
109110
foreach ($data as $key => $value) {
110111
if (str_starts_with($key, '__')) {
111-
$metadata[$key] = $value;
112+
if (! \is_string($value)) {
113+
throw new \LogicException('Invalid metadata value');
114+
}
115+
$metadata[mb_substr($key, 2)] = $value;
112116
unset($data[$key]);
113117
}
114118
}
115119
$object = $this->denormalizer->denormalize($data, $this->class, null, $context + [
116120
AbstractNormalizer::ALLOW_EXTRA_ATTRIBUTES => false,
117121
]);
118-
119-
// attach metadata to the object as dynamic properties
120-
foreach ($metadata as $key => $value) {
121-
/**
122-
* @phpstan-ignore-next-line
123-
*/
124-
$object->{$key} = $value;
125-
}
122+
/** @phpstan-ignore-next-line */
123+
$object->__metadata = new Metadata(...$metadata);
126124

127125
return $object;
128126
} catch (ExtraAttributesException $extraAttributesException) {

src/Storage/FilesystemStorage.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public function load(): iterable
6464
}
6565
$ids[$id] = true;
6666

67-
yield $id => $this->decode($file);
67+
yield $id => $this->decode($id, $file);
6868
}
6969
}
7070

@@ -73,7 +73,7 @@ public function get(string $id): array
7373
foreach ($this->roots as $root) {
7474
$path = $root.$id;
7575
if (file_exists($path)) {
76-
return $this->decode(new \SplFileObject($path));
76+
return $this->decode($id, new \SplFileObject($path));
7777
}
7878
}
7979

@@ -109,13 +109,14 @@ public static function resolveOptions(array $options): array
109109
return $resolver->resolve($options);
110110
}
111111

112-
private function decode(\SplFileInfo $file): array
112+
private function decode(string $id, \SplFileInfo $file): array
113113
{
114114
if ($this->decoder->supports($file) === false) {
115115
throw new \RuntimeException(\sprintf('Decoder does not know how to decode %1$s file', $file->getRealPath()));
116116
}
117117

118118
$decoded = $this->decoder->decode($file);
119+
$decoded['__id'] = $id;
119120
$decoded['__path'] = $file->getRealPath();
120121

121122
return $decoded;

src/Storage/MemoryStorage.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,20 @@
2323
*/
2424
final class MemoryStorage implements StorageWithOptions
2525
{
26-
public function __construct(
27-
/**
28-
* @var array<string, array>
29-
*/
30-
private array $values,
31-
) {
26+
/**
27+
* @var array<string, array<string, mixed>>
28+
*/
29+
private array $values;
30+
31+
/**
32+
* @param array<string, array<string, mixed>> $values
33+
*/
34+
public function __construct(array $values)
35+
{
36+
foreach (array_keys($values) as $id) {
37+
$values[$id]['__id'] = $id;
38+
}
39+
$this->values = $values;
3240
}
3341

3442
public static function resolveOptions(array $options): array

0 commit comments

Comments
 (0)