Skip to content

Commit

Permalink
Allow specifying file visibility when creating variants
Browse files Browse the repository at this point in the history
  • Loading branch information
frasmage committed Dec 11, 2021
1 parent 8bc6efb commit d708b89
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 10 deletions.
30 changes: 21 additions & 9 deletions docs/source/variants.rst
Expand Up @@ -102,27 +102,39 @@ Output Destination

By default, variants will be created in the same disk and directory as the original file, with a filename that includes the variant name as as suffix. You can choose to customize the output disk, directory and filename.

..
::

<?php
$manipulator->toDisk('uploads');
$manipulator->toDirectory('files/variants');
$manipulation->toDisk('uploads');
$manipulation->toDirectory('files/variants');

// shorthand for the above
$manipulator->toDestination('uploads', 'files/variants');
$manipulation->toDestination('uploads', 'files/variants');

$manipulator->useFilename('my-custom-filename');
$manipulator->useHashForFilename();
$manipulator->useOriginalFilename(); //restore default behaviour
$manipulation->useFilename('my-custom-filename');
$manipulation->useHashForFilename();
$manipulation->useOriginalFilename(); //restore default behaviour

If another file exists at the output destination, the ImageManipulator will attempt to find a unique filename by appending an incrementing number. This can be configured to throw an exception instead if a conflict is discovered.

::

<?php
$manipulator->onDuplicateIncrement(); // default behaviour
$manipulator->onDuplicateError();
$manipulation->onDuplicateIncrement(); // default behaviour
$manipulation->onDuplicateError();

File Visibility
^^^^^^^^^^^^^^^

By default, newly created variants will use the default filesystem visibility of the destination filesystem disk. To modify this, you may use one of the following methods.

::

<?php
$manipulation->makePrivate();
$manipulation->makePublic();
// to copy the visibility of the original media file
$manipulation->matchOriginalVisibility();

Before Save Callback
^^^^^^^^^^^^^^^^^^^^
Expand Down
32 changes: 32 additions & 0 deletions src/ImageManipulation.php
Expand Up @@ -58,6 +58,9 @@ class ImageManipulation
/** @var string */
private $onDuplicateBehaviour = self::ON_DUPLICATE_INCREMENT;

/** @var string|null */
private $visibility;

/** @var callable|null */
private $beforeSave;

Expand Down Expand Up @@ -322,6 +325,35 @@ public function getOnDuplicateBehaviour(): string
return $this->onDuplicateBehaviour;
}

public function makePrivate(): self
{
$this->visibility = 'private';
return $this;
}

public function makePublic(): self
{
$this->visibility = 'public';
return $this;
}

public function matchOriginalVisibility(): self
{
$this->visibility = 'match';
return $this;
}

public function setVisibility(?string $visibility): self
{
$this->visibility = $visibility;
return $this;
}

public function getVisibility(): ?string
{
return $this->visibility;
}

/**
* @param callable $beforeSave
* @return $this
Expand Down
15 changes: 14 additions & 1 deletion src/ImageManipulator.php
Expand Up @@ -134,8 +134,21 @@ public function createImageVariant(
->delete($originalVariant->getDiskPath());
}

$visibility = $manipulation->getVisibility();
if ($visibility == 'match') {
$visibility = ($media->isVisible() ? 'public' : 'private');
}
$options = [];
if ($visibility) {
$options = ['visibility' => $visibility];
}

$this->filesystem->disk($variant->disk)
->writeStream($variant->getDiskPath(), $outputStream->detach());
->writeStream(
$variant->getDiskPath(),
$outputStream->detach(),
$options
);

$variant->save();

Expand Down
27 changes: 27 additions & 0 deletions tests/Integration/ImageManipulationTest.php
Expand Up @@ -106,4 +106,31 @@ public function test_get_duplicate_behaviours()
$manipulation->getOnDuplicateBehaviour()
);
}

public function test_visibility()
{
$manipulation = new ImageManipulation($this->getMockCallable());
$this->assertNull($manipulation->getVisibility());

$manipulation->makePublic();
$this->assertEquals('public', $manipulation->getVisibility());

$manipulation->makePrivate();
$this->assertEquals('private', $manipulation->getVisibility());

$manipulation->matchOriginalVisibility();
$this->assertEquals('match', $manipulation->getVisibility());

$manipulation->setVisibility('public');
$this->assertEquals('public', $manipulation->getVisibility());

$manipulation->setVisibility('private');
$this->assertEquals('private', $manipulation->getVisibility());

$manipulation->setVisibility('match');
$this->assertEquals('match', $manipulation->getVisibility());

$manipulation->setVisibility(null);
$this->assertNull($manipulation->getVisibility());
}
}
48 changes: 48 additions & 0 deletions tests/Integration/ImageManipulatorTest.php
Expand Up @@ -580,6 +580,54 @@ function (Image $image) {
$this->assertFalse($previousVariant->fileExists());
}

public function visibilityProvider()
{
return [
['uploads', 'public', null, true],
['uploads', 'private', null, true],
['tmp', 'public', null, false],
['tmp', 'private', null, false],
['tmp', 'public', 'match', true],
['tmp', 'private', 'match', false],
['tmp', 'public', 'private', false],
['tmp', 'private', 'public', true]
];
}

/** @dataProvider visibilityProvider */
public function test_variant_created_with_visibility(
string $disk,
string $originalVisibility,
?string $manipulationVisibility,
bool $expectedVisibility
) {
$this->useFilesystem($disk);
$this->useDatabase();

$media = $this->makeMedia(
[
'disk' => $disk,
'directory' => 'foo',
'filename' => 'bar',
'extension' => 'png',
'mime_type' => 'image/png',
'aggregate_type' => 'image'
]
);
$this->seedFileForMedia($media, $this->sampleFile());
$originalVisibility == 'public' ? $media->makePublic() : $media->makePrivate();

$manipulation = ImageManipulation::make($this->getMockCallable())
->setVisibility($manipulationVisibility)
->toDisk($disk);

$imageManipulator = $this->getManipulator();
$imageManipulator->defineVariant('test', $manipulation);

$result = $imageManipulator->createImageVariant($media, 'test', true);
$this->assertSame($expectedVisibility, $result->isVisible());
}

public function getManipulator(): ImageManipulator
{
return new ImageManipulator(
Expand Down

0 comments on commit d708b89

Please sign in to comment.