TildBJ
4/24/2017 - 8:27 PM

Replaces missing image-files within the filesystem of a TYPO3-Instance

Replaces missing image-files within the filesystem of a TYPO3-Instance

// FileRendering in FE
$signalSlotDispatcher->connect(
    \TYPO3\CMS\Core\Resource\ResourceStorage::class,
    \TYPO3\CMS\Core\Resource\Service\FileProcessingService::SIGNAL_PreFileProcess,
    \BjoernBresser\Tyr\Aspect\FileReplaceProcessing::class,
    'processFile'
);
$signalSlotDispatcher->connect(
    \TYPO3\CMS\Core\Resource\ResourceStorage::class,
    \TYPO3\CMS\Core\Resource\ResourceStorage::SIGNAL_PreGeneratePublicUrl,
    \BjoernBresser\Tyr\Aspect\FileReplaceProcessing::class,
    'generatePublicUrl'
);

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\TYPO3\CMS\Core\Resource\Driver\LocalDriver::class] = [
  'className' => \BjoernBresser\Tyr\Aspect\FileReplaceProcessing::class
];
<?php

namespace BjoernBresser\Tyr\Aspect;

/**
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 *
 * (c) 2017 Björn Christopher Bresser, bjoern.bresser@gmail.com
 */


use TYPO3\CMS\Core\Resource\Driver\LocalDriver;
use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\ProcessedFile;
use TYPO3\CMS\Core\Resource\Service\FileProcessingService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;

/**
 * Class FileReplaceProcessing
 *
 * @package BjoernBresser\Tyr\Aspect
 */
class FileReplaceProcessing extends LocalDriver
{

    protected $imageTypes = ['png', 'jpe', 'jpeg', 'jpg', 'gif', 'bmp', 'ico', 'tiff', 'tif', 'svg', 'svgz'];
    protected $videoTypes = ['mp4', 'ovg', 'ogv', 'webm'];

    /**
     * @param FileProcessingService $obj
     * @param LocalDriver $driver
     * @param ProcessedFile $processedFile
     * @param File $fileObject
     * @param string $context
     * @param array $configuration
     */
    public function processFile($obj, $driver, $processedFile, $fileObject, $context, $configuration)
    {
        // Refuse working in Production or Testing context
        if (!GeneralUtility::getApplicationContext()->isDevelopment() && !$GLOBALS['TYPO3_CONF_VARS']['FE']['replaceImages']) {
            return;
        }
        if ($processedFile) {
            $fileMimeType = $processedFile->getOriginalFile()->getExtension();
            if (in_array($fileMimeType, $this->imageTypes)) {
                if (!file_exists(PATH_site . $fileObject->getPublicUrl())) {
                    $dimensions = $this->getImageDimensions($configuration, $fileObject);
                    $this->writeImageFile($fileObject->getPublicUrl(), $dimensions);
                }
            }
        }
    }

    /**
     * @param $obj
     * @param $driver
     * @param File $relativeToCurrentScript
     * @param $urlData
     */
    public function generatePublicUrl($obj, $driver, $relativeToCurrentScript, $urlData) {

        // Refuse working in Production or Testing context
        if (!GeneralUtility::getApplicationContext()->isDevelopment() && !$GLOBALS['TYPO3_CONF_VARS']['FE']['replaceImages']) {
            return;
        }
        $fileMimeType = $relativeToCurrentScript->getProperty('extension');
        if (in_array($fileMimeType, $this->imageTypes)) {
            $identifier = $relativeToCurrentScript->getProperty('identifier');
            $storage = $relativeToCurrentScript->getStorage()->getConfiguration();
            $basePath = $storage['basePath'];
            $fileUrl = $basePath . $identifier;
            if (!file_exists(PATH_site . $fileUrl)) {
                $dimensions = $this->getImageDimensions([], $relativeToCurrentScript);
                $this->writeImageFile($fileUrl, $dimensions);
            }
        }
    }



    /**
     * @param string $fileUrl absoluteUrl
     * @param array $dimensions
     */
    private function writeVideoFile($fileUrl, $extension)
    {
        $url = sprintf("http://clips.vorwaerts-gmbh.de/big_buck_bunny.%s",
            $extension
        );

        $file = file_get_contents($url);
        $path = dirname($fileUrl);

        if (!is_dir($path)) {
            mkdir($path, 0777, true);
            GeneralUtility::fixPermissions($path, true);
        }
        GeneralUtility::writeFile($fileUrl, $file, true);
    }


    /**
     * @param string $fileUrl
     * @param array $dimensions
     */
    private function writeImageFile($fileUrl, $dimensions)
    {
        // @todo: Create Image with Imagemagic/GraphicMagic
        $url = sprintf("https://placeholdit.imgix.net/~text?txtsize=%d&txt=%dx%d&w=%d&h=%d",
            $dimensions['txtsize'], $dimensions['width'], $dimensions['height'], $dimensions['width'], $dimensions['height']
        );

        $file = file_get_contents($url);
        $path = dirname($fileUrl);

        if (!is_dir($path)) {
            mkdir($path, 0777, true);
            GeneralUtility::fixPermissions($path, true);
        }
        GeneralUtility::writeFile(PATH_site . $fileUrl, $file, true);
    }

    /**
     * @param array $configuration
     * @param File $fileObject
     * @return array
     */
    private function getImageDimensions($configuration, $fileObject)
    {
        $height = $width = 500;

        // Check Configuration
        if ($configuration['width']) {
            $width = $configuration['width'];
            $height = $configuration['height'];
        } else if ($fileObject->getProperty('width')) {
            $width = $fileObject->getProperty('width');
            $height = $fileObject->getProperty('height');
        }

        return [
            'height' => $height,
            'width' => $width,
            'txtsize' => $height / 10
        ];
    }


    /**
     * Returns information about a file.
     *
     * @param string $fileIdentifier In the case of the LocalDriver, this is the (relative) path to the file.
     * @param array $propertiesToExtract Array of properties which should be extracted, if empty all will be extracted
     * @return array
     * @throws \InvalidArgumentException
     */
    public function getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract = array()) {
        $absoluteFilePath = $this->getAbsolutePath($fileIdentifier);
        $extension = pathinfo($fileIdentifier, PATHINFO_EXTENSION);
        if (in_array($extension, $this->videoTypes)) {
            if (!file_exists($absoluteFilePath)) {
                $this->writeVideoFile($absoluteFilePath, $extension);
            }
        } elseif (in_array($extension, $this->imageTypes)) {

        }
        parent::getFileInfoByIdentifier($fileIdentifier, $propertiesToExtract = []);
    }

}