Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 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   * @package    tool_xmldb
  19   * @copyright  2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  20   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  21   */
  22  
  23  /**
  24   * This class will show all the actions available under the XMLDB editor interface
  25   *
  26   * From here, files can be created, edited, saved and deleted, plus some
  27   * extra utilities like displaying docs, xml info and performing various consistency tests
  28   *
  29   * @package    tool_xmldb
  30   * @copyright  2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  31   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32   */
  33  class main_view extends XMLDBAction {
  34  
  35      /**
  36       * Init method, every subclass will have its own
  37       */
  38      function init() {
  39          parent::init();
  40  
  41          // Set own custom attributes
  42          $this->sesskey_protected = false; // This action doesn't need sesskey protection
  43  
  44          // Get needed strings
  45          $this->loadStrings(array(
  46              'load' => 'tool_xmldb',
  47              'create' => 'tool_xmldb',
  48              'edit' => 'tool_xmldb',
  49              'save' => 'tool_xmldb',
  50              'revert' => 'tool_xmldb',
  51              'unload' => 'tool_xmldb',
  52              'delete' => 'tool_xmldb',
  53              'reservedwords' => 'tool_xmldb',
  54              'gotolastused' => 'tool_xmldb',
  55              'checkindexes' => 'tool_xmldb',
  56              'checkdefaults' => 'tool_xmldb',
  57              'checkforeignkeys' => 'tool_xmldb',
  58              'checkbigints' => 'tool_xmldb',
  59              'checkoraclesemantics' => 'tool_xmldb',
  60              'doc' => 'tool_xmldb',
  61              'filemodifiedoutfromeditor' => 'tool_xmldb',
  62              'viewxml' => 'tool_xmldb',
  63              'pendingchangescannotbesavedreload' => 'tool_xmldb'
  64          ));
  65      }
  66  
  67      /**
  68       * Invoke method, every class will have its own
  69       * returns true/false on completion, setting both
  70       * errormsg and output as necessary
  71       */
  72      function invoke() {
  73          parent::invoke();
  74  
  75          $result = true;
  76  
  77          // Set own core attributes
  78          $this->does_generate = ACTION_GENERATE_HTML;
  79  
  80          // These are always here
  81          global $CFG, $XMLDB, $SESSION, $DB;
  82  
  83          // Get lastused
  84          $o = '';
  85          if (isset($SESSION->lastused)) {
  86              if ($lastused = $SESSION->lastused) {
  87                  // Print link
  88                  $o .= '<p class="centerpara"><a href="#lastused">' . $this->str['gotolastused'] . '</a></p>';
  89              }
  90          } else {
  91              $lastused = NULL;
  92          }
  93  
  94          // Calculate the buttons
  95          $b = '<p class="centerpara buttons">';
  96          // The reserved_words button
  97          $b .= '&nbsp;<a href="index.php?action=view_reserved_words">[' . $this->str['reservedwords'] . ']</a>';
  98          // The docs button
  99          $b .= '&nbsp;<a href="index.php?action=generate_all_documentation">[' . $this->str['doc'] . ']</a>';
 100          // The check indexes button
 101          $b .= '&nbsp;<a href="index.php?action=check_indexes&amp;sesskey=' . sesskey() . '">[' . $this->str['checkindexes'] . ']</a>';
 102          // The check defaults button
 103          $b .= '&nbsp;<a href="index.php?action=check_defaults&amp;sesskey=' . sesskey() . '">[' . $this->str['checkdefaults'] . ']</a>';
 104          // The check bigints button (only for MySQL and PostgreSQL) MDL-11038a
 105          if ($DB->get_dbfamily() == 'mysql' || $DB->get_dbfamily() == 'postgres') {
 106              $b .= '&nbsp;<a href="index.php?action=check_bigints&amp;sesskey=' . sesskey() . '">[' . $this->str['checkbigints'] . ']</a>';
 107          }
 108          // The check semantics button (only for Oracle) MDL-29416
 109          if ($DB->get_dbfamily() == 'oracle') {
 110              $b .= '&nbsp;<a href="index.php?action=check_oracle_semantics&amp;sesskey=' . sesskey() . '">[' . $this->str['checkoraclesemantics'] . ']</a>';
 111          }
 112          $b .= '&nbsp;<a href="index.php?action=check_foreign_keys&amp;sesskey=' . sesskey() . '">[' . $this->str['checkforeignkeys'] . ']</a>';
 113          $b .= '</p>';
 114          // Send buttons to output
 115          $o .= $b;
 116  
 117          // Do the job
 118  
 119          // Get the list of DB directories
 120          $result = $this->launch('get_db_directories');
 121          // Display list of DB directories if everything is ok
 122          if ($result && !empty($XMLDB->dbdirs)) {
 123              $o .= '<table id="listdirectories" border="0" cellpadding="5" cellspacing="1"' .
 124                  ' class="table-striped table-sm admintable generaltable">';
 125              $row = 0;
 126              foreach ($XMLDB->dbdirs as $key => $dbdir) {
 127                  // Detect if this is the lastused dir
 128                  $hithis = false;
 129                  if (str_replace($CFG->dirroot, '', $key) == $lastused) {
 130                      $hithis = true;
 131                  }
 132                  $elementtext = str_replace($CFG->dirroot . '/', '', $key);
 133                  // Calculate the dbdir has_changed field if needed
 134                  if (!isset($dbdir->has_changed) && isset($dbdir->xml_loaded)) {
 135                      $dbdir->xml_changed = false;
 136                      if (isset($XMLDB->editeddirs[$key])) {
 137                          $editeddir = $XMLDB->editeddirs[$key];
 138                          if (isset($editeddir->xml_file)) {
 139                              $structure = $editeddir->xml_file->getStructure();
 140                              if ($structure->hasChanged()) {
 141                                  $dbdir->xml_changed = true;
 142                                  $editeddir->xml_changed = true;
 143                              }
 144                          }
 145                      }
 146                  }
 147                  // The file name (link to edit if the file is loaded)
 148                  if ($dbdir->path_exists &&
 149                      file_exists($key . '/install.xml') &&
 150                      is_readable($key . '/install.xml') &&
 151                      is_readable($key) &&
 152                      !empty($dbdir->xml_loaded)) {
 153                      $f = '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">' . $elementtext . '</a>';
 154                  } else {
 155                      $f = $elementtext;
 156                  }
 157                  // Calculate the buttons
 158                  $b = ' <td class="button cell">';
 159                  // The create button
 160                  if ($dbdir->path_exists &&
 161                      !file_exists($key . '/install.xml') &&
 162                      is_writeable($key)) {
 163                      $b .= '<a href="index.php?action=create_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['create'] . ']</a>';
 164                  } else {
 165                      $b .= '[' . $this->str['create'] . ']';
 166                  }
 167                  $b .= '</td><td class="button cell">';
 168                  // The load button
 169                  if ($dbdir->path_exists &&
 170                      file_exists($key . '/install.xml') &&
 171                      is_readable($key . '/install.xml') &&
 172                      empty($dbdir->xml_loaded)) {
 173                      $b .= '<a href="index.php?action=load_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['load'] . ']</a>';
 174                  } else {
 175                      $b .= '[' . $this->str['load'] . ']';
 176                  }
 177                  $b .= '</td><td class="button cell">';
 178                  // The edit button
 179                  if ($dbdir->path_exists &&
 180                      file_exists($key . '/install.xml') &&
 181                      is_readable($key . '/install.xml') &&
 182                      is_readable($key) &&
 183                      !empty($dbdir->xml_loaded)) {
 184                      $b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['edit'] . ']</a>';
 185                  } else {
 186                      $b .= '[' . $this->str['edit'] . ']';
 187                  }
 188                  $b .= '</td><td class="button cell">';
 189                  // The save button
 190                  if ($dbdir->path_exists &&
 191                      file_exists($key . '/install.xml') &&
 192                      is_writeable($key . '/install.xml') &&
 193                      is_writeable($key) &&
 194                      !empty($dbdir->xml_loaded) &&
 195                      !empty($dbdir->xml_changed)) {
 196                      $b .= '<a href="index.php?action=save_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['save'] . ']</a>';
 197                      // Check if the file has been manually edited while being modified in the editor
 198                      if ($dbdir->filemtime != filemtime($key . '/install.xml')) {
 199                          // File manually modified. Add to action error, will be displayed inline.
 200                          $this->errormsg = $this->str['filemodifiedoutfromeditor'];
 201                      }
 202                  } else {
 203                      $b .= '[' . $this->str['save'] . ']';
 204                  }
 205                  $b .= '</td><td class="button cell">';
 206                  // The document button
 207                  if ($dbdir->path_exists &&
 208                      file_exists($key . '/install.xml') &&
 209                      is_readable($key . '/install.xml') &&
 210                      is_readable($key)) {
 211                      $b .= '<a href="index.php?action=generate_documentation&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['doc'] . ']</a>';
 212                  } else {
 213                      $b .= '[' . $this->str['doc'] . ']';
 214                  }
 215                  $b .= '</td><td class="button cell">';
 216                  // The view xml button
 217                  if ($dbdir->path_exists &&
 218                      file_exists($key . '/install.xml') &&
 219                      is_readable($key . '/install.xml')) {
 220                      $b .= '<a href="index.php?action=view_xml&amp;file=' . urlencode(str_replace($CFG->dirroot, '', $key) . '/install.xml') . '">[' . $this->str['viewxml'] . ']</a>';
 221                  } else {
 222                      $b .= '[' . $this->str['viewxml'] . ']';
 223                  }
 224                  $b .= '</td><td class="button cell">';
 225                  // The revert button
 226                  if ($dbdir->path_exists &&
 227                      file_exists($key . '/install.xml') &&
 228                      is_readable($key . '/install.xml') &&
 229                      is_writeable($key) &&
 230                      !empty($dbdir->xml_loaded) &&
 231                      !empty($dbdir->xml_changed)) {
 232                      $b .= '<a href="index.php?action=revert_changes&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['revert'] . ']</a>';
 233                  } else {
 234                      $b .= '[' . $this->str['revert'] . ']';
 235                  }
 236                  $b .= '</td><td class="button cell">';
 237                  // The unload button
 238                  if ($dbdir->path_exists &&
 239                      file_exists($key . '/install.xml') &&
 240                      is_readable($key . '/install.xml') &&
 241                      !empty($dbdir->xml_loaded) &&
 242                      empty($dbdir->xml_changed)) {
 243                      $b .= '<a href="index.php?action=unload_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '&amp;time=' . time() . '&amp;postaction=main_view#lastused">[' . $this->str['unload'] . ']</a>';
 244                  } else {
 245                      $b .= '[' . $this->str['unload'] . ']';
 246                  }
 247                  $b .= '</td><td class="button cell">';
 248                  // The delete button
 249                  if ($dbdir->path_exists &&
 250                      file_exists($key . '/install.xml') &&
 251                      is_readable($key . '/install.xml') &&
 252                      is_writeable($key) &&
 253                      empty($dbdir->xml_loaded)) {
 254                      $b .= '<a href="index.php?action=delete_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['delete'] . ']</a>';
 255                  } else {
 256                      $b .= '[' . $this->str['delete'] . ']';
 257                  }
 258                  $b .= '</td>';
 259                  // include the higlight
 260                  if ($hithis) {
 261                      $o .= '<tr class="highlight"><td class="directory cell"><a name="lastused" />' . $f . '</td>' . $b . '</tr>';
 262                  } else {
 263                      $o .= '<tr class="r' . $row . '"><td class="directory cell">' . $f . '</td>' . $b . '</tr>';
 264                  }
 265                  $row = ($row + 1) % 2;
 266                  // show errors if they exist
 267                  if (isset($dbdir->xml_file)) {
 268                      if ($structure = $dbdir->xml_file->getStructure()) {
 269                          $errors = !empty($this->errormsg) ? array($this->errormsg) : array();
 270                          $structureerrors = $structure->getAllErrors();
 271                          if ($structureerrors) {
 272                              $errors = array_merge($errors, $structureerrors);
 273                          }
 274                          if (!empty($errors)) {
 275                              if ($hithis) {
 276                                  $o .= '<tr class="highlight"><td class="error cell" colspan="10">' . implode (', ', $errors) . '</td></tr>';
 277                              } else {
 278                                  $o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">' . implode (', ', $errors) . '</td></tr>';
 279                              }
 280                          }
 281                      }
 282                  }
 283                  // If there are changes pending to be saved, but the file cannot be written... inform here
 284                  if ($dbdir->path_exists &&
 285                      file_exists($key . '/install.xml') &&
 286                      !empty($dbdir->xml_loaded) &&
 287                      !empty($dbdir->xml_changed) &&
 288                      (!is_writeable($key . '/install.xml') || !is_writeable($key))) {
 289  
 290                      if ($hithis) {
 291                          $o .= '<tr class="highlight"><td class="error cell" colspan="10">';
 292                      } else {
 293                          $o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">';
 294                      }
 295                      $o .= $this->str['pendingchangescannotbesavedreload'];
 296                      $o .= '</td></tr>';
 297                  }
 298              }
 299              $o .= '</table>';
 300  
 301              // Set the output
 302              $this->output = $o;
 303          }
 304  
 305          // Finally, return result
 306          return $result;
 307      }
 308  }
 309