Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

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

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  /**
  19   * This file is part of the Database module for Moodle
  20   *
  21   * @copyright 2005 Martin Dougiamas  http://dougiamas.com
  22   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   * @package mod_data
  24   */
  25  
  26  require_once('../../config.php');
  27  require_once ('lib.php');
  28  
  29  $id    = optional_param('id', 0, PARAM_INT);  // course module id
  30  $d     = optional_param('d', 0, PARAM_INT);   // database id
  31  $mode  = optional_param('mode', 'listtemplate', PARAM_ALPHA);
  32  $useeditor = optional_param('useeditor', null, PARAM_BOOL);
  33  
  34  $url = new moodle_url('/mod/data/templates.php');
  35  
  36  if ($id) {
  37      $url->param('id', $id);
  38      if (! $cm = get_coursemodule_from_id('data', $id)) {
  39          print_error('invalidcoursemodule');
  40      }
  41      if (! $course = $DB->get_record('course', array('id'=>$cm->course))) {
  42          print_error('coursemisconf');
  43      }
  44      if (! $data = $DB->get_record('data', array('id'=>$cm->instance))) {
  45          print_error('invalidcoursemodule');
  46      }
  47  
  48  } else {
  49      $url->param('d', $d);
  50      if (! $data = $DB->get_record('data', array('id'=>$d))) {
  51          print_error('invalidid', 'data');
  52      }
  53      if (! $course = $DB->get_record('course', array('id'=>$data->course))) {
  54          print_error('coursemisconf');
  55      }
  56      if (! $cm = get_coursemodule_from_instance('data', $data->id, $course->id)) {
  57          print_error('invalidcoursemodule');
  58      }
  59  }
  60  
  61  $url->param('mode', $mode);
  62  $PAGE->set_url($url);
  63  
  64  require_login($course, false, $cm);
  65  
  66  $context = context_module::instance($cm->id);
  67  require_capability('mod/data:managetemplates', $context);
  68  
  69  if ($useeditor !== null) {
  70      // The useeditor param was set. Update the value for this template.
  71      data_set_config($data, "editor_{$mode}", !!$useeditor);
  72  }
  73  
  74  if (!$DB->count_records('data_fields', array('dataid'=>$data->id))) {      // Brand new database!
  75      redirect($CFG->wwwroot.'/mod/data/field.php?d='.$data->id);  // Redirect to field entry
  76  }
  77  
  78  // Trigger an event for viewing templates.
  79  $event = \mod_data\event\template_viewed::create(array(
  80      'context' => $context,
  81      'courseid' => $course->id,
  82      'other' => array(
  83          'dataid' => $data->id
  84      )
  85  ));
  86  $event->add_record_snapshot('data', $data);
  87  $event->trigger();
  88  
  89  /// Print the page header
  90  
  91  $strdata = get_string('modulenameplural','data');
  92  
  93  // For the javascript for inserting template tags: initialise the default textarea to
  94  // 'edit_template' - it is always present in all different possible views.
  95  
  96  if ($mode == 'singletemplate') {
  97      $PAGE->navbar->add(get_string($mode,'data'));
  98  }
  99  
 100  $PAGE->requires->js('/mod/data/data.js');
 101  $PAGE->set_title($data->name);
 102  $PAGE->set_heading($course->fullname);
 103  $PAGE->set_pagelayout('admin');
 104  $PAGE->force_settings_menu(true);
 105  $PAGE->activityheader->disable();
 106  
 107  echo $OUTPUT->header();
 108  
 109  $actionbar = new \mod_data\output\action_bar($data->id, $url);
 110  echo $actionbar->get_templates_action_bar();
 111  
 112  echo $OUTPUT->heading(get_string($mode, 'data'), 2, 'mb-4');
 113  
 114  /// Processing submitted data, i.e updating form.
 115  $resettemplate = false;
 116  
 117  if (($mytemplate = data_submitted()) && confirm_sesskey()) {
 118      $newtemplate = new stdClass();
 119      $newtemplate->id = $data->id;
 120      $newtemplate->{$mode} = $mytemplate->template;
 121  
 122      if (!empty($mytemplate->defaultform)) {
 123          // Reset the template to default, but don't save yet.
 124          $resettemplate = true;
 125          $data->{$mode} = data_generate_default_template($data, $mode, 0, false, false);
 126          if ($mode == 'listtemplate') {
 127              $data->listtemplateheader = '';
 128              $data->listtemplatefooter = '';
 129          }
 130      } else {
 131          if (isset($mytemplate->listtemplateheader)){
 132              $newtemplate->listtemplateheader = $mytemplate->listtemplateheader;
 133          }
 134          if (isset($mytemplate->listtemplatefooter)){
 135              $newtemplate->listtemplatefooter = $mytemplate->listtemplatefooter;
 136          }
 137          if (isset($mytemplate->rsstitletemplate)){
 138              $newtemplate->rsstitletemplate = $mytemplate->rsstitletemplate;
 139          }
 140  
 141          // Check for multiple tags, only need to check for add template.
 142          if ($mode != 'addtemplate' or data_tags_check($data->id, $newtemplate->{$mode})) {
 143              $DB->update_record('data', $newtemplate);
 144              echo $OUTPUT->notification(get_string('templatesaved', 'data'), 'notifysuccess');
 145  
 146              // Trigger an event for saving the templates.
 147              $event = \mod_data\event\template_updated::create(array(
 148                  'context' => $context,
 149                  'courseid' => $course->id,
 150                  'other' => array(
 151                      'dataid' => $data->id,
 152                  )
 153              ));
 154              $event->trigger();
 155          }
 156      }
 157  } else {
 158      echo '<div class="template_heading">'.get_string('header'.$mode,'data').'</div>';
 159  }
 160  
 161  /// If everything is empty then generate some defaults
 162  if (empty($data->addtemplate) and empty($data->singletemplate) and
 163      empty($data->listtemplate) and empty($data->rsstemplate)) {
 164      data_generate_default_template($data, 'singletemplate');
 165      data_generate_default_template($data, 'listtemplate');
 166      data_generate_default_template($data, 'addtemplate');
 167      data_generate_default_template($data, 'asearchtemplate');           //Template for advanced searches.
 168      data_generate_default_template($data, 'rsstemplate');
 169  }
 170  
 171  editors_head_setup();
 172  
 173  // Determine whether to use HTML editors.
 174  if (($mode === 'csstemplate') || ($mode === 'jstemplate')) {
 175      // The CSS and JS templates aren't HTML.
 176      $usehtmleditor = false;
 177  } else {
 178      $usehtmleditor = data_get_config($data, "editor_{$mode}", true);
 179  }
 180  
 181  $datafieldtype = '';
 182  if ($usehtmleditor) {
 183      $format = FORMAT_HTML;
 184      $datafieldtype = ' data-fieldtype="editor" ';
 185  } else {
 186      $format = FORMAT_PLAIN;
 187  }
 188  
 189  $editor = editors_get_preferred_editor($format);
 190  $strformats = format_text_menu();
 191  $formats =  $editor->get_supported_formats();
 192  foreach ($formats as $fid) {
 193      $formats[$fid] = $strformats[$fid];
 194  }
 195  $options = array();
 196  $options['trusttext'] = false;
 197  $options['forcehttps'] = false;
 198  $options['subdirs'] = false;
 199  $options['maxfiles'] = 0;
 200  $options['maxbytes'] = 0;
 201  $options['changeformat'] = 0;
 202  $options['noclean'] = false;
 203  
 204  echo '<form id="tempform" action="templates.php?d='.$data->id.'&amp;mode='.$mode.'" method="post">';
 205  echo '<div>';
 206  echo '<input name="sesskey" value="'.sesskey().'" type="hidden" />';
 207  // Print button to autogen all forms, if all templates are empty
 208  
 209  if (!$resettemplate) {
 210      // Only reload if we are not resetting the template to default.
 211      $data = $DB->get_record('data', array('id'=>$d));
 212  }
 213  echo $OUTPUT->box_start('generalbox boxaligncenter boxwidthwide');
 214  echo '<table cellpadding="4" cellspacing="0" border="0">';
 215  
 216  if ($mode == 'listtemplate'){
 217      // Print the list template header.
 218      echo '<tr>';
 219      echo '<td>&nbsp;</td>';
 220      echo '<td>';
 221      echo '<div class="template_heading"><label for="edit-listtemplateheader">'.get_string('header','data').'</label></div>';
 222  
 223      $field = 'listtemplateheader';
 224      $editor->set_text($data->listtemplateheader);
 225      $editor->use_editor($field, $options);
 226      echo "<div><textarea id='{$field}' {$datafieldtype} name='{$field}' class='form-control' rows='15' cols='80'>" .
 227          s($data->listtemplateheader) . '</textarea></div>';
 228  
 229      echo '</td>';
 230      echo '</tr>';
 231  }
 232  
 233  // Print the main template.
 234  
 235  echo '<tr><td valign="top">';
 236  if ($mode != 'csstemplate' and $mode != 'jstemplate') {
 237      // Add all the available fields for this data.
 238      echo '<label for="availabletags">'.get_string('availabletags','data').'</label>';
 239      echo $OUTPUT->help_icon('availabletags', 'data');
 240      echo '<br />';
 241  
 242      echo '<div class="no-overflow" id="availabletags_wrapper">';
 243      echo '<select name="fields1[]" id="availabletags" size="12" onclick="insert_field_tags(this)" class="form-control">';
 244  
 245      $fields = $DB->get_records('data_fields', array('dataid'=>$data->id));
 246      echo '<optgroup label="'.get_string('fields', 'data').'">';
 247      foreach ($fields as $field) {
 248          echo '<option value="[['.$field->name.']]" title="'.$field->description.'">'.$field->name.' - [['.$field->name.']]</option>';
 249      }
 250      echo '</optgroup>';
 251  
 252      if ($mode == 'addtemplate') {
 253          echo '<optgroup label="'.get_string('fieldids', 'data').'">';
 254          foreach ($fields as $field) {
 255              if (in_array($field->type, array('picture', 'checkbox', 'date', 'latlong', 'radiobutton'))) {
 256                  continue; //ids are not usable for these composed items
 257              }
 258              echo '<option value="[['.$field->name.'#id]]" title="'.$field->description.' id">'.$field->name.' id - [['.$field->name.'#id]]</option>';
 259          }
 260          echo '</optgroup>';
 261          if (core_tag_tag::is_enabled('mod_data', 'data_records')) {
 262              echo '<optgroup label="'.get_string('other', 'data').'">';
 263              echo '<option value="##tags##">' . get_string('tags') . ' - ##tags##</option>';
 264              echo '</optgroup>';
 265          }
 266      }
 267  
 268      // Print special tags. fix for MDL-7031
 269      if ($mode != 'addtemplate' && $mode != 'asearchtemplate') {             //Don't print special tags when viewing the advanced search template and add template.
 270          echo '<optgroup label="'.get_string('buttons', 'data').'">';
 271          echo '<option value="##edit##">' .get_string('edit', 'data'). ' - ##edit##</option>';
 272          echo '<option value="##delete##">' .get_string('delete', 'data'). ' - ##delete##</option>';
 273          echo '<option value="##approve##">' .get_string('approve', 'data'). ' - ##approve##</option>';
 274          echo '<option value="##disapprove##">' .get_string('disapprove', 'data'). ' - ##disapprove##</option>';
 275          if ($mode != 'rsstemplate') {
 276              echo '<option value="##export##">' .get_string('export', 'data'). ' - ##export##</option>';
 277          }
 278          if ($mode != 'singletemplate') {
 279              // more points to single template - not useable there
 280              echo '<option value="##more##">' .get_string('more', 'data'). ' - ##more##</option>';
 281              echo '<option value="##moreurl##">' .get_string('moreurl', 'data'). ' - ##moreurl##</option>';
 282              echo '<option value="##delcheck##">' .get_string('delcheck', 'data'). ' - ##delcheck##</option>';
 283          }
 284          echo '</optgroup>';
 285          echo '<optgroup label="'.get_string('other', 'data').'">';
 286          echo '<option value="##timeadded##">'.get_string('timeadded', 'data'). ' - ##timeadded##</option>';
 287          echo '<option value="##timemodified##">'.get_string('timemodified', 'data'). ' - ##timemodified##</option>';
 288          echo '<option value="##user##">' .get_string('user'). ' - ##user##</option>';
 289          echo '<option value="##userpicture##">' . get_string('userpic') . ' - ##userpicture##</option>';
 290          echo '<option value="##approvalstatus##">' .get_string('approvalstatus', 'data'). ' - ##approvalstatus##</option>';
 291  
 292          if (core_tag_tag::is_enabled('mod_data', 'data_records')) {
 293              echo '<option value="##tags##">' . get_string('tags') . ' - ##tags##</option>';
 294          }
 295  
 296          if ($mode != 'singletemplate') {
 297              // more points to single template - not useable there
 298              echo '<option value="##comments##">' .get_string('comments', 'data'). ' - ##comments##</option>';
 299          }
 300          echo '</optgroup>';
 301      }
 302  
 303      if ($mode == 'asearchtemplate') {
 304          echo '<optgroup label="'.get_string('other', 'data').'">';
 305          echo '<option value="##firstname##">' .get_string('authorfirstname', 'data'). ' - ##firstname##</option>';
 306          echo '<option value="##lastname##">' .get_string('authorlastname', 'data'). ' - ##lastname##</option>';
 307          echo '</optgroup>';
 308      }
 309  
 310      echo '</select>';
 311      echo '</div>';
 312  }
 313  echo '</td>';
 314  
 315  echo '<td valign="top">';
 316  if ($mode == 'listtemplate'){
 317      echo '<div class="template_heading"><label for="edit-template">'.get_string('multientry','data').'</label></div>';
 318  } else {
 319      echo '<div class="template_heading"><label for="edit-template">'.get_string($mode,'data').'</label></div>';
 320  }
 321  
 322  $field = 'template';
 323  $editor->set_text($data->{$mode});
 324  $editor->use_editor($field, $options);
 325  echo '<div>';
 326  echo '<textarea class="form-control" id="' . $field . '" ' . $datafieldtype .
 327       'name="' . $field . '" rows="15" cols="80">' . s($data->{$mode}) . '</textarea>';
 328  echo '</div>';
 329  echo '</td>';
 330  echo '</tr>';
 331  
 332  if ($mode == 'listtemplate'){
 333      echo '<tr>';
 334      echo '<td>&nbsp;</td>';
 335      echo '<td>';
 336      echo '<div class="template_heading"><label for="edit-listtemplatefooter">'.get_string('footer','data').'</label></div>';
 337  
 338      $field = 'listtemplatefooter';
 339      $editor->set_text($data->listtemplatefooter);
 340      $editor->use_editor($field, $options);
 341      echo '<div>';
 342      echo '<textarea id="' . $field . '" class="form-control" ' . $datafieldtype .
 343           'name="' . $field . '" rows="15" cols="80">' . s($data->listtemplatefooter) . '</textarea>';
 344      echo '</div>';
 345      echo '</td>';
 346      echo '</tr>';
 347  } else if ($mode == 'rsstemplate') {
 348      echo '<tr>';
 349      echo '<td>&nbsp;</td>';
 350      echo '<td>';
 351      echo '<div class="template_heading">';
 352      echo '<label for="edit-rsstitletemplate">' . get_string('rsstitletemplate', 'data') . '</label>';
 353      echo '</div>';
 354  
 355      $field = 'rsstitletemplate';
 356      $editor->set_text($data->rsstitletemplate);
 357      $editor->use_editor($field, $options);
 358      echo '<div>';
 359      echo '<textarea id="' . $field . '" name="' . $field . '" ' . $datafieldtype .
 360           'class="form-control" rows="15" cols="80">' . s($data->rsstitletemplate) . '</textarea>';
 361      echo '</div>';
 362      echo '</td>';
 363      echo '</tr>';
 364  }
 365  
 366  echo '</table>';
 367  echo html_writer::start_div('container-fluid mt-4');
 368  echo html_writer::start_div('row');
 369  
 370  $resettemplatebutton = html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'defaultform',
 371      'class' => 'btn btn-secondary', 'value' => get_string('resettemplate', 'data')]);
 372  $savetemplatebutton = html_writer::empty_tag('input', ['type' => 'submit', 'class' => 'btn btn-primary ml-2',
 373      'value' => get_string('savetemplate', 'data')]);
 374  
 375  echo html_writer::div($resettemplatebutton . $savetemplatebutton);
 376  
 377  if ($mode != 'csstemplate' and $mode != 'jstemplate') {
 378      // Output the toggle template editor element.
 379      $toggletemplateeditor = html_writer::checkbox('useeditor', 1, $usehtmleditor,
 380          get_string('editorenable', 'data'), null, ['class' => 'pl-2']);
 381      echo html_writer::div($toggletemplateeditor, 'ml-auto');
 382      $PAGE->requires->js_call_amd('mod_data/templateseditor', 'init', ['d' => $d, 'mode' => $mode]);
 383  }
 384  echo html_writer::end_div();
 385  echo html_writer::end_div();
 386  
 387  echo $OUTPUT->box_end();
 388  echo '</div>';
 389  echo '</form>';
 390  
 391  /// Finish the page
 392  echo $OUTPUT->footer();