From 71d36148220420e1c6b129180fa1dd07b5a21631 Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Mon, 2 Jun 2014 02:47:02 +0200 Subject: [PATCH 1/5] Allowed to upload multiple files. --- ContributionPlugin.php | 7 +++ controllers/ContributionController.php | 16 +++-- models/ContributionType.php | 17 ++--- plugin.ini | 2 +- views/admin/types/form.php | 28 ++++++--- views/public/contribution/contribute.php | 19 ++++-- views/public/contribution/type-form.php | 59 +++++++++++++++--- views/public/css/form.css | 7 ++- .../javascripts/contribution-public-form.js | 62 ++++++++++++++++++- 9 files changed, 179 insertions(+), 38 deletions(-) diff --git a/ContributionPlugin.php b/ContributionPlugin.php index 4afff01e..8437dde4 100644 --- a/ContributionPlugin.php +++ b/ContributionPlugin.php @@ -112,6 +112,7 @@ public function hookInstall() `item_type_id` INT UNSIGNED NOT NULL, `display_name` VARCHAR(255) NOT NULL, `file_permissions` ENUM('Disallowed', 'Allowed', 'Required') NOT NULL DEFAULT 'Disallowed', + `multiple_files` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (`id`), UNIQUE KEY `item_type_id` (`item_type_id`) ) ENGINE=MyISAM;"; @@ -259,6 +260,12 @@ public function hookUpgrade($args) set_option('contribution_open', get_option('contribution_simple')); delete_option('contribution_simple'); } + + if (version_compare($oldVersion, '3.1.1', '<')) { + $db = $this->_db; + $sql = "ALTER TABLE `$db->ContributionType` ADD COLUMN `multiple_files` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0'"; + $db->query($sql); + } } public function hookUninstallMessage() diff --git a/controllers/ContributionController.php b/controllers/ContributionController.php index 96e931c1..662bbbf3 100644 --- a/controllers/ContributionController.php +++ b/controllers/ContributionController.php @@ -159,7 +159,7 @@ public function _setupContributeSubmit($typeId) /** * Creates the reCAPTCHA object and returns it. - * + * * @return Zend_Captcha_Recaptcha|null */ protected function _setupCaptcha() @@ -244,7 +244,7 @@ protected function _processForm($post) $itemMetadata['collection_id'] = (int) $collectionId; } - $fileMetadata = $this->_processFileUpload($contributionType); + $fileMetadata = $this->_processFilesUpload($contributionType); // This is a hack to allow the file upload job to succeed // even with the synchronous job dispatcher. @@ -310,10 +310,14 @@ protected function _processUserProfile($post, $user) /** * Deals with files specified on the contribution form. * + * @todo Check if multiple files are allowed. + * @todo Error when option is required and when multiple files are allowed: an empty contributed_file input generate an error. + * * @param ContributionType $contributionType Type of contribution. - * @return array File upload array. + * @return array Files upload array. */ - protected function _processFileUpload($contributionType) { + protected function _processFilesUpload($contributionType) + { if ($contributionType->isFileAllowed()) { $options = array(); if ($contributionType->isFileRequired()) { @@ -385,13 +389,13 @@ protected function _addElementTextsToItem($item, $elements) */ protected function _validateContribution($post) { - + // ReCaptcha ignores the first argument. if ($this->_captcha and !$this->_captcha->isValid(null, $_POST)) { $this->_helper->flashMessenger(__('Your CAPTCHA submission was invalid, please try again.'), 'error'); return false; } - + if ($post['terms-agree'] == 0) { $this->_helper->flashMessenger(__('You must agree to the Terms and Conditions.'), 'error'); return false; diff --git a/models/ContributionType.php b/models/ContributionType.php index adfbaafb..b532534e 100644 --- a/models/ContributionType.php +++ b/models/ContributionType.php @@ -22,9 +22,12 @@ class ContributionType extends Omeka_Record_AbstractRecord public $item_type_id; public $display_name; public $file_permissions = 'Disallowed'; - - protected $_related = array('ContributionTypeElements' => 'getTypeElements', - 'ItemType' => 'getItemType'); + public $multiple_files = 0; + + protected $_related = array( + 'ContributionTypeElements' => 'getTypeElements', + 'ItemType' => 'getItemType', + ); protected function filterPostData($post) { @@ -34,7 +37,7 @@ protected function filterPostData($post) } return $post; } - + protected function _validate() { if(empty($this->item_type_id)) { @@ -47,7 +50,7 @@ protected function _initializeMixins() $this->_mixins[] = new Mixin_ContributionOrder($this, 'ContributionTypeElement', 'type_id', 'Elements'); } - + /** * Get the type elements associated with this type. * @@ -57,7 +60,7 @@ public function getTypeElements() { return $this->_db->getTable('ContributionTypeElement')->findByType($this); } - + /** * Get the item type associated with this type. * @@ -173,7 +176,7 @@ public function getPossibleTypeElements() } return $options; } - + public function getRecordUrl($action = 'show') { return url("contribution/types/$action/id/{$this->id}"); diff --git a/plugin.ini b/plugin.ini index b9dfbc78..6b839bfc 100644 --- a/plugin.ini +++ b/plugin.ini @@ -6,7 +6,7 @@ link="http://omeka.org/codex/Plugins/Contribution_2.0" support_link="http://omeka.org/forums/forum/plugins" omeka_minimum_version="2.3" omeka_target_version="2.3" -version="3.1.0" +version="3.1.1" tags="social, items" license="GPLv3" required_plugins="GuestUser" diff --git a/views/admin/types/form.php b/views/admin/types/form.php index 3cdd85b0..40e1e79b 100644 --- a/views/admin/types/form.php +++ b/views/admin/types/form.php @@ -1,8 +1,8 @@ -getTable('ContributionType')->getPossibleItemTypes(); $itemTypeOptions = array('' => 'Select an Item Type') + $itemTypeOptions; ?> -
+
@@ -42,17 +42,27 @@ formSelect('file_permissions', $contribution_type->file_permissions, array(), ContributionType::getPossibleFilePermissions()); ?>
- - + + +
+
+ +
+
+

