MDL-51306 mod_folder: Add button to download entire folder.
authorAndrew Hancox <andrewdchancox@googlemail.com>
Wed, 7 Oct 2015 10:46:45 +0000 (11:46 +0100)
committerAndrew Hancox <andrewdchancox@googlemail.com>
Tue, 2 Feb 2016 15:07:48 +0000 (15:07 +0000)
mod/folder/db/install.xml
mod/folder/db/upgrade.php
mod/folder/download_folder.php [new file with mode: 0644]
mod/folder/lang/en/folder.php
mod/folder/lib.php
mod/folder/mod_form.php
mod/folder/renderer.php
mod/folder/settings.php
mod/folder/version.php

index 1c63071..9fc25e1 100644 (file)
@@ -15,6 +15,7 @@
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
         <FIELD NAME="display" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Display type of folder contents - on a separate page or inline"/>
         <FIELD NAME="showexpanded" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" COMMENT="1 = expanded, 0 = collapsed for sub-folders"/>
+        <FIELD NAME="showdownloadfolder" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" COMMENT="1 = show download folder button"/>
       </FIELDS>
       <KEYS>
         <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
index 05d297a..85ef365 100644 (file)
@@ -128,5 +128,17 @@ function xmldb_folder_upgrade($oldversion) {
     // Moodle v3.0.0 release upgrade line.
     // Put any upgrade step following this.
 
+
+    // Add showdownloadfolder option.
+    if ($oldversion < 2016020201) {
+        $table = new xmldb_table('folder');
+        $field = new xmldb_field('showdownloadfolder', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'showexpanded');
+        if (!$dbman->field_exists($table, $field)) {
+            $dbman->add_field($table, $field, 'showdownloadfolder');
+        }
+
+        upgrade_mod_savepoint(true, 2016020201, 'folder');
+    }
+
     return true;
 }
diff --git a/mod/folder/download_folder.php b/mod/folder/download_folder.php
new file mode 100644 (file)
index 0000000..178e795
--- /dev/null
@@ -0,0 +1,62 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Folder download
+ *
+ * @package   mod_folder
+ * @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
+ * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(__DIR__ . "/../../config.php");
+
+$id = required_param('id', PARAM_INT);  // Course module ID.
+$cm = get_coursemodule_from_id('folder', $id, 0, true, MUST_EXIST);
+
+$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
+
+require_course_login($course, true, $cm);
+$context = context_module::instance($cm->id);
+require_capability('mod/folder:view', $context);
+
+$folder = $DB->get_record('folder', array('id' => $cm->instance), '*', MUST_EXIST);
+
+$foldertree = new folder_tree($folder, $cm);
+$downloadable = folder_archive_available($folder, $foldertree);
+if (!$downloadable) {
+    print_error('cannotdownloaddir', 'repository');
+}
+
+// Completion.
+$completion = new completion_info($course);
+$completion->set_module_viewed($cm);
+
+$fs = get_file_storage();
+$file = $fs->get_file($context->id, 'mod_folder', 'content', 0, '/', '.');
+if (!$file) {
+    print_error('cannotdownloaddir', 'repository');
+}
+
+$zipper   = get_file_packer('application/zip');
+$filename = clean_filename($folder->name . "-" . date("Ymd")) . ".zip";
+$temppath = make_request_directory() . $filename;
+
+if ($zipper->archive_to_pathname(array('/' => $file), $temppath)) {
+    send_temp_file($temppath, $filename);
+} else {
+    print_error('cannotdownloaddir', 'repository');
+}
index f17e18a..e37f9a1 100644 (file)
@@ -25,6 +25,7 @@
 
 $string['contentheader'] = 'Content';
 $string['dnduploadmakefolder'] = 'Unzip files and create folder';
+$string['downloadfolder'] = 'Download folder';
 $string['eventfolderupdated'] = 'Folder updated';
 $string['folder:addinstance'] = 'Add a new folder';
 $string['folder:managefiles'] = 'Manage files in folder module';
@@ -50,5 +51,12 @@ Also note that participants view actions can not be logged in this case.';
 $string['displaypage'] = 'On a separate page';
 $string['displayinline'] = 'Inline on a course page';
 $string['noautocompletioninline'] = 'Automatic completion on viewing of activity can not be selected together with "Display inline" option';
+$string['showdownloadfolder'] = 'Show download folder button';
+$string['showdownloadfolder_help'] = 'If set to \'yes\', a button will be shown to allow users to download a zip archive containing all files.';
 $string['showexpanded'] = 'Show subfolders expanded';
 $string['showexpanded_help'] = 'If set to \'yes\', subfolders are shown expanded by default; otherwise they are shown collapsed.';
