Simplify Media Library upload logic (#5026)
Based heavily off the work done by @alxy in #4314 May require https://github.com/rainlab/pages-plugin/pull/421 if testing with RainLab.Pages. Replaces #4314, related: #4311, Credit to @alxy for the initial work.
This commit is contained in:
parent
459677a168
commit
4f7e2995c7
|
|
@ -1,15 +1,15 @@
|
|||
<?php namespace Backend\FormWidgets;
|
||||
|
||||
use App;
|
||||
use Config;
|
||||
use File;
|
||||
use Event;
|
||||
use Lang;
|
||||
use Event;
|
||||
use Config;
|
||||
use Request;
|
||||
use Backend;
|
||||
use BackendAuth;
|
||||
use Backend\Classes\FormWidgetBase;
|
||||
use Backend\Models\EditorSetting;
|
||||
use Backend\Classes\FormWidgetBase;
|
||||
|
||||
/**
|
||||
* Rich Editor
|
||||
|
|
@ -20,6 +20,8 @@ use Backend\Models\EditorSetting;
|
|||
*/
|
||||
class RichEditor extends FormWidgetBase
|
||||
{
|
||||
use \Backend\Traits\UploadableWidget;
|
||||
|
||||
//
|
||||
// Configurable properties
|
||||
//
|
||||
|
|
@ -39,6 +41,11 @@ class RichEditor extends FormWidgetBase
|
|||
*/
|
||||
public $readOnly = false;
|
||||
|
||||
/**
|
||||
* @var string|null Path in the Media Library where uploaded files should be stored. If null it will be pulled from Request::input('path');
|
||||
*/
|
||||
public $uploadPath = '/uploaded-files';
|
||||
|
||||
//
|
||||
// Object properties
|
||||
//
|
||||
|
|
|
|||
|
|
@ -446,7 +446,6 @@ textarea.fr-code {display:none;width:100%;resize:none;-moz-resize:none;-webkit-r
|
|||
.fr-view .fr-video.fr-dvi {display:inline-block}
|
||||
.fr-view .fr-video.fr-dvi.fr-fvl {float:left}
|
||||
.fr-view .fr-video.fr-dvi.fr-fvr {float:right}
|
||||
.fr-view {}
|
||||
.fr-view .oc-text-gray {color:#AAA !important}
|
||||
.fr-view .oc-text-bordered {border-top:solid 1px #222;border-bottom:solid 1px #222;padding:10px 0}
|
||||
.fr-view .oc-text-spaced {letter-spacing:1px}
|
||||
|
|
@ -544,6 +543,11 @@ body .fr-popup .fr-checkbox span {border-color:#d1d6d9}
|
|||
.field-richeditor.size-giant .fr-wrapper {height:350px}
|
||||
.field-richeditor.size-giant .fr-wrapper .fr-view {min-height:350px}
|
||||
.field-richeditor.size-giant .height-indicator {height:350px;display:none}
|
||||
.field-richeditor.size-tiny.stretch {min-height:90px}
|
||||
.field-richeditor.size-small.stretch {min-height:140px}
|
||||
.field-richeditor.size-large.stretch {min-height:240px}
|
||||
.field-richeditor.size-huge.stretch {min-height:290px}
|
||||
.field-richeditor.size-giant.stretch {min-height:390px}
|
||||
.fr-tooltip {z-index:9997 !important}
|
||||
.fr-popup {z-index:9995 !important}
|
||||
.fr-toolbar {z-index:11 !important}
|
||||
|
|
|
|||
|
|
@ -157,11 +157,11 @@ Base.call(this)
|
|||
this.init()}
|
||||
RichEditor.prototype=Object.create(BaseProto)
|
||||
RichEditor.prototype.constructor=RichEditor
|
||||
RichEditor.DEFAULTS={linksHandler:null,stylesheet:null,fullpage:false,editorLang:'en',useMediaManager:false,toolbarButtons:null,allowEmptyTags:null,allowTags:null,noWrapTags:null,removeTags:null,lineBreakerTags:null,imageStyles:null,linkStyles:null,paragraphStyles:null,tableStyles:null,tableCellStyles:null,aceVendorPath:'/',readOnly:false}
|
||||
RichEditor.DEFAULTS={linksHandler:null,uploadHandler:null,stylesheet:null,fullpage:false,editorLang:'en',useMediaManager:false,toolbarButtons:null,allowEmptyTags:null,allowTags:null,noWrapTags:null,removeTags:null,lineBreakerTags:null,imageStyles:null,linkStyles:null,paragraphStyles:null,tableStyles:null,tableCellStyles:null,aceVendorPath:'/',readOnly:false}
|
||||
RichEditor.prototype.init=function(){var self=this;this.$el.one('dispose-control',this.proxy(this.dispose))
|
||||
if(!this.$textarea.attr('id')){this.$textarea.attr('id','element-'+Math.random().toString(36).substring(7))}
|
||||
this.initFroala()}
|
||||
RichEditor.prototype.initFroala=function(){var froalaOptions={editorClass:'control-richeditor',language:this.options.editorLang,fullPage:this.options.fullpage,pageLinksHandler:this.options.linksHandler,aceEditorVendorPath:this.options.aceVendorPath,toolbarSticky:false}
|
||||
RichEditor.prototype.initFroala=function(){var froalaOptions={editorClass:'control-richeditor',language:this.options.editorLang,fullPage:this.options.fullpage,pageLinksHandler:this.options.linksHandler,uploadHandler:this.options.uploadHandler,aceEditorVendorPath:this.options.aceVendorPath,toolbarSticky:false}
|
||||
if(this.options.toolbarButtons){froalaOptions.toolbarButtons=this.options.toolbarButtons.split(',')}
|
||||
else{froalaOptions.toolbarButtons=$.oc.richEditorButtons}
|
||||
froalaOptions.imageStyles=this.options.imageStyles?this.options.imageStyles:{'oc-img-rounded':'Rounded','oc-img-bordered':'Bordered'}
|
||||
|
|
@ -178,9 +178,12 @@ froalaOptions.htmlDoNotWrapTags=this.options.noWrapTags?this.options.noWrapTags.
|
|||
if(this.options.removeTags){froalaOptions.htmlRemoveTags=this.options.removeTags.split(/[\s,]+/)}
|
||||
froalaOptions.lineBreakerTags=this.options.lineBreakerTags?this.options.lineBreakerTags.split(/[\s,]+/):['figure, table, hr, iframe, form, dl']
|
||||
froalaOptions.shortcutsEnabled=['show','bold','italic','underline','indent','outdent','undo','redo']
|
||||
froalaOptions.requestHeaders={'X-CSRF-TOKEN':$('meta[name="csrf-token"]').attr('content'),'X-Requested-With':'XMLHttpRequest'}
|
||||
var $form=this.$el.closest('form')
|
||||
var formData={};if($form.length>0){$.each($form.serializeArray(),function(index,field){formData[field.name]=field.value;})}
|
||||
froalaOptions.imageUploadURL=froalaOptions.fileUploadURL=window.location
|
||||
froalaOptions.imageUploadParam=froalaOptions.fileUploadParam='file_data'
|
||||
froalaOptions.imageUploadParams=froalaOptions.fileUploadParams={X_OCTOBER_MEDIA_MANAGER_QUICK_UPLOAD:1,_token:$('meta[name="csrf-token"]').attr('content')}
|
||||
froalaOptions.imageUploadParams=froalaOptions.fileUploadParams=$.extend(formData,{_handler:froalaOptions.uploadHandler,})
|
||||
var placeholder=this.$textarea.attr('placeholder')
|
||||
froalaOptions.placeholderText=placeholder?placeholder:''
|
||||
froalaOptions.height=this.$el.hasClass('stretch')?Infinity:$('.height-indicator',this.$el).height()
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
RichEditor.DEFAULTS = {
|
||||
linksHandler: null,
|
||||
uploadHandler: null,
|
||||
stylesheet: null,
|
||||
fullpage: false,
|
||||
editorLang: 'en',
|
||||
|
|
@ -79,6 +80,7 @@
|
|||
language: this.options.editorLang,
|
||||
fullPage: this.options.fullpage,
|
||||
pageLinksHandler: this.options.linksHandler,
|
||||
uploadHandler: this.options.uploadHandler,
|
||||
aceEditorVendorPath: this.options.aceVendorPath,
|
||||
toolbarSticky: false
|
||||
}
|
||||
|
|
@ -153,13 +155,27 @@
|
|||
|
||||
froalaOptions.shortcutsEnabled = ['show', 'bold', 'italic', 'underline', 'indent', 'outdent', 'undo', 'redo']
|
||||
|
||||
// Ensure that October recognizes AJAX requests from Froala
|
||||
froalaOptions.requestHeaders = {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
|
||||
// Get the data from the parent form for including in the request
|
||||
var $form = this.$el.closest('form')
|
||||
var formData = {};
|
||||
if ($form.length > 0) {
|
||||
$.each($form.serializeArray(), function (index, field) {
|
||||
formData[field.name] = field.value;
|
||||
})
|
||||
}
|
||||
|
||||
// File upload
|
||||
froalaOptions.imageUploadURL = froalaOptions.fileUploadURL = window.location
|
||||
froalaOptions.imageUploadParam = froalaOptions.fileUploadParam = 'file_data'
|
||||
froalaOptions.imageUploadParams = froalaOptions.fileUploadParams = {
|
||||
X_OCTOBER_MEDIA_MANAGER_QUICK_UPLOAD: 1,
|
||||
_token: $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
froalaOptions.imageUploadParams = froalaOptions.fileUploadParams = $.extend(formData, {
|
||||
_handler: froalaOptions.uploadHandler,
|
||||
})
|
||||
|
||||
var placeholder = this.$textarea.attr('placeholder')
|
||||
froalaOptions.placeholderText = placeholder ? placeholder : ''
|
||||
|
|
|
|||
|
|
@ -106,6 +106,14 @@
|
|||
&.size-large { .richeditor-set-height(@size-large); }
|
||||
&.size-huge { .richeditor-set-height(@size-huge); }
|
||||
&.size-giant { .richeditor-set-height(@size-giant); }
|
||||
|
||||
&.stretch {
|
||||
&.size-tiny { min-height: @size-tiny; }
|
||||
&.size-small { min-height: @size-small; }
|
||||
&.size-large { min-height: @size-large; }
|
||||
&.size-huge { min-height: @size-huge; }
|
||||
&.size-giant { min-height: @size-giant; }
|
||||
}
|
||||
}
|
||||
|
||||
.fr-tooltip {
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@
|
|||
<?php if (isset($tableStyles)): ?>data-table-styles="<?= e(json_encode($tableStyles)) ?>"<?php endif ?>
|
||||
<?php if (isset($tableCellStyles)): ?>data-table-cell-styles="<?= e(json_encode($tableCellStyles)) ?>"<?php endif ?>
|
||||
data-links-handler="<?= $this->getEventHandler('onLoadPageLinksForm') ?>"
|
||||
data-upload-handler="<?= $this->getEventHandler('onUpload') ?>"
|
||||
data-ace-vendor-path="<?= Url::asset('/modules/backend/formwidgets/codeeditor/assets/vendor/ace') ?>"
|
||||
data-control="richeditor"
|
||||
<?= $field->getAttributes() ?>>
|
||||
<?= $field->getAttributes() ?>
|
||||
>
|
||||
<textarea
|
||||
placeholder="<?= e(trans($field->placeholder)) ?>"
|
||||
name="<?= $name ?>"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
<?php namespace Backend\Traits;
|
||||
|
||||
use Str;
|
||||
use File;
|
||||
use Lang;
|
||||
use Request;
|
||||
use Response;
|
||||
use ApplicationException;
|
||||
use System\Classes\MediaLibrary;
|
||||
use October\Rain\Filesystem\Definitions as FileDefinitions;
|
||||
|
||||
/**
|
||||
* Uploadable Widget Trait
|
||||
* Adds media library upload features to back-end widgets
|
||||
*
|
||||
* @package october\backend
|
||||
* @author Alexey Bobkov, Samuel Georges
|
||||
*/
|
||||
trait UploadableWidget
|
||||
{
|
||||
// /**
|
||||
// * @var string Path in the Media Library where uploaded files should be stored. If empty it will be pulled from Request::input('path');
|
||||
// */
|
||||
// public $uploadPath;
|
||||
|
||||
/**
|
||||
* Process file uploads submitted via AJAX
|
||||
*
|
||||
* @return void
|
||||
* @throws ApplicationException If the file "file_data" wasn't detected in the request or if the file failed to pass validation / security checks
|
||||
*/
|
||||
public function onUpload()
|
||||
{
|
||||
if ($this->readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!Request::hasFile('file_data')) {
|
||||
throw new ApplicationException('File missing from request');
|
||||
}
|
||||
|
||||
$uploadedFile = Request::file('file_data');
|
||||
|
||||
$fileName = $uploadedFile->getClientOriginalName();
|
||||
|
||||
/*
|
||||
* Convert uppcare case file extensions to lower case
|
||||
*/
|
||||
$extension = strtolower($uploadedFile->getClientOriginalExtension());
|
||||
$fileName = File::name($fileName).'.'.$extension;
|
||||
|
||||
/*
|
||||
* File name contains non-latin characters, attempt to slug the value
|
||||
*/
|
||||
if (!$this->validateFileName($fileName)) {
|
||||
$fileNameClean = $this->cleanFileName(File::name($fileName));
|
||||
$fileName = $fileNameClean . '.' . $extension;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for unsafe file extensions
|
||||
*/
|
||||
if (!$this->validateFileType($fileName)) {
|
||||
throw new ApplicationException(Lang::get('backend::lang.media.type_blocked'));
|
||||
}
|
||||
|
||||
/*
|
||||
* See mime type handling in the asset manager
|
||||
*/
|
||||
if (!$uploadedFile->isValid()) {
|
||||
throw new ApplicationException($uploadedFile->getErrorMessage());
|
||||
}
|
||||
|
||||
// Use the configured upload path unless it's null, in which case use the user-provided path
|
||||
$path = !empty($this->uploadPath) ? $this->uploadPath : Request::input('path');
|
||||
$path = MediaLibrary::validatePath($path);
|
||||
$filePath = $path . '/' . $fileName;
|
||||
|
||||
/*
|
||||
* getRealPath() can be empty for some environments (IIS)
|
||||
*/
|
||||
$realPath = empty(trim($uploadedFile->getRealPath()))
|
||||
? $uploadedFile->getPath() . DIRECTORY_SEPARATOR . $uploadedFile->getFileName()
|
||||
: $uploadedFile->getRealPath();
|
||||
|
||||
MediaLibrary::instance()->put(
|
||||
$filePath,
|
||||
File::get($realPath)
|
||||
);
|
||||
|
||||
/**
|
||||
* @event media.file.upload
|
||||
* Called after a file is uploaded
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* Event::listen('media.file.upload', function ((\Backend\Widgets\MediaManager) $mediaWidget, (string) &$path, (\Symfony\Component\HttpFoundation\File\UploadedFile) $uploadedFile) {
|
||||
* \Log::info($path . " was upoaded.");
|
||||
* });
|
||||
*
|
||||
* Or
|
||||
*
|
||||
* $mediaWidget->bindEvent('file.upload', function ((string) &$path, (\Symfony\Component\HttpFoundation\File\UploadedFile) $uploadedFile) {
|
||||
* \Log::info($path . " was uploaded");
|
||||
* });
|
||||
*
|
||||
*/
|
||||
$this->fireSystemEvent('media.file.upload', [&$filePath, $uploadedFile]);
|
||||
|
||||
$response = Response::make([
|
||||
'link' => MediaLibrary::url($filePath),
|
||||
'result' => 'success'
|
||||
]);
|
||||
} catch (Exception $ex) {
|
||||
$response = Response::make($ex->getMessage(), 400);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a proposed media item file name.
|
||||
*
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateFileName($name)
|
||||
{
|
||||
if (!preg_match('/^[\w@\.\s_\-]+$/iu', $name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($name, '..') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for blocked / unsafe file extensions
|
||||
*
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateFileType($name)
|
||||
{
|
||||
$extension = strtolower(File::extension($name));
|
||||
|
||||
$allowedFileTypes = FileDefinitions::get('defaultExtensions');
|
||||
|
||||
if (!in_array($extension, $allowedFileTypes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a slug form the string. A modified version of Str::slug
|
||||
* with the main difference that it accepts @-signs
|
||||
*
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function cleanFileName($name)
|
||||
{
|
||||
$title = Str::ascii($name);
|
||||
|
||||
// Convert all dashes/underscores into separator
|
||||
$flip = $separator = '-';
|
||||
$title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
|
||||
|
||||
// Remove all characters that are not the separator, letters, numbers, whitespace or @.
|
||||
$title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s@]+!u', '', mb_strtolower($title));
|
||||
|
||||
// Replace all separator characters and whitespace by a single separator
|
||||
$title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
|
||||
|
||||
return trim($title, $separator);
|
||||
}
|
||||
}
|
||||
|
|
@ -26,6 +26,8 @@ use Form as FormHelper;
|
|||
*/
|
||||
class MediaManager extends WidgetBase
|
||||
{
|
||||
use \Backend\Traits\UploadableWidget;
|
||||
|
||||
const FOLDER_ROOT = '/';
|
||||
|
||||
const VIEW_MODE_GRID = 'grid';
|
||||
|
|
@ -67,8 +69,6 @@ class MediaManager extends WidgetBase
|
|||
$this->readOnly = $readOnly;
|
||||
|
||||
parent::__construct($controller, []);
|
||||
|
||||
$this->checkUploadPostback();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1497,170 +1497,6 @@ class MediaManager extends WidgetBase
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the upload post flag
|
||||
* @return void
|
||||
*/
|
||||
protected function checkUploadPostback()
|
||||
{
|
||||
if ($this->readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
$fileName = null;
|
||||
$quickMode = false;
|
||||
|
||||
if (
|
||||
(!($uniqueId = Request::header('X-OCTOBER-FILEUPLOAD')) || $uniqueId != $this->getId()) &&
|
||||
(!$quickMode = post('X_OCTOBER_MEDIA_MANAGER_QUICK_UPLOAD'))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!Input::hasFile('file_data')) {
|
||||
throw new ApplicationException('File missing from request');
|
||||
}
|
||||
|
||||
$uploadedFile = Input::file('file_data');
|
||||
|
||||
$fileName = $uploadedFile->getClientOriginalName();
|
||||
|
||||
/*
|
||||
* Convert uppcare case file extensions to lower case
|
||||
*/
|
||||
$extension = strtolower($uploadedFile->getClientOriginalExtension());
|
||||
$fileName = File::name($fileName).'.'.$extension;
|
||||
|
||||
/*
|
||||
* File name contains non-latin characters, attempt to slug the value
|
||||
*/
|
||||
if (!$this->validateFileName($fileName)) {
|
||||
$fileNameClean = $this->cleanFileName(File::name($fileName));
|
||||
$fileName = $fileNameClean . '.' . $extension;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for unsafe file extensions
|
||||
*/
|
||||
if (!$this->validateFileType($fileName)) {
|
||||
throw new ApplicationException(Lang::get('backend::lang.media.type_blocked'));
|
||||
}
|
||||
|
||||
/*
|
||||
* See mime type handling in the asset manager
|
||||
*/
|
||||
if (!$uploadedFile->isValid()) {
|
||||
throw new ApplicationException($uploadedFile->getErrorMessage());
|
||||
}
|
||||
|
||||
$path = $quickMode ? '/uploaded-files' : Input::get('path');
|
||||
$path = MediaLibrary::validatePath($path);
|
||||
$filePath = $path.'/'.$fileName;
|
||||
|
||||
/*
|
||||
* getRealPath() can be empty for some environments (IIS)
|
||||
*/
|
||||
$realPath = empty(trim($uploadedFile->getRealPath()))
|
||||
? $uploadedFile->getPath() . DIRECTORY_SEPARATOR . $uploadedFile->getFileName()
|
||||
: $uploadedFile->getRealPath();
|
||||
|
||||
MediaLibrary::instance()->put(
|
||||
$filePath,
|
||||
File::get($realPath)
|
||||
);
|
||||
|
||||
/**
|
||||
* @event media.file.upload
|
||||
* Called after a file is uploaded
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* Event::listen('media.file.upload', function ((\Backend\Widgets\MediaManager) $mediaWidget, (string) &$path, (\Symfony\Component\HttpFoundation\File\UploadedFile) $uploadedFile) {
|
||||
* \Log::info($path . " was upoaded.");
|
||||
* });
|
||||
*
|
||||
* Or
|
||||
*
|
||||
* $mediaWidget->bindEvent('file.upload', function ((string) &$path, (\Symfony\Component\HttpFoundation\File\UploadedFile) $uploadedFile) {
|
||||
* \Log::info($path . " was uploaded");
|
||||
* });
|
||||
*
|
||||
*/
|
||||
$this->fireSystemEvent('media.file.upload', [&$filePath, $uploadedFile]);
|
||||
|
||||
$response = Response::make([
|
||||
'link' => MediaLibrary::url($filePath),
|
||||
'result' => 'success'
|
||||
]);
|
||||
}
|
||||
catch (Exception $ex) {
|
||||
$response = Response::make($ex->getMessage(), 400);
|
||||
}
|
||||
|
||||
// Override the controller response
|
||||
$this->controller->setResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate a proposed media item file name.
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateFileName($name)
|
||||
{
|
||||
if (!preg_match('/^[\w@\.\s_\-]+$/iu', $name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strpos($name, '..') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for blocked / unsafe file extensions
|
||||
* @param string
|
||||
* @return bool
|
||||
*/
|
||||
protected function validateFileType($name)
|
||||
{
|
||||
$extension = strtolower(File::extension($name));
|
||||
|
||||
$allowedFileTypes = FileDefinitions::get('defaultExtensions');
|
||||
|
||||
if (!in_array($extension, $allowedFileTypes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a slug form the string. A modified version of Str::slug
|
||||
* with the main difference that it accepts @-signs
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function cleanFileName($name)
|
||||
{
|
||||
$title = Str::ascii($name);
|
||||
|
||||
// Convert all dashes/underscores into separator
|
||||
$flip = $separator = '-';
|
||||
$title = preg_replace('!['.preg_quote($flip).']+!u', $separator, $title);
|
||||
|
||||
// Remove all characters that are not the separator, letters, numbers, whitespace or @.
|
||||
$title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s@]+!u', '', mb_strtolower($title));
|
||||
|
||||
// Replace all separator characters and whitespace by a single separator
|
||||
$title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);
|
||||
|
||||
return trim($title, $separator);
|
||||
}
|
||||
|
||||
//
|
||||
// Cropping
|
||||
//
|
||||
|
|
|
|||
|
|
@ -277,7 +277,6 @@ MediaManager.prototype.doObjectsCollide=function(aTop,aLeft,aWidth,aHeight,bTop,
|
|||
MediaManager.prototype.initUploader=function(){if(!this.itemListElement||this.options.readOnly)
|
||||
return
|
||||
var uploaderOptions={clickable:this.$el.find('[data-control="upload"]').get(0),url:this.options.url,paramName:'file_data',timeout:0,headers:{},createImageThumbnails:false}
|
||||
if(this.options.uniqueId){uploaderOptions.headers['X-OCTOBER-FILEUPLOAD']=this.options.uniqueId}
|
||||
var token=$('meta[name="csrf-token"]').attr('content')
|
||||
if(token){uploaderOptions.headers['X-CSRF-TOKEN']=token}
|
||||
this.dropzone=new Dropzone(this.$el.get(0),uploaderOptions)
|
||||
|
|
@ -307,7 +306,8 @@ progressBar.setAttribute('class','progress-bar')}
|
|||
MediaManager.prototype.uploadQueueComplete=function(){this.$el.find('[data-command="cancel-uploading"]').addClass('hide')
|
||||
this.$el.find('[data-command="close-uploader"]').removeClass('hide')
|
||||
this.refresh()}
|
||||
MediaManager.prototype.uploadSending=function(file,xhr,formData){formData.append('path',this.$el.find('[data-type="current-folder"]').val())}
|
||||
MediaManager.prototype.uploadSending=function(file,xhr,formData){formData.append('path',this.$el.find('[data-type="current-folder"]').val())
|
||||
xhr.setRequestHeader('X-OCTOBER-REQUEST-HANDLER',this.options.uploadHandler)}
|
||||
MediaManager.prototype.uploadCancelAll=function(){this.dropzone.removeAllFiles(true)
|
||||
this.hideUploadUi()}
|
||||
MediaManager.prototype.updateUploadBar=function(templateName,classNames){var fileNumberLabel=this.$el.get(0).querySelector('[data-label="file-number-and-progress"]'),successTemplate=fileNumberLabel.getAttribute('data-'+templateName+'-template'),progressBar=this.$el.get(0).querySelector('[data-control="upload-progress-bar"]')
|
||||
|
|
@ -465,7 +465,7 @@ eventHandled=true
|
|||
break;}
|
||||
if(eventHandled){ev.preventDefault()
|
||||
ev.stopPropagation()}}
|
||||
MediaManager.DEFAULTS={url:window.location,alias:'',uniqueId:null,deleteEmpty:'Please select files to delete.',deleteConfirm:'Delete the selected file(s)?',moveEmpty:'Please select files to move.',selectSingleImage:'Please select a single image.',selectionNotImage:'The selected item is not an image.',bottomToolbar:false,cropAndInsertButton:false}
|
||||
MediaManager.DEFAULTS={url:window.location,uploadHandler:null,alias:'',deleteEmpty:'Please select files to delete.',deleteConfirm:'Delete the selected file(s)?',moveEmpty:'Please select files to move.',selectSingleImage:'Please select a single image.',selectionNotImage:'The selected item is not an image.',bottomToolbar:false,cropAndInsertButton:false}
|
||||
var old=$.fn.mediaManager
|
||||
$.fn.mediaManager=function(option){var args=Array.prototype.slice.call(arguments,1),result=undefined
|
||||
this.each(function(){var $this=$(this)
|
||||
|
|
|
|||
|
|
@ -721,10 +721,6 @@
|
|||
// fallback: implement method that would set a flag that the uploader is not supported by the browser
|
||||
}
|
||||
|
||||
if (this.options.uniqueId) {
|
||||
uploaderOptions.headers['X-OCTOBER-FILEUPLOAD'] = this.options.uniqueId
|
||||
}
|
||||
|
||||
/*
|
||||
* Add CSRF token to headers
|
||||
*/
|
||||
|
|
@ -800,6 +796,7 @@
|
|||
|
||||
MediaManager.prototype.uploadSending = function(file, xhr, formData) {
|
||||
formData.append('path', this.$el.find('[data-type="current-folder"]').val())
|
||||
xhr.setRequestHeader('X-OCTOBER-REQUEST-HANDLER', this.options.uploadHandler)
|
||||
}
|
||||
|
||||
MediaManager.prototype.uploadCancelAll = function() {
|
||||
|
|
@ -1284,8 +1281,8 @@
|
|||
|
||||
MediaManager.DEFAULTS = {
|
||||
url: window.location,
|
||||
uploadHandler: null,
|
||||
alias: '',
|
||||
uniqueId: null,
|
||||
deleteEmpty: 'Please select files to delete.',
|
||||
deleteConfirm: 'Delete the selected file(s)?',
|
||||
moveEmpty: 'Please select files to move.',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
data-control="media-manager"
|
||||
class="layout"
|
||||
data-alias="<?= $this->alias ?>"
|
||||
data-unique-id="<?= $this->getId() ?>"
|
||||
data-upload-handler="<?= $this->getEventHandler('onUpload') ?>"
|
||||
data-delete-empty="<?= e(trans('backend::lang.media.delete_empty')) ?>"
|
||||
data-delete-confirm="<?= e(trans('backend::lang.media.delete_confirm')) ?>"
|
||||
data-move-empty="<?= e(trans('backend::lang.media.move_empty')) ?>"
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@
|
|||
<div data-control="toolbar">
|
||||
<?php if (!$this->readOnly) : ?>
|
||||
<div class="btn-group offset-right">
|
||||
<button type="button" class="btn btn-primary oc-icon-upload" data-control="upload"
|
||||
><?= e(trans('backend::lang.media.upload')) ?></button>
|
||||
<button type="button" class="btn btn-primary oc-icon-upload" data-control="upload"><?= e(trans('backend::lang.media.upload')) ?></button>
|
||||
<button type="button" class="btn btn-primary oc-icon-folder" data-command="create-folder"><?= e(trans('backend::lang.media.add_folder')) ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
|
@ -14,10 +13,8 @@
|
|||
|
||||
<?php if (!$this->readOnly) : ?>
|
||||
<div class="btn-group offset-right">
|
||||
<button type="button" class="btn btn-default oc-icon-reply-all" data-command="move"
|
||||
><?= e(trans('backend::lang.media.move')) ?></button>
|
||||
<button type="button" class="btn btn-default oc-icon-trash" data-command="delete"
|
||||
><?= e(trans('backend::lang.media.delete')) ?></button>
|
||||
<button type="button" class="btn btn-default oc-icon-reply-all" data-command="move"><?= e(trans('backend::lang.media.move')) ?></button>
|
||||
<button type="button" class="btn btn-default oc-icon-trash" data-command="delete"><?= e(trans('backend::lang.media.delete')) ?></button>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue