Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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  
  25  require_once("../../config.php");
  26  require_once ("lib.php");
  27  require_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));
  35  if ($choosefile !== false) {
  36      $url->param('choosefile', $choosefile);
  37  }
  38  if ($action !== false) {
  39      $url->param('action', $action);
  40  }
  41  $PAGE->set_url($url);
  42  
  43  if (! $cm = get_coursemodule_from_id('feedback', $id)) {
  44      print_error('invalidcoursemodule');
  45  }
  46  
  47  if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
  48      print_error('coursemisconf');
  49  }
  50  
  51  if (! $feedback = $DB->get_record("feedback", array("id"=>$cm->instance))) {
  52      print_error('invalidcoursemodule');
  53  }
  54  
  55  $context = context_module::instance($cm->id);
  56  
  57  require_login($course, true, $cm);
  58  
  59  require_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  
  70  if ($mform->is_cancelled()) {
  71      redirect('edit.php?id='.$id.'&do_show=templates');
  72  }
  73  
  74  // process if we are happy file is ok
  75  if ($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);
  97  echo $OUTPUT->header();
  98  echo $OUTPUT->heading(format_string($feedback->name));
  99  /// print the tabs
 100  $current_tab = 'templates';
 101  require ('tabs.php');
 102  
 103  /// Print the main part of the page
 104  ///////////////////////////////////////////////////////////////////////////
 105  ///////////////////////////////////////////////////////////////////////////
 106  ///////////////////////////////////////////////////////////////////////////
 107  echo $OUTPUT->heading(get_string('import_questions', 'feedback'), 3);
 108  
 109  if (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  
 119  echo $OUTPUT->footer();
 120  
 121  function 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  
 138  function 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  
 274  function 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  }