+$string['maxsizetodownload'] = 'Maximum folder download size (MB)';
+$string['maxsizetodownload_help'] = 'If set then users will not be able to downlod zip archives of folder where the total size is larger than this value.';
+
+
+
index aa96de4..fe7dcd7 100644 (file)
@@ -482,3 +482,48 @@ function folder_view($folder, $course, $cm, $context) {
     $completion = new completion_info($course);
     $completion->set_module_viewed($cm);
 }
+
+/**
+ * Check if the folder can be zipped and downloaded.
+ * @param stdClass $folder
+ * @param folder_tree $foldertree
+ * @return bool True if the folder can be zipped and downloaded.
+ * @throws \dml_exception
+ */
+function folder_archive_available($folder, $foldertree) {
+    if (!$folder->showdownloadfolder) {
+        return false;
+    }
+
+    $size = folder_get_directory_size($foldertree->dir);
+    $maxsize = get_config('folder', 'maxsizetodownload') * 1024 * 1024;
+
+    if ($size == 0) {
+        return false;
+    }
+
+    if (!empty($maxsize) && $size > $maxsize) {
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Recursively measure the size of the files in a directory.
+ * @param array $directory
+ * @return int size of directory contents in bytes
+ */
+function folder_get_directory_size($directory) {
+    $size = 0;
+
+    foreach ($directory['files'] as $file) {
+        $size += $file->get_filesize();
+    }
+
+    foreach ($directory['subdirs'] as $subdirectory) {
+        $size += folder_get_directory_size($subdirectory);
+    }
+
+    return $size;
+}
\ No newline at end of file
index 7c6764c..ec57d86 100644 (file)
@@ -63,6 +63,11 @@ class mod_folder_mod_form extends moodleform_mod {
         $mform->addElement('advcheckbox', 'showexpanded', get_string('showexpanded', 'folder'));
         $mform->addHelpButton('showexpanded', 'showexpanded', 'mod_folder');
         $mform->setDefault('showexpanded', $config->showexpanded);
+
+        // Adding option to enable downloading archive of folder.
+        $mform->addElement('advcheckbox', 'showdownloadfolder', get_string('showdownloadfolder', 'folder'));
+        $mform->addHelpButton('showdownloadfolder', 'showdownloadfolder', 'mod_folder');
+        $mform->setDefault('showdownloadfolder', true);
         //-------------------------------------------------------
         $this->standard_coursemodule_elements();
 
index cf31a3d..1731ed5 100644 (file)
@@ -65,11 +65,26 @@ class mod_folder_renderer extends plugin_renderer_base {
                 'generalbox foldertree');
 
         // Do not append the edit button on the course page.
-        if ($folder->display != FOLDER_DISPLAY_INLINE && has_capability('mod/folder:managefiles', $context)) {
+        if ($folder->display != FOLDER_DISPLAY_INLINE) {
+            $containercontents = '';
+            $downloadable = folder_archive_available($folder, $foldertree);
+
+            if ($downloadable) {
+                $containercontents .= $this->output->single_button(
+                    new moodle_url('/mod/folder/download_folder.php', array('id' => $cm->id)),
+                    get_string('downloadfolder', 'folder')
+                );
+            }
+
+            if (has_capability('mod/folder:managefiles', $context)) {
+                $containercontents .= $this->output->single_button(
+                    new moodle_url('/mod/folder/edit.php', array('id' => $cm->id)),
+                    get_string('edit')
+                );
+            }
             $output .= $this->output->container(
-                    $this->output->single_button(new moodle_url('/mod/folder/edit.php',
-                    array('id' => $cm->id)), get_string('edit')),
-                    'mdl-align folder-edit-button');
+                $containercontents,
+                'mdl-align folder-edit-button');
         }
         return $output;
     }
index f07e58d..e65c4e4 100644 (file)
@@ -28,6 +28,10 @@ defined('MOODLE_INTERNAL') || die;
 if ($ADMIN->fulltree) {
     //--- general settings -----------------------------------------------------------------------------------
     $settings->add(new admin_setting_configcheckbox('folder/showexpanded',
-            get_string('showexpanded', 'folder'),
-            get_string('showexpanded_help', 'folder'), 1));
+        get_string('showexpanded', 'folder'),
+        get_string('showexpanded_help', 'folder'), 1));
+
+    $settings->add(new admin_setting_configtext('folder/maxsizetodownload',
+        get_string('maxsizetodownload', 'folder'),
+        get_string('maxsizetodownload_help', 'folder'), '', PARAM_INT));
 }
index cd48911..5bfa7f7 100644 (file)
@@ -24,7 +24,7 @@
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2015111600;       // The current module version (Date: YYYYMMDDXX)
+$plugin->version   = 2016020201;       // The current module version (Date: YYYYMMDDXX)
 $plugin->requires  = 2015111000;    // Requires this Moodle version
 $plugin->component = 'mod_folder';     // Full name of the plugin (used for diagnostics)
 $plugin->cron      = 0;