[BUGFIX] File upload directly in Doc-module is missing 37/27237/4
authorFrans Saris <franssaris@gmail.com>
Sat, 1 Feb 2014 15:44:43 +0000 (16:44 +0100)
committerBenjamin Mack <benni@typo3.org>
Mon, 3 Feb 2014 07:08:30 +0000 (08:08 +0100)
Since the introduction of FAL the option to upload a file
directly in your form has disappeared.

With this change the upload posibility is back with some extras.
* progress is shown
* drag&drop of files
* multiple file upload

The options is can be disabled just like before in the
user settings and for each field in TCA.

foreign_selector_fieldTcaOverride.config.appearance.fileUploadAllowed = 0

The upload button is only shown for browsers that support
drag&drop upload. And only for FAL fields (sys_file_reference).

Resolves: #55545
Releases: 6.2
Change-Id: I4b984099095d7f66c3d37023cd6c547b2ff5d59f
Reviewed-on: https://review.typo3.org/27237
Reviewed-by: Benjamin Mack
Tested-by: Benjamin Mack
typo3/sysext/backend/Classes/Form/Element/InlineElement.php
typo3/sysext/backend/Classes/Form/FormEngine.php
typo3/sysext/backend/Resources/Public/JavaScript/DragUploader.js
typo3/sysext/filelist/Resources/Private/Templates/file_list.html
typo3/sysext/lang/locallang_core.xlf
typo3/sysext/t3skin/Resources/Public/Css/visual/module_file_list.css

