Skip to content

Instantly share code, notes, and snippets.

@michaelfeinbier
Last active September 27, 2019 15:30
Show Gist options
  • Select an option

  • Save michaelfeinbier/5a6a4ff2c7ea82a08ff5c3c8671e93ad to your computer and use it in GitHub Desktop.

Select an option

Save michaelfeinbier/5a6a4ff2c7ea82a08ff5c3c8671e93ad to your computer and use it in GitHub Desktop.
*Use Kraken.IO with TYPO3* - This post-processes every image generated by the frontend and stored in /_processed_/ regardless of the used StorageDriver - however, if the image could not be processed by Kraken.IO the processed image will remain untouched
/** @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher $signalSlotDispatcher */
$signalSlotDispatcher = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\SignalSlot\Dispatcher::class);
$signalSlotDispatcher->connect(
\TYPO3\CMS\Core\Resource\ResourceStorage::class,
\TYPO3\CMS\Core\Resource\Service\FileProcessingService::SIGNAL_PostFileProcess,
\Dnp\DnpPlugins\ImageProcessing\KrakenIoPostProcessor::class,
'process'
);
<?php
namespace Dnp\DnpPlugins\ImageProcessing;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\Resource;
use TYPO3\CMS\Core\Resource\Processing\ImageCropScaleMaskTask;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* This post-processor slots in the FileProcessingService and optimizes the image generated by ImageMagick
* with the Kraken.IO API right after a new /_processed_/* file is generated by TYPO3.
*
* @author Michael Feinbier <[email protected]>
**/
class KrakenIoPostProcessor
{
/**
* @var \TYPO3\CMS\Core\Log\Logger
*/
protected $logger;
/**
* @var RequestFactory
*/
protected $requestFactory;
/**
* @var \Kraken
*/
protected $krakenApi;
public function __construct()
{
/** @var $logManager LogManager */
$logManager = GeneralUtility::makeInstance(LogManager::class);
$this->logger = $logManager->getLogger(__CLASS__);
$this->requestFactory = GeneralUtility::makeInstance(RequestFactory::class);
// Load API Credentials from Extension Configuration
$apiCredentials = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['dnp_plugins']);
$this->krakenApi = GeneralUtility::makeInstance(\Kraken::class, $apiCredentials['apiKey'], $apiCredentials['apiSecret']);
}
/**
* Post Process the image after the ImageCropScaleMaskTask generated a new image
*
* @param Resource\Service\FileProcessingService $fileProcessingService
* @param Resource\Driver\DriverInterface $driver
* @param Resource\ProcessedFile $processedFile
* @param Resource\FileInterface $fileObject
* @param string $taskType
* @param array $configuration
*/
public function process(
Resource\Service\FileProcessingService $fileProcessingService,
Resource\Driver\DriverInterface $driver,
Resource\ProcessedFile $processedFile,
Resource\FileInterface $fileObject,
$taskType,
$configuration
) {
// for now - we only process ImageCropScaleMaskTask
$task = $processedFile->getTask();
if (!$task instanceof ImageCropScaleMaskTask) {
return;
}
// when a new image was generated, fetch a new updated image
if ($task->isExecuted() && $task->isSuccessful() && $processedFile->isProcessed()) {
$url = $this->getOptimizedImage($task->getTargetFile());
if ($url) {
$this->saveOptimizedFile($url, $processedFile);
$task->setExecuted(true);
}
}
}
/**
* @param Resource\FileInterface $file
*
* @return string|bool
*/
protected function getOptimizedImage(Resource\FileInterface $file)
{
// @TODO maybe use $api->url() together with $file->getPublicUrl()
$result = $this->krakenApi->upload([
'lossy' => true,
'wait' => true,
'dev' => false,
'file' => $file->getForLocalProcessing(false),
]);
if ($result['success']) {
$this->logger->debug('kraken compress successful', $result);
return $result['kraked_url'];
}
$this->logger->error('kraken error', $result);
return false;
}
/**
* @param string $url
* @param Resource\ProcessedFile $targetFile
*/
protected function saveOptimizedFile($url, Resource\ProcessedFile $targetFile)
{
$tempFile = GeneralUtility::tempnam('kraken');
$this->requestFactory->request($url, 'GET', [
'sink' => $tempFile,
]);
$targetFile->updateWithLocalFile($tempFile);
unlink($tempFile);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment