MDL-16094 File storage conversion Quiz and Questions
[moodle.git] / question / contextmoveq.php
1 <?php
2 /**
3  * Page for moving questions
4  *
5  * @author me@jamiep.org
6  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
7  * @package questionbank
8  */
10 // Includes.
11 require_once(dirname(__FILE__) . '/../config.php');
12 require_once(dirname(__FILE__) . '/editlib.php');
13 require_once($CFG->dirroot.'/question/contextmoveq_form.php');
15 $ids = required_param('ids', PARAM_SEQUENCE); // question ids
17 if (!$cmid = optional_param('cmid', 0, PARAM_INT)){
18     $courseid = required_param('courseid', PARAM_INT);
19 }
21 $tocatid = required_param('tocatid', PARAM_INT);
22 $returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
24 $thispageurl = new moodle_url('/question/contextmoveq.php');
25 $thispageurl->params(compact('tocatid', 'ids', 'returnurl'));
27 if ($cmid){
28     list($module, $cm) = get_module_from_cmid($cmid);
29     require_login($cm->course, false, $cm);
30     $thiscontext = get_context_instance(CONTEXT_MODULE, $cmid);
31     if (!$returnurl) {
32         $returnurl = "{$CFG->wwwroot}/question/edit.php?cmid={$cm->id}";
33     }
34     $thispageurl->param('cmid', $cmid);
35 } elseif ($courseid) {
36     require_login($courseid, false);
37     $thiscontext = get_context_instance(CONTEXT_COURSE, $courseid);
38     $module = null;
39     $cm = null;
40     if (!$returnurl) {
41         $returnurl = "{$CFG->wwwroot}/question/edit.php?courseid={$COURSE->id}";
42     }
43     $thispageurl->param('courseid', $COURSE->id);
44 } else {
45     print_error('missingcourseorcmid', 'question');
46 }
47 $contexts = new question_edit_contexts($thiscontext);
49 list($usql, $params) = $DB->get_in_or_equal(explode(',', $ids));
51 if (!$questions = $DB->get_records_sql("SELECT q.*, c.contextid FROM {question} q, {question_categories} c  WHERE q.id $usql AND c.id = q.category", $params)) {
52     print_error('questiondoesnotexist', 'question', $returnurl);
53 }
54 if (!$tocat = $DB->get_record('question_categories', array('id' => $tocatid))){
55     print_error('categorydoesnotexist', 'question', $returnurl);
56 }
57 $tocat->context = get_context_instance_by_id($tocat->contextid);
58 require_capability('moodle/question:add', $tocat->context);
59 $tocoursefilesid =  get_filesdir_from_context($tocat->context);
60 $urls = array();
62 if ($tocoursefilesid == SITEID){
63     $toareaname = get_string('filesareasite', 'question');
64 } else {
65     $toareaname = get_string('filesareacourse', 'question');
66 }
67 $fromcoursefilesid = 0;
68 foreach (array_keys($questions) as $id){
69     question_require_capability_on($questions[$id], 'move');
70     get_question_options($questions[$id]);
71     $questions[$id]->context = get_context_instance_by_id($questions[$id]->contextid);
72     $thisfilesid =  get_filesdir_from_context($questions[$id]->context);
73     if ($fromcoursefilesid && $thisfilesid != $fromcoursefilesid){
74        print_error('cannotmovequestion', 'question');
75     } else {
76        $fromcoursefilesid =  $thisfilesid;
77     }
78     if ($tocoursefilesid != $fromcoursefilesid){
79         $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
80     }
81 }
83 $brokenurls = array();
84 foreach (array_keys($urls) as $url){
85     if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
86         $brokenurls[] = $url;
87     }
88 }
89 if ($fromcoursefilesid == SITEID){
90     $fromareaname = get_string('filesareasite', 'question');
91 } else {
92     $fromareaname = get_string('filesareacourse', 'question');
93 }
95 $contextmoveform = new question_context_move_question_form($thispageurl,
96         compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
97                     'fromcoursefilesid', 'tocoursefilesid'));
98 if ($contextmoveform->is_cancelled()){
99     redirect($returnurl);
100 }elseif ($moveformdata = $contextmoveform->get_data()) {
101     if (isset($moveformdata->urls) && is_array($moveformdata->urls)){
102         check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
103         $flipurls = array_keys($urls);
104         //actions on files
105         foreach ($moveformdata->urls as $key => $urlaction){
106             $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
107             $destination = $flipurls[$key];
108             if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
109                 // Ensure the target folder exists.
110                 check_dir_exists(dirname($CFG->dataroot."/$tocoursefilesid/".$destination), true);
112                 // Then make sure the destination file name does not exist. If it does, change the name to be unique.
113                 while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
114                     $matches = array();
115                     //check for '_'. copyno after filename, before extension.
116                     if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
117                         $copyno = $matches[1]+1;
118                     } else {
119                         $copyno = 1;
120                     }
121                     //replace old copy no with incremented one.
122                     $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
123                 }
124             }
125             switch ($urlaction){
126                 case QUESTION_FILECOPY :
127                     if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
128                         print_error('errorfilecannotbecopied', 'question', $returnurl, $source);
129                     }
130                     break;
131                 case QUESTION_FILEMOVE :
132                     if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
133                         print_error('errorfilecannotbemoved', 'question', $returnurl, $source);
134                     }
135                     break;
136                 case QUESTION_FILEMOVELINKSONLY :
137                 case QUESTION_FILEDONOTHING :
138                     break;
139                 default :
140                     print_error('invalidaction', '', $returnurl);
141             }
142             //now search and replace urls in questions.
143             switch ($urlaction){
144                 case QUESTION_FILECOPY :
145                 case QUESTION_FILEMOVE :
146                 case QUESTION_FILEMOVELINKSONLY :
147                     $url = $flipurls[$key];
148                     $questionswithlinks = array_unique($urls[$url]);
149                     foreach ($questionswithlinks as $questionid){
150                         $QTYPES[$questions[$questionid]->qtype]->replace_file_links($questions[$questionid], $fromcoursefilesid, $tocoursefilesid, $url, $destination);
151                     }
152                     break;
153                 case  QUESTION_FILEDONOTHING :
154                     break;
155                 default :
156                     print_error('invalidaction', '', $returnurl);
157                     break;
158             }
161         }
162     }
164 /// Now move questions.
165     if (!question_move_questions_to_category($ids, $tocat->id)) {
166         print_error('errormovingquestions', 'question', $returnurl, $ids);
167     }
168     if ($returnurl) {
169         $returnurl = new moodle_url('/' . $returnurl);
170     }
171     redirect($returnurl);
174 $streditingcategories = get_string('editcategories', 'quiz');
175 $strmovingquestions = get_string('movingquestions', 'question');
176 $PAGE->set_url($thispageurl->out());
177 $PAGE->navbar->add($strmovingquestions);
178 $PAGE->set_title($strmovingquestions);
179 $PAGE->set_heading($COURSE->fullname);
180 echo $OUTPUT->header();
182 //parameter for get_string
183 $questionsstr = new object();
184 $questionsstr->tocontext = print_context_name($tocat->context);
185 $questionsstr->fromareaname = $fromareaname;
187 //comma seperated string "'xx', 'cx', 'sdf' and 'fgdhfg'"
188 $questionnamestojoin = array();
189 foreach ($questions as $question){
190    $questionnamestojoin[] =  $question->name;
192 $tojoincount = count($questionnamestojoin);
194 if ($tojoincount > 1){
195     $a = new object();
196     $a->one = $questionnamestojoin[$tojoincount -2].'"</strong>';
197     $a->two = '<strong>"'.$questionnamestojoin[$tojoincount -1];
198     $questionnamestojoin[$tojoincount -2] = get_string('and', '', $a);
199     unset($questionnamestojoin[$tojoincount -1]);
201 $questionsstr->questions = '<strong>"'.join($questionnamestojoin, '"</strong>, <strong>"').'"</strong>';
203 if (count($urls)){
204     $defaults = array();
205     for ($default_key = 0; $default_key < count($urls); $default_key++){
206         $defaults['urls'][$default_key] = QUESTION_FILECOPY;
207     }
208     $contextmoveform->set_data($defaults);
210     //some parameters for get_string
211     $questionsstr->urlcount = count($urls);
213     $questionsstr->toareaname = $toareaname;
215     echo $OUTPUT->box(get_string('movingquestionsandfiles', 'question', $questionsstr), 'boxwidthnarrow boxaligncenter generalbox');
216 } else {
217     echo $OUTPUT->box(get_string('movingquestionsnofiles', 'question', $questionsstr), 'boxwidthnarrow boxaligncenter generalbox');
219 $contextmoveform->display();
220 echo $OUTPUT->footer();