index d259303..7525ce5 100644 (file)
@@ -877,6 +877,7 @@ class InlineElement {
                $allowed = $config['allowed'];
                $objectPrefix = $this->inlineNames['object'] . self::Structure_Separator . $foreign_table;
                $mode = 'db';
+               $showUpload = FALSE;
                if (!empty($conf['appearance']['createNewRelationLinkTitle'])) {
                        $createNewRelationText = $GLOBALS['LANG']->sL($conf['appearance']['createNewRelationLinkTitle'], TRUE);
                } else {
@@ -886,17 +887,57 @@ class InlineElement {
                        if (isset($config['appearance']['elementBrowserType'])) {
                                $mode = $config['appearance']['elementBrowserType'];
                        }
+                       if ($mode === 'file') {
+                               $showUpload = TRUE;
+                       }
+                       if (isset($config['appearance']['fileUploadAllowed'])) {
+                               $showUpload = (bool)$config['appearance']['fileUploadAllowed'];
+                       }
                        if (isset($config['appearance']['elementBrowserAllowed'])) {
                                $allowed = $config['appearance']['elementBrowserAllowed'];
                        }
                }
                $browserParams = '|||' . $allowed . '|' . $objectPrefix . '|inline.checkUniqueElement||inline.importElement';
                $onClick = 'setFormValueOpenBrowser(\'' . $mode . '\', \'' . $browserParams . '\'); return false;';
+
                $item = '<a href="#" class="t3-button" onclick="' . htmlspecialchars($onClick) . '">' . IconUtility::getSpriteIcon('actions-insert-record', array('title' => $createNewRelationText)) . $createNewRelationText . '</a>';
+
+               if ($showUpload && $this->fObj->edit_docModuleUpload) {
+                       $maxFileSize = GeneralUtility::getMaxUploadFileSize() * 1024;
+                       $folder = $folder = $GLOBALS['BE_USER']->getDefaultUploadFolder();
+                       $item .= ' <a href="#" class="t3-button t3-drag-uploader"
+                               style="display:none"
+                               data-dropzone-target="#'.htmlspecialchars($this->inlineNames['object']).'"
+                               data-insert-dropzone-before="1"
+                               data-file-irre-object="'.htmlspecialchars($objectPrefix).'"
+                               data-file-allowed="'.htmlspecialchars($allowed).'"
+                               data-target-folder="'.htmlspecialchars($folder->getCombinedIdentifier()).'"
+                               data-max-file-size="'.htmlspecialchars($maxFileSize).'"
+                               ><span class="t3-icon t3-icon-actions t3-icon-actions-edit t3-icon-edit-upload">&nbsp;</span>';
+                       $item .= $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xlf:file_upload.select-and-submit', TRUE);
+                       $item .= '</a>';
+
+                       $this->loadDragUploadJs();
+               }
                return $item;
        }
 
        /**
+        * Load the required javascript for the DragUploader
+        */
+       protected function loadDragUploadJs() {
+
+               /** @var $pageRenderer \TYPO3\CMS\Core\Page\PageRenderer */
+               $pageRenderer = $GLOBALS['SOBE']->doc->getPageRenderer();
+               $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FileListLocalisation');
+               $pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/DragUploader');
+               $pageRenderer->addInlineLanguagelabelFile(
+                       \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('lang') . 'locallang_core.xlf',
+                       'file_upload'
+               );
+       }
+
+       /**
         * Creates the HTML code of a general link to be used on a level of inline children.
         * The possible keys for the parameter $type are 'newRecord', 'localize' and 'synchronize'.
         *
index 7125a1d..d12c4c0 100644 (file)
@@ -330,6 +330,11 @@ class FormEngine {
         */
        public $edit_showFieldHelp = '';
 
+       /**
+        * @var bool
+        */
+       public $edit_docModuleUpload = FALSE;
+
        // If set, the forms will be rendered a little wider, more precisely with a factor of $this->form_largeComp.
        /**
         * @todo Define visibility
@@ -645,7 +650,7 @@ class FormEngine {
                $this->setNewBEDesign();
                $this->docLarge = $GLOBALS['BE_USER']->uc['edit_wideDocument'] ? 1 : 0;
                $this->edit_showFieldHelp = $GLOBALS['BE_USER']->uc['edit_showFieldHelp'];
-               $this->edit_docModuleUpload = $GLOBALS['BE_USER']->uc['edit_docModuleUpload'];
+               $this->edit_docModuleUpload = (bool)$GLOBALS['BE_USER']->uc['edit_docModuleUpload'];
                $this->inline->init($this);
                $this->suggest->init($this);
        }
index cfb6769..802fa7a 100644 (file)
@@ -25,20 +25,27 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
         */
 
        // register the constructor
-       var DragUploaderPlugin = function() {
+       var DragUploaderPlugin = function(element) {
                var me = this;
-
                me.$body = $('body');
-               me.$dragMask = $('<div />').addClass('t3-body-drag-mask').appendTo(me.$body);
-               me.$dropzone = $('<div />').addClass('t3-dropzone').hide().insertAfter('#typo3-inner-docbody h1:first');
+               me.$element = $(element);
+               me.$trigger = $(me.$element.data('dropzone-trigger'));
+               me.$dropzone = $('<div />').addClass('t3-dropzone').hide();
+               if (me.$element.data('file-irre-object') && me.$element.nextAll(me.$element.data('dropzone-target')).length !== 0) {
+                       me.dropZoneInsertBefore = true;
+                       me.$dropzone.insertBefore(me.$element.data('dropzone-target'));
+               } else {
+                       me.dropZoneInsertBefore = false;
+                       me.$dropzone.insertAfter(me.$element.data('dropzone-target'));
+               }
                me.$dropzoneMask = $('<div />').addClass('t3-dropzone-mask').appendTo(me.$dropzone);
                me.$fileInput = $('<input type="file" multiple name="files[]" />').addClass('t3-upload-file-picker').appendTo(me.$body);
-               me.$fileList = $('#typo3-filelist');
+               me.$fileList = $(me.$element.data('progress-container'));
                me.fileListColumnCount = $('thead tr:first td', me.$fileList).length;
-
-               me.fileDenyPattern = new RegExp($('[data-file-deny-pattern]').attr('data-file-deny-pattern'), 'i');
-               me.maxFileSize = parseInt($('[data-max-file-size]').attr('data-max-file-size'));
-               me.target = $('[data-target-folder]').attr('data-target-folder');
+               me.filesExtensionsAllowed = me.$element.data('file-allowed');
+               me.fileDenyPattern = me.$element.data('file-deny-pattern') ? new RegExp(me.$element.data('file-deny-pattern'), 'i') : false;
+               me.maxFileSize = parseInt(me.$element.data('max-file-size'));
+               me.target = me.$element.data('target-folder');
 
                me.browserCapabilities = {
                        fileReader: typeof FileReader != 'undefined',
@@ -90,7 +97,9 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
 
                        // ask user if we should override files
                        var override = confirm(TYPO3.l10n.localize('file_upload.overwriteExistingFiles'));
-
+                       if (!me.$fileList.is(':visible')) {
+                               me.$fileList.show();
+                       }
                        // Add each file to queue and start upload
                        $.each(files, function(i, file) {
                                new FileQueueItem(me, file, override);
@@ -105,7 +114,17 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                        me.$dropzone.removeClass('t3-dropzone-drop-ok');
                };
 
+               // bind file picker to default upload button
+               me.bindUploadButton = function(button) {
+                       button.click(function(event) {
+                               event.preventDefault();
+                               me.$fileInput.click();
+                               me.showDropzone();
+                       });
+               };
+
                if (me.browserCapabilities.DnD) {
+                       me.$element.show();
                        me.$body.on('dragover', me.dragFileIntoDocument);
                        me.$body.on('dragend', me.dragAborted);
                        me.$body.on('drop', me.ignoreDrop);
@@ -119,20 +138,27 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                                .click(function(){me.$fileInput.click()});
                        $('<span />').addClass('t3-icon t3-icon-actions t3-icon-actions-close t3-dropzone-close').html('&nbsp;').click(me.hideDropzone).appendTo(me.$dropzone);
 
+                       // no filelist then create own progress table
+                       if (me.$fileList.length === 0) {
+                               me.$fileList = $('<table />').attr('id', 'typo3-filelist').addClass('t3-upload-queue').html('<tbody></tbody>').hide();
+                               if (me.dropZoneInsertBefore) {
+                                       me.$fileList.insertAfter(me.$dropzone);
+                               } else {
+                                       me.$fileList.insertBefore(me.$dropzone);
+                               }
+                               me.fileListColumnCount = 7;
+                       }
+
                        me.$fileInput.on('change', function() {
                                me.processFiles(this.files);
                        });
 
-                       // bind file picker to default upload button
-                       $('#button-upload').click(function(event) {
-                               event.preventDefault();
-                               me.$fileInput.click();
-                               me.showDropzone();
-                       });
+                       me.bindUploadButton(me.$trigger.length ? me.$trigger : me.$element);
                }
        };
 
        var FileQueueItem = function(dragUploader, file, override) {
+
                var me = this;
                me.dragUploader = dragUploader;
                me.file = file;
@@ -192,7 +218,25 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                                if (data.result.upload[0].iconClasses) {
                                        me.$iconCol.html('<span class="' + data.result.upload[0].iconClasses + '">&nbsp;</span>');
                                }
-                               setTimeout(function() {me.showFileInfo(data.result.upload[0])}, 3000);
+
+                               if (me.dragUploader.$element.data('file-irre-object')) {
+                                       inline.importElement(
+                                               me.dragUploader.$element.data('file-irre-object'),
+                                               'sys_file',
+                                               data.result.upload[0].uid,
+                                               'file'
+                                       );
+                                       setTimeout(function() {
+                                               me.$row.remove();
+                                               if ($('tr', me.dragUploader.$fileList).length === 0) {
+                                                       me.dragUploader.$fileList.hide();
+                                               }
+                                       }, 3000);
+
+
+                               } else {
+                                       setTimeout(function() {me.showFileInfo(data.result.upload[0])}, 3000);
+                               }
                        }
                };
 
@@ -228,6 +272,18 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                        return string;
                };
 
+               me.checkAllowedExtensions = function() {
+                       if (!me.dragUploader.filesExtensionsAllowed) {
+                               return true;
+                       }
+                       var extension = me.file.name.split('.').pop();
+                       var allowed = me.dragUploader.filesExtensionsAllowed.split(',');
+                       if ($.inArray(extension.toLowerCase(), allowed) !== -1) {
+                               return true;
+                       }
+                       return false;
+               }
+
                // position queue item in file list
                if ($('tbody tr.t3-upload-queue-item', me.dragUploader.$fileList).length === 0) {
                        me.$row.prependTo($('tbody', me.dragUploader.$fileList));
@@ -242,15 +298,20 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                // check file size
                if (me.file.size > me.dragUploader.maxFileSize) {
                        me.updateMessage(TYPO3.l10n.localize('file_upload.maxFileSizeExceeded')
-                         .replace(/\{0\}/g, me.file.name)
-                         .replace(/\{1\}/g, me.fileSizeAsString(me.dragUploader.maxFileSize)));
+                               .replace(/\{0\}/g, me.file.name)
+                               .replace(/\{1\}/g, me.fileSizeAsString(me.dragUploader.maxFileSize)));
                        me.$row.addClass('error');
 
-               // check filename/extension
-               } else if (me.file.name.match(me.dragUploader.fileDenyPattern)) {
+               // check filename/extension against deny pattern
+               } else if (me.dragUploader.fileDenyPattern && me.file.name.match(me.dragUploader.fileDenyPattern)) {
                        me.updateMessage(TYPO3.l10n.localize('file_upload.fileNotAllowed').replace(/\{0\}/g, me.file.name));
                        me.$row.addClass('error');
 
+               } else if (!me.checkAllowedExtensions()) {
+                       me.updateMessage(TYPO3.l10n.localize('file_upload.fileExtensionExpected')
+                               .replace(/\{0\}/g, me.dragUploader.filesExtensionsAllowed)
+                       );
+                       me.$row.addClass('error');
                } else {
                        me.updateMessage('- ' + me.fileSizeAsString(me.file.size));
 
@@ -317,7 +378,7 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                        })
                };
 
