Skip to content

Commit

Permalink
NEW File converter API
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Apr 4, 2024
1 parent 0cee400 commit 77f5ebf
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/Conversion/FileConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace SilverStripe\Assets\Conversion;

use SilverStripe\Assets\Storage\DBFile;

interface FileConverter
{
/**
* Checks whether this converter supports a conversion from one file type to another.
*
* @param DBFile|string $from A DBFile instance or specific file extension
* @param array $options Any options defined for this converter which should apply to the conversion
*/
public function supports(DBFile|string $from, string $toExtension, array $options = []): bool;

/**
* Converts the given DBFile instance to another file type.
*
* @param array $options Any options defined for this converter which should apply to the conversion
*/
public function convert(DBFile $original, string $toExtension, array $options = []): DBFile;
}
71 changes: 71 additions & 0 deletions src/Conversion/InterventionImageConverter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace SilverStripe\Assets\Conversion;

use SilverStripe\Assets\Image_Backend;
use SilverStripe\Assets\InterventionBackend;
use SilverStripe\Assets\Storage\AssetStore;
use SilverStripe\Assets\Storage\DBFile;
use SilverStripe\Core\Injector\Injector;

/**
* Image converter powered by the Intervention Image library, assuming you haven't swapped out the ImageBackend implementation.
*/
class InterventionImageConverter implements FileConverter
{
public function supports(DBFile|string $from, string $toExtension, array $options = []): bool
{
// If backend is not InterventionBackend, return false
// GD and Imagick support different things so be dynamic between those
if ($from instanceof DBFile) {
$backend = $from->getImageBackend();
$from = $from->getExtension() ?: $from->getMimeType();
} else {
$backend = Injector::inst()->get(Image_Backend::class);
}
// This converter requires intervention image
if (!is_a($backend, InterventionBackend::class)) {
return false;
}
/** @var InterventionBackend $backend */
$driver = $backend->getImageManager()->config['driver'] ?? null;
switch ($driver) {
case 'gd':
return $this->supportedByGd($from, $toExtension);
case 'imagick':
return $this->supportedByImagick($from, $toExtension);
// If the driver is somehow not GD or Imagick, we have no way to know what it might support
default:
return false;
}
// We shouldn't get here, but if we do, we clearly don't know what's going on and therefore can't support it
return false;
}

public function convert(DBFile $original, string $toExtension, array $options = []): DBFile
{
// TODO allow swapping quality
// TODO find any other options intervention supports
return $original->manipulateExtension(
$toExtension,
function (AssetStore $store, string $filename, string $hash, string $variant) use ($original) {
$backend = $original->getImageBackend();
$config = ['conflict' => AssetStore::CONFLICT_USE_EXISTING];
$tuple = $backend->writeToStore($store, $filename, $hash, $variant, $config);
return [$tuple, $backend];
}
);
}

private function supportedByGd(string $from, string $to): bool
{
// TODO: Follow the logic in AbstractEncoder::process() and the various methods in Encoder
return false;
}

private function supportedByImagick(string $from, string $to): bool
{
// TODO: Follow the logic in AbstractEncoder::process() and the various methods in Encoder
return false;
}
}

0 comments on commit 77f5ebf

Please sign in to comment.