Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PS-670-rendition-video_enhance3 #494

Merged
merged 12 commits into from
Dec 9, 2024
2 changes: 2 additions & 0 deletions databox/api/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,5 @@ services:
$decorated: '@.inner'

Alchemy\RenditionFactory\Templating\TemplateResolverInterface: '@App\Asset\Attribute\TemplateResolver'

App\Validator\ValidRenditionDefinitionConstraintValidator: ~
36 changes: 36 additions & 0 deletions databox/api/src/Command/DocumentationDumperCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace App\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Alchemy\RenditionFactory\RenditionBuilderConfigurationDocumentation;


#[AsCommand('app:documentation:dump')]
class DocumentationDumperCommand extends Command
{
public function __construct(
private readonly RenditionBuilderConfigurationDocumentation $renditionBuilderConfigurationDocumentation,
)
{
parent::__construct();
}

protected function configure(): void
{
parent::configure();
}
jygaulier marked this conversation as resolved.
Show resolved Hide resolved

protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln('# ' . $this->renditionBuilderConfigurationDocumentation::getName());
$output->writeln($this->renditionBuilderConfigurationDocumentation->generate());

return 0;
jygaulier marked this conversation as resolved.
Show resolved Hide resolved
}
}
7 changes: 4 additions & 3 deletions databox/api/src/Entity/Core/RenditionDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace App\Entity\Core;

use Alchemy\CoreBundle\Entity\AbstractUuidEntity;
use Alchemy\CoreBundle\Entity\Traits\CreatedAtTrait;
use Alchemy\CoreBundle\Entity\Traits\UpdatedAtTrait;
use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
Expand All @@ -16,10 +18,8 @@
use App\Api\Model\Input\RenditionDefinitionInput;
use App\Api\Provider\RenditionDefinitionCollectionProvider;
use App\Controller\Core\RenditionDefinitionSortAction;

use Alchemy\CoreBundle\Entity\Traits\CreatedAtTrait;
use Alchemy\CoreBundle\Entity\Traits\UpdatedAtTrait;
use App\Entity\Traits\WorkspaceTrait;
use App\Validator as CustomAssert;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection as DoctrineCollection;
use Doctrine\DBAL\Types\Types;
Expand Down Expand Up @@ -153,6 +153,7 @@ class RenditionDefinition extends AbstractUuidEntity implements \Stringable
#[Groups([RenditionDefinition::GROUP_LIST, RenditionDefinition::GROUP_READ, RenditionDefinition::GROUP_WRITE])]
#[ORM\Column(type: Types::TEXT, nullable: true)]
#[ApiProperty(security: self::GRANT_ADMIN_PROP)]
#[CustomAssert\ValidRenditionDefinitionConstraint]
private ?string $definition = null;

#[Groups([RenditionDefinition::GROUP_READ])]
Expand Down
17 changes: 17 additions & 0 deletions databox/api/src/Validator/ValidRenditionDefinitionConstraint.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace App\Validator;

use Symfony\Component\Validator\Constraint;

/** @uses ValidRenditionDefinitionConstraintValidator */
#[\Attribute]
class ValidRenditionDefinitionConstraint extends Constraint
{
public function getTargets(): string|array
{
return self::PROPERTY_CONSTRAINT;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace App\Validator;

use Alchemy\RenditionFactory\Config\buildConfigValidator;
use Alchemy\RenditionFactory\Config\YamlLoader;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ValidRenditionDefinitionConstraintValidator extends ConstraintValidator
{
/** @uses buildConfigValidator */
public function __construct(private readonly YamlLoader $yamlLoader, private readonly buildConfigValidator $validator)
{
}

/**
* @param string $value
* @param ValidRenditionDefinitionConstraint $constraint
*/
public function validate($value, Constraint $constraint): void
{
if(!$value) {
return;
}
try {
$config = $this->yamlLoader->parse($value);
$this->validator->validate($config);
} catch (\Exception $e) {
$this->context
->buildViolation($e->getMessage())
->addViolation();
}
}
}
56 changes: 37 additions & 19 deletions lib/php/rendition-factory-bundle/Resources/config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ services:
autoconfigure: true

Alchemy\RenditionFactory\Command\CreateCommand: ~
Alchemy\RenditionFactory\Command\ConfigurationValidateCommand: ~

Alchemy\RenditionFactory\Context\TransformationContextFactory: ~
Alchemy\RenditionFactory\FileFamilyGuesser: ~
Expand Down Expand Up @@ -44,43 +45,56 @@ services:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\TransformerModuleInterface::TAG }

# FFMpeg "formats"
Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\JpegFormat:
# Output "formats"
Alchemy\RenditionFactory\Transformer\Video\Format\JpegFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\MkvFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\MkvFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\Mpeg4Format:
Alchemy\RenditionFactory\Transformer\Video\Format\Mpeg4Format:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\MpegFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\MpegFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\QuicktimeFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\QuicktimeFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\WebmFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\WebmFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\AnimatedGifFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\AnimatedGifFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\AnimatedPngFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\AnimatedPngFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\AnimatedWebpFormat:
Alchemy\RenditionFactory\Transformer\Video\Format\AnimatedWebpFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\FFMpeg\Format\FormatInterface::TAG }
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\Format\WavFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\Format\AacFormat:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\Format\Mp3Format:
tags:
- { name: !php/const Alchemy\RenditionFactory\Transformer\Video\Format\FormatInterface::TAG }

