zenstruck / filesystem

Wrapper for league/flysystem with alternate API and added functionality.
MIT License
19 stars 3 forks source link

[Core] "Node Metadata" system #94

Open kbond opened 1 year ago

kbond commented 1 year ago

While flysystem provides a standard set of metadata (ie size/last modified/etc), it would be nice if we could have the ability to add more metadata dynamically.

I'm thinking of a MetadataProvider interface:

interface MetadataProvider
{
    public function metadataValue(Node $node, string $key): mixed;

    /**
     * @return list<string> List of metadata "keys" supported by this provider
     */
    public function supportedMetadata(Node $node): array;
}

And a metadata object:

final class Metadata
{
    /** @var array<string, mixed> */
    private array $cache = [];

    public function __construct(private Node $node, private MetadataProvider $provider)
    {
    }

    public function get(string $key): mixed
    {
        return $this->cache[$key] ??= $this->provider->metadataValue($this->node, $key);
    }

    /**
     * @return array<string, mixed>
     */
    public function all(): array
    {
        $supported = $this->provider->supportedMetadata($this->node);

        return $this->cache = \array_map(fn($k) => $this->get($key), \array_combine($supported, $supported);
    }
}

Flysystem adapters could implement this interface or an implementation could be registered as a feature to FlysystemFilesystem.

The current image metadata system (dimensions, exif, iptc) could be moved to a LocalImageMetadataProvider.

Related to #83.