Commit 5c294e73 authored by chr.fritsch's avatar chr.fritsch Committed by chr.fritsch

Issue #2877034 by Primsi, chr.fritsch: Use dropzonejs client side resizing

parent 43a557a3
......@@ -59,6 +59,39 @@ function template_preprocess_dropzonejs(array &$variables) {
$variables['uploaded_files'] = $element['uploaded_files'];
}
/**
* Implements hook_library_info_build().
*/
function dropzonejs_library_info_build() {
$libraries = [];
if (\Drupal::moduleHandler()->moduleExists('libraries')) {
$exif_path = libraries_get_path('exif-js') . '/exif.js';
}
else {
$exif_path = DRUPAL_ROOT . '/libraries/exif-js/exif.js';
}
if ($exif_found = file_exists($exif_path)) {
$libraries['exif-js'] = [
'title' => 'Exif',
'website' => 'https://github.com/exif-js/exif-js',
'version' => 'v2.3.0',
'license' => [
'name' => 'MIT',
'url' => 'https://github.com/exif-js/exif-js/blob/master/LICENSE.md',
'gpl-compatible' => TRUE,
],
'js' => [
'/libraries/exif-js/exif.js' => [],
],
];
}
return $libraries;
}
/**
* Implements hook_library_info_alter().
*/
......@@ -66,5 +99,9 @@ function dropzonejs_library_info_alter(&$libraries, $extension) {
if ($extension == 'dropzonejs' && \Drupal::moduleHandler()->moduleExists('libraries')) {
$libraries['dropzonejs']['js'] = ['/' . libraries_get_path('dropzone') . '/dist/min/dropzone.min.js' => []];
$libraries['dropzonejs']['css']['component'] = ['/' . libraries_get_path('dropzone') . '/dist/min/dropzone.min.css' => []];
if ($exif_path = libraries_get_path('exif-js')) {
$libraries['exif-js']['js'] = ['/' . $exif_path . '/exif.js' => []];
}
}
}
......@@ -20,55 +20,38 @@ entity_browser.browser.widget.dropzonejs:
extensions:
type: string
label: 'Allowed file extensions'
clientside_resize:
type: boolean
label: 'Use clientside resize'
resize_width:
type: integer
label: 'Maximum width'
resize_height:
type: integer
label: 'Maximum height'
resize_quality:
type: float
label: 'Resize quality'
resize_method:
type: string
label: 'Method used for resizing'
thumbnail_method:
type: string
label: 'Method used for generating the thumbnail'
entity_browser.browser.widget.dropzonejs_media_entity:
type: mapping
type: entity_browser.browser.widget.dropzonejs
label: 'Media Entity DropzoneJS widget configuration'
mapping:
media_type:
type: string
label: 'Media type'
submit_text:
type: string
label: 'Submit button text'
auto_select:
type: boolean
label: 'Automatically submit selection'
upload_location:
type: string
label: 'Upload location'
dropzone_description:
type: string
label: 'Dropzone drag-n-drop zone text'
max_filesize:
type: string
label: 'Maximum size of files'
extensions:
type: string
label: 'Allowed file extensions'
entity_browser.browser.widget.dropzonejs_media_entity_inline_entity_form:
type: mapping
type: entity_browser.browser.widget.dropzonejs_media_entity
label: 'Media Entity DropzoneJS with edit widget configuration'
mapping:
media_type:
type: string
label: 'Media type'
submit_text:
type: string
label: 'Submit button text'
upload_location:
type: string
label: 'Upload location'
dropzone_description:
type: string
label: 'Dropzone drag-n-drop zone text'
max_filesize:
type: string
label: 'Maximum size of files'
extensions:
type: string
label: 'Allowed file extensions'
form_mode:
type: string
label: 'Form mode'
......@@ -5,6 +5,7 @@
* Install function hooks for the DropzoneJS entity browser widget module.
*/
use Drupal\dropzonejs_eb_widget\Plugin\EntityBrowser\Widget\DropzoneJsEbWidget;
use Drupal\dropzonejs_eb_widget\Plugin\EntityBrowser\Widget\MediaEntityDropzoneJsEbWidget;
use Drupal\entity_browser\Entity\EntityBrowser;
......@@ -47,3 +48,36 @@ function dropzonejs_eb_widget_update_8201() {
}
}
/**
* Update configurations for new keys.
*/
function dropzonejs_eb_widget_update_8202() {
/** @var \Drupal\entity_browser\Entity\EntityBrowser[] $entity_browsers */
$entity_browsers = EntityBrowser::loadMultiple();
foreach ($entity_browsers as $entity_browser) {
/** @var \Drupal\entity_browser\WidgetInterface[] $widgets */
$widgets = $entity_browser->getWidgets();
$has_config_changes = FALSE;
foreach ($widgets as $widget) {
if ($widget instanceof DropzoneJsEbWidget) {
$config = $widget->getConfiguration();
$config['settings']['clientside_resize'] = FALSE;
$config['settings']['resize_height'] = 0;
$config['settings']['resize_method'] = 'contain';
$config['settings']['resize_quality'] = 1.0;
$config['settings']['resize_width'] = 0;
$config['settings']['thumbnail_method'] = 'contain';
$widget->setConfiguration($config);
$has_config_changes = TRUE;
}
}
if ($has_config_changes) {
$entity_browser->save();
}
}
}
......@@ -104,6 +104,12 @@ class DropzoneJsEbWidget extends WidgetBase {
'dropzone_description' => $this->t('Drop files here to upload them'),
'max_filesize' => file_upload_max_size() / pow(Bytes::KILOBYTE, 2) . 'M',
'extensions' => 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp',
'clientside_resize' => FALSE,
'resize_width' => NULL,
'resize_height' => NULL,
'resize_quality' => 1,
'resize_method' => 'contain',
'thumbnail_method' => 'contain',
] + parent::defaultConfiguration();
}
......@@ -127,8 +133,17 @@ class DropzoneJsEbWidget extends WidgetBase {
'#max_filesize' => $config['settings']['max_filesize'],
'#extensions' => $config['settings']['extensions'],
'#max_files' => ($cardinality > 0) ? $cardinality : 0,
'#clientside_resize' => $config['settings']['clientside_resize'],
];
if ($config['settings']['clientside_resize']) {
$form['upload']['#resize_width'] = $config['settings']['resize_width'];
$form['upload']['#resize_height'] = $config['settings']['resize_height'];
$form['upload']['#resize_quality'] = $config['settings']['resize_quality'];
$form['upload']['#resize_method'] = $config['settings']['resize_method'];
$form['upload']['#thumbnail_method'] = $config['settings']['thumbnail_method'];
}
$form['#attached']['library'][] = 'dropzonejs/widget';
// Disable the submit button until the upload sucesfully completed.
$form['#attached']['library'][] = 'dropzonejs_eb_widget/common';
......@@ -360,6 +375,107 @@ class DropzoneJsEbWidget extends WidgetBase {
'#default_value' => $configuration['extensions'],
];
$exif_found = \Drupal::service('library.discovery')->getLibraryByName('dropzonejs', 'exif-js');
$form['clientside_resize'] = [
'#type' => 'checkbox',
'#title' => $this->t('Use client side resizing'),
'#default_value' => $configuration['clientside_resize'],
];
if (!$exif_found) {
$form['clientside_resize']['#description'] = $this->t('Requires droopzone version v4.4.0 or higher and the <a href="@exif" target="_blank">exif</a> library.', ['@exif' => 'https://github.com/exif-js/exif-js']);
// We still want to provide a way to disable this if the library does not
// exist.
if ($configuration['clientside_resize'] == FALSE) {
$form['clientside_resize']['#disabled'] = TRUE;
}
}
$form['resize_width'] = [
'#type' => 'number',
'#title' => $this->t('Max width'),
'#default_value' => $configuration['resize_width'],
'#size' => 60,
'#field_suffix' => 'px',
'#min' => 0,
'#states' => [
'visible' => [
':input[name="table[' . $this->uuid() . '][form][clientside_resize]"]' => [
'checked' => TRUE,
],
]
]
];
$form['resize_height'] = [
'#type' => 'number',
'#title' => $this->t('Max height'),
'#default_value' => $configuration['resize_height'],
'#size' => 60,
'#field_suffix' => 'px',
'#min' => 0,
'#states' => [
'visible' => [
':input[name="table[' . $this->uuid() . '][form][clientside_resize]"]' => [
'checked' => TRUE,
],
]
]
];
$form['resize_quality'] = [
'#type' => 'number',
'#title' => $this->t('Resize quality'),
'#default_value' => $configuration['resize_quality'],
'#min' => 0,
'#max' => 1,
'#step' => 0.1,
'#states' => [
'visible' => [
':input[name="table[' . $this->uuid() . '][form][clientside_resize]"]' => [
'checked' => TRUE,
],
]
]
];
$form['resize_method'] = [
'#type' => 'select',
'#title' => $this->t('Resize method'),
'#default_value' => $configuration['resize_method'],
'#options' => [
'contain' => $this->t('Contain (scale)'),
'crop' => $this->t('Crop'),
],
'#states' => [
'visible' => [
':input[name="table[' . $this->uuid() . '][form][clientside_resize]"]' => [
'checked' => TRUE,
],
]
]
];
$form['thumbnail_method'] = [
'#type' => 'select',
'#title' => $this->t('Thumbnail method'),
'#default_value' => $configuration['thumbnail_method'],
'#options' => [
'contain' => $this->t('Contain (scale)'),
'crop' => $this->t('Crop'),
],
'#states' => [
'visible' => [
':input[name="table[' . $this->uuid() . '][form][clientside_resize]"]' => [
'checked' => TRUE,
],
]
]
];
return $form;
}
......
......@@ -13,22 +13,42 @@ use Drupal\Core\Url;
/**
* Provides a DropzoneJS atop of the file element.
*
* Configuration options are:
* - #title
* Required options are:
* - #title (string)
* The main field title.
* - #description
* - #description (string)
* Description under the field.
* - #dropzone_description
* - #dropzone_description (string)
* Will be visible inside the upload area.
* - #max_filesize
* - #max_filesize (string)
* 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
* - #extensions (string)
* A string of valid extensions separated by a space.
* - #max_files
* - #max_files (integer)
* Number of files that can be uploaded.
* If < 1, there is no limit.
* - #clientside_resize (bool)
* Whether or not to use DropzoneJS clientside resizing. It requires v4.4.0+
* version of the library.
*
* Optional options are:
* - #resize_width (integer)
* (optional) The maximum with in px. If omitted defaults to NULL.
* - #resize_height (integer)
* (optional) The maximum height in px. If omitted defaults to NULL.
* - #resize_quality (float)
* (optional) The quality of the resize. Accepts values from 0 - 1. Ie: 0.8.
* Defautls to 1.
* - #resize_method (string)
* (optional) Accepts 'contain', which scales the image, or 'crop' which crops
* the image. Defaults to 'contain'.
* - #thumbnail_method (string).
* (optional) Accepts 'contain', which scales the image, or 'crop' which crops
* the image. Defaults to 'contain'.
*
* @todo Not sure about the version for clientside.
*
* When submitted the element returns an array of temporary file locations. It's
* the duty of the environment that implements this element to handle the
......@@ -121,6 +141,17 @@ class DropzoneJs extends FormElement {
],
];
if (!empty($element['#clientside_resize'])) {
$element['#attached']['drupalSettings']['dropzonejs']['instances'][$element['#id']] += [
'resizeWidth' => !empty($element['#resize_width']) ? $element['#resize_width'] : NULL,
'resizeHeight' => !empty($element['#resize_height']) ? $element['#resize_height'] : NULL,
'resizeQuality' => !empty($element['#resize_quality']) ? $element['#resize_quality'] : 1,
'resizeMethod' => !empty($element['#resize_method']) ? $element['#resize_method'] : 'contain',
'thumbnailMethod' => !empty($element['#thumbnail_method']) ? $element['#thumbnail_method'] : 'contain',
];
array_unshift($element['#attached']['library'], 'dropzonejs/exif-js');
}
static::setAttributes($element, ['dropzone-enable']);
return $element;
}
......
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