merging MOODLE_19_QUESTIONS with HEAD
authorjamiesensei <jamiesensei>
Thu, 9 Aug 2007 22:44:14 +0000 (22:44 +0000)
committerjamiesensei <jamiesensei>
Thu, 9 Aug 2007 22:44:14 +0000 (22:44 +0000)
question/category_form.php [new file with mode: 0644]
question/contextmove.php [new file with mode: 0644]
question/contextmove_form.php [new file with mode: 0644]
question/contextmoveq.php [new file with mode: 0644]
question/contextmoveq_form.php [new file with mode: 0644]
question/export_form.php [new file with mode: 0644]
question/import_form.php [new file with mode: 0644]
question/move_form.php [new file with mode: 0644]

diff --git a/question/category_form.php b/question/category_form.php
new file mode 100644 (file)
index 0000000..47ae3b2
--- /dev/null
@@ -0,0 +1,39 @@
+<?php  //$Id$
+
+require_once($CFG->libdir.'/formslib.php');
+
+class question_category_edit_form extends moodleform {
+
+    function definition() {
+        global $CFG;
+        $mform    =& $this->_form;
+
+        $contexts   = $this->_customdata['contexts'];
+        $currentcat   = $this->_customdata['currentcat'];
+//--------------------------------------------------------------------------------
+        $mform->addElement('header', 'categoryheader', get_string('addcategory', 'quiz'));
+        $mform->setHelpButton('categoryheader', array('categories_edit', get_string('addcategory', 'quiz'), 'quiz'));
+
+        $questioncategoryel = $mform->addElement('questioncategory', 'parent', get_string('parent', 'quiz'),
+                    array('contexts'=>$contexts, 'top'=>true, 'currentcat'=>$currentcat, 'nochildrenof'=>$currentcat));
+        $mform->setType('parent', PARAM_SEQUENCE);
+        if (1 == count_records_sql("SELECT count(*) FROM {$CFG->prefix}question_categories as c1, {$CFG->prefix}question_categories as c2 WHERE c2.id = $currentcat AND c1.contextid = c2.contextid")){
+            $mform->hardFreeze('parent');
+        }
+
+        $mform->addElement('text','name', get_string('name'),'maxlength="254" size="50"');
+        $mform->setDefault('name', '');
+        $mform->addRule('name', get_string('categorynamecantbeblank', 'quiz'), 'required', null, 'client');
+        $mform->setType('name', PARAM_MULTILANG);
+
+        $mform->addElement('textarea', 'info', get_string('categoryinfo', 'quiz'), array('rows'=> '10', 'cols'=>'45'));
+        $mform->setDefault('info', '');
+        $mform->setType('info', PARAM_MULTILANG);
+//--------------------------------------------------------------------------------
+        $this->add_action_buttons(false, get_string('addcategory', 'quiz'));
+//--------------------------------------------------------------------------------
+        $mform->addElement('hidden', 'id', 0);
+        $mform->setType('id', PARAM_INT);
+    }
+}
+?>
diff --git a/question/contextmove.php b/question/contextmove.php
new file mode 100644 (file)
index 0000000..ad7ad18
--- /dev/null
@@ -0,0 +1,249 @@
+<?php // $Id$
+/**
+ * Allows someone with appropriate permissions to move a category and associated
+ * files to another context.
+ *
+ * @author Jamie Pratt
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package questionbank
+ */
+
+    require_once("../config.php");
+    require_once($CFG->dirroot."/question/editlib.php");
+    require_once($CFG->dirroot."/question/contextmove_form.php");
+
+    list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) = question_edit_setup('categories');
+
+    // get values from form for actions on this page
+    $toparent = required_param('toparent', PARAM_SEQUENCE);
+    $cattomove = required_param('cattomove', PARAM_INT);
+    $totop = optional_param('totop', 0, PARAM_INT); // optional param moves category to top of peers. Default is
+        //to add it to the bottom.
+
+
+
+    $onerrorurl = $CFG->wwwroot.'/question/category.php?'.$thispageurl->get_query_string();
+    list($toparent, $contextto) = explode(',', $toparent);
+    if (!empty($toparent)){//not top level category, make it a child of $toparent
+        if (!$toparent = get_record('question_categories', 'id', $toparent)){
+            error('Invalid category id for parent!', $onerrorurl);
+        }
+        $contextto = $toparent->contextid;
+    } else {
+        $toparent = new object();
+        $toparent->id = 0;
+        $toparent->contextid = $contextto;
+    }
+    if (!$cattomove = get_record('question_categories', 'id', $cattomove)){
+        error('Invalid category id to move!', $onerrorurl);
+    }
+    if ($cattomove->contextid == $contextto){
+        error("You shouldn't have got here if you're not moving a category to another context.", $onerrorurl);
+    }
+    $cattomove->categorylist = question_categorylist($cattomove->id);
+
+    $thispageurl->params(array('cattomove'=>$cattomove->id,
+                                  'toparent'=>"{$toparent->id},{$toparent->contextid}",
+                                  'totop'=>$totop));
+
+    $contextfrom = get_context_instance_by_id($cattomove->contextid);
+    $contextto = get_context_instance_by_id($contextto);
+    $contexttostring = print_context_name($contextto);
+
+    require_capability('moodle/question:managecategory', $contextfrom);
+    require_capability('moodle/question:managecategory', $contextto);
+
+
+    $fromcoursefilesid = get_filesdir_from_context($contextfrom);//siteid or courseid
+    $tocoursefilesid = get_filesdir_from_context($contextto);//siteid or courseid
+    if ($fromcoursefilesid != $tocoursefilesid){
+        $questions = get_records_select('question', "category IN ({$cattomove->categorylist})");
+        $urls = array();
+        if ($questions){
+            foreach ($questions as $id => $question){
+                $QTYPES[$questions[$id]->qtype]->get_question_options(&$questions[$id]);
+                $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
+            }
+        }
+        ksort($urls);
+    } else {
+        $urls = array();
+    }
+    $brokenurls = array();
+    foreach (array_keys($urls) as $url){
+        if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
+            $brokenurls[] = $url;
+        }
+    }
+    if ($fromcoursefilesid == SITEID){
+        $fromareaname = get_string('filesareasite', 'question');
+    } else {
+        $fromareaname = get_string('filesareacourse', 'question');
+    }
+    if ($tocoursefilesid == SITEID){
+        $toareaname = get_string('filesareasite', 'question');
+    } else {
+        $toareaname = get_string('filesareacourse', 'question');
+    }
+    $contextmoveform = new question_context_move_form($thispageurl,
+                            compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
+                                    'fromcoursefilesid', 'tocoursefilesid'));
+    if ($contextmoveform->is_cancelled()){
+        $thispageurl->remove_params('cattomove', 'toparent', 'totop');
+        redirect($CFG->wwwroot."/question/category.php?".$thispageurl->get_query_string());
+    }elseif ($moveformdata = $contextmoveform->get_data()) {
+        if (is_array($moveformdata->urls)){
+            check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
+            $flipurls = array_keys($urls);
+            foreach ($moveformdata->urls as $key => $urlaction){
+                $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
+                $destination = $flipurls[$key];
+                if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
+                    while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
+                        $matches = array();
+                        //check for '_'. copyno after filename, before extension.
+                        if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
+                            $copyno = $matches[1]+1;
+                        } else {
+                            $copyno = 1;
+                        }
+                        //replace old copy no with incremented one.
+                        $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
+                    }
+                }
+                switch ($urlaction){
+                    case QUESTION_FILECOPY :
+                        if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
+                            print_error('errorfilecannotbecopied', 'question', $onerrorurl, $source);
+                        }
+                        break;
+                    case QUESTION_FILEMOVE :
+                        if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
+                            print_error('errorfilecannotbemoved', 'question', $onerrorurl, $source);
+                        }
+                        break;
+                    case QUESTION_FILEDONOTHING :
+                    case QUESTION_FILEMOVELINKSONLY :
+                        break;
+                    default :
+                        error('Invalid action selected!', $onerrorurl);
+                }
+                switch ($urlaction){
+                    //now search and replace urls in questions.
+                    case QUESTION_FILECOPY :
+                    case QUESTION_FILEMOVE :
+                    case QUESTION_FILEMOVELINKSONLY :
+                        $url = $flipurls[$key];
+                        $questionids = array_unique($urls[$url]);
+                        foreach ($questionids as $questionid){
+                            $question = $questions[$questionid];
+                            $QTYPES[$question->qtype]->replace_file_links($question, $fromcoursefilesid, $tocoursefilesid, $url, $destination);
+                        }
+                        break;
+                    case  QUESTION_FILEDONOTHING :
+                    default :
+                        break;
+                }
+
+
+            }
+        }
+
+        //adjust sortorder before we make the cat a peer of it's new peers
+        $peers = get_records_select_menu('question_categories', "contextid = {$toparent->contextid} AND ".
+                                                                 "parent = {$toparent->id}", "sortorder ASC",
+                                                                 "id, id");
+        $peers = array_keys($peers);
+        if ($totop){
+           array_unshift($peers, $cattomove->id);
+        } else {
+           $peers[] = $cattomove->id;
+        }
+        $sortorder = 0;
+        foreach ($peers as $peer) {
+            if (! set_field('question_categories', "sortorder", $sortorder, "id", $peer)) {
+                print_error('listupdatefail', '', $onerrorurl);
+            }
+            $sortorder++;
+        }
+        //now move category
+        $cat = new object();
+        $cat->id = $cattomove->id;
+        $cat->parent = $toparent->id;
+        //set context of category we are moving and all children also!
+        if (!execute_sql("UPDATE {$CFG->prefix}question_categories SET contextid = {$contextto->id} WHERE id IN ({$cattomove->categorylist})", false)){
+            error("Could not move the category '$newname' to ".$contexttostring, $onerrorurl);
+        }
+        //finally set the new parent id
+        if (!update_record("question_categories", $cat)) {
+            error("Could not update the category '$updatename'", $onerrorurl);
+        }
+        $thispageurl->remove_params('cattomove', 'toparent', 'totop');
+        redirect($CFG->wwwroot."/question/category.php?".$thispageurl->get_query_string(array('cat'=>"{$cattomove->id},{$contextto->id}")));
+    }
+
+    $streditingcategories = get_string('editcategories', 'quiz');
+    $crumbs = array();
+    if ($cm!==null) {
+        // Page header
+        $strupdatemodule = has_capability('moodle/course:manageactivities', $contexts->lowest())
+            ? update_module_button($cm->id, $COURSE->id, get_string('modulename', $cm->modname))
+            : "";
+        $crumbs[] = array('name' => get_string('modulenameplural', $cm->modname),
+                            'link' => "$CFG->wwwroot/mod/{$cm->modname}/index.php?id=$COURSE->id",
+                            'type' => 'activity');
+        $crumbs[] = array('name' => format_string($module->name),
+                            'link' => "$CFG->wwwroot/mod/{$cm->modname}/view.php?id={$cm->id}",
+                            'type' => 'title');
+    } else {
+        // Print basic page layout.
+        $strupdatemodule = '';
+    }
+
+
+    $crumbs[] = array('name' => $streditingcategories, 'link' => $thispageurl->out(), 'type' => 'title');
+    $crumbs[] = array('name' => get_string('movingcategory', 'question'), 'link' => '', 'type' => 'title');
+
+    $navigation = build_navigation($crumbs);
+    print_header_simple($streditingcategories, '', $navigation, "", "", true, $strupdatemodule);
+
+    // print tabs
+    if ($cm!==null) {
+        $currenttab = 'edit';
+        $mode = 'categories';
+        ${$cm->modname} = $module;
+        include($CFG->dirroot."/mod/{$cm->modname}/tabs.php");
+    } else {
+        $currenttab = 'categories';
+        $context = $contexts->lowest();
+        include('tabs.php');
+    }
+    //parameter for get_string
+    $cattomove->contextto = $contexttostring;
+    if (count($urls)){
+        $defaults = array();
+        for ($default_key =0; $default_key < count($urls); $default_key++){
+            switch ($tocoursefilesid){
+                case SITEID:
+                    $defaults['urls'][$default_key] = QUESTION_FILEMOVE;
+                    break;
+                default :
+                    $defaults['urls'][$default_key] = QUESTION_FILECOPY;
+                    break;
+
+            }
+        }
+        $contextmoveform->set_data($defaults);
+        //some parameters for get_string
+        $cattomove->urlcount = count($urls);
+        $cattomove->toareaname = $toareaname;
+        $cattomove->fromareaname = $fromareaname;
+
+        print_box(get_string('movingcategoryandfiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
+    } else {
+        print_box(get_string('movingcategorynofiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
+    }
+    $contextmoveform->display();
+    print_object($brokenurls);
+    print_footer($COURSE);
+?>
diff --git a/question/contextmove_form.php b/question/contextmove_form.php
new file mode 100644 (file)
index 0000000..c732d58
--- /dev/null
@@ -0,0 +1,104 @@
+<?php  //$Id$
+
+require_once($CFG->libdir.'/formslib.php');
+
+class question_context_move_form extends moodleform {
+
+    function definition() {
+        global $CFG;
+        $mform    =& $this->_form;
+
+//--------------------------------------------------------------------------------
+        $urls   = $this->_customdata['urls'];
+        $fromareaname   = $this->_customdata['fromareaname'];
+        $toareaname   = $this->_customdata['toareaname'];
+        $fileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
+                      QUESTION_FILECOPY=>get_string('copy', 'question', $fromareaname),
+                      QUESTION_FILEMOVE=>get_string('move', 'question', $fromareaname),
+                      QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
+        $brokenfileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
+                  QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
+        $brokenurls   = $this->_customdata['brokenurls'];
+        if (count($urls)){
+
+            $mform->addElement('header','general', get_string('filestomove', 'question', $toareaname));
+
+            $i = 0;
+            foreach (array_keys($urls) as $url){
+                $iconname = mimeinfo('icon', $url);
+                $icontype = mimeinfo('type', $url);
+                $img = "<img src=\"$CFG->pixpath/f/$iconname\"  class=\"icon\" alt=\"$icontype\" />";
+                if (in_array($url, $brokenurls)){
+                    $mform->addElement('select', "urls[$i]", $img.$url, $brokenfileoptions);
+                } else {
+                    $mform->addElement('select', "urls[$i]", $img.$url, $fileoptions);
+                }
+                $i++;
+            }
+
+        }
+        if (count($brokenurls)){
+            $mform->addElement('advcheckbox','ignorebroken', get_string('ignorebroken', 'question'));
+        }
+        //--------------------------------------------------------------------------------
+        $this->add_action_buttons(true, get_string('movecategory', 'question'));
+
+    }
+
+    function validation($data){
+        $errors = array();
+        $tocoursefilesid = $this->_customdata['tocoursefilesid'];
+        $fromcoursefilesid = $this->_customdata['fromcoursefilesid'];
+        if (isset($data['urls'])  && (count($data['urls']))){
+            foreach ($data['urls'] as $key => $urlaction){
+                switch ($urlaction){
+                    case QUESTION_FILEMOVE :
+                        if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $fromcoursefilesid))){
+                            $errors["urls[$key]"] = get_string('filecantmovefrom', 'question');
+                        }
+                        //no break; COPY check is also applied to MOVE action
+                    case QUESTION_FILECOPY :
+                        if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $tocoursefilesid))){
+                            $errors["urls[$key]"] = get_string('filecantmoveto', 'question');
+                        }
+                        break;
+                    case QUESTION_FILEMOVELINKSONLY :
+                    case  QUESTION_FILEDONOTHING :
+                        break;
+                }
+            }
+        }
+        //check that there hasn't been any changes in files between time form was displayed
+        //and now when it has been submitted.
+        if (isset($data['urls'])  &&
+            (count($data['urls'])
+                != count($this->_customdata['urls']))){
+            $errors['urls[0]'] = get_string('errorfileschanged', 'question');
+        }
+        return $errors;
+    }
+    /*
+     * We want these errors to show up on first loading the form which is not the default for
+     * validation method which is not run until submission.
+     */
+    function definition_after_data(){
+        $mform = $this->_form;
+        $brokenurls   = $this->_customdata['brokenurls'];
+        if (count($brokenurls)){
+            $ignoreval = $mform->getElementValue('ignorebroken');
+            if (!$ignoreval){
+                $urls   = $this->_customdata['urls'];
+                $i = 0;
+                foreach (array_keys($urls) as $url){
+                    if (in_array($url, $brokenurls)){
+                        $mform->setElementError("urls[$i]", get_string('broken', 'question'));
+                    } else {
+                        $mform->setElementError("urls[$i]", '');
+                    }
+                    $i++;
+                }
+            }
+        }
+    }
+}
+?>
diff --git a/question/contextmoveq.php b/question/contextmoveq.php
new file mode 100644 (file)
index 0000000..a65eba4
--- /dev/null
@@ -0,0 +1,245 @@
+<?php // $Id$
+/**
+ * Page for moving questions
+ *
+ * @author me@jamiep.org
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package questionbank
+ */
+
+// Includes.
+require_once(dirname(__FILE__) . '/../config.php');
+require_once(dirname(__FILE__) . '/editlib.php');
+require_once($CFG->dirroot.'/question/contextmoveq_form.php');
+
+$ids = required_param('ids',PARAM_SEQUENCE); // question ids
+
+if (!$cmid = optional_param('cmid', 0, PARAM_INT)){
+    $courseid = required_param('courseid', PARAM_INT);
+}
+
+$tocatid = required_param('tocatid', PARAM_INT);
+$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
+
+$thispageurl = new moodle_url();
+$thispageurl->params(compact('tocatid', 'ids', 'returnurl'));
+
+if ($cmid){
+    list($module, $cm) = get_module_from_cmid($cmid);
+    require_login($cm->course, false, $cm);
+    $thiscontext = get_context_instance(CONTEXT_MODULE, $cmid);
+    if (!$returnurl) {
+        $returnurl = "{$CFG->wwwroot}/question/edit.php?cmid={$cm->id}";
+    }
+    $thispageurl->param('cmid', $cmid);
+} elseif ($courseid) {
+    require_login($courseid, false);
+    $thiscontext = get_context_instance(CONTEXT_COURSE, $courseid);
+    $module = null;
+    $cm = null;
+    if (!$returnurl) {
+        $returnurl = "{$CFG->wwwroot}/question/edit.php?courseid={$COURSE->id}";
+    }
+    $thispageurl->param('courseid', $COURSE->id);
+} else {
+    error('Need to pass courseid or cmid to this script.');
+}
+
+
+if (!$questions = get_records_sql("SELECT q.*, c.contextid FROM {$CFG->prefix}question q, {$CFG->prefix}question_categories c  WHERE q.id IN ($ids) AND c.id = q.category")) {
+    print_error('questiondoesnotexist', 'question', $returnurl);
+}
+if (!$tocat = get_record('question_categories', 'id', $tocatid)){
+    print_error('categorydoesnotexist', 'question', $returnurl);
+}
+$tocat->context = get_context_instance_by_id($tocat->contextid);
+require_capability('moodle/question:add', $tocat->context);
+$tocoursefilesid =  get_filesdir_from_context($tocat->context);
+$urls = array();
+
+if ($tocoursefilesid == SITEID){
+    $toareaname = get_string('filesareasite', 'question');
+} else {
+    $toareaname = get_string('filesareacourse', 'question');
+}
+$fromcoursefilesid = 0;
+foreach (array_keys($questions) as $id){
+    question_require_capability_on($questions[$id], 'move');
+    get_question_options($questions[$id]);
+    $questions[$id]->context = get_context_instance_by_id($questions[$id]->contextid);
+    $thisfilesid =  get_filesdir_from_context($questions[$id]->context);
+    if ($fromcoursefilesid && $thisfilesid != $fromcoursefilesid){
+       error('You can\'t use this script to move questions that have files associated with them from different areas.');
+    } else {
+       $fromcoursefilesid =  $thisfilesid;
+    }
+    if ($tocoursefilesid != $fromcoursefilesid){
+        $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
+    }
+}
+
+$brokenurls = array();
+foreach (array_keys($urls) as $url){
+    if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
+        $brokenurls[] = $url;
+    }
+}
+if ($fromcoursefilesid == SITEID){
+    $fromareaname = get_string('filesareasite', 'question');
+} else {
+    $fromareaname = get_string('filesareacourse', 'question');
+}
+
+$contextmoveform = new question_context_move_question_form($thispageurl,
+        compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
+                    'fromcoursefilesid', 'tocoursefilesid'));
+if ($contextmoveform->is_cancelled()){
+    redirect($returnurl);
+}elseif ($moveformdata = $contextmoveform->get_data()) {
+    if (is_array($moveformdata->urls)){
+        check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
+        $flipurls = array_keys($urls);
+        //actions on files
+        foreach ($moveformdata->urls as $key => $urlaction){
+            $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
+            $destination = $flipurls[$key];
+            if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
+                while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
+                    $matches = array();
+                    //check for '_'. copyno after filename, before extension.
+                    if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
+                        $copyno = $matches[1]+1;
+                    } else {
+                        $copyno = 1;
+                    }
+                    //replace old copy no with incremented one.
+                    $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
+                }
+            }
+            switch ($urlaction){
+                case QUESTION_FILECOPY :
+                    if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
+                        print_error('errorfilecannotbecopied', 'question', $onerrorurl, $source);
+                    }
+                    break;
+                case QUESTION_FILEMOVE :
+                    if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
+                        print_error('errorfilecannotbemoved', 'question', $onerrorurl, $source);
+                    }
+                    break;
+                case QUESTION_FILEMOVELINKSONLY :
+                case QUESTION_FILEDONOTHING :
+                    break;
+                default :
+                    error('Invalid action selected!', $onerrorurl);
+            }
+            //now search and replace urls in questions.
+            switch ($urlaction){
+                case QUESTION_FILECOPY :
+                case QUESTION_FILEMOVE :
+                case QUESTION_FILEMOVELINKSONLY :
+                    $url = $flipurls[$key];
+                    $questionswithlinks = array_unique($urls[$url]);
+                    foreach ($questionswithlinks as $questionid){
+                        $QTYPES[$questions[$questionid]->qtype]->replace_file_links($questions[$questionid], $fromcoursefilesid, $tocoursefilesid, $url, $destination);
+                    }
+                    break;
+                case  QUESTION_FILEDONOTHING :
+                    break;
+                default :
+                    error('Invalid action selected!', $onerrorurl);
+                    break;
+            }
+
+
+        }
+    }
+    //now move questions
+    if (!execute_sql("UPDATE {$CFG->prefix}question SET category = {$tocat->id} WHERE id IN ({$ids})", false)){
+        error("Could not move the questions {$ids} to category ".$tocat->name, $onerrorurl);
+    }
+    redirect($returnurl);
+}
+
+$streditingcategories = get_string('editcategories', 'quiz');
+$crumbs = array();
+if ($cmid) {
+    // Page header
+    $context = get_context_instance(CONTEXT_MODULE, $cm->id);
+    $strupdatemodule = has_capability('moodle/course:manageactivities', $context)
+        ? update_module_button($cm->id, $COURSE->id, get_string('modulename', $cm->modname))
+        : "";
+    $crumbs[] = array('name' => get_string('modulenameplural', $cm->modname),
+                        'link' => "$CFG->wwwroot/mod/{$cm->modname}/index.php?id=$COURSE->id",
+                        'type' => 'activity');
+    $crumbs[] = array('name' => format_string($module->name),
+                        'link' => "$CFG->wwwroot/mod/{$cm->modname}/view.php?id={$cm->id}",
+                        'type' => 'title');
+} else {
+    // Print basic page layout.
+    $strupdatemodule = '';
+}
+$strmovingquestions = get_string('movingquestions', 'question');
+$crumbs[] = array('name' => $strmovingquestions, 'link' => '', 'type' => 'title');
+
+$navigation = build_navigation($crumbs);
+print_header_simple($strmovingquestions, '', $navigation, "", "", true, $strupdatemodule);
+
+// print tabs
+if ($cm!==null) {
+    $currenttab = 'edit';
+    $mode = 'questions';
+    ${$cm->modname} = $module;
+    include($CFG->dirroot."/mod/{$cm->modname}/tabs.php");
+} else {
+    $currenttab = 'questions';
+    include('tabs.php');
+}
+//parameter for get_string
+$questionsstr = new object();
+$questionsstr->tocontext = print_context_name($tocat->context);
+$questionsstr->fromareaname = $fromareaname;
+
+//comma seperated string "'xx', 'cx', 'sdf' and 'fgdhfg'"
+$questionnamestojoin = array();
+foreach ($questions as $question){
+   $questionnamestojoin[] =  $question->name;
+}
+$tojoincount = count($questionnamestojoin);
+
+if ($tojoincount > 1){
+    $a = new object();
+    $a->one = $questionnamestojoin[$tojoincount -2].'"</strong>';
+    $a->two = '<strong>"'.$questionnamestojoin[$tojoincount -1];
+    $questionnamestojoin[$tojoincount -2] = get_string('and', '', $a);
+    unset($questionnamestojoin[$tojoincount -1]);
+}
+$questionsstr->questions = '<strong>"'.join($questionnamestojoin, '"</strong>, <strong>"').'"</strong>';
+
+if (count($urls)){
+    $defaults = array();
+    for ($default_key =0; $default_key < count($urls); $default_key++){
+        switch ($tocoursefilesid){
+            case SITEID:
+                $defaults['urls'][$default_key] = QUESTION_FILEMOVE;
+                break;
+            default :
+                $defaults['urls'][$default_key] = QUESTION_FILECOPY;
+                break;
+
+        }
+    }
+    $contextmoveform->set_data($defaults);
+
+    //some parameters for get_string
+    $questionsstr->urlcount = count($urls);
+
+    $questionsstr->toareaname = $toareaname;
+
+    print_box(get_string('movingquestionsandfiles', 'question', $questionsstr), 'boxwidthnarrow boxaligncenter generalbox');
+} else {
+    print_box(get_string('movingquestionsnofiles', 'question', $questionsstr), 'boxwidthnarrow boxaligncenter generalbox');
+}
+$contextmoveform->display();
+print_footer($COURSE);
+?>
\ No newline at end of file
diff --git a/question/contextmoveq_form.php b/question/contextmoveq_form.php
new file mode 100644 (file)
index 0000000..6617b87
--- /dev/null
@@ -0,0 +1,108 @@
+<?php  //$Id$
+
+require_once($CFG->libdir.'/formslib.php');
+
+class question_context_move_question_form extends moodleform {
+
+    function definition() {
+        global $CFG;
+        $mform    =& $this->_form;
+
+//--------------------------------------------------------------------------------
+        $urls   = $this->_customdata['urls'];
+        $fromareaname   = $this->_customdata['fromareaname'];
+        $toareaname   = $this->_customdata['toareaname'];
+        $fileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
+                  QUESTION_FILECOPY=>get_string('copy', 'question', $fromareaname),
+                  QUESTION_FILEMOVE=>get_string('move', 'question', $fromareaname),
+                  QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
+        $brokenfileoptions = array(QUESTION_FILEDONOTHING=>get_string('donothing', 'question'),
+                  QUESTION_FILEMOVELINKSONLY=>get_string('movelinksonly', 'question', $fromareaname));
+
+        $brokenurls   = $this->_customdata['brokenurls'];
+        if (count($urls)){
+
+            $mform->addElement('header','general', get_string('filestomove', 'question', $toareaname));
+
+            $i = 0;
+            foreach (array_keys($urls) as $url){
+                $iconname = mimeinfo('icon', $url);
+                $icontype = mimeinfo('type', $url);
+                $img = "<img src=\"$CFG->pixpath/f/$iconname\"  class=\"icon\" alt=\"$icontype\" />";
+                if (in_array($url, $brokenurls)){
+                    $mform->addElement('select', "urls[$i]", $img.$url, $brokenfileoptions);
+                } else {
+                    $mform->addElement('select', "urls[$i]", $img.$url, $fileoptions);
+                }
+                $i++;
+            }
+
+        }
+        if (count($brokenurls)){
+            $mform->addElement('advcheckbox','ignorebroken', get_string('ignorebroken', 'question'));
+        }
+//--------------------------------------------------------------------------------
+        $this->add_action_buttons(true, get_string('moveq', 'question'));
+    }
+
+    function validation($data){
+        $errors = array();
+        $tocoursefilesid = $this->_customdata['tocoursefilesid'];
+        $fromcoursefilesid = $this->_customdata['fromcoursefilesid'];
+        if (isset($data['urls'])  && (count($data['urls']))){
+            foreach ($data['urls'] as $key => $urlaction){
+                switch ($urlaction){
+                    case QUESTION_FILEMOVE :
+                        if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $fromcoursefilesid))){
+                            $errors["urls[$key]"] = get_string('filecantmovefrom', 'question');
+                        }
+                    case QUESTION_FILECOPY :
+                        if (!has_capability('moodle/course:managefiles', get_context_instance(CONTEXT_COURSE, $tocoursefilesid))){
+                            $errors["urls[$key]"] = get_string('filecantmoveto', 'question');
+                        }
+                        break;
+                    case QUESTION_FILEMOVELINKSONLY :
+                    case  QUESTION_FILEDONOTHING :
+                        break;
+                }
+            }
+        }
+        //check that there hasn't been any changes in files between time form was displayed
+        //and now when it has been submitted.
+        if (isset($data['urls'])  &&
+            (count($data['urls'])
+                != count($this->_customdata['urls']))){
+            $errors['urls[0]'] = get_string('errorfileschanged', 'question');
+
+        }
+        return $errors;
+    }
+    /*
+     * We want these errors to show up on first loading the form which is not the default for
+     * validation method which is not run until submission.
+     */
+    function definition_after_data(){
+        static $done = false;
+        if (!$done){
+            $mform = $this->_form;
+            $brokenurls   = $this->_customdata['brokenurls'];
+            if (count($brokenurls)){
+                $ignoreval = $mform->getElementValue('ignorebroken');
+                if (!$ignoreval){
+                    $urls   = $this->_customdata['urls'];
+                    $i = 0;
+                    foreach (array_keys($urls) as $url){
+                        if (in_array($url, $brokenurls)){
+                            $mform->setElementError("urls[$i]", get_string('broken', 'question'));
+                        } else {
+                            $mform->setElementError("urls[$i]", '');
+                        }
+                        $i++;
+                    }
+                }
+            }
+            $done = true;
+        }
+    }
+}
+?>
diff --git a/question/export_form.php b/question/export_form.php
new file mode 100644 (file)
index 0000000..d455055
--- /dev/null
@@ -0,0 +1,44 @@
+<?php  //$Id$
+
+require_once($CFG->libdir.'/formslib.php');
+
+class question_export_form extends moodleform {
+
+    function definition() {
+        $mform    =& $this->_form;
+
+        $defaultcategory   = $this->_customdata['defaultcategory'];
+        $contexts   = $this->_customdata['contexts'];
+        $defaultfilename = $this->_customdata['defaultfilename'];
+//--------------------------------------------------------------------------------
+        $mform->addElement('header','general', get_string('general', 'form'));
+
+        $mform->addElement('questioncategory', 'category', get_string('category','quiz'), compact('contexts'));
+        $mform->setDefault('category', $defaultcategory);
+        $mform->setHelpButton('category', array('exportcategory', get_string('exportcategory','question'), 'quiz'));
+
+        $categorygroup = array();
+        $categorygroup[] =& $mform->createElement('checkbox', 'cattofile', '', get_string('tofilecategory', 'question'));
+        $categorygroup[] =& $mform->createElement('checkbox', 'contexttofile', '', get_string('tofilecontext', 'question'));
+        $mform->addGroup($categorygroup, 'categorygroup', '', '', false);
+        $mform->disabledIf('categorygroup', 'cattofile', 'notchecked');
+        $mform->setDefault('cattofile', 1);
+        $mform->setDefault('contexttofile', 1);
+        
+
+        $fileformatnames = get_import_export_formats('export');
+        $mform->addElement('select', 'format', get_string('fileformat','quiz'), $fileformatnames);
+        $mform->setDefault('format', 'gift');
+        $mform->setHelpButton('format', array('export', get_string('exportquestions', 'quiz'), 'quiz'));
+
+        $mform->addElement('text', 'exportfilename', get_string('exportname', 'quiz'), array('size'=>40));
+        $mform->setDefault('exportfilename', $defaultfilename);
+        $mform->setType('exportfilename', PARAM_CLEANFILE);
+
+
+//--------------------------------------------------------------------------------
+        $this->add_action_buttons(false, get_string('exportquestions', 'quiz'));
+//--------------------------------------------------------------------------------
+    }
+}
+?>
diff --git a/question/import_form.php b/question/import_form.php
new file mode 100644 (file)
index 0000000..e3ef67a
--- /dev/null
@@ -0,0 +1,69 @@
+<?php  //$Id$
+
+require_once($CFG->libdir.'/formslib.php');
+require_once($CFG->libdir.'/form/selectgroups.php');
+
+class question_import_form extends moodleform {
+
+    function definition() {
+        global $COURSE;
+        $mform    =& $this->_form;
+
+        $defaultcategory   = $this->_customdata['defaultcategory'];
+        $contexts   = $this->_customdata['contexts'];
+//--------------------------------------------------------------------------------
+        $mform->addElement('header','general', get_string('general', 'form'));
+
+        $mform->addElement('questioncategory', 'category', get_string('category','quiz'), compact('contexts'));
+        $mform->setDefault('category', $defaultcategory);
+        $mform->setHelpButton('category', array('importcategory', get_string('importcategory','quiz'), 'quiz'));
+
+        $categorygroup = array();
+        $categorygroup[] =& $mform->createElement('checkbox', 'catfromfile', '', get_string('getcategoryfromfile', 'question'));
+        $categorygroup[] =& $mform->createElement('checkbox', 'contextfromfile', '', get_string('getcontextfromfile', 'question'));
+        $mform->addGroup($categorygroup, 'categorygroup', '', '', false);
+        $mform->disabledIf('categorygroup', 'catfromfile', 'notchecked');
+        $mform->setDefault('catfromfile', 1);
+        $mform->setDefault('contextfromfile', 1);
+
+        $fileformatnames = get_import_export_formats('import');
+        $mform->addElement('select', 'format', get_string('fileformat','quiz'), $fileformatnames);
+        $mform->setDefault('format', 'gift');
+
+        $matchgrades = array();
+        $matchgrades['error'] = get_string('matchgradeserror','quiz');
+        $matchgrades['nearest'] = get_string('matchgradesnearest','quiz');
+        $mform->addElement('select', 'matchgrades', get_string('matchgrades','quiz'), $matchgrades);
+        $mform->setHelpButton('matchgrades', array('matchgrades', get_string('matchgrades','quiz'), 'quiz'));
+        $mform->setDefault('matchgrades', 'error');
+
+        $mform->addElement('selectyesno', 'stoponerror', get_string('stoponerror', 'quiz'));
+        $mform->setDefault('stoponerror', 1);
+        $mform->setHelpButton('stoponerror', array('stoponerror', get_string('stoponerror', 'quiz'), 'quiz'));
+        
+//--------------------------------------------------------------------------------
+        $mform->addElement('header', 'importfileupload', get_string('importfileupload','quiz'));
+
+        $this->set_upload_manager(new upload_manager('newfile', true, false, $COURSE, false, 0, false, true, false));
+        $mform->addElement('file', 'newfile', get_string('upload'));
+//--------------------------------------------------------------------------------
+        $this->add_action_buttons(true, get_string('uploadthisfile'));
+
+//--------------------------------------------------------------------------------
+        $mform->addElement('header', 'importfilearea', get_string('importfilearea','quiz'));
+
+        $mform->addElement('choosecoursefile', 'choosefile', get_string('choosefile','quiz'));
+//--------------------------------------------------------------------------------
+        $this->add_action_buttons(true, get_string('importfromthisfile','quiz'));
+//--------------------------------------------------------------------------------
+    }
+    function get_importfile_name(){
+        if ($this->is_submitted() and $this->is_validated()) {
+            // return the temporary filename to process
+            return $this->_upload_manager->files['newfile']['tmp_name'];
+        }else{
+            return  NULL;
+        }
+    }
+}
+?>
diff --git a/question/move_form.php b/question/move_form.php
new file mode 100644 (file)
index 0000000..72fdc3e
--- /dev/null
@@ -0,0 +1,23 @@
+<?php  //$Id$
+
+require_once($CFG->libdir.'/formslib.php');
+
+class question_move_form extends moodleform {
+
+    function definition() {
+        $mform    =& $this->_form;
+
+        $currentcat   = $this->_customdata['currentcat'];
+        $contexts   = $this->_customdata['contexts'];
+//--------------------------------------------------------------------------------
+
+        $mform->addElement('questioncategory', 'category', get_string('category','quiz'), compact('contexts', 'currentcat'));
+
+
+//--------------------------------------------------------------------------------
+        $this->add_action_buttons(true, get_string('categorymoveto', 'quiz'));
+//--------------------------------------------------------------------------------
+        $mform->addElement('hidden', 'delete', $currentcat);
+    }
+}
+?>