MDL-22504 Fixed issues raised by Sam Hemelryk
authorDavo Smith <git@davosmith.co.uk>
Fri, 4 May 2012 11:12:52 +0000 (12:12 +0100)
committerDavo Smith <git@davosmith.co.uk>
Fri, 4 May 2012 11:12:52 +0000 (12:12 +0100)
lang/en/dndupload.php
lib/ajax/dndupload.js
lib/ajax/dndupload.php
lib/dnduploadlib.php
mod/folder/lib.php
mod/page/lib.php
mod/resource/lib.php
mod/url/lib.php
theme/base/style/course.css

index 3dbe1cc..4b4b65a 100644 (file)
@@ -31,6 +31,8 @@ $string['errorcreatingactivity'] = 'Unable to create an instance of activity \'{
 $string['errorfiletoobig'] = 'The file was bigger than the limit of {$a} bytes';
 $string['errornouploadrepo'] = 'There is no upload repository enabled for this site';
 $string['filetoolarge'] = 'is too large to upload';
+$string['fileuploadwithcontent'] = 'File uploads should not include the content parameter';
+$string['moddoesnotsupporttype'] = 'Module {$a->modname} does not support uploads of type {$a->type}';
 $string['nameforlink'] = 'What do you want to call this link?';
 $string['nameforpage'] = 'What do you want to call this page?';
 $string['noajax'] = 'AJAX course editing must be enabled for drag and drop upload to work';
