View source
<?php
namespace Drupal\dropzonejs;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Utility\Token;
use Drupal\file\FileInterface;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesserInterface;
use Drupal\Core\File\FileSystemInterface;
class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
use StringTranslationTrait;
protected $entityTypeManager;
protected $mimeTypeGuesser;
protected $fileSystem;
protected $logger;
protected $renderer;
protected $configFactory;
protected $token;
protected $messenger;
protected $streamWrapperManager;
public function __construct(EntityTypeManagerInterface $entity_type_manager, MimeTypeGuesserInterface $mimetype_guesser, FileSystemInterface $file_system, LoggerChannelFactoryInterface $logger_factory, RendererInterface $renderer, ConfigFactoryInterface $config_factory, Token $token, MessengerInterface $messenger, StreamWrapperManagerInterface $stream_wrapper_manager) {
$this->entityTypeManager = $entity_type_manager;
$this->mimeTypeGuesser = $mimetype_guesser;
$this->fileSystem = $file_system;
$this->logger = $logger_factory
->get('dropzonejs');
$this->renderer = $renderer;
$this->configFactory = $config_factory;
$this->token = $token;
$this->messenger = $messenger;
$this->streamWrapperManager = $stream_wrapper_manager;
}
public function createFile($uri, $destination, $extensions, AccountProxyInterface $user, array $validators = []) {
$uri = $this->streamWrapperManager
->normalizeUri($uri);
$file_info = new \SplFileInfo($uri);
$file = $this->entityTypeManager
->getStorage('file')
->create([
'uid' => $user
->id(),
'status' => 0,
'filename' => $file_info
->getFilename(),
'uri' => $uri,
'filesize' => $file_info
->getSize(),
'filemime' => $this->mimeTypeGuesser
->guess($uri),
]);
$destination = PlainTextOutput::renderFromHtml($this->token
->replace($destination));
$renamed = $this
->renameExecutableExtensions($file);
if ($renamed && !empty($extensions)) {
$extensions .= ' txt';
$this->messenger
->addMessage($this
->t('For security reasons, your upload has been renamed to %filename.', [
'%filename' => $file
->getFilename(),
]));
}
$errors = $this
->validateFile($file, $extensions, $validators);
if (!empty($errors)) {
$message = [
'error' => [
'#markup' => $this
->t('The specified file %name could not be uploaded.', [
'%name' => $file
->getFilename(),
]),
],
'item_list' => [
'#theme' => 'item_list',
'#items' => $errors,
],
];
$this->messenger
->addError($this->renderer
->renderPlain($message));
return FALSE;
}
if (!$this
->prepareDestination($file, $destination)) {
$this->messenger
->addError($this
->t('The file could not be uploaded because the destination %destination is invalid.', [
'%destination' => $destination,
]));
return FALSE;
}
$move_result = $this->fileSystem
->move($uri, $file
->getFileUri());
if (!$move_result) {
$this->messenger
->addError($this
->t('File upload error. Could not move uploaded file.'));
$this->logger
->notice('Upload error. Could not move uploaded file %file to destination %destination.', [
'%file' => $file
->getFilename(),
'%destination' => $file
->getFileUri(),
]);
return FALSE;
}
$this->fileSystem
->chmod($file
->getFileUri());
return $file;
}
public function validateFile(FileInterface $file, $extensions, array $additional_validators = []) {
$validators = $additional_validators;
if (!empty($extensions)) {
$validators['file_validate_extensions'] = [
$extensions,
];
}
$validators['file_validate_name_length'] = [];
return file_validate($file, $validators);
}
protected function renameExecutableExtensions(FileInterface $file) {
if (!$this->configFactory
->get('system.file')
->get('allow_insecure_uploads') && preg_match('/\\.(php|pl|py|cgi|asp|js)(\\.|$)/i', $file
->getFilename()) && substr($file
->getFilename(), -4) != '.txt') {
$file
->setMimeType('text/plain');
$file
->setFilename($file
->getFilename() . '.txt');
return TRUE;
}
return FALSE;
}
protected function prepareDestination(FileInterface $file, $destination) {
$destination_scheme = $this->streamWrapperManager::getScheme($destination);
if (!$this->streamWrapperManager
->isValidScheme($destination_scheme)) {
return FALSE;
}
if (!file_exists($destination)) {
$this->fileSystem
->mkdir($destination, NULL, TRUE);
}
if (substr($destination, -1) != '/') {
$destination .= '/';
}
$destination = $this->fileSystem
->getDestinationFilename($destination . $file
->getFilename(), FileSystemInterface::EXISTS_RENAME);
$file
->setFileUri($destination);
return TRUE;
}
}