merging MOODLE_19_QUESTIONS with HEAD
[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 = get_record('question_categories', 'id', $toparent)){
29             error('Invalid category id for parent!', $onerrorurl);
30         }
31         $contextto = $toparent->contextid;
32     } else {
33         $toparent = new object();
34         $toparent->id = 0;
35         $toparent->contextid = $contextto;
36     }
37     if (!$cattomove = get_record('question_categories', 'id', $cattomove)){
38         error('Invalid category id to move!', $onerrorurl);
39     }
40     if ($cattomove->contextid == $contextto){
41         error("You shouldn't have got here if you're not moving a category to another context.", $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         $questions = get_records_select('question', "category IN ({$cattomove->categorylist})");
61         $urls = array();
62         if ($questions){
63             foreach ($questions as $id => $question){
64                 $QTYPES[$questions[$id]->qtype]->get_question_options(&$questions[$id]);
65                 $urls = array_merge_recursive($urls, $QTYPES[$questions[$id]->qtype]->find_file_links($questions[$id], $fromcoursefilesid));
66             }
67         }
68         ksort($urls);
69     } else {
70         $urls = array();
71     }
72     $brokenurls = array();
73     foreach (array_keys($urls) as $url){
74         if (!file_exists($CFG->dataroot."/$fromcoursefilesid/".$url)){
75             $brokenurls[] = $url;
76         }
77     }
78     if ($fromcoursefilesid == SITEID){
79         $fromareaname = get_string('filesareasite', 'question');
80     } else {
81         $fromareaname = get_string('filesareacourse', 'question');
82     }
83     if ($tocoursefilesid == SITEID){
84         $toareaname = get_string('filesareasite', 'question');
85     } else {
86         $toareaname = get_string('filesareacourse', 'question');
87     }
88     $contextmoveform = new question_context_move_form($thispageurl,
89                             compact('urls', 'fromareaname', 'toareaname', 'brokenurls',
90                                     'fromcoursefilesid', 'tocoursefilesid'));
91     if ($contextmoveform->is_cancelled()){
92         $thispageurl->remove_params('cattomove', 'toparent', 'totop');
93         redirect($CFG->wwwroot."/question/category.php?".$thispageurl->get_query_string());
94     }elseif ($moveformdata = $contextmoveform->get_data()) {
95         if (is_array($moveformdata->urls)){
96             check_dir_exists($CFG->dataroot."/$tocoursefilesid/", true);
97             $flipurls = array_keys($urls);
98             foreach ($moveformdata->urls as $key => $urlaction){
99                 $source = $CFG->dataroot."/$fromcoursefilesid/".$flipurls[$key];
100                 $destination = $flipurls[$key];
101                 if (($urlaction != QUESTION_FILEDONOTHING) && ($urlaction != QUESTION_FILEMOVELINKSONLY)){
102                     while (file_exists($CFG->dataroot."/$tocoursefilesid/".$destination)){
103                         $matches = array();
104                         //check for '_'. copyno after filename, before extension.
105                         if (preg_match('!\_([0-9]+)(\.[^\.\\/]+)?$!', $destination, $matches)){
106                             $copyno = $matches[1]+1;
107                         } else {
108                             $copyno = 1;
109                         }
110                         //replace old copy no with incremented one.
111                         $destination = preg_replace('!(\_[0-9]+)?(\.[^\.\\/]+)?$!', '_'.$copyno.'\\2', $destination, 1);
112                     }
113                 }
114                 switch ($urlaction){
115                     case QUESTION_FILECOPY :
116                         if (!copy($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
117                             print_error('errorfilecannotbecopied', 'question', $onerrorurl, $source);
118                         }
119                         break;
120                     case QUESTION_FILEMOVE :
121                         if (!rename($source, $CFG->dataroot."/$tocoursefilesid/".$destination)){
122                             print_error('errorfilecannotbemoved', 'question', $onerrorurl, $source);
123                         }
124                         break;
125                     case QUESTION_FILEDONOTHING :
126                     case QUESTION_FILEMOVELINKSONLY :
127                         break;
128                     default :
129                         error('Invalid action selected!', $onerrorurl);
130                 }
131                 switch ($urlaction){
132                     //now search and replace urls in questions.
133                     case QUESTION_FILECOPY :
134                     case QUESTION_FILEMOVE :
135                     case QUESTION_FILEMOVELINKSONLY :
136                         $url = $flipurls[$key];
137                         $questionids = array_unique($urls[$url]);
138                         foreach ($questionids as $questionid){
139                             $question = $questions[$questionid];
140                             $QTYPES[$question->qtype]->replace_file_links($question, $fromcoursefilesid, $tocoursefilesid, $url, $destination);
141                         }
142                         break;
143                     case  QUESTION_FILEDONOTHING :
144                     default :
145                         break;
146                 }
149             }
150         }
152         //adjust sortorder before we make the cat a peer of it's new peers
153         $peers = get_records_select_menu('question_categories', "contextid = {$toparent->contextid} AND ".
154                                                                  "parent = {$toparent->id}", "sortorder ASC",
155                                                                  "id, id");
156         $peers = array_keys($peers);
157         if ($totop){
158            array_unshift($peers, $cattomove->id);
159         } else {
160            $peers[] = $cattomove->id;
161         }
162         $sortorder = 0;
163         foreach ($peers as $peer) {
164             if (! set_field('question_categories', "sortorder", $sortorder, "id", $peer)) {
165                 print_error('listupdatefail', '', $onerrorurl);
166             }
167             $sortorder++;
168         }
169         //now move category
170         $cat = new object();
171         $cat->id = $cattomove->id;
172         $cat->parent = $toparent->id;
173         //set context of category we are moving and all children also!
174         if (!execute_sql("UPDATE {$CFG->prefix}question_categories SET contextid = {$contextto->id} WHERE id IN ({$cattomove->categorylist})", false)){
175             error("Could not move the category '$newname' to ".$contexttostring, $onerrorurl);
176         }
177         //finally set the new parent id
178         if (!update_record("question_categories", $cat)) {
179             error("Could not update the category '$updatename'", $onerrorurl);
180         }
181         $thispageurl->remove_params('cattomove', 'toparent', 'totop');
182         redirect($CFG->wwwroot."/question/category.php?".$thispageurl->get_query_string(array('cat'=>"{$cattomove->id},{$contextto->id}")));
183     }
185     $streditingcategories = get_string('editcategories', 'quiz');
186     $crumbs = array();
187     if ($cm!==null) {
188         // Page header
189         $strupdatemodule = has_capability('moodle/course:manageactivities', $contexts->lowest())
190             ? update_module_button($cm->id, $COURSE->id, get_string('modulename', $cm->modname))
191             : "";
192         $crumbs[] = array('name' => get_string('modulenameplural', $cm->modname),
193                             'link' => "$CFG->wwwroot/mod/{$cm->modname}/index.php?id=$COURSE->id",
194                             'type' => 'activity');
195         $crumbs[] = array('name' => format_string($module->name),
196                             'link' => "$CFG->wwwroot/mod/{$cm->modname}/view.php?id={$cm->id}",
197                             'type' => 'title');
198     } else {
199         // Print basic page layout.
200         $strupdatemodule = '';
201     }
204     $crumbs[] = array('name' => $streditingcategories, 'link' => $thispageurl->out(), 'type' => 'title');
205     $crumbs[] = array('name' => get_string('movingcategory', 'question'), 'link' => '', 'type' => 'title');
207     $navigation = build_navigation($crumbs);
208     print_header_simple($streditingcategories, '', $navigation, "", "", true, $strupdatemodule);
210     // print tabs
211     if ($cm!==null) {
212         $currenttab = 'edit';
213         $mode = 'categories';
214         ${$cm->modname} = $module;
215         include($CFG->dirroot."/mod/{$cm->modname}/tabs.php");
216     } else {
217         $currenttab = 'categories';
218         $context = $contexts->lowest();
219         include('tabs.php');
220     }
221     //parameter for get_string
222     $cattomove->contextto = $contexttostring;
223     if (count($urls)){
224         $defaults = array();
225         for ($default_key =0; $default_key < count($urls); $default_key++){
226             switch ($tocoursefilesid){
227                 case SITEID:
228                     $defaults['urls'][$default_key] = QUESTION_FILEMOVE;
229                     break;
230                 default :
231                     $defaults['urls'][$default_key] = QUESTION_FILECOPY;
232                     break;
234             }
235         }
236         $contextmoveform->set_data($defaults);
237         //some parameters for get_string
238         $cattomove->urlcount = count($urls);
239         $cattomove->toareaname = $toareaname;
240         $cattomove->fromareaname = $fromareaname;
242         print_box(get_string('movingcategoryandfiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
243     } else {
244         print_box(get_string('movingcategorynofiles', 'question', $cattomove), 'boxwidthnarrow boxaligncenter generalbox');
245     }
246     $contextmoveform->display();
247     print_object($brokenurls);
248     print_footer($COURSE);
249 ?>