Alchemy\RenditionFactory\Transformer\Video\Format\OutputFormatsDocumentation: ~

Imagine\Imagick\Imagine: ~
Imagine\Image\ImagineInterface: '@Imagine\Imagick\Imagine'
Expand All @@ -89,3 +103,7 @@ services:
Alchemy\RenditionFactory\Format\FormatGuesser: ~
Alchemy\RenditionFactory\Format\FormatFactory: ~
Alchemy\RenditionFactory\Config\ModuleOptionsResolver: ~

Alchemy\RenditionFactory\RenditionBuilderConfigurationDocumentation: ~

Alchemy\RenditionFactory\Config\buildConfigValidator: ~
jygaulier marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Alchemy\RenditionFactory\Command;

use Alchemy\RenditionFactory\Config\buildConfigValidator;
use Alchemy\RenditionFactory\Config\YamlLoader;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand('alchemy:rendition-factory:conf:validate')]
class ConfigurationValidateCommand extends Command
{
public function __construct(
private readonly YamlLoader $yamlLoader,
private readonly buildConfigValidator $validator,
) {
parent::__construct();
}

protected function configure(): void
{
parent::configure();

$this->addArgument('config', InputArgument::REQUIRED, 'A build config YAML file to validate')
->setHelp('Validate a config file.')
;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$config = $this->yamlLoader->load($input->getArgument('config'));
$this->validator->validate($config);

$output->writeln('Configuration is valid.');

return 0;
jygaulier marked this conversation as resolved.
Show resolved Hide resolved
}
}
5 changes: 2 additions & 3 deletions lib/php/rendition-factory/src/Config/YamlLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,7 @@ private function parseFamilyConfig(array $data): FamilyBuildConfig

$transformations = [];
foreach ($data['transformations'] as $transformation) {
if ($transformation['enabled'] ?? true) {
$transformations[] = $this->parseTransformation($transformation);
}
$transformations[] = $this->parseTransformation($transformation);
4rthem marked this conversation as resolved.
Show resolved Hide resolved
}

return new FamilyBuildConfig($transformations, $data['normalization'] ?? []);
Expand All @@ -72,6 +70,7 @@ private function parseTransformation(array $transformation): Transformation
{
return new Transformation(
$transformation['module'],
$transformation['enabled'] ?? true,
$transformation['options'] ?? [],
$transformation['description'] ?? null
);
Expand Down
57 changes: 57 additions & 0 deletions lib/php/rendition-factory/src/Config/buildConfigValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace Alchemy\RenditionFactory\Config;

use Alchemy\RenditionFactory\DTO\BuildConfig\BuildConfig;
use Alchemy\RenditionFactory\DTO\FamilyEnum;
use Alchemy\RenditionFactory\Transformer\TransformerModuleInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\Definition\Processor;
use Symfony\Component\DependencyInjection\Attribute\TaggedLocator;
use Symfony\Component\DependencyInjection\ServiceLocator;

readonly class buildConfigValidator
jygaulier marked this conversation as resolved.
Show resolved Hide resolved
{
public function __construct(
#[TaggedLocator(TransformerModuleInterface::TAG, defaultIndexMethod: 'getName')]
private ServiceLocator $transformers,
) {
}

public function getTransformers(): ServiceLocator
{
return $this->transformers;
}

public function validate(BuildConfig $config): void
{
foreach (FamilyEnum::cases() as $family) {
$familyConfig = $config->getFamily($family);
if (null === $familyConfig) {
continue;
}
foreach ($familyConfig->getTransformations() as $transformation) {
$transformerName = $transformation->getModule();

/** @var TransformerModuleInterface $transformer */
$transformer = $this->transformers->get($transformerName);

try {
$this->checkTransformerConfiguration($transformer, $transformation->toArray());
} catch (\Throwable $e) {
$msg = sprintf("Error in module \"%s\"\n%s", $transformerName, $e->getMessage());
throw new InvalidConfigurationException($msg);
}
}
}
}

private function checkTransformerConfiguration(TransformerModuleInterface $transformer, array $options): void
{
$documentation = $transformer->getDocumentation();
$treeBuilder = $documentation->getTreeBuilder();

$processor = new Processor();
$processor->process($treeBuilder->buildTree(), ['root' => $options]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ public function getTransformations(): array
return $this->transformations;
}

public function getEnabledTransformations(): array
{
return array_filter($this->transformations, function (Transformation $transformation) {
return $transformation->isEnabled();
});
}

public function getNormalization(): array
{
return $this->normalization;
Expand Down
16 changes: 16 additions & 0 deletions lib/php/rendition-factory/src/DTO/BuildConfig/Transformation.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{
public function __construct(
private string $module,
private bool $enabled,
private array $options,
private ?string $description,
) {
Expand All @@ -25,4 +26,19 @@ public function getOptions(): array
{
return $this->options;
}

public function isEnabled(): bool
{
return $this->enabled;
}

public function toArray(): array
{
return [
'module' => $this->module,
'enabled' => $this->enabled,
'options' => $this->options,
'description' => $this->description,
];
}
}
Loading
Loading