Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]

   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      throw new \moodle_exception('invalidcoursemodule');
  45  }
  46  
  47  if (! $course = $DB->get_record("course", array("id"=>$cm->course))) {
  48      throw new \moodle_exception('coursemisconf');
  49  }
  50  
  51  if (! $feedback = $DB->get_record("feedback", array("id"=>$cm->instance))) {
  52      throw new \moodle_exception('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  $actionbar = new \mod_feedback\output\edit_action_bar($cm->id, $url);
  61  
  62  $mform = new feedback_import_form();
  63  $newformdata = array('id'=>$id,
  64                      'deleteolditems'=>'1',
  65                      'action'=>'choosefile',
  66                      'confirmadd'=>'1',
  67                      'do_show'=>'templates');
  68  $mform->set_data($newformdata);
  69  $formdata = $mform->get_data();
  70  
  71  if ($mform->is_cancelled()) {
  72      redirect('edit.php?id='.$id.'&do_show=templates');
  73  }
  74  
  75  // process if we are happy file is ok
  76  if ($choosefile) {
  77      $xmlcontent = $mform->get_file_content('choosefile');
  78  
  79      if (!$xmldata = feedback_load_xml_data($xmlcontent)) {
  80          throw new \moodle_exception('cannotloadxml', 'feedback', 'edit.php?id='.$id);
  81      }
  82  
  83      $importerror = feedback_import_loaded_data($xmldata, $feedback->id);
  84      if ($importerror->stat == true) {
  85          $url = 'edit.php?id='.$id.'&do_show=templates';
  86          redirect($url, get_string('import_successfully', 'feedback'), 3);
  87          exit;
  88      }
  89  }
  90  
  91  
  92  /// Print the page header
  93  $strfeedbacks = get_string("modulenameplural", "feedback");
  94  $strfeedback  = get_string("modulename", "feedback");
  95  
  96  $PAGE->set_heading($course->fullname);
  97  $PAGE->set_title($feedback->name);
  98  $PAGE->activityheader->set_attrs([
  99      "hidecompletion" => true,
 100      "description" => ''
 101  ]);
 102  echo $OUTPUT->header();
 103  /** @var \mod_feedback\output\renderer $renderer */
 104  $renderer = $PAGE->get_renderer('mod_feedback');
 105  echo $renderer->main_action_bar($actionbar);
 106  
 107  /// Print the main part of the page
 108  ///////////////////////////////////////////////////////////////////////////
 109  ///////////////////////////////////////////////////////////////////////////
 110  ///////////////////////////////////////////////////////////////////////////
 111  if (!$PAGE->has_secondary_navigation()) {
 112      echo $OUTPUT->heading(get_string('import_questions', 'feedback'), 3);
 113  }
 114  
 115  if (isset($importerror->msg) AND is_array($importerror->msg)) {
 116      echo $OUTPUT->box_start('generalbox errorboxcontent boxaligncenter');
 117      foreach ($importerror->msg as $msg) {
 118          echo $msg.'<br />';
 119      }
 120      echo $OUTPUT->box_end();
 121  }
 122  
 123  $mform->display();
 124  
 125  echo $OUTPUT->footer();
 126  
 127  function feedback_load_xml_data($xmlcontent) {
 128      global $CFG;
 129      require_once($CFG->dirroot.'/lib/xmlize.php');
 130  
 131      if (!$xmlcontent = feedback_check_xml_utf8($xmlcontent)) {
 132          return false;
 133      }
 134  
 135      $data = xmlize($xmlcontent, 1, 'UTF-8');
 136  
 137      if (intval($data['FEEDBACK']['@']['VERSION']) != 200701) {
 138          return false;
 139      }
 140      $data = $data['FEEDBACK']['#']['ITEMS'][0]['#']['ITEM'];
 141      return $data;
 142  }
 143  
 144  function feedback_import_loaded_data(&$data, $feedbackid) {
 145      global $CFG, $DB;
 146  
 147      feedback_load_feedback_items();
 148  
 149      $deleteolditems = optional_param('deleteolditems', 0, PARAM_INT);
 150  
 151      $error = new stdClass();
 152      $error->stat = true;
 153      $error->msg = array();
 154  
 155      if (!is_array($data)) {
 156          $error->msg[] = get_string('data_is_not_an_array', 'feedback');
 157          $error->stat = false;
 158          return $error;
 159      }
 160  
 161      if ($deleteolditems) {
 162          feedback_delete_all_items($feedbackid);
 163          $position = 0;
 164      } else {
 165          //items will be add to the end of the existing items
 166          $position = $DB->count_records('feedback_item', array('feedback'=>$feedbackid));
 167      }
 168  
 169      //depend items we are storing temporary in an mapping list array(new id => dependitem)
 170      //we also store a mapping of all items array(oldid => newid)
 171      $dependitemsmap = array();
 172      $itembackup = array();
 173      foreach ($data as $item) {
 174          $position++;
 175          //check the typ
 176          $typ = $item['@']['TYPE'];
 177  
 178          //check oldtypes first
 179          switch($typ) {
 180              case 'radio':
 181                  $typ = 'multichoice';
 182                  $oldtyp = 'radio';
 183                  break;
 184              case 'dropdown':
 185                  $typ = 'multichoice';
 186                  $oldtyp = 'dropdown';
 187                  break;
 188              case 'check':
 189                  $typ = 'multichoice';
 190                  $oldtyp = 'check';
 191                  break;
 192              case 'radiorated':
 193                  $typ = 'multichoicerated';
 194                  $oldtyp = 'radiorated';
 195                  break;
 196              case 'dropdownrated':
 197                  $typ = 'multichoicerated';
 198                  $oldtyp = 'dropdownrated';
 199                  break;
 200              default:
 201                  $oldtyp = $typ;
 202          }
 203  
 204          $itemclass = 'feedback_item_'.$typ;
 205          if ($typ != 'pagebreak' AND !class_exists($itemclass)) {
 206              $error->stat = false;
 207              $error->msg[] = 'type ('.$typ.') not found';
 208              continue;
 209          }
 210          $itemobj = new $itemclass();
 211  
 212          $newitem = new stdClass();
 213          $newitem->feedback = $feedbackid;
 214          $newitem->template = 0;
 215          $newitem->typ = $typ;
 216          $newitem->name = trim($item['#']['ITEMTEXT'][0]['#']);
 217          $newitem->label = trim($item['#']['ITEMLABEL'][0]['#']);
 218          if ($typ === 'captcha' || $typ === 'label') {
 219              $newitem->label = '';
 220              $newitem->name = '';
 221          }
 222          $newitem->options = trim($item['#']['OPTIONS'][0]['#']);
 223          $newitem->presentation = trim($item['#']['PRESENTATION'][0]['#']);
 224          //check old types of radio, check, and so on
 225          switch($oldtyp) {
 226              case 'radio':
 227                  $newitem->presentation = 'r>>>>>'.$newitem->presentation;
 228                  break;
 229              case 'dropdown':
 230                  $newitem->presentation = 'd>>>>>'.$newitem->presentation;
 231                  break;
 232              case 'check':
 233                  $newitem->presentation = 'c>>>>>'.$newitem->presentation;
 234                  break;
 235              case 'radiorated':
 236                  $newitem->presentation = 'r>>>>>'.$newitem->presentation;
 237                  break;
 238              case 'dropdownrated':
 239                  $newitem->presentation = 'd>>>>>'.$newitem->presentation;
 240                  break;
 241          }
 242  
 243          if (isset($item['#']['DEPENDITEM'][0]['#'])) {
 244              $newitem->dependitem = intval($item['#']['DEPENDITEM'][0]['#']);
 245          } else {
 246              $newitem->dependitem = 0;
 247          }
 248          if (isset($item['#']['DEPENDVALUE'][0]['#'])) {
 249              $newitem->dependvalue = trim($item['#']['DEPENDVALUE'][0]['#']);
 250          } else {
 251              $newitem->dependvalue = '';
 252          }
 253          $olditemid = intval($item['#']['ITEMID'][0]['#']);
 254  
 255          if ($typ != 'pagebreak') {
 256              $newitem->hasvalue = $itemobj->get_hasvalue();
 257          } else {
 258              $newitem->hasvalue = 0;
 259          }
 260          $newitem->required = intval($item['@']['REQUIRED']);
 261          $newitem->position = $position;
 262          $newid = $DB->insert_record('feedback_item', $newitem);
 263  
 264          $itembackup[$olditemid] = $newid;
 265          if ($newitem->dependitem) {
 266              $dependitemsmap[$newid] = $newitem->dependitem;
 267          }
 268  
 269      }
 270      //remapping the dependency
 271      foreach ($dependitemsmap as $key => $dependitem) {
 272          $newitem = $DB->get_record('feedback_item', array('id'=>$key));
 273          $newitem->dependitem = $itembackup[$newitem->dependitem];
 274          $DB->update_record('feedback_item', $newitem);
 275      }
 276  
 277      return $error;
 278  }
 279  
 280  function feedback_check_xml_utf8($text) {
 281      //find the encoding
 282      $searchpattern = '/^\<\?xml.+(encoding=\"([a-z0-9-]*)\").+\?\>/is';
 283  
 284      if (!preg_match($searchpattern, $text, $match)) {
 285          return false; //no xml-file
 286      }
 287  
 288      //$match[0] = \<\? xml ... \?\> (without \)
 289      //$match[1] = encoding="...."
 290      //$match[2] = ISO-8859-1 or so on
 291      if (isset($match[0]) AND !isset($match[1])) { //no encoding given. we assume utf-8
 292          return $text;
 293      }
 294  
 295      //encoding is given in $match[2]
 296      if (isset($match[0]) AND isset($match[1]) AND isset($match[2])) {
 297          $enc = $match[2];
 298          return core_text::convert($text, $enc);
 299      }
 300  }