Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 35 additions & 25 deletions src/ImageManipulator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ImageManipulator
/**
* @var ImageManipulation[]
*/
private $variantManipulations = [];
private $variantDefinitions = [];

/**
* @var FilesystemManager
Expand All @@ -30,26 +30,43 @@ public function __construct(ImageManager $imageManager, FilesystemManager $files
$this->filesystem = $filesystem;
}

public function addVariantManipulation(
public function defineVariant(
string $variantName,
ImageManipulation $manipulation
) {
$this->variantManipulations[$variantName] = $manipulation;
$this->variantDefinitions[$variantName] = $manipulation;
}

public function hasVariantDefinition(string $variantName): bool
{
return isset($this->variantDefinitions[$variantName]);
}

/**
* @param string $variantName
* @return ImageManipulation
* @throws ImageManipulationException if Variant is not defined
*/
public function getVariantDefinition(string $variantName): ImageManipulation
{
if (isset($this->variantDefinitions[$variantName])) {
return $this->variantDefinitions[$variantName];
}

throw ImageManipulationException::unknownVariant($variantName);
}

/**
* @param ImageManipulation $manipulation
* @param Media $media
* @return StreamInterface
* @param string $variantName
* @return Media
* @throws ImageManipulationException
*/
public function createVariant(string $variantName, Media $media): Media
public function createImageVariant(Media $media, string $variantName): Media
{
if ($media->aggregate_type != Media::TYPE_IMAGE) {
throw ImageManipulationException::invalidMediaType($media->aggregate_type);
}
$this->validateMedia($media);

$manipulation = $this->getVariantManipulation($variantName);
$manipulation = $this->getVariantDefinition($variantName);

$outputFormat = $this->determineOutputFormat($manipulation, $media);
$image = $this->imageManager->make($media->stream());
Expand Down Expand Up @@ -89,20 +106,6 @@ public function createVariant(string $variantName, Media $media): Media
return $newMedia;
}

/**
* @param string $variantName
* @return ImageManipulation
* @throws ImageManipulationException
*/
private function getVariantManipulation(string $variantName): ImageManipulation
{
if (isset($this->variantManipulations[$variantName])) {
return $this->variantManipulations[$variantName];
}

throw ImageManipulationException::unknownVariant($variantName);
}

private function getMimeTypeForOutputFormat(string $outputFormat): string
{
return ImageManipulation::MIME_TYPE_MAP[$outputFormat];
Expand All @@ -112,7 +115,7 @@ private function getMimeTypeForOutputFormat(string $outputFormat): string
* @param ImageManipulation $manipulation
* @param Media $media
* @return string
* @throws ImageManipulationException
* @throws ImageManipulationException If output format cannot be determined
*/
private function determineOutputFormat(
ImageManipulation $manipulation,
Expand Down Expand Up @@ -143,4 +146,11 @@ private function determineOutputFormat(

throw ImageManipulationException::unknownOutputFormat();
}

public function validateMedia(Media $media)
{
if ($media->aggregate_type != Media::TYPE_IMAGE) {
throw ImageManipulationException::invalidMediaType($media->aggregate_type);
}
}
}
86 changes: 86 additions & 0 deletions src/Jobs/CreateImageVariants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

namespace Plank\Mediable\Jobs;

use Carbon\Traits\Serialization;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Plank\Mediable\Exceptions\ImageManipulationException;
use Plank\Mediable\ImageManipulator;
use Plank\Mediable\Media;

class CreateImageVariants implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, Serialization;

/**
* @var string[]
*/
private $variantNames;
/**
* @var Media
*/
private $model;

/**
* CreateImageVariants constructor.
* @param Media $model
* @param string|string[] $variantNames
* @throws ImageManipulationException
*/
public function __construct(Media $model, $variantNames)
{
$variantNames = (array) $variantNames;
$this->validate($model, $variantNames);

$this->variantNames = $variantNames;
$this->model = $model;
}

public function handle()
{
foreach ($this->getVariantNames() as $variantName) {
$this->getImageManipulator()->createImageVariant(
$this->getModel(),
$variantName
);
}
}

/**
* @return string[]
*/
public function getVariantNames(): array
{
return $this->variantNames;
}

/**
* @return Media
*/
public function getModel(): Media
{
return $this->model;
}

/**
* @param Media $model
* @param array $variantNames
* @throws ImageManipulationException
*/
private function validate(Media $media, array $variantNames): void
{
$imageManipulator = $this->getImageManipulator();
$imageManipulator->validateMedia($media);
foreach ($variantNames as $variantName) {
$imageManipulator->getVariantDefinition($variantName);
}
}

private function getImageManipulator(): ImageManipulator
{
return app(ImageManipulator::class);
}
}
55 changes: 0 additions & 55 deletions src/Jobs/ProcessImageVariant.php

This file was deleted.

5 changes: 5 additions & 0 deletions src/Media.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ public function getAllVariantsAndSelf(): Collection
return $collection;
}

public function hasVariant(string $variantName): bool
{
return $this->findVariant($variantName) !== null;
}

