View source
<?php
namespace Drupal\minisite;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\file\FileInterface;
use Drupal\minisite\Exception\ArchiveException;
use Drupal\minisite\Exception\AssetException;
use Drupal\minisite\Exception\InvalidContentArchiveException;
use Drupal\minisite\Exception\InvalidFormatArchiveException;
use Drupal\minisite\Exception\MissingArchiveException;
class Minisite implements MinisiteInterface {
protected $archiveFile;
protected $description;
protected $entityType;
protected $entityBundle;
protected $entityId;
protected $entityLanguage;
protected $fieldName;
protected $aliasPrefix;
protected $assetContainer;
protected $allowedExtensions;
public function __construct(EntityInterface $entity, $field_name, FileInterface $archive_file, $allowed_extensions = MinisiteInterface::ALLOWED_EXTENSIONS) {
$this->entityType = $entity
->getEntityTypeId();
$this->entityBundle = $entity
->bundle();
$this->entityId = $entity
->id();
$this->entityLanguage = $entity
->language()
->getId();
$this->fieldName = $field_name;
$this->allowedExtensions = $allowed_extensions;
$this
->setArchiveFile($archive_file);
$this->description = '';
}
public static function createInstance(FieldItemListInterface $items) {
$archive_file = $items->entity;
if (!$archive_file) {
return NULL;
}
$field_definition = $items
->getFieldDefinition();
try {
$entity = $items
->getEntity();
$description = '';
$parent_alias = '';
if (!empty($items
->get(0))) {
$description = $items
->get(0)->description;
$value = $items
->get(0)
->getValue();
$entity_alias = self::getEntityPathAlias($entity);
if (!empty($value['options']['alias_status']) && !empty($entity_alias)) {
$parent_alias = $entity_alias;
}
}
$instance = new self($entity, $field_definition
->getName(), $archive_file, $field_definition
->getSetting('minisite_extensions'));
if (!empty($description)) {
$instance
->setDescription($description);
}
if (!empty($parent_alias)) {
$instance
->setAlias($parent_alias);
}
} catch (ArchiveException $exception) {
$instance = NULL;
}
return $instance;
}
public function getArchiveFile() {
return $this->archiveFile;
}
public function setArchiveFile(FileInterface $file) {
static::validateArchive($file, $this->allowedExtensions);
$this->archiveFile = $file;
$this
->processArchive();
}
public function setAlias($alias_prefix) {
$this->aliasPrefix = $alias_prefix;
if (isset($this->assetContainer)) {
$this->assetContainer
->updateAliases($alias_prefix);
}
}
public function getDescription() {
return $this->description;
}
public function setDescription($description) {
$this->description = $description;
}
public function getIndexAssetUrl() {
$asset = $this->assetContainer
->getIndexAsset();
if (empty($asset)) {
throw new InvalidContentArchiveException([
sprintf('Missing index file %s', AssetInterface::INDEX_FILE),
]);
}
return $asset
->getUrl();
}
public function getIndexAssetUri() {
$uri = $this->assetContainer
->getIndexAssetUri();
if (empty($uri)) {
throw new InvalidContentArchiveException([
sprintf('Missing index file %s', AssetInterface::INDEX_FILE),
]);
}
return $uri;
}
protected function processArchive() {
$asset_directory = $this
->prepareAssetDirectory();
$files = LegacyWrapper::scanDirectory($asset_directory, '/.*/');
if (!$files) {
$archiver = self::getArchiver($this->archiveFile
->getFileUri());
$archiver
->listContents();
$archiver
->extract($asset_directory);
$files = LegacyWrapper::scanDirectory($asset_directory, '/.*/');
}
$this->assetContainer = new AssetContainer();
foreach (array_keys($files) as $file_uri) {
$this->assetContainer
->add($this->entityType, $this->entityBundle, $this->entityId, $this->entityLanguage, $this->fieldName, $file_uri);
}
if (!empty($this->aliasPrefix)) {
$this->assetContainer
->updateAliases($this->aliasPrefix);
}
}
public function save() {
$this->assetContainer
->saveAll();
}
public function delete() {
$this->assetContainer
->deleteAll();
$this->archiveFile
->delete();
$this->archiveFile = NULL;
}
public static function validateArchive(FileInterface $file, $content_extensions) {
if (!is_readable($file
->getFileUri())) {
throw new MissingArchiveException($file
->getFileUri());
}
FileValidator::validateFileExtension($file
->getFilename(), static::supportedArchiveExtensions());
$archiver = self::getArchiver($file
->getFileUri(), $file
->getFilename());
if (!$archiver) {
throw new InvalidFormatArchiveException($file
->getFilename());
}
try {
$files = $archiver
->listContents();
} catch (\Exception $exception) {
throw new InvalidFormatArchiveException($file
->getFilename());
}
ArchiveValidator::validate($files, $content_extensions);
}
public static function getCommonArchiveDir() {
return \Drupal::config('system.file')
->get('default_scheme') . '://' . MinisiteInterface::ARCHIVE_UPLOAD_DIR;
}
public static function getCommonAssetDir() {
return \Drupal::config('system.file')
->get('default_scheme') . '://' . MinisiteInterface::ASSET_DIR;
}
public static function supportedArchiveExtensions() {
return explode(' ', MinisiteInterface::SUPPORTED_ARCHIVE_EXTENSIONS);
}
public function getCacheTags() {
return $this->archiveFile
->getCacheTags();
}
protected static function getEntityPathAlias(EntityInterface $entity) {
if ($entity
->hasField('path')) {
$path_items = $entity->path
->get(0)
->getValue();
}
return !empty($path_items) && !empty($path_items['alias']) ? $entity
->toUrl()
->toString() : '';
}
protected function prepareAssetDirectory() {
$fs = \Drupal::service('file_system');
$dir = $this
->getAssetDirectory();
if (!file_exists($dir)) {
if (!$fs
->prepareDirectory($dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
throw new AssetException(sprintf('Unable to prepare asset directory "%s"', $dir));
}
}
return $dir;
}
public function getAssetDirectory() {
$suffix = $this->archiveFile
->get('uuid')->value;
return self::getCommonAssetDir() . DIRECTORY_SEPARATOR . $suffix;
}
protected static function getArchiver($uri, $filename = NULL) {
$fs = \Drupal::service('file_system');
$filename_real = $fs
->realpath($uri);
$filename = $filename ? $filename : $fs
->basename($uri);
try {
$archiver = \Drupal::getContainer()
->get('plugin.manager.minisite_archiver')
->getInstance([
'filepath' => $filename_real,
'filename' => $filename,
]);
} catch (\Exception $exception) {
return NULL;
}
return $archiver;
}
}