+
+ formCheckbox("multiple_files", null, array('checked' => $contribution_type->multiple_files)); ?> +
+
+
-
    - +
  • Element->name); ?> @@ -65,7 +75,7 @@
    - +
    Element->description); ?>
    @@ -96,7 +106,7 @@ ?> - +
  • @@ -112,7 +122,7 @@
    - + exists()): ?> 'big red button delete-confirm')); ?> diff --git a/views/public/contribution/contribute.php b/views/public/contribution/contribute.php index 30bc025d..fe442b93 100644 --- a/views/public/contribution/contribute.php +++ b/views/public/contribution/contribute.php @@ -6,13 +6,13 @@ * @package Contribution */ -queue_js_file('contribution-public-form'); $contributionPath = get_option('contribution_page_path'); if(!$contributionPath) { $contributionPath = 'contribution'; } queue_css_file('form'); +queue_js_file('contribution-public-form'); //load user profiles js and css if needed if(get_option('contribution_user_profile_type') && plugin_is_active('UserProfiles') ) { queue_js_file('admin-globals'); @@ -32,7 +32,7 @@
    - +

    redirect = absolute_url(); ?> -

    You must '>create an account or '>log in before contributing. You can still leave your identity to site visitors anonymous.

    +

    You must '>create an account or '>log in before contributing. You can still leave your identity to site visitors anonymous.

    @@ -54,7 +54,18 @@
    - + partial('contribution/type-form.php', $partialOptions); + }?>
    diff --git a/views/public/contribution/type-form.php b/views/public/contribution/type-form.php index 9512c838..f4513653 100644 --- a/views/public/contribution/type-form.php +++ b/views/public/contribution/type-form.php @@ -5,18 +5,40 @@

    display_name); ?>

    multiple_files; + if ($type->isFileRequired()): $required = true; ?> + + +
    + formLabel('contributed_file', __('Upload a file'), array( + 'id' => 'file-inputs', + )); ?> +
    +
    + formFile('contributed_file[0]', array('class' => 'fileinput button')); ?> +

    +
    +
    +
    +
    formLabel('contributed_file', __('Upload a file')); ?>
    - formFile('contributed_file', array('class' => 'fileinput')); ?> + formFile('contributed_file', array('class' => 'fileinput button')); ?> +

    + @@ -29,14 +51,35 @@ isFileAllowed()): ?> -
    -
    - formLabel('contributed_file', __('Upload a file (Optional)')); ?> -
    -
    - formFile('contributed_file', array('class' => 'fileinput')); ?> + + +
    + formLabel('contributed_file', __('Upload a file (Optional)'), array( + 'id' => 'file-inputs', + )); ?> +
    +
    + formFile('contributed_file[0]', array('class' => 'fileinput button')); ?> +

    +
    + +
    +
    + formLabel('contributed_file', __('Upload a file (Optional)')); ?> +
    +
    + formFile('contributed_file', array('class' => 'fileinput button')); ?> +

    +
    +
    + + @@ -90,7 +133,7 @@

    description; ?>

    - Elements as $element) { echo $this->profileElementForm($element, $profile); } diff --git a/views/public/css/form.css b/views/public/css/form.css index 1cd40f8a..2a87f42c 100644 --- a/views/public/css/form.css +++ b/views/public/css/form.css @@ -1,7 +1,7 @@ div#contribution-type-form div.inputs { width: 60%; - + } div#location_form { @@ -24,4 +24,7 @@ p#contribution-userprofile-visibility { div.contribution-userprofile.exists { display: none; -} \ No newline at end of file +} +#upload-files input { + display: block; +} diff --git a/views/public/javascripts/contribution-public-form.js b/views/public/javascripts/contribution-public-form.js index 5c28871a..9e7d6c36 100644 --- a/views/public/javascripts/contribution-public-form.js +++ b/views/public/javascripts/contribution-public-form.js @@ -1,3 +1,63 @@ +if (!Omeka) { + var Omeka = {}; +} + +// From admin/themes/default/javascripts/items.js. +if (typeof Omeka === 'undefined') { + Omeka = {}; +} + +Omeka.Items = {}; + +(function ($) { + /** + * Enable drag and drop sorting for files. + */ + Omeka.Items.enableSorting = function () { + $('.sortable').sortable({ + items: 'li.file', + forcePlaceholderSize: true, + forceHelperSize: true, + revert: 200, + placeholder: "ui-sortable-highlight", + containment: 'document', + update: function (event, ui) { + $(this).find('.file-order').each(function (index) { + $(this).val(index + 1); + }); + } + }); + $( ".sortable" ).disableSelection(); + + $( ".sortable input[type=checkbox]" ).each(function () { + $(this).css("display", "none"); + }); + }; + + /** + * Allow adding an arbitrary number of file input elements to the items form so that + * more than one file can be uploaded at once. + * + * @param {string} label + */ + Omeka.Items.enableAddFiles = function (label) { + var filesDiv = $('#files-metadata .files'); + + var link = $('' + label + ''); + link.click(function (event) { + event.preventDefault(); + var inputs = filesDiv.find('input'); + var inputCount = inputs.length; + var fileHtml = '
    '; + $(fileHtml).insertAfter(inputs.last()).hide().slideDown(200, function () { + // Extra show fixes IE bug. + $(this).show(); + }); + }); + + $('#upload-files').after(link); + }; +})(jQuery); function toggleProfileEdit() { jQuery('div.contribution-userprofile').toggle(); @@ -26,7 +86,7 @@ function enableContributionAjaxForm(url) { form.empty(); if (value != "") { jQuery.post(url, {contribution_type: value}, function(data) { - form.append(data); + form.append(data); form.show(duration, function() { form.trigger('contribution-form-shown'); form.trigger('omeka:tabselected'); From aaceda9ac7b2444182b28976e2eb528887c78ed1 Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Mon, 18 Aug 2014 02:47:02 +0200 Subject: [PATCH 2/5] Fixed error message when multiple files are downloaded. --- controllers/ContributionController.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/controllers/ContributionController.php b/controllers/ContributionController.php index 662bbbf3..b7107dc2 100644 --- a/controllers/ContributionController.php +++ b/controllers/ContributionController.php @@ -244,6 +244,7 @@ protected function _processForm($post) $itemMetadata['collection_id'] = (int) $collectionId; } + // TODO Check if there is at least one file if one file or more is required and remove the catch below. $fileMetadata = $this->_processFilesUpload($contributionType); // This is a hack to allow the file upload job to succeed @@ -265,6 +266,11 @@ protected function _processForm($post) // Copying this cruddy hack if (strstr($e->getMessage(), "'contributed_file'")) { $this->_helper->flashMessenger("You must upload a file when making a {$contributionType->display_name} contribution.", 'error'); + } + // Check multiple files. + elseif (strstr($e->getMessage(), "contributed_file_")) { + $this->_helper->flashMessenger(__('One or more files have not been uploaded.') + . ' ' . __('You must upload a file when making a %s contribution.', $contributionType->display_name), 'error'); } else { $this->_helper->flashMessenger($e->getMessage()); } @@ -273,6 +279,7 @@ protected function _processForm($post) $this->_helper->flashMessenger($e->getMessage()); return false; } + $this->_addElementTextsToItem($item, $post['Elements']); // Allow plugins to deal with the inputs they may have added to the form. fire_plugin_hook('contribution_save_form', array('contributionType'=>$contributionType,'record'=>$item, 'post'=>$post)); @@ -320,11 +327,7 @@ protected function _processFilesUpload($contributionType) { if ($contributionType->isFileAllowed()) { $options = array(); - if ($contributionType->isFileRequired()) { - $options['ignoreNoFile'] = false; - } else { - $options['ignoreNoFile'] = true; - } + $options['ignoreNoFile'] = !$contributionType->isFileRequired(); $fileMetadata = array( 'file_transfer_type' => 'Upload', From 294813880175512ce5ab15f861c7ab64365583dd Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Fri, 19 Sep 2014 02:47:02 +0200 Subject: [PATCH 3/5] Renamed 'contributed_file' to 'file' in order to use default upload method. --- controllers/ContributionController.php | 6 +++--- views/public/contribution/type-form.php | 16 ++++++++-------- .../javascripts/contribution-public-form.js | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/controllers/ContributionController.php b/controllers/ContributionController.php index b7107dc2..fe6e5e16 100644 --- a/controllers/ContributionController.php +++ b/controllers/ContributionController.php @@ -264,11 +264,11 @@ protected function _processForm($post) return false; } catch (Omeka_File_Ingest_InvalidException $e) { // Copying this cruddy hack - if (strstr($e->getMessage(), "'contributed_file'")) { + if (strstr($e->getMessage(), "'file'")) { $this->_helper->flashMessenger("You must upload a file when making a {$contributionType->display_name} contribution.", 'error'); } // Check multiple files. - elseif (strstr($e->getMessage(), "contributed_file_")) { + elseif (strstr($e->getMessage(), "file_")) { $this->_helper->flashMessenger(__('One or more files have not been uploaded.') . ' ' . __('You must upload a file when making a %s contribution.', $contributionType->display_name), 'error'); } else { @@ -331,7 +331,7 @@ protected function _processFilesUpload($contributionType) $fileMetadata = array( 'file_transfer_type' => 'Upload', - 'files' => 'contributed_file', + 'files' => 'file', 'file_ingest_options' => $options ); diff --git a/views/public/contribution/type-form.php b/views/public/contribution/type-form.php index f4513653..1b59f60a 100644 --- a/views/public/contribution/type-form.php +++ b/views/public/contribution/type-form.php @@ -18,12 +18,12 @@ });
    - formLabel('contributed_file', __('Upload a file'), array( + formLabel('file', __('Upload a file'), array( 'id' => 'file-inputs', )); ?>
    - formFile('contributed_file[0]', array('class' => 'fileinput button')); ?> + formFile('file[0]', array('class' => 'fileinput button')); ?>

    @@ -31,10 +31,10 @@
    - formLabel('contributed_file', __('Upload a file')); ?> + formLabel('file', __('Upload a file')); ?>
    - formFile('contributed_file', array('class' => 'fileinput button')); ?> + formFile('file', array('class' => 'fileinput button')); ?>

    @@ -58,12 +58,12 @@ });
    - formLabel('contributed_file', __('Upload a file (Optional)'), array( + formLabel('file', __('Upload a file (Optional)'), array( 'id' => 'file-inputs', )); ?>
    - formFile('contributed_file[0]', array('class' => 'fileinput button')); ?> + formFile('file[0]', array('class' => 'fileinput button')); ?>

    @@ -71,10 +71,10 @@
    - formLabel('contributed_file', __('Upload a file (Optional)')); ?> + formLabel('file', __('Upload a file (Optional)')); ?>
    - formFile('contributed_file', array('class' => 'fileinput button')); ?> + formFile('file', array('class' => 'fileinput button')); ?>

    diff --git a/views/public/javascripts/contribution-public-form.js b/views/public/javascripts/contribution-public-form.js index 9e7d6c36..263209ce 100644 --- a/views/public/javascripts/contribution-public-form.js +++ b/views/public/javascripts/contribution-public-form.js @@ -48,7 +48,7 @@ Omeka.Items = {}; event.preventDefault(); var inputs = filesDiv.find('input'); var inputCount = inputs.length; - var fileHtml = '
    '; + var fileHtml = '
    '; $(fileHtml).insertAfter(inputs.last()).hide().slideDown(200, function () { // Extra show fixes IE bug. $(this).show(); From aed239807154ae3bfb4389737016f30d0fb5192e Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Mon, 19 Dec 2016 00:00:00 +0100 Subject: [PATCH 4/5] Allowed to upload multiple files when type is not preset. --- views/public/contribution/contribute.php | 1 + views/public/contribution/type-form.php | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/views/public/contribution/contribute.php b/views/public/contribution/contribute.php index fe442b93..7065e6f3 100644 --- a/views/public/contribution/contribute.php +++ b/views/public/contribution/contribute.php @@ -56,6 +56,7 @@
    display_name); ?> multiple_files; if ($type->isFileRequired()): @@ -13,9 +14,13 @@
    formLabel('file', __('Upload a file'), array( @@ -53,9 +58,13 @@ ?>
    formLabel('file', __('Upload a file (Optional)'), array( @@ -88,7 +97,7 @@
    formLabel('contribution_email', __('Email (Optional)')); + echo $this->formLabel('contribution_email', __('Email (Optional)')); } else { echo $this->formLabel('contribution_email', __('Email (Required)')); } From c498290237bb03066aedc1ee8ad82ec479edcbeb Mon Sep 17 00:00:00 2001 From: Daniel Berthereau Date: Mon, 19 Dec 2016 00:00:00 +0100 Subject: [PATCH 5/5] Simplified upload of multiple files. --- views/public/contribution/type-form.php | 92 ++++++++----------------- 1 file changed, 28 insertions(+), 64 deletions(-) diff --git a/views/public/contribution/type-form.php b/views/public/contribution/type-form.php index 98d2ebd2..547030eb 100644 --- a/views/public/contribution/type-form.php +++ b/views/public/contribution/type-form.php @@ -1,94 +1,58 @@ -

    - +isFileRequired(); +$isAllowed = $type->isFileAllowed(); +$allowMultipleFiles = $isAllowed && $type->multiple_files; +?>

    display_name); ?>

    multiple_files; - -if ($type->isFileRequired()): - $required = true; -?> - - - +if ($isRequired): ?>
    - formLabel('file', __('Upload a file'), array( - 'id' => 'file-inputs', - )); ?> -
    -
    - formFile('file[0]', array('class' => 'fileinput button')); ?> -

    -
    -
    -
    - -
    formLabel('file', __('Upload a file')); ?>
    -
    - formFile('file', array('class' => 'fileinput button')); ?> -

    +
    +
    + formFile($allowMultipleFiles ? 'file[0]' : 'file', array('class' => 'fileinput button')); ?> +

    +
    - - getTypeElements() as $contributionTypeElement) { echo $this->elementForm($contributionTypeElement->Element, $item, array('contributionTypeElement'=>$contributionTypeElement)); } ?> -isFileAllowed()): -?> - - +
    - formLabel('file', __('Upload a file (Optional)'), array( - 'id' => 'file-inputs', - )); ?> -
    -
    - formFile('file[0]', array('class' => 'fileinput button')); ?> -

    -
    -
    -
    - -
    formLabel('file', __('Upload a file (Optional)')); ?>
    -
    - formFile('file', array('class' => 'fileinput button')); ?> -

    +
    +
    + formFile($allowMultipleFiles ? 'file[0]' : 'file', array('class' => 'fileinput button')); ?> +

    +
    + + @@ -156,4 +120,4 @@ // on a type-by-type basis). fire_plugin_hook('contribution_type_form', array('type'=>$type, 'view'=>$this)); ?> - +