126 lines
5.4 KiB
PHP
126 lines
5.4 KiB
PHP
<?php
|
|
/*************************************************************************************/
|
|
/* This file is part of the Thelia package. */
|
|
/* */
|
|
/* Copyright (c) OpenStudio */
|
|
/* email : dev@thelia.net */
|
|
/* web : http://www.thelia.net */
|
|
/* */
|
|
/* For the full copyright and license information, please view the LICENSE.txt */
|
|
/* file that was distributed with this source code. */
|
|
/*************************************************************************************/
|
|
namespace Thelia\Action;
|
|
|
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
|
use Thelia\Core\Event\Document\DocumentEvent;
|
|
use Thelia\Core\Event\TheliaEvents;
|
|
use Thelia\Exception\DocumentException;
|
|
use Thelia\Model\ConfigQuery;
|
|
use Thelia\Tools\URL;
|
|
|
|
/**
|
|
*
|
|
* Document management actions. This class handles document processing an caching.
|
|
*
|
|
* Basically, documents are stored outside the web space (by default in local/media/documents),
|
|
* and cached in the web space (by default in web/local/documents).
|
|
*
|
|
* In the documents caches directory, a subdirectory for documents categories (eg. product, category, folder, etc.) is
|
|
* automatically created, and the cached document is created here. Plugin may use their own subdirectory as required.
|
|
*
|
|
* The cached document name contains a hash of the processing options, and the original (normalized) name of the document.
|
|
*
|
|
* A copy (or symbolic link, by default) of the original document is always created in the cache, so that the full
|
|
* resolution document is always available.
|
|
*
|
|
* If a problem occurs, an DocumentException may be thrown.
|
|
*
|
|
* @package Thelia\Action
|
|
* @author Franck Allimant <franck@cqfdev.fr>
|
|
*
|
|
*/
|
|
class Document extends BaseCachedFile implements EventSubscriberInterface
|
|
{
|
|
/**
|
|
* @var string Config key for document delivery mode
|
|
*/
|
|
const CONFIG_DELIVERY_MODE = 'original_document_delivery_mode';
|
|
|
|
/**
|
|
* @return string root of the document cache directory in web space
|
|
*/
|
|
protected function getCacheDirFromWebRoot()
|
|
{
|
|
return ConfigQuery::read('document_cache_dir_from_web_root', 'cache' . DS . 'documents');
|
|
}
|
|
|
|
/**
|
|
* Process document and write the result in the document cache.
|
|
*
|
|
* When the original document is required, create either a symbolic link with the
|
|
* original document in the cache dir, or copy it in the cache dir if it's not already done.
|
|
*
|
|
* This method updates the cache_file_path and file_url attributes of the event
|
|
*
|
|
* @param DocumentEvent $event Event
|
|
*
|
|
* @throws \Thelia\Exception\DocumentException
|
|
* @throws \InvalidArgumentException , DocumentException
|
|
*/
|
|
public function processDocument(DocumentEvent $event)
|
|
{
|
|
$subdir = $event->getCacheSubdirectory();
|
|
$sourceFile = $event->getSourceFilepath();
|
|
|
|
if (null == $subdir || null == $sourceFile) {
|
|
throw new \InvalidArgumentException("Cache sub-directory and source file path cannot be null");
|
|
}
|
|
|
|
$originalDocumentPathInCache = $this->getCacheFilePath($subdir, $sourceFile, true);
|
|
|
|
if (! file_exists($originalDocumentPathInCache)) {
|
|
if (! file_exists($sourceFile)) {
|
|
throw new DocumentException(sprintf("Source document file %s does not exists.", $sourceFile));
|
|
}
|
|
|
|
$mode = ConfigQuery::read(self::CONFIG_DELIVERY_MODE, 'symlink');
|
|
|
|
if ($mode == 'symlink') {
|
|
if (false === symlink($sourceFile, $originalDocumentPathInCache)) {
|
|
throw new DocumentException(sprintf("Failed to create symbolic link for %s in %s document cache directory", basename($sourceFile), $subdir));
|
|
}
|
|
} else {
|
|
// mode = 'copy'
|
|
if (false === @copy($sourceFile, $originalDocumentPathInCache)) {
|
|
throw new DocumentException(sprintf("Failed to copy %s in %s document cache directory", basename($sourceFile), $subdir));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Compute the document URL
|
|
$documentUrl = $this->getCacheFileURL($subdir, basename($originalDocumentPathInCache));
|
|
|
|
// Update the event with file path and file URL
|
|
$event->setDocumentPath($documentUrl);
|
|
$event->setDocumentUrl(URL::getInstance()->absoluteUrl($documentUrl, null, URL::PATH_TO_FILE, $this->cdnBaseUrl));
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public static function getSubscribedEvents()
|
|
{
|
|
return array(
|
|
TheliaEvents::DOCUMENT_PROCESS => array("processDocument", 128),
|
|
|
|
// Implemented in parent class BaseCachedFile
|
|
TheliaEvents::DOCUMENT_CLEAR_CACHE => array("clearCache", 128),
|
|
TheliaEvents::DOCUMENT_DELETE => array("deleteFile", 128),
|
|
TheliaEvents::DOCUMENT_SAVE => array("saveFile", 128),
|
|
TheliaEvents::DOCUMENT_UPDATE => array("updateFile", 128),
|
|
TheliaEvents::DOCUMENT_UPDATE_POSITION => array("updatePosition", 128),
|
|
TheliaEvents::DOCUMENT_TOGGLE_VISIBILITY => array("toggleVisibility", 128),
|
|
);
|
|
}
|
|
}
|