-               $('body').dragUploader();
+               $('.t3-drag-uploader').dragUploader();
 
        };
 
@@ -332,7 +393,7 @@ define('TYPO3/CMS/Backend/DragUploader', ['jquery'], function($) {
                DragUploader.initialize();
 
                // load required modules to hook in the post initialize function
-               if (undefined !== TYPO3.settings && undefined !== TYPO3.settings.RequireJS.PostInitializationModules && undefined !== TYPO3.settings.RequireJS.PostInitializationModules['TYPO3/CMS/Backend/DragUploader']) {
+               if (undefined !== TYPO3.settings && undefined !== TYPO3.settings.RequireJS && undefined !== TYPO3.settings.RequireJS.PostInitializationModules && undefined !== TYPO3.settings.RequireJS.PostInitializationModules['TYPO3/CMS/Backend/DragUploader']) {
                        $.each(TYPO3.settings.RequireJS.PostInitializationModules['TYPO3/CMS/Backend/DragUploader'], function(pos, moduleName) {
                                require([moduleName]);
                        });
index 2af8b85..4d1ce46 100644 (file)
@@ -1,5 +1,7 @@
 <!-- ###FULLDOC### begin -->
-<div class="typo3-fullDoc" data-target-folder="###FOLDER_IDENTIFIER###" data-file-deny-pattern="###FILEDENYPATERN###" data-max-file-size="###MAXFILESIZE###">
+<div class="typo3-fullDoc t3-drag-uploader" data-target-folder="###FOLDER_IDENTIFIER###" data-progress-container="#typo3-filelist"
+        data-dropzone-trigger="#button-upload" data-dropzone-target="#typo3-inner-docbody h1:first"
+        data-file-deny-pattern="###FILEDENYPATERN###" data-max-file-size="###MAXFILESIZE###">
        <div id="typo3-docheader">
                <div class="typo3-docheader-functions">
                        <div class="left">###CSH### ###FUNC_MENU###</div>
index 9308126..8d859f5 100644 (file)
@@ -445,12 +445,18 @@ Do you want to continue WITHOUT saving?</source>
                        <trans-unit id="file_upload.dropzonehint.message" xml:space="preserve">
                                <source>Drop your files here, or &lt;u&gt;click, browse &amp; choose files&lt;/u&gt;</source>
                        </trans-unit>
+                       <trans-unit id="file_upload.select-and-submit" xml:space="preserve">
+                               <source>Select &amp; upload files</source>
+                       </trans-unit>
                        <trans-unit id="file_upload.maxFileSizeExceeded" xml:space="preserve">
                                <source>File &quot;{0}&quot; exceeds maximum file size of {1}!</source>
                        </trans-unit>
                        <trans-unit id="file_upload.fileNotAllowed" xml:space="preserve">
                                <source>Filename &quot;{0}&quot; is not allowed!</source>
                        </trans-unit>
+                       <trans-unit id="file_upload.fileExtensionExpected" xml:space="preserve">
+                               <source>Upload failed! A file with &quot;{0}&quot; extension is expected!</source>
+                       </trans-unit>
                        <trans-unit id="file_upload.uploadFailed" xml:space="preserve">
                                <source>Upload of file &quot;{0}&quot; failed!</source>
                        </trans-unit>
index e1d329e..cfede77 100644 (file)
@@ -57,6 +57,7 @@ table#typo3-filelist tr td div.typo3-editCtrl {
        margin-bottom: 1px;
        position: relative;
        cursor: pointer;
+       margin-top: 10px;
 }
 .t3-dropzone .t3-dropzone-close {
        position: absolute;
@@ -87,9 +88,15 @@ table#typo3-filelist tr td div.typo3-editCtrl {
        width: 1px;
        visibility: hidden;
 }
+table.t3-upload-queue {
+       margin: 10px 0;
+}
 table#typo3-filelist tr.file_list_normal.t3-upload-queue-item.last td {
        border-bottom: 1px solid #666666;
 }
+table#typo3-filelist.t3-upload-queue tr.file_list_normal.t3-upload-queue-item.last td {
+       border-bottom: 1px solid #A2AAB8;
+}
 table#typo3-filelist tr.file_list_normal.t3-upload-queue-item.uploading td {
        color: #9D9D9D;
 }