question MDL-19820 Updated print_header and build_navigation to OUTPUT and PAGE equiv...
[moodle.git] / question / contextmove.php
1 <?php // $Id$
2 /**
3  * Allows someone with appropriate permissions to move a category and associated
4  * files to another context.
5  *
6  * @author Jamie Pratt
7  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
8  * @package questionbank
9  */
11     require_once("../config.php");
12     require_once($CFG->dirroot."/question/editlib.php");
13     require_once($CFG->dirroot."/question/contextmove_form.php");
15     list($thispageurl, $contexts, $cmid, $cm, $module, $pagevars) = question_edit_setup('categories');
17     // get values from form for actions on this page
18     $toparent = required_param('toparent', PARAM_SEQUENCE);
19     $cattomove = required_param('cattomove', PARAM_INT);
20     $totop = optional_param('totop', 0, PARAM_INT); // optional param moves category to top of peers. Default is
21         //to add it to the bottom.
25     $onerrorurl = $CFG->wwwroot.'/question/category.php?'.$thispageurl->get_query_string();
26     list($toparent, $contextto) = explode(',', $toparent);
27     if (!empty($toparent)){//not top level category, make it a child of $toparent
28         if (!$toparent = $DB->get_record('question_categories', array('id' => $toparent))){
29             print_error('invalidcategoryidforparent', 'question', $onerrorurl);
30         }
31         $contextto = $toparent->contextid;
32     } else {
33         $toparent = new object();
34         $toparent->id = 0;
35         $toparent->contextid = $contextto;
36     }
37     if (!$cattomove = $DB->get_record('question_categories', array('id' => $cattomove))){
38         print_error('invalidcategoryidtomove', 'question', $onerrorurl);
39     }
40     if ($cattomove->contextid == $contextto){
41         print_error('contexterror', '', $onerrorurl);
42     }
43     $cattomove->categorylist = question_categorylist($cattomove->id);
45     $thispageurl->params(array('cattomove'=>$cattomove->id,
46                                   'toparent'=>"{$toparent->id},{$toparent->contextid}",
47                                   'totop'=>$totop));
49     $contextfrom = get_context_instance_by_id($cattomove->contextid);
50     $contextto = get_context_instance_by_id($contextto);
51     $contexttostring = print_context_name($contextto);
53     require_capability('moodle/question:managecategory', $contextfrom);
54     require_capability('moodle/question:managecategory', $contextto);
57     $fromcoursefilesid = get_filesdir_from_context($contextfrom);//siteid or courseid
58     $tocoursefilesid = get_filesdir_from_context($contextto);//siteid or courseid
59     if ($fromcoursefilesid != $tocoursefilesid){
60         list($usql, $params) = $DB->get_in_or_equal(explode(',', $cattomove->categorylist));
61         $questions = $DB->get_records_select('question', "category $usql", $params);
62         $urls = array();
63         if ($questions){
64             foreach ($questions as $id => $question){
65                 $QTYPES[$questions[$id]->qtype]->get_question_options($questions[$id]);
66                 $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
67             }
68         }
69         ksort($urls);
70     } else {
71         $urls = array();
72     }
73     $brokenurls = array();
74     foreach (array_keys($urls) as $url){
75         if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
76             $brokenurls[] = $url;
77         }
78     }
79     if ($fromcoursefilesid == SITEID){
80         $fromareaname = get_string('filesareasite', 'question');
81     } else {
82         $fromareaname = get_string('filesareacourse', 'question');
83     }
84     if ($tocoursefilesid == SITEID){
85         $toareaname = get_string('filesareasite', 'question');
86     } else {
87         $toareaname = get_string('filesareacourse', 'question');
88     }
89     $contextmoveform = new question_context_move_form($thispageurl,
90                             compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
91                                     'fromcoursefilesid', 'tocoursefilesid'));
92     if ($contextmoveform->is_cancelled()){
93         $thispageurl->remove_params('cattomove', 'toparent', 'totop');
94         redirect($CFG->wwwroot."/question/category.php?".$thispageurl->get_query_string());
95     }elseif ($moveformdata = $contextmoveform->get_data()) {
96         if (isset($moveformdata->urls) && is_array($moveformdata->urls)){
97             check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
98             $flipurls = array_keys($urls);
99             foreach ($moveformdata->urls as $key => $urlaction){
100                 $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
101                 $destination = $flipurls[$key];
102                 if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
103                     // Ensure the target folder exists.
104                     check_dir_exists(dirname($CFG->dataroot."/$tocoursefilesid/".$destination), true);
106                     // Then make sure the destination file name does not exist. If it does, change the name to be unique.
107                     while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
108                         $matches = array();
109                         //check for '_'. copyno after filename, before extension.
110                         if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
111                             $copyno = $matches[1]+1;
112                         } else {
113                             $copyno = 1;
114                         }
115                         //replace old copy no with incremented one.
116                         $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
117                     }
118                 }
119                 switch ($urlaction){
120                     case QUESTION_FILECOPY :
121                         if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
122                             print_error('errorfilecannotbecopied', 'question', $onerrorurl, $source);
123                         }
124                         break;
125                     case QUESTION_FILEMOVE :
126                         if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
127                             print_error('errorfilecannotbemoved', 'question', $onerrorurl, $source);
128                         }
129                         break;
130                     case QUESTION_FILEDONOTHING :
131                     case QUESTION_FILEMOVELINKSONLY :
132                         break;
133                     default :
134                         print_error('invalidaction', '', $onerrorurl);
135                 }
136                 switch ($urlaction){
137                     //now search and replace urls in questions.
138                     case QUESTION_FILECOPY :
139                     case QUESTION_FILEMOVE :
140                     case QUESTION_FILEMOVELINKSONLY :
141                         $url = $flipurls[$key];
142                         $questionids = array_unique($urls[$url]);
143                         foreach ($questionids as $questionid){
144                             $question = $questions[$questionid];
145                             $QTYPES[$question->qtype]->replace_file_links($question, $fromcoursefilesid, $tocoursefilesid, $url, $destination);
146                         }
147                         break;
148                     case  QUESTION_FILEDONOTHING :
149                     default :
150                         break;
151                 }
154             }
155         }
157         //adjust sortorder before we make the cat a peer of it's new peers
158         $peers = $DB->get_records_select_menu('question_categories',
159                 'contextid = ? AND parent = ?', array($toparent->contextid, $toparent->id),
160                 'sortorder ASC', 'id, 1');
161         $peers = array_keys($peers);
162         if ($totop){
163            array_unshift($peers, $cattomove->id);
164         } else {
165            $peers[] = $cattomove->id;
166         }
167         $sortorder = 0;
168         foreach ($peers as $peer) {
169             if (! $DB->set_field('question_categories', "sortorder", $sortorder, array("id" => $peer))) {
170                 print_error('listupdatefail', '', $onerrorurl);
171             }
172             $sortorder++;
173         }
174         //now move category
175         $cat = new object();
176         $cat->id = $cattomove->id;
177         $cat->parent = $toparent->id;
178         //set context of category we are moving and all children also!
179         list($usql, $params) = $DB->get_in_or_equal(explode(',', $cattomove->categorylist));
180         $params = array_merge(array($contextto->id), $params);
182         $DB->execute("UPDATE {question_categories} SET contextid = ? WHERE id $usql", $params);
183         //finally set the new parent id
184         $DB->update_record("question_categories", $cat);
185         $thispageurl->remove_params('cattomove', 'toparent', 'totop');
186         redirect($CFG->wwwroot."/question/category.php?".$thispageurl->get_query_string(array('cat'=>"{$cattomove->id},{$contextto->id}")));
187     }
189     $streditingcategories = get_string('editcategories', 'quiz');
190     if ($cm!==null) {
191         // Page header
192         $strupdatemodule = has_capability('moodle/course:manageactivities', $contexts->lowest())
193             ? update_module_button($cm->id, $COURSE->id, get_string('modulename', $cm->modname))
194             : "";
195         $PAGE->navbar->add(get_string('modulenameplural', $cm->modname), new moodle_url($CFG->wwwroot.'/mod/'.$cm->modname.'/index.php', array('id'=>$COURSE->id)));
196         $PAGE->navbar->add(format_string($module->name), new moodle_url($CFG->wwwroot.'/mod/'.$cm->modname.'/view.php', array('id'=>$cm->id)));
197     } else {
198         // Print basic page layout.
199         $strupdatemodule = '';
200     }
202     $PAGE->navbar->add($streditingcategories, $thispageurl->out());
203     $PAGE->navbar->add(get_string('movingcategory', 'question'));
204     $PAGE->set_title($streditingcategories);
205     $PAGE->set_button($strupdatemodule);
206     echo $OUTPUT->header();
208     // print tabs
209     if ($cm!==null) {
210         $currenttab = 'edit';
211         $mode = 'categories';
212         ${$cm->modname} = $module;
213         include($CFG->dirroot."/mod/{$cm->modname}/tabs.php");
214     } else {
215         $currenttab = 'categories';
216         $context = $contexts->lowest();
217         include('tabs.php');
218     }
219     //parameter for get_string
220     $cattomove->contextto = $contexttostring;
221     if (count($urls)){
222         $defaults = array();
223         for ($default_key = 0; $default_key < count($urls); $default_key++){
224             $defaults['urls'][$default_key] = QUESTION_FILECOPY;
225         }
226         $contextmoveform->set_data($defaults);
227         //some parameters for get_string
228         $cattomove->urlcount = count($urls);
229         $cattomove->toareaname = $toareaname;
230         $cattomove->fromareaname = $fromareaname;
232         echo $OUTPUT->box(get_string('movingcategoryandfiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
233     } else {
234         echo $OUTPUT->box(get_string('movingcategorynofiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
235     }
236     $contextmoveform->display();
237     echo $OUTPUT->footer();
238 ?>