public function findVariant(string $variantName): ?Media
{
$filter = function (Media $media) use ($variantName) {
Expand Down
41 changes: 26 additions & 15 deletions tests/Integration/ImageManipulatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,36 @@

class ImageManipulatorTest extends TestCase
{
public function test_it_sets_and_has_variants()
{
$manipulator = $this->getManipulator();
$this->assertFalse($manipulator->hasVariantDefinition('foo'));
$manipulator->defineVariant(
'foo',
new ImageManipulation($this->getMockCallable())
);
$this->assertTrue($manipulator->hasVariantDefinition('foo'));
}

public function test_it_throws_for_non_image_media()
{
$this->expectException(ImageManipulationException::class);
$this->expectErrorMessage(
"Cannot manipulate media with an aggregate type other than 'image', got 'document'."
);
$this->getManipulator()->createVariant(
'variant',
$this->makeMedia(['aggregate_type' => 'document'])
$this->getManipulator()->createImageVariant(
$this->makeMedia(['aggregate_type' => 'document']),
'variant'
);
}

public function test_it_throws_for_unknown_variants()
{
$this->expectException(ImageManipulationException::class);
$this->expectErrorMessage("Unknown variant 'invalid'.");
$this->getManipulator()->createVariant(
'invalid',
$this->makeMedia(['aggregate_type' => 'image'])
$this->getManipulator()->createImageVariant(
$this->makeMedia(['aggregate_type' => 'image']),
'invalid'
);
}

Expand All @@ -54,8 +65,8 @@ function (Image $image) {
);
$this->seedFileForMedia($media);
$manipulator = $this->getManipulator();
$manipulator->addVariantManipulation('foo', $manipulation);
$manipulator->createVariant('foo', $media);
$manipulator->defineVariant('foo', $manipulation);
$manipulator->createImageVariant($media, 'foo');
}

public function test_it_can_create_a_variant()
Expand All @@ -75,7 +86,7 @@ public function test_it_can_create_a_variant()
);
$this->seedFileForMedia($media, $this->sampleFile());

$beforeSave = $this->getMockCallback();
$beforeSave = $this->getMockCallable();
$beforeSave->expects($this->once())
->method('__invoke')
->with(
Expand All @@ -95,8 +106,8 @@ function (Image $image) {
)->beforeSave($beforeSave);

$imageManipulator = $this->getManipulator();
$imageManipulator->addVariantManipulation('test', $manipulation);
$result = $imageManipulator->createVariant('test', $media);
$imageManipulator->defineVariant('test', $manipulation);
$result = $imageManipulator->createImageVariant($media, 'test');

$this->assertTrue($result->exists);
$this->assertEquals('tmp', $result->disk);
Expand Down Expand Up @@ -137,8 +148,8 @@ function (Image $image) {
);

$imageManipulator = $this->getManipulator();
$imageManipulator->addVariantManipulation('test', $manipulation);
$result = $imageManipulator->createVariant('test', $media);
$imageManipulator->defineVariant('test', $manipulation);
$result = $imageManipulator->createImageVariant($media, 'test');

$this->assertEquals('test', $result->variant_name);
$this->assertEquals(19, $result->original_media_id);
Expand Down Expand Up @@ -183,8 +194,8 @@ function (Image $image) {
)->setOutputFormat($format)->setOutputQuality($quality);

$imageManipulator = $this->getManipulator();
$imageManipulator->addVariantManipulation('test', $manipulation);
$result = $imageManipulator->createVariant('test', $media);
$imageManipulator->defineVariant('test', $manipulation);
$result = $imageManipulator->createImageVariant($media, 'test');

$this->assertEquals($format, $result->extension);
$this->assertEquals($mime, $result->mime_type);
Expand Down
34 changes: 34 additions & 0 deletions tests/Integration/Jobs/CreateImageVariantsTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

namespace Plank\Mediable\Tests\Integration\Jobs;

use Plank\Mediable\ImageManipulation;
use Plank\Mediable\ImageManipulator;
use Plank\Mediable\Jobs\CreateImageVariants;
use Plank\Mediable\Tests\TestCase;

class CreateImageVariantsTest extends TestCase
{
public function test_it_will_trigger_image_manipulation()
{
$model = $this->makeMedia(['aggregate_type' => 'image']);
$variant1 = 'foo';
$variant2 = 'bar';

$manipulator = $this->createMock(ImageManipulator::class);
$manipulator->expects($this->once())
->method('validateMedia')
->with($model);
$manipulator->expects($this->exactly(2))
->method('getVariantDefinition')
->withConsecutive([$variant1], [$variant2])
->willReturn($this->createMock(ImageManipulation::class));
$manipulator->expects($this->exactly(2))
->method('createImageVariant')
->withConsecutive([$model, $variant1], [$model, $variant2]);
app()->instance(ImageManipulator::class, $manipulator);

$job = new CreateImageVariants($model, [$variant1, $variant2]);
$job->handle();
}
}
Loading