Commit 7a8d52e2 authored by Primsi's avatar Primsi
Browse files

by primsi: further bugfixes and improvements

parent 079026cb
......@@ -90,13 +90,13 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
$this->fileSystem = $file_system;
$this->logger = $logger_factory->get('dropzonejs');
$this->renderer = $renderer;
$this->config = $config_factory;
$this->configFactory = $config_factory;
}
/**
* {@inheritdoc}
*/
public function saveFile($uri, $destination, $extensions, AccountProxyInterface $user) {
public function saveFile($uri, $destination, $extensions, AccountProxyInterface $user, $validators = []) {
// Create the file entity.
$file = $this->fileEntityFromUri($uri, $user);
......@@ -110,7 +110,7 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
}
// Validate the file.
$errors = $this->validateFile($file, $extensions);
$errors = $this->validateFile($file, $extensions, $validators);
if (!empty($errors)) {
$message = [
'error' => [
......@@ -144,13 +144,13 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
// If we made it this far it's safe to record this file in the database.
$file->save();
return $file->id();
return $file;
}
/**
* {@inheritdoc}
*/
protected function fileEntityFromUri($uri, AccountProxyInterface $user) {
public function fileEntityFromUri($uri, AccountProxyInterface $user) {
$uri = file_stream_wrapper_uri_normalize($uri);
$file_info = new \SplFileInfo($uri);
......@@ -172,6 +172,27 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
/**
* {@inheritdoc}
*/
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'] = [];
// Call the validation functions specified by this function's caller.
return file_validate($file, $validators);
}
/**
* Rename potentially executable files.
*
* @param \Drupal\file\FileInterface $file
* The file entity object.
*
* @return bool
* Whether the file was renamed or not.
*/
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');
......@@ -182,20 +203,19 @@ class DropzoneJsUploadSave implements DropzoneJsUploadSaveInterface {
return FALSE;
}
/**
* {@inheritdoc}
*/
protected function validateFile(FileInterface $file, $extensions) {
$validators = [];
$validators['file_validate_extensions'] = $extensions;
$validators['file_validate_name_length'] = [];
// Call the validation functions specified by this function's caller.
return file_validate($file, $validators);
}
/**
* {@inheritdoc}
* Validate and set destination the destination URI.
*
* @param \Drupal\file\FileInterface $file
* The file entity object.
* @param string $destination
* A string containing the URI that the file should be copied to. This must
* be a stream wrapper URI.
*
* @return bool
* True if the destination was sucesfully validated and set, otherwise
* false.
*/
protected function prepareDestination(FileInterface $file, $destination) {
// Assert that the destination contains a valid stream.
......
......@@ -29,11 +29,46 @@ interface DropzoneJsUploadSaveInterface {
* A space separated list of valid extensions.
* @param \Drupal\Core\Session\AccountProxyInterfac $user
* The owner of the file.
* @param array $validators
* An optional, associative array of callback functions used to validate the
* file. See file_validate() for more documentation. Note that we add
* file_validate_extensions and file_validate_name_length in this method
* already.
*
* @return int|bool
* The id of the newly created file entity or false if saving failed.
* @return \Drupal\file\FileInterface|bool
* The saved file entity of the newly created file entity or false if
* saving failed.
*/
public function saveFile($uri, $destination, $extensions, AccountProxyInterface $user, $validators = []);
/**
* Prepare a file entity from uri.
*
* @param string $uri
* File's uri.
* @param \Drupal\Core\Session\AccountProxyInterface $user
* The owner of the file.
*
* @return \Drupal\file\FileInterface
* A new entity file entity object, not saved yet.
*/
public function fileEntityFromUri($uri, AccountProxyInterface $user);
/**
* Validate the uploaded file.
*
* @param \Drupal\file\FileInterface $file
* The file entity object.
* @param array $extensions
* A space separated string of valid extensions.
* @param array $additional_validators
* An optional, associative array of callback functions used to validate the
* file. See file_validate() for more documentation. Note that we add
* file_validate_extensions and file_validate_name_length in this method
* already.
*
* @todo Add possibility to add more validators.
* @return array
* An array containing validation error messages.
*/
public function saveFile($uri, $destination, $extensions, AccountProxyInterface $user);
public function validateFile(FileInterface $file, $extensions, array $additional_validators = []);
}
......@@ -7,6 +7,7 @@
namespace Drupal\dropzonejs\Element;
use Drupal\Component\Utility\Bytes;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Form\FormStateInterface;
......@@ -23,7 +24,8 @@ use Drupal\Core\Render\Element\FormElement;
* - #dropzone_description
* Will be visible inside the upload area.
* - #max_filesize
* Used by dropzonejs and expressed in MB. See
* Used by dropzonejs and expressed in number + unit (i.e. 1.1M) This will be
* converted to a form that DropzoneJs understands. See:
* http://www.dropzonejs.com/#config-maxFilesize
* - #extensions
* A string of valid extensions separated by a space.
......@@ -54,6 +56,7 @@ class DropzoneJs extends FormElement {
'#pre_render' => [[$class, 'preRenderDropzoneJs']],
'#theme' => 'dropzonejs',
'#theme_wrappers' => ['form_element'],
'#tree' => TRUE,
'#attached' => [
'library' => ['dropzonejs/dropzonejs', 'dropzonejs/integration']
],
......@@ -85,13 +88,16 @@ class DropzoneJs extends FormElement {
* The $element with prepared variables ready for input.html.twig.
*/
public static function preRenderDropzoneJs($element) {
// Convert the human size input to bytes, convert it to MB and round it.
$max_size = round(Bytes::toInt($element['#max_filesize']) / pow(Bytes::KILOBYTE, 2), 2);
$element['#attached']['drupalSettings']['dropzonejs'] = [
'upload_path' => \Drupal::url('dropzonejs.upload'),
'instances' => [
// Configuration keys are matched with DropzoneJS configuration
// options.
$element['#id'] => [
'maxFilesize' => $element['#max_filesize'],
'maxFilesize' => $max_size,
'dictDefaultMessage' => $element['#dropzone_description'],
'acceptedFiles' => '.' . str_replace(' ', ',.', self::getValidExtensions($element)),
],
......@@ -110,7 +116,7 @@ class DropzoneJs extends FormElement {
$return['uploaded_files'] = NULL;
if ($input !== FALSE) {
$user_input = NestedArray::getValue($form_state->getUserInput(), $element['#parents'], $key_exists);
$user_input = NestedArray::getValue($form_state->getUserInput(), $element['#parents'] + ['uploaded_files']);
if (!empty($user_input['uploaded_files'])) {
$file_names = array_filter(explode(';', $user_input['uploaded_files']));
......@@ -132,7 +138,10 @@ class DropzoneJs extends FormElement {
$move_result = file_unmanaged_move($old_filepath, $new_filepath);
if ($move_result) {
$return['uploaded_files'][] = $move_result;
$return['uploaded_files'][] = [
'path' => $move_result,
'filename' => $name,
];
}
else {
drupal_set_message(t('There was a problem while processing the file named @name', ['@name' => $name]), 'error');
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment