diff --git a/Config/Filter/Argument/Point.php b/Config/Filter/Argument/Point.php new file mode 100644 index 000000000..33b0d8a6d --- /dev/null +++ b/Config/Filter/Argument/Point.php @@ -0,0 +1,44 @@ +x = $x; + $this->y = $y; + } + + public function getX(): ?int + { + return $this->x; + } + + public function getY(): ?int + { + return $this->y; + } +} diff --git a/Config/Filter/Argument/Size.php b/Config/Filter/Argument/Size.php new file mode 100644 index 000000000..e3ec10213 --- /dev/null +++ b/Config/Filter/Argument/Size.php @@ -0,0 +1,48 @@ +width = $width; + $this->height = $height; + } + + public function getWidth(): ?int + { + return $this->width; + } + + public function getHeight(): ?int + { + return $this->height; + } +} diff --git a/Config/Filter/Type/AutoRotate.php b/Config/Filter/Type/AutoRotate.php new file mode 100644 index 000000000..7eaafc73a --- /dev/null +++ b/Config/Filter/Type/AutoRotate.php @@ -0,0 +1,20 @@ +color = $color; + $this->transparency = $transparency; + $this->position = $position; + $this->size = $size; + } + + public function getColor(): ?string + { + return $this->color; + } + + public function getTransparency(): ?string + { + return $this->transparency; + } + + public function getPosition(): ?string + { + return $this->position; + } + + public function getSize(): Size + { + return $this->size; + } +} diff --git a/Config/Filter/Type/Crop.php b/Config/Filter/Type/Crop.php new file mode 100644 index 000000000..633a9182f --- /dev/null +++ b/Config/Filter/Type/Crop.php @@ -0,0 +1,49 @@ +startPoint = $startPoint; + $this->size = $size; + } + + public function getStartPoint(): Point + { + return $this->startPoint; + } + + public function getSize(): Size + { + return $this->size; + } +} diff --git a/Config/Filter/Type/Downscale.php b/Config/Filter/Type/Downscale.php new file mode 100644 index 000000000..4d2732928 --- /dev/null +++ b/Config/Filter/Type/Downscale.php @@ -0,0 +1,52 @@ +max = $max; + $this->by = $by; + } + + public function getMax(): ?Size + { + return $this->max; + } + + public function getBy(): ?float + { + return $this->by; + } +} diff --git a/Config/Filter/Type/FilterAbstract.php b/Config/Filter/Type/FilterAbstract.php new file mode 100644 index 000000000..3b1eb2782 --- /dev/null +++ b/Config/Filter/Type/FilterAbstract.php @@ -0,0 +1,29 @@ +axis = $axis; + } + + public function getAxis(): string + { + return $this->axis; + } +} diff --git a/Config/Filter/Type/Grayscale.php b/Config/Filter/Type/Grayscale.php new file mode 100644 index 000000000..5bb5a82bd --- /dev/null +++ b/Config/Filter/Type/Grayscale.php @@ -0,0 +1,20 @@ +mode = $mode; + } + + public function getMode(): string + { + return $this->mode; + } +} diff --git a/Config/Filter/Type/Paste.php b/Config/Filter/Type/Paste.php new file mode 100644 index 000000000..c92906e93 --- /dev/null +++ b/Config/Filter/Type/Paste.php @@ -0,0 +1,37 @@ +start = $start; + } + + public function getStart(): Point + { + return $this->start; + } +} diff --git a/Config/Filter/Type/RelativeResize.php b/Config/Filter/Type/RelativeResize.php new file mode 100644 index 000000000..a93ff07a9 --- /dev/null +++ b/Config/Filter/Type/RelativeResize.php @@ -0,0 +1,72 @@ +heighten = $heighten; + $this->widen = $widen; + $this->increase = $increase; + $this->scale = $scale; + } + + public function getHeighten(): ?float + { + return $this->heighten; + } + + public function getWiden(): ?float + { + return $this->widen; + } + + public function getIncrease(): ?float + { + return $this->increase; + } + + public function getScale(): ?float + { + return $this->scale; + } +} diff --git a/Config/Filter/Type/Resize.php b/Config/Filter/Type/Resize.php new file mode 100644 index 000000000..9edb27cdd --- /dev/null +++ b/Config/Filter/Type/Resize.php @@ -0,0 +1,37 @@ +size = $size; + } + + public function getSize(): Size + { + return $this->size; + } +} diff --git a/Config/Filter/Type/Rotate.php b/Config/Filter/Type/Rotate.php new file mode 100644 index 000000000..ef4cd3851 --- /dev/null +++ b/Config/Filter/Type/Rotate.php @@ -0,0 +1,35 @@ +angle = $angle; + } + + public function getAngle(): int + { + return $this->angle; + } +} diff --git a/Config/Filter/Type/Scale.php b/Config/Filter/Type/Scale.php new file mode 100644 index 000000000..7f0447602 --- /dev/null +++ b/Config/Filter/Type/Scale.php @@ -0,0 +1,52 @@ +dimensions = $dimensions; + $this->to = $to; + } + + public function getDimensions(): Size + { + return $this->dimensions; + } + + public function getTo(): ?float + { + return $this->to; + } +} diff --git a/Config/Filter/Type/Strip.php b/Config/Filter/Type/Strip.php new file mode 100644 index 000000000..bfdf3f019 --- /dev/null +++ b/Config/Filter/Type/Strip.php @@ -0,0 +1,20 @@ +size = $size; + $this->mode = $mode; + $this->allowUpscale = $allowUpscale; + $this->filter = $filter; + } + + public function getSize(): Size + { + return $this->size; + } + + public function getMode(): ?string + { + return $this->mode; + } + + public function isAllowUpscale(): ?bool + { + return $this->allowUpscale; + } + + public function getFilter(): ?string + { + return $this->filter; + } +} diff --git a/Config/Filter/Type/Upscale.php b/Config/Filter/Type/Upscale.php new file mode 100644 index 000000000..acd227208 --- /dev/null +++ b/Config/Filter/Type/Upscale.php @@ -0,0 +1,52 @@ +min = $min; + $this->by = $by; + } + + public function getMin(): Size + { + return $this->min; + } + + public function getBy(): ?float + { + return $this->by; + } +} diff --git a/Config/Filter/Type/Watermark.php b/Config/Filter/Type/Watermark.php new file mode 100644 index 000000000..aff94ddb0 --- /dev/null +++ b/Config/Filter/Type/Watermark.php @@ -0,0 +1,57 @@ +image = $image; + $this->position = $position; + $this->size = $size; + } + + public function getImage(): string + { + return $this->image; + } + + public function getPosition(): string + { + return $this->position; + } + + public function getSize(): ?float + { + return $this->size; + } +} diff --git a/Config/FilterFactoryCollection.php b/Config/FilterFactoryCollection.php new file mode 100644 index 000000000..c46c3e35c --- /dev/null +++ b/Config/FilterFactoryCollection.php @@ -0,0 +1,57 @@ +filterFactories[$filterFactory->getName()] = $filterFactory; + } + } + + /** + * @param string $name + * + * @throws NotFoundException + * + * @return FilterFactoryInterface + */ + public function getFilterFactoryByName(string $name): FilterFactoryInterface + { + if (!isset($this->filterFactories[$name])) { + throw new NotFoundException(sprintf("Filter factory with name '%s' was not found.", $name)); + } + + return $this->filterFactories[$name]; + } + + /** + * @return FilterFactoryInterface[] + */ + public function getAll() + { + return $this->filterFactories; + } +} diff --git a/Config/FilterInterface.php b/Config/FilterInterface.php new file mode 100644 index 000000000..6b45461ef --- /dev/null +++ b/Config/FilterInterface.php @@ -0,0 +1,28 @@ +name = $name; + $this->dataLoader = $dataLoader; + $this->quality = $quality; + $this->setFilters($filters); + } + + public function getName(): string + { + return $this->name; + } + + public function getDataLoader(): ?string + { + return $this->dataLoader; + } + + public function getQuality(): ?int + { + return $this->quality; + } + + /** + * @return FilterInterface[] + */ + public function getFilters(): array + { + return $this->filters; + } + + /** + * @param FilterInterface[] $filters + */ + private function setFilters(array $filters): void + { + foreach ($filters as $filter) { + if (!($filter instanceof FilterInterface)) { + throw new InvalidArgumentException('Unknown filter provided.'); + } + } + $this->filters = $filters; + } +} diff --git a/Config/StackBuilder.php b/Config/StackBuilder.php new file mode 100644 index 000000000..d399bd537 --- /dev/null +++ b/Config/StackBuilder.php @@ -0,0 +1,51 @@ +stackFactory = $stackFactory; + $this->filterFactoryCollection = $filterFactoryCollection; + } + + public function build(string $stackName, array $stackData): StackInterface + { + $filters = []; + if (!empty($stackData['filters'])) { + foreach ($stackData['filters'] as $filterName => $filterData) { + $filterFactory = $this->filterFactoryCollection->getFilterFactoryByName($filterName); + $filters[] = $filterFactory->create($filterData); + } + } + + return $this->stackFactory->create( + $stackName, + $stackData['data_loader'], + $stackData['quality'], + $filters + ); + } +} diff --git a/Config/StackBuilderInterface.php b/Config/StackBuilderInterface.php new file mode 100644 index 000000000..56319d230 --- /dev/null +++ b/Config/StackBuilderInterface.php @@ -0,0 +1,17 @@ +stackBuilder = $stackBuilder; + $this->filtersConfiguration = $filtersConfiguration; + } + + /** + * @return StackInterface[] + */ + public function getStacks() + { + if (!empty($this->stacks)) { + return $this->stacks; + } + + foreach ($this->filtersConfiguration as $filterSetName => $filterSetData) { + $this->stacks[] = $this->stackBuilder->build($filterSetName, $filterSetData); + } + + return $this->stacks; + } +} diff --git a/Config/StackInterface.php b/Config/StackInterface.php new file mode 100644 index 000000000..9275b7fb9 --- /dev/null +++ b/Config/StackInterface.php @@ -0,0 +1,26 @@ +sizeFactory = $sizeFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Background::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + $color = $options['color'] ?? null; + $transparency = $options['transparency'] ?? null; + $position = $options['position'] ?? null; + $size = $this->sizeFactory->createFromOptions($options); + + return new Background($color, $transparency, $position, $size); + } +} diff --git a/Factory/Config/Filter/CropFactory.php b/Factory/Config/Filter/CropFactory.php new file mode 100644 index 000000000..7660e2a40 --- /dev/null +++ b/Factory/Config/Filter/CropFactory.php @@ -0,0 +1,60 @@ +sizeFactory = $sizeFactory; + $this->pointFactory = $pointFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Crop::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + return new Crop( + $this->pointFactory->createFromOptions($options, 'start'), + $this->sizeFactory->createFromOptions($options) + ); + } +} diff --git a/Factory/Config/Filter/DownscaleFactory.php b/Factory/Config/Filter/DownscaleFactory.php new file mode 100644 index 000000000..cf9b05c20 --- /dev/null +++ b/Factory/Config/Filter/DownscaleFactory.php @@ -0,0 +1,53 @@ +sizeFactory = $sizeFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Downscale::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + $max = $this->sizeFactory->createFromOptions($options, 'max'); + $by = isset($options['by']) ? (float) $options['by'] : null; + + return new Downscale($max, $by); + } +} diff --git a/Factory/Config/Filter/FlipFactory.php b/Factory/Config/Filter/FlipFactory.php new file mode 100644 index 000000000..546478529 --- /dev/null +++ b/Factory/Config/Filter/FlipFactory.php @@ -0,0 +1,39 @@ +pointFactory = $pointFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Paste::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + return new Paste($this->pointFactory->createFromOptions($options, 'start')); + } +} diff --git a/Factory/Config/Filter/RelativeResizeFactory.php b/Factory/Config/Filter/RelativeResizeFactory.php new file mode 100644 index 000000000..95fe036bf --- /dev/null +++ b/Factory/Config/Filter/RelativeResizeFactory.php @@ -0,0 +1,44 @@ +sizeFactory = $sizeFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Resize::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + return new Resize($this->sizeFactory->createFromOptions($options)); + } +} diff --git a/Factory/Config/Filter/RotateFactory.php b/Factory/Config/Filter/RotateFactory.php new file mode 100644 index 000000000..7dc12beb5 --- /dev/null +++ b/Factory/Config/Filter/RotateFactory.php @@ -0,0 +1,41 @@ +sizeFactory = $sizeFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Scale::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + $dimensions = $this->sizeFactory->createFromOptions($options, 'dim'); + $to = isset($options['to']) ? (float) $options['to'] : null; + + return new Scale($dimensions, $to); + } +} diff --git a/Factory/Config/Filter/StripFactory.php b/Factory/Config/Filter/StripFactory.php new file mode 100644 index 000000000..9eef666d2 --- /dev/null +++ b/Factory/Config/Filter/StripFactory.php @@ -0,0 +1,39 @@ +sizeFactory = $sizeFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Thumbnail::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + $size = $this->sizeFactory->createFromOptions($options); + $mode = $options['mode'] ?? null; + $allowUpscale = $options['allow_upscale'] ?? null; + $filter = $options['filter'] ?? null; + + return new Thumbnail($size, $mode, $allowUpscale, $filter); + } +} diff --git a/Factory/Config/Filter/UpscaleFactory.php b/Factory/Config/Filter/UpscaleFactory.php new file mode 100644 index 000000000..296022490 --- /dev/null +++ b/Factory/Config/Filter/UpscaleFactory.php @@ -0,0 +1,53 @@ +sizeFactory = $sizeFactory; + } + + /** + * {@inheritdoc} + */ + public function getName(): string + { + return Upscale::NAME; + } + + /** + * {@inheritdoc} + */ + public function create(array $options): FilterInterface + { + $min = $this->sizeFactory->createFromOptions($options, 'min'); + $by = isset($options['by']) ? (float) $options['by'] : null; + + return new Upscale($min, $by); + } +} diff --git a/Factory/Config/Filter/WatermarkFactory.php b/Factory/Config/Filter/WatermarkFactory.php new file mode 100644 index 000000000..74e152ebe --- /dev/null +++ b/Factory/Config/Filter/WatermarkFactory.php @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + %liip_imagine.filter_sets% + + + diff --git a/Tests/Config/FilterSetBuilderTest.php b/Tests/Config/FilterSetBuilderTest.php new file mode 100644 index 000000000..8280c49bd --- /dev/null +++ b/Tests/Config/FilterSetBuilderTest.php @@ -0,0 +1,112 @@ +filterSetFactoryMock = $this->createMock(StackFactoryInterface::class); + $this->filterFactoryCollectionMock = $this->createMock(FilterFactoryCollection::class); + $this->model = new StackBuilder($this->filterSetFactoryMock, $this->filterFactoryCollectionMock); + } + + public function testBuildWithEmptyFilters() + { + $name = 'foo'; + $dataLoader = 'bar'; + $quality = 42; + $filters = []; + + $filterSetMock = $this->createMock(StackInterface::class); + + $this->filterSetFactoryMock->expects($this->once()) + ->method('create') + ->with($name, $dataLoader, $quality, $filters) + ->will($this->returnValue($filterSetMock)); + + $this->filterFactoryCollectionMock->expects($this->never()) + ->method('getFilterFactoryByName'); + + $filterSet = $this->model->build($name, [ + 'data_loader' => $dataLoader, + 'quality' => $quality, + 'filters' => $filters, + ]); + $this->assertSame($filterSetMock, $filterSet); + } + + public function testBuildWithFilters() + { + $name = 'foo'; + $dataLoader = 'bar'; + $quality = 42; + + $filterCode = 'foo_filter'; + $filterData = ['foo_data']; + $filters = [ + $filterCode => $filterData, + ]; + + $filterMock = $this->createMock(FilterInterface::class); + $filterFactoryMock = $this->createMock(FilterFactoryInterface::class); + $filterSetMock = $this->createMock(StackInterface::class); + + $filterFactoryMock->expects($this->once()) + ->method('create') + ->with($filterData) + ->will($this->returnValue($filterMock)); + + $this->filterSetFactoryMock->expects($this->once()) + ->method('create') + ->will($this->returnValue($filterSetMock)); + + $this->filterFactoryCollectionMock->expects($this->once()) + ->method('getFilterFactoryByName') + ->with($filterCode) + ->will($this->returnValue($filterFactoryMock)); + + $filterSet = $this->model->build($name, [ + 'data_loader' => $dataLoader, + 'quality' => $quality, + 'filters' => $filters, + ]); + $this->assertSame($filterSetMock, $filterSet); + } +} diff --git a/Tests/Config/FilterSetCollectionTest.php b/Tests/Config/FilterSetCollectionTest.php new file mode 100644 index 000000000..8b82aa51b --- /dev/null +++ b/Tests/Config/FilterSetCollectionTest.php @@ -0,0 +1,41 @@ +createMock(StackInterface::class); + + $stackBuilderMock = $this->createMock(StackBuilderInterface::class); + $stackBuilderMock->expects($this->once()) + ->method('build') + ->with($filterSetName, $filterSetData) + ->will($this->returnValue($filterSetMock)); + + $model = new StackCollection($stackBuilderMock, [$filterSetName => $filterSetData]); + $this->assertSame([$filterSetMock], $model->getStacks()); + $this->assertSame([$filterSetMock], $model->getStacks()); + } +} diff --git a/Tests/Config/FilterSetTest.php b/Tests/Config/FilterSetTest.php new file mode 100644 index 000000000..30c159295 --- /dev/null +++ b/Tests/Config/FilterSetTest.php @@ -0,0 +1,44 @@ +expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Unknown filter provided.'); + + $this->buildFilterSet(['not_a_filter']); + } + + public function testSetFiltersWithValidFilterSuccess() + { + $filterMock = $this->createMock(FilterInterface::class); + $this->buildFilterSet([$filterMock]); + } + + /** + * @param array $filters + */ + private function buildFilterSet(array $filters) + { + new Stack('filter_name', 'data_loader', 42, $filters); + } +}