1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * prints the form to import items from xml-file
19 *
20 * @author Andreas Grabs
21 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
22 * @package mod_feedback
23 */
24
25require_once("../../config.php");
26require_once("lib.php");
27require_once('import_form.php');
28
29// get parameters
30$id = required_param('id', PARAM_INT);
31$choosefile = optional_param('choosefile', false, PARAM_PATH);
32$action = optional_param('action', false, PARAM_ALPHA);
33
34$url = new moodle_url('/mod/feedback/import.php', array('id'=>$id));
35if ($choosefile !== false) {
36    $url->param('choosefile', $choosefile);
37}
38if ($action !== false) {
39    $url->param('action', $action);
40}
41$PAGE->set_url($url);
42
43if (! $cm = get_coursemodule_from_id('feedback', $id)) {
44    print_error('invalidcoursemodule');
45}
46
47if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
48    print_error('coursemisconf');
49}
50
51if (! $feedback = $DB->get_record("feedback", array("id"=>$cm->instance))) {
52    print_error('invalidcoursemodule');
53}
54
55$context = context_module::instance($cm->id);
56
57require_login($course, true, $cm);
58
59require_capability('mod/feedback:edititems', $context);
60
61$mform = new feedback_import_form();
62$newformdata = array('id'=>$id,
63                    'deleteolditems'=>'1',
64                    'action'=>'choosefile',
65                    'confirmadd'=>'1',
66                    'do_show'=>'templates');
67$mform->set_data($newformdata);
68$formdata = $mform->get_data();
69
70if ($mform->is_cancelled()) {
71    redirect('edit.php?id='.$id.'&do_show=templates');
72}
73
74// process if we are happy file is ok
75if ($choosefile) {
76    $xmlcontent = $mform->get_file_content('choosefile');
77
78    if (!$xmldata = feedback_load_xml_data($xmlcontent)) {
79        print_error('cannotloadxml', 'feedback', 'edit.php?id='.$id);
80    }
81
82    $importerror = feedback_import_loaded_data($xmldata, $feedback->id);
83    if ($importerror->stat == true) {
84        $url = 'edit.php?id='.$id.'&do_show=templates';
85        redirect($url, get_string('import_successfully', 'feedback'), 3);
86        exit;
87    }
88}
89
90
91/// Print the page header
92$strfeedbacks = get_string("modulenameplural", "feedback");
93$strfeedback  = get_string("modulename", "feedback");
94
95$PAGE->set_heading($course->fullname);
96$PAGE->set_title($feedback->name);
97echo $OUTPUT->header();
98echo $OUTPUT->heading(format_string($feedback->name));
99/// print the tabs
100$current_tab = 'templates';
101require('tabs.php');
102
103/// Print the main part of the page
104///////////////////////////////////////////////////////////////////////////
105///////////////////////////////////////////////////////////////////////////
106///////////////////////////////////////////////////////////////////////////
107echo $OUTPUT->heading(get_string('import_questions', 'feedback'), 3);
108
109if (isset($importerror->msg) AND is_array($importerror->msg)) {
110    echo $OUTPUT->box_start('generalbox errorboxcontent boxaligncenter');
111    foreach ($importerror->msg as $msg) {
112        echo $msg.'<br />';
113    }
114    echo $OUTPUT->box_end();
115}
116
117$mform->display();
118
119echo $OUTPUT->footer();
120
121function feedback_load_xml_data($xmlcontent) {
122    global $CFG;
123    require_once($CFG->dirroot.'/lib/xmlize.php');
124
125    if (!$xmlcontent = feedback_check_xml_utf8($xmlcontent)) {
126        return false;
127    }
128
129    $data = xmlize($xmlcontent, 1, 'UTF-8');
130
131    if (intval($data['FEEDBACK']['@']['VERSION']) != 200701) {
132        return false;
133    }
134    $data = $data['FEEDBACK']['#']['ITEMS'][0]['#']['ITEM'];
135    return $data;
136}
137
138function feedback_import_loaded_data(&$data, $feedbackid) {
139    global $CFG, $DB;
140
141    feedback_load_feedback_items();
142
143    $deleteolditems = optional_param('deleteolditems', 0, PARAM_INT);
144
145    $error = new stdClass();
146    $error->stat = true;
147    $error->msg = array();
148
149    if (!is_array($data)) {
150        $error->msg[] = get_string('data_is_not_an_array', 'feedback');
151        $error->stat = false;
152        return $error;
153    }
154
155    if ($deleteolditems) {
156        feedback_delete_all_items($feedbackid);
157        $position = 0;
158    } else {
159        //items will be add to the end of the existing items
160        $position = $DB->count_records('feedback_item', array('feedback'=>$feedbackid));
161    }
162
163    //depend items we are storing temporary in an mapping list array(new id => dependitem)
164    //we also store a mapping of all items array(oldid => newid)
165    $dependitemsmap = array();
166    $itembackup = array();
167    foreach ($data as $item) {
168        $position++;
169        //check the typ
170        $typ = $item['@']['TYPE'];
171
172        //check oldtypes first
173        switch($typ) {
174            case 'radio':
175                $typ = 'multichoice';
176                $oldtyp = 'radio';
177                break;
178            case 'dropdown':
179                $typ = 'multichoice';
180                $oldtyp = 'dropdown';
181                break;
182            case 'check':
183                $typ = 'multichoice';
184                $oldtyp = 'check';
185                break;
186            case 'radiorated':
187                $typ = 'multichoicerated';
188                $oldtyp = 'radiorated';
189                break;
190            case 'dropdownrated':
191                $typ = 'multichoicerated';
192                $oldtyp = 'dropdownrated';
193                break;
194            default:
195                $oldtyp = $typ;
196        }
197
198        $itemclass = 'feedback_item_'.$typ;
199        if ($typ != 'pagebreak' AND !class_exists($itemclass)) {
200            $error->stat = false;
201            $error->msg[] = 'type ('.$typ.') not found';
202            continue;
203        }
204        $itemobj = new $itemclass();
205
206        $newitem = new stdClass();
207        $newitem->feedback = $feedbackid;
208        $newitem->template = 0;
209        $newitem->typ = $typ;
210        $newitem->name = trim($item['#']['ITEMTEXT'][0]['#']);
211        $newitem->label = trim($item['#']['ITEMLABEL'][0]['#']);
212        if ($typ === 'captcha' || $typ === 'label') {
213            $newitem->label = '';
214            $newitem->name = '';
215        }
216        $newitem->options = trim($item['#']['OPTIONS'][0]['#']);
217        $newitem->presentation = trim($item['#']['PRESENTATION'][0]['#']);
218        //check old types of radio, check, and so on
219        switch($oldtyp) {
220            case 'radio':
221                $newitem->presentation = 'r>>>>>'.$newitem->presentation;
222                break;
223            case 'dropdown':
224                $newitem->presentation = 'd>>>>>'.$newitem->presentation;
225                break;
226            case 'check':
227                $newitem->presentation = 'c>>>>>'.$newitem->presentation;
228                break;
229            case 'radiorated':
230                $newitem->presentation = 'r>>>>>'.$newitem->presentation;
231                break;
232            case 'dropdownrated':
233                $newitem->presentation = 'd>>>>>'.$newitem->presentation;
234                break;
235        }
236
237        if (isset($item['#']['DEPENDITEM'][0]['#'])) {
238            $newitem->dependitem = intval($item['#']['DEPENDITEM'][0]['#']);
239        } else {
240            $newitem->dependitem = 0;
241        }
242        if (isset($item['#']['DEPENDVALUE'][0]['#'])) {
243            $newitem->dependvalue = trim($item['#']['DEPENDVALUE'][0]['#']);
244        } else {
245            $newitem->dependvalue = '';
246        }
247        $olditemid = intval($item['#']['ITEMID'][0]['#']);
248
249        if ($typ != 'pagebreak') {
250            $newitem->hasvalue = $itemobj->get_hasvalue();
251        } else {
252            $newitem->hasvalue = 0;
253        }
254        $newitem->required = intval($item['@']['REQUIRED']);
255        $newitem->position = $position;
256        $newid = $DB->insert_record('feedback_item', $newitem);
257
258        $itembackup[$olditemid] = $newid;
259        if ($newitem->dependitem) {
260            $dependitemsmap[$newid] = $newitem->dependitem;
261        }
262
263    }
264    //remapping the dependency
265    foreach ($dependitemsmap as $key => $dependitem) {
266        $newitem = $DB->get_record('feedback_item', array('id'=>$key));
267        $newitem->dependitem = $itembackup[$newitem->dependitem];
268        $DB->update_record('feedback_item', $newitem);
269    }
270
271    return $error;
272}
273
274function feedback_check_xml_utf8($text) {
275    //find the encoding
276    $searchpattern = '/^\<\?xml.+(encoding=\"([a-z0-9-]*)\").+\?\>/is';
277
278    if (!preg_match($searchpattern, $text, $match)) {
279        return false; //no xml-file
280    }
281
282    //$match[0] = \<\? xml ... \?\> (without \)
283    //$match[1] = encoding="...."
284    //$match[2] = ISO-8859-1 or so on
285    if (isset($match[0]) AND !isset($match[1])) { //no encoding given. we assume utf-8
286        return $text;
287    }
288
289    //encoding is given in $match[2]
290    if (isset($match[0]) AND isset($match[1]) AND isset($match[2])) {
291        $enc = $match[2];
292        return core_text::convert($text, $enc);
293    }
294}
295