index 3030495..a128423 100644 (file)
@@ -178,6 +178,9 @@ M.course_dndupload = {
     types_includes: function(e, type) {
         var i;
         var types = e._event.dataTransfer.types;
+        if (types == null) {
+            return false;
+        }
         for (i=0; i<types.length; i++) {
             if (types[i] == type) {
                 return true;
index 8845ef0..ae562bd 100644 (file)
@@ -35,5 +35,5 @@ $modulename = required_param('module', PARAM_PLUGIN);
 $displayname = optional_param('displayname', null, PARAM_TEXT);
 $contents = optional_param('contents', null, PARAM_RAW); // It will be up to each plugin to clean this data, before saving it.
 
-$dndproc = new dndupload_processor($courseid, $section, $type, $modulename);
+$dndproc = new dndupload_ajax_processor($courseid, $section, $type, $modulename);
 $dndproc->process($displayname, $contents);
index 2cee00c..e6bddc1 100644 (file)
@@ -107,12 +107,13 @@ class dndupload_handler {
                         get_string('nameforpage', 'core_dndupload'), 30);
 
         // Loop through all modules to find handlers.
-        $mods = get_plugin_list('mod');
-        foreach ($mods as $modname => $modpath) {
+        $mods = get_plugin_list_with_function('mod', 'dndupload_register');
+        foreach ($mods as $component => $funcname) {
+            list($modtype, $modname) = normalize_component($component);
             if (!course_allowed_module($course, $modname)) {
                 continue;
             }
-            $resp = plugin_callback('mod', $modname, 'dndupload', 'register', array());
+            $resp = $funcname();
             if (!$resp) {
                 continue;
             }
@@ -167,7 +168,7 @@ class dndupload_handler {
         $add->priority = $priority;
         $add->handlers = array();
 
-        $this->types[] = $add;
+        $this->types[$identifier] = $add;
     }
 
     /**
@@ -180,19 +181,16 @@ class dndupload_handler {
      *                        for a type and the user needs to make a choice between them
      */
     public function add_type_handler($type, $module, $message) {
-        foreach ($this->types as $knowntype) {
-            if ($knowntype->identifier == $type) {
-                $add = new stdClass;
-                $add->type = $type;
-                $add->module = $module;
-                $add->message = $message;
-
-                $knowntype->handlers[] = $add;
-                return;
-            }
+        if (!$this->is_known_type($type)) {
+            throw new coding_exception("Trying to add handler for unknown type $type");
         }
 
-        throw new coding_exception("Trying to add handler for unknown type $type");
+        $add = new stdClass;
+        $add->type = $type;
+        $add->module = $module;
+        $add->message = $message;
+
+        $this->types[$type]->handlers[] = $add;
     }
 
     /**
@@ -205,6 +203,8 @@ class dndupload_handler {
      *                        for a type and the user needs to make a choice between them
      */
     public function add_file_handler($extension, $module, $message) {
+        $extension = strtolower($extension);
+
         $add = new stdClass;
         $add->extension = $extension;
         $add->module = $module;
@@ -220,12 +220,7 @@ class dndupload_handler {
      * @return bool True if the type is registered
      */
     public function is_known_type($type) {
-        foreach ($this->types as $knowntype) {
-            if ($knowntype->identifier == $type) {
-                return true;
-            }
-        }
-        return false;
+        return array_key_exists($type, $this->types);
     }
 
     /**
@@ -237,13 +232,12 @@ class dndupload_handler {
      * @return bool True if the module has registered to handle that type
      */
     public function has_type_handler($module, $type) {
-        foreach ($this->types as $knowntype) {
-            if ($knowntype->identifier == $type) {
-                foreach ($knowntype->handlers as $handler) {
-                    if ($handler->module == $module) {
-                        return true;
-                    }
-                }
+        if (!$this->is_known_type($type)) {
+            throw new coding_exception("Checking for handler for unknown type $type");
+        }
+        foreach ($this->types[$type]->handlers as $handler) {
+            if ($handler->module == $module) {
+                return true;
             }
         }
         return false;
@@ -344,7 +338,7 @@ class dndupload_handler {
  * @copyright  2012 Davo Smith
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-class dndupload_processor {
+class dndupload_ajax_processor {
 
     /** Returned when no error has occurred */
     const ERROR_OK = 0;
@@ -384,6 +378,10 @@ class dndupload_processor {
     public function __construct($courseid, $section, $type, $modulename) {
         global $DB;
 
+        if (!defined('AJAX_SCRIPT')) {
+            throw new coding_exception('dndupload_ajax_processor should only be used within AJAX requests');
+        }
+
         $this->course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
 
         require_login($this->course, false);
@@ -422,6 +420,9 @@ class dndupload_processor {
 
         if ($this->is_file_upload()) {
             require_capability('moodle/course:managefiles', $this->context);
+            if ($content != null) {
+                throw new moodle_exception('fileuploadwithcontent', 'core_dndupload');
+            }
         }
 
         require_sesskey();
@@ -477,6 +478,12 @@ class dndupload_processor {
      * @param string $content the content uploaded to the browser
      */
     protected function handle_other_upload($content) {
+        // Check this plugin is registered to handle this type of upload
+        if (!$this->dnduploadhandler->has_type_handler($this->module->name, $this->type)) {
+            $info = (object)array('modname' => $this->module->name, 'type' => $this->type);
+            throw new moodle_exception('moddoesnotsupporttype', 'core_dndupload', $info);
+        }
+
         // Create a course module to hold the new instance.
         $this->create_course_module();
 
@@ -570,10 +577,8 @@ class dndupload_processor {
 
         if (!$instanceid) {
             // Something has gone wrong - undo everything we can.
-            $modcontext = context_module::instance($this->cm->id);
-            delete_context(CONTEXT_MODULE, $this->cm->id);
-            $DB->delete_records('course_modules', array('id' => $this->cm->id));
-            throw new moodle_exception('errorcreatingactivity', 'core_dndupload');
+            delete_course_module($this->cm->id);
+            throw new moodle_exception('errorcreatingactivity', 'core_dndupload', '', $this->module->name);
         }
 
         $DB->set_field('course_modules', 'instance', $instanceid, array('id' => $this->cm->id));
@@ -620,15 +625,18 @@ class dndupload_processor {
      * @param cm_info $mod details of the mod just created
      */
     protected function send_response($mod) {
+        global $OUTPUT;
+
         $resp = new stdClass();
         $resp->error = self::ERROR_OK;
-        $resp->icon = $mod->get_icon_url().'';
+        $resp->icon = $mod->get_icon_url()->out();
         $resp->name = $mod->name;
-        $resp->link = $mod->get_url().'';
+        $resp->link = $mod->get_url()->out();
         $resp->elementid = 'module-'.$mod->id;
         $resp->commands = make_editing_buttons($mod, true, true, 0, $mod->sectionnum);
         $resp->onclick = $mod->get_on_click();
 
+        echo $OUTPUT->header();
         echo json_encode($resp);
         die();
     }
index 8085b5b..fb87a3c 100644 (file)
@@ -375,7 +375,7 @@ function folder_export_contents($cm, $baseurl) {
  * Register the ability to handle drag and drop file uploads
  * @return array containing details of the files / types the mod can handle
  */
-function folder_dndupload_register() {
+function mod_folder_dndupload_register() {
     return array('files' => array(
                      array('extension' => 'zip', 'message' => get_string('dnduploadmakefolder', 'mod_folder'))
                  ));
@@ -386,17 +386,19 @@ function folder_dndupload_register() {
  * @param object $uploadinfo details of the file / content that has been uploaded
  * @return int instance id of the newly created mod
  */
-function folder_dndupload_handle($uploadinfo) {
+function mod_folder_dndupload_handle($uploadinfo) {
     global $DB, $USER;
 
-    $folder = new stdClass();
-    $folder->course = $uploadinfo->course->id;
-    $folder->name = $uploadinfo->displayname;
-    $folder->intro = '<p>'.$uploadinfo->displayname.'</p>';
-    $folder->introformat = FORMAT_HTML;
-    $folder->timemodified = time();
+    // Gather the required info.
+    $data = new stdClass();
+    $data->course = $uploadinfo->course->id;
+    $data->name = $uploadinfo->displayname;
+    $data->intro = '<p>'.$uploadinfo->displayname.'</p>';
+    $data->introformat = FORMAT_HTML;
+    $data->coursemodule = $uploadinfo->coursemodule;
+    $data->files = null; // We will unzip the file and sort out the contents below.
 
-    $folder->id = $DB->insert_record('folder', $folder);
+    $data->id = folder_add_instance($data, null);
 
     // Retrieve the file from the draft file area.
     $context = context_module::instance($uploadinfo->coursemodule);
@@ -410,9 +412,9 @@ function folder_dndupload_handle($uploadinfo) {
     $fs->delete_area_files($context->id, 'mod_folder', 'temp', 0);
 
     if ($success) {
-        return $folder->id;
+        return $data->id;
     }
 
-    $DB->delete_records('folder', array('id' => $folder->id));
+    $DB->delete_records('folder', array('id' => $data->id));
     return false;
 }
index 321848b..1f7d665 100644 (file)
@@ -489,7 +489,7 @@ function page_export_contents($cm, $baseurl) {
  * Register the ability to handle drag and drop file uploads
  * @return array containing details of the files / types the mod can handle
  */
-function page_dndupload_register() {
+function mod_page_dndupload_register() {
     return array('types' => array(
                      array('identifier' => 'text/html', 'message' => get_string('createpage', 'page')),
                      array('identifier' => 'text', 'message' => get_string('createpage', 'page'))
@@ -501,37 +501,29 @@ function page_dndupload_register() {
  * @param object $uploadinfo details of the file / content that has been uploaded
  * @return int instance id of the newly created mod
  */
-function page_dndupload_handle($uploadinfo) {
-    global $DB, $CFG;
-    require_once("$CFG->libdir/resourcelib.php");
-
-    $config = get_config('page');
-    $display = $config->display;
-    if ($display == RESOURCELIB_DISPLAY_POPUP) {
-        $displayoptions['popupwidth'] = $config->popupwidth;
-        $displayoptions['popupheight'] = $config->popupheight;
-    }
-    $displayoptions['printheading'] = $config->printheading;
-    $displayoptions['printintro'] = $config->printintro;
-    $displayoptions = serialize($displayoptions);
-
-    $page = new stdClass();
-    $page->course = $uploadinfo->course->id;
-    $page->name = $uploadinfo->displayname;
-    $page->intro = '<p>'.$uploadinfo->displayname.'</p>';
-    $page->introformat = FORMAT_HTML;
+function mod_page_dndupload_handle($uploadinfo) {
+    // Gather the required info.
+    $data = new stdClass();
+    $data->course = $uploadinfo->course->id;
+    $data->name = $uploadinfo->displayname;
+    $data->intro = '<p>'.$uploadinfo->displayname.'</p>';
+    $data->introformat = FORMAT_HTML;
     if ($uploadinfo->type == 'text/html') {
-        $page->contentformat = FORMAT_HTML;
-        $page->content = clean_param($uploadinfo->content, PARAM_CLEANHTML);
+        $data->contentformat = FORMAT_HTML;
+        $data->content = clean_param($uploadinfo->content, PARAM_CLEANHTML);
     } else {
-        $page->contentformat = FORMAT_PLAIN;
-        $page->content = clean_param($uploadinfo->content, PARAM_TEXT);
+        $data->contentformat = FORMAT_PLAIN;
+        $data->content = clean_param($uploadinfo->content, PARAM_TEXT);
     }
-    $page->display = $display;
-    $page->displayoptions = $displayoptions;
-    $page->timemodified = time();
+    $data->coursemodule = $uploadinfo->coursemodule;
 
-    $page->id = $DB->insert_record('page', $page);
+    // Set the display options to the site defaults.
+    $config = get_config('page');
+    $data->display = $config->display;
+    $data->popupheight = $config->popupheight;
+    $data->popupwidth = $config->popupwidth;
+    $data->printheading = $config->printheading;
+    $data->printintro = $config->printintro;
 
-    return $page->id;
+    return page_add_instance($data, null);
 }
index d43a48d..ff884ea 100644 (file)
@@ -88,6 +88,7 @@ function resource_get_post_actions() {
 function resource_add_instance($data, $mform) {
     global $CFG, $DB;
     require_once("$CFG->libdir/resourcelib.php");
+    require_once("$CFG->dirroot/mod/resource/locallib.php");
     $cmid = $data->coursemodule;
     $data->timemodified = time();
 
@@ -495,7 +496,7 @@ function resource_export_contents($cm, $baseurl) {
  * Register the ability to handle drag and drop file uploads
  * @return array containing details of the files / types the mod can handle
  */
-function resource_dndupload_register() {
+function mod_resource_dndupload_register() {
     return array('files' => array(
                      array('extension' => '*', 'message' => get_string('dnduploadresource', 'mod_resource'))
                  ));
@@ -506,44 +507,23 @@ function resource_dndupload_register() {
  * @param object $uploadinfo details of the file / content that has been uploaded
  * @return int instance id of the newly created mod
  */
-function resource_dndupload_handle($uploadinfo) {
-    global $DB, $CFG;
-    require_once("$CFG->libdir/resourcelib.php");
-
-    // Set display options to site defaults.
+function mod_resource_dndupload_handle($uploadinfo) {
+    // Gather the required info.
+    $data = new stdClass();
+    $data->course = $uploadinfo->course->id;
+    $data->name = $uploadinfo->displayname;
+    $data->intro = '<p>'.$uploadinfo->displayname.'</p>';
+    $data->introformat = FORMAT_HTML;
+    $data->coursemodule = $uploadinfo->coursemodule;
+    $data->files = $uploadinfo->draftitemid;
+
+    // Set the display options to the site defaults.
     $config = get_config('resource');
-    $display = $config->display;
-    $displayoptions = array();
-    if ($display == RESOURCELIB_DISPLAY_POPUP) {
-        $displayoptions['popupheight'] = $config->popupheight;
-        $displayoptions['popupwidth'] = $config->popupwidth;
-    }
-    if (in_array($display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) {
-        $displayoptions['printheading'] = $config->printheading;
-        $displayoptions['printintro'] = $config->printintro;
-    }
-    $displayoptions = serialize($displayoptions);
-
-    // Create the database entry.
-    $resource = new stdClass();
-    $resource->course = $uploadinfo->course->id;
-    $resource->name = $uploadinfo->displayname;
-    $resource->intro = '<p>'.$uploadinfo->displayname.'</p>';
-    $resource->introformat = FORMAT_HTML;
-    $resource->display = $display;
-    $resource->displayoptions = $displayoptions;
-    $resource->timemodified = time();
-
-    $resource->id = $DB->insert_record('resource', $resource);
-
-    // Retrieve the file from the draft file area.
-    $context = context_module::instance($uploadinfo->coursemodule);
-    file_save_draft_area_files($uploadinfo->draftitemid, $context->id, 'mod_resource', 'content', 0, array('subdirs' => false));
-    $fs = get_file_storage();
-    $files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder', false);
-    // Only ever one file - set it as the 'main' file.
-    $file = reset($files);
-    file_set_sortorder($context->id, 'mod_resource', 'content', 0, $file->get_filepath(), $file->get_filename(), 1);
+    $data->display = $config->display;
+    $data->popupheight = $config->popupheight;
+    $data->popupwidth = $config->popupwidth;
+    $data->printheading = $config->printheading;
+    $data->printintro = $config->printintro;
 
-    return $resource->id;
+    return resource_add_instance($data, null);
 }
index 30c7707..8661b71 100644 (file)
@@ -348,7 +348,7 @@ function url_export_contents($cm, $baseurl) {
  * Register the ability to handle drag and drop file uploads
  * @return array containing details of the files / types the mod can handle
  */
-function url_dndupload_register() {
+function mod_url_dndupload_register() {
     return array('types' => array(
                      array('identifier' => 'url', 'message' => get_string('createurl', 'url'))
                  ));
@@ -359,33 +359,23 @@ function url_dndupload_register() {
  * @param object $uploadinfo details of the file / content that has been uploaded
  * @return int instance id of the newly created mod
  */
-function url_dndupload_handle($uploadinfo) {
-    global $DB, $CFG;
-    require_once("$CFG->libdir/resourcelib.php");
+function mod_url_dndupload_handle($uploadinfo) {
+    // Gather all the required data.
+    $data = new stdClass();
+    $data->course = $uploadinfo->course->id;
+    $data->name = $uploadinfo->displayname;
+    $data->intro = '<p>'.$uploadinfo->displayname.'</p>';
+    $data->introformat = FORMAT_HTML;
+    $data->externalurl = clean_param($uploadinfo->content, PARAM_URL);
+    $data->timemodified = time();
 
+    // Set the display options to the site defaults.
     $config = get_config('url');
-    $display = $config->display;
-    if ($display == RESOURCELIB_DISPLAY_POPUP) {
-        $displayoptions['popupwidth'] = $config->popupwidth;
-        $displayoptions['popupheight'] = $config->popupheight;
-    }
-    if (in_array($display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) {
-        $displayoptions['printheading'] = $config->printheading;
-        $displayoptions['printintro'] = $config->printintro;
-    }
-    $displayoptions = serialize($displayoptions);
-
-    $url = new stdClass();
-    $url->course = $uploadinfo->course->id;
-    $url->name = $uploadinfo->displayname;
-    $url->intro = '<p>'.$uploadinfo->displayname.'</p>';
-    $url->introformat = FORMAT_HTML;
-    $url->externalurl = clean_param($uploadinfo->content, PARAM_URL);
-    $url->display = $display;
-    $url->displayoptions = $displayoptions;
-    $url->timemodified = time();
-
-    $url->id = $DB->insert_record('url', $url);
+    $data->display = $config->display;
+    $data->popupwidth = $config->popupwidth;
+    $data->popupheight = $config->popupheight;
+    $data->printheading = $config->printheading;
+    $data->printintro = $config->printintro;
 
-    return $url->id;
+    return url_add_instance($data, null);
 }
index 7b6e4d4..3588bf8 100644 (file)
@@ -130,6 +130,6 @@ table.category_subcategories td {white-space: nowrap;}
 /* Course drag and drop upload styles */
 #dndupload-status {width:60%;margin:0 auto;padding:2px;border:1px solid #ddd;text-align:center;background:#ffc}
 .dndupload-preview {color:#909090;border:1px dashed #909090;}
-.dndupload-progress-outer {width:70px;border:solid black 1px;height:10px;display:inline-block;margin:0;padding:0;overflow:clip;position:relative;}
+.dndupload-progress-outer {width:70px;border:solid black 1px;height:10px;display:inline-block;margin:0;padding:0;overflow:hidden;position:relative;}
 .dndupload-progress-inner {width:0%;height:100%;background-color:green;display:inline-block;margin:0;padding:0;float:left;}
 .dndupload-hidden {display:none;}