Skip to content

Symfony - storage_filename_strategy configuration not evaluated #216

@MaSpeng

Description

@MaSpeng

The Symfony integration as of version 2.0 of this bundle does not evaluate the storage_filename_strategy and connections.<connection_name>.storage.filename_strategy configuration.

The service db_tools.storage will be configured with strategies resolved from the deprecated configuration path db_tools.storage.filename_strategy at

$strategies = [];
foreach (($config['storage']['filename_strategy'] ?? []) as $connectionName => $strategyId) {
// Default is handled directly by the storage service.
if ($strategyId !== null && $strategyId !== 'default' && $strategyId !== 'datetime') {
if ($container->hasDefinition($strategyId)) {
$strategies[$connectionName] = new Reference($strategyId);
} elseif (\class_exists($strategyId)) {
if (!\is_subclass_of($strategyId, FilenameStrategyInterface::class)) {
throw new InvalidArgumentException(\sprintf('"db_tools.connections.%s.filename_strategy": class "%s" does not implement "%s"', $connectionName, $strategyId, FilenameStrategyInterface::class));
}
$serviceId = '.db_tools.filename_strategy.' . \sha1($strategyId);
$container->setDefinition($serviceId, (new Definition())->setClass($strategyId));
$strategies[$connectionName] = new Reference($serviceId);
} else {
throw new InvalidArgumentException(\sprintf('"db_tools.connections.%s.filename_strategy": class or service "%s" does not exist or is not registered in container', $connectionName, $strategyId));
}
break;
}
}
if ($strategies) {
$container->getDefinition('db_tools.storage')->setArgument(1, $strategies);
}

Due to the initialization of the configuration object at

return new DbToolsConfiguration(true, false);
its not possible anymore to use this configuration path.

The configuration at db_tools.storage_filename_strategy and db_tools.connections.<connection_name>.storage_filename_strategy does not seem to be taken into account at all.


For anyone facing the same issue, as temporary a workaround, it is possible to update the definition of the service `db_tools.storage` through a custom compiler pass.
<?php

declare(strict_types=1);

namespace App\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Reference;

class DbToolsCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        /**
         * @var array<int, array{
         *      storage_filename_strategy?: 'default'|'datetime'|string,
         *      connections: array<string, array{
         *          storage_filename_strategy?: 'default'|'datetime'|string,
         *      }
         *  } $dbToolsConfigurations
         */
        $dbToolsConfigurations = $container->getExtensionConfig('db_tools');
        if (count($dbToolsConfigurations) > 1) {
            throw new LogicException('More than one db tool configuration defined.');
        }

        $dbToolsConfiguration = $dbToolsConfigurations[0];
        if ([] === $dbToolsConfiguration) {
            return;
        }

        $storageFilenameStrategies = [];

        $defaultStorageFilenameStrategy = $this->retrieveStorageFilenameStrategyFromConfiguration(
            $dbToolsConfiguration,
        );
        if (null !== $defaultStorageFilenameStrategy) {
            $storageFilenameStrategies['default'] = $defaultStorageFilenameStrategy;
        }

        if (array_key_exists('connections', $dbToolsConfiguration)) {
            foreach ($dbToolsConfiguration['connections'] as $connectionName => $connectionConfiguration) {
                $storageFilenameStrategy = $this->retrieveStorageFilenameStrategyFromConfiguration(
                    $connectionConfiguration,
                );
                if (null === $storageFilenameStrategy) {
                    continue;
                }

                $storageFilenameStrategies[$connectionName] = $storageFilenameStrategy;
            }
        }

        if ($storageFilenameStrategies === []) {
            return;
        }

        $dbToolsStorageDefinition = $container->getDefinition('db_tools.storage');

        $dbToolsStorageDefinition->replaceArgument(1, $storageFilenameStrategies);
    }

    /**
     * @param array{storage_filename_strategy?: 'default'|'datetime'|string} $configuration
     *
     * @return Reference|null
     */
    private function retrieveStorageFilenameStrategyFromConfiguration(array $configuration): ?Reference
    {
        if (!array_key_exists('storage_filename_strategy', $configuration)
            || in_array($configuration['storage_filename_strategy'], ['default', 'datetime'])
        ) {
            return null;
        }

        return new Reference($configuration['storage_filename_strategy']);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions