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.
   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 the PHP needed (upgrade block) to perform
  25   * the desired DDL action with the specified table
  26   *
  27   * @package    tool_xmldb
  28   * @copyright  2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
  29   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  30   */
  31  class view_structure_php extends XMLDBAction {
  32  
  33      /**
  34       * Init method, every subclass will have its own
  35       */
  36      function init() {
  37          parent::init();
  38  
  39          // Set own custom attributes
  40          $this->sesskey_protected = false; // This action doesn't need sesskey protection
  41  
  42          // Get needed strings
  43          $this->loadStrings(array(
  44              'selectaction' => 'tool_xmldb',
  45              'selecttable' => 'tool_xmldb',
  46              'view' => 'tool_xmldb',
  47              'back' => 'tool_xmldb'
  48          ));
  49      }
  50  
  51      /**
  52       * Invoke method, every class will have its own
  53       * returns true/false on completion, setting both
  54       * errormsg and output as necessary
  55       */
  56      function invoke() {
  57          parent::invoke();
  58  
  59          $result = true;
  60  
  61          // Set own core attributes
  62          $this->does_generate = ACTION_GENERATE_HTML;
  63  
  64          // These are always here
  65          global $CFG, $XMLDB, $OUTPUT;
  66  
  67          // Do the job, setting result as needed
  68          // Get the dir containing the file
  69          $dirpath = required_param('dir', PARAM_PATH);
  70          $dirpath = $CFG->dirroot . $dirpath;
  71  
  72          // Get the correct dirs
  73          if (!empty($XMLDB->dbdirs)) {
  74              $dbdir = $XMLDB->dbdirs[$dirpath];
  75          } else {
  76              return false;
  77          }
  78          if (!empty($XMLDB->editeddirs)) {
  79              $editeddir = $XMLDB->editeddirs[$dirpath];
  80              $structure = $editeddir->xml_file->getStructure();
  81          }
  82  
  83          $tables = $structure->getTables();
  84          $table = reset($tables);
  85          $defaulttable = null;
  86          if ($table) {
  87              $defaulttable = $table->getName();
  88          }
  89  
  90          // Get parameters
  91          $commandparam = optional_param('command', 'create_table', PARAM_PATH);
  92          $tableparam = optional_param('table', $defaulttable, PARAM_PATH);
  93  
  94          // The back to edit xml button
  95          $b = ' <p class="centerpara buttons">';
  96          $b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
  97          $b .= '</p>';
  98          $o = $b;
  99  
 100          // Calculate the popup of commands
 101          $commands = array('create_table',
 102                           'drop_table',
 103                           'rename_table');
 104          foreach ($commands as $command) {
 105              $popcommands[$command] = str_replace('_', ' ', $command);
 106          }
 107          // Calculate the popup of tables
 108          foreach ($tables as $table) {
 109              $poptables[$table->getName()] = $table->getName();
 110          }
 111          // Now build the form
 112          $o.= '<form id="form" action="index.php" method="post">';
 113          $o.='<div>';
 114          $o.= '    <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
 115          $o.= '    <input type="hidden" name ="action" value="view_structure_php" />';
 116          $o.= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
 117          $o.= '      <tr><td><label for="menucommand" accesskey="c">' . $this->str['selectaction'] .' </label>' . html_writer::select($popcommands, 'command', $commandparam, false) . '&nbsp;<label for="menutable" accesskey="t">' . $this->str['selecttable'] . ' </label>' .html_writer::select($poptables, 'table', $tableparam, false) . '</td></tr>';
 118          $o.= '      <tr><td colspan="2" align="center"><input type="submit" value="' .$this->str['view'] . '" /></td></tr>';
 119          $o.= '    </table>';
 120          $o.= '</div></form>';
 121          $o.= '    <table id="phpcode" class="boxaligncenter" cellpadding="5">';
 122          $o .= '      <tr><td><textarea cols="80" rows="32" class="form-control">';
 123          // Based on current params, call the needed function
 124          switch ($commandparam) {
 125              case 'create_table':
 126                  $o.= s($this->create_table_php($structure, $tableparam));
 127                  break;
 128              case 'drop_table':
 129                  $o.= s($this->drop_table_php($structure, $tableparam));
 130                  break;
 131              case 'rename_table':
 132                  $o.= s($this->rename_table_php($structure, $tableparam));
 133                  break;
 134          }
 135          $o.= '</textarea></td></tr>';
 136          $o.= '    </table>';
 137  
 138          $this->output = $o;
 139  
 140          // Launch postaction if exists (leave this here!)
 141          if ($this->getPostAction() && $result) {
 142              return $this->launch($this->getPostAction());
 143          }
 144  
 145          // Return ok if arrived here
 146          return $result;
 147      }
 148  
 149      /**
 150       * This function will generate all the PHP code needed to
 151       * create one table using XMLDB objects and functions
 152       *
 153       * @param xmldb_structure structure object containing all the info
 154       * @param string table table code to be created
 155       * @return string PHP code to be used to create the table
 156       */
 157      function create_table_php($structure, $table) {
 158  
 159          $result = '';
 160          // Validate if we can do it
 161          if (!$table = $structure->getTable($table)) {
 162              return false;
 163          }
 164          if ($table->getAllErrors()) {
 165              return false;
 166          }
 167  
 168          // Add the standard PHP header
 169          $result .= XMLDB_PHP_HEADER;
 170  
 171          // Add contents
 172          $result .= XMLDB_LINEFEED;
 173          $result .= '        // Define table ' . $table->getName() . ' to be created.' . XMLDB_LINEFEED;
 174          $result .= '        $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
 175          $result .= XMLDB_LINEFEED;
 176          $result .= '        // Adding fields to table ' . $table->getName() . '.' . XMLDB_LINEFEED;
 177          // Iterate over each field
 178          foreach ($table->getFields() as $field) {
 179              // The field header, with name
 180              $result .= '        $table->add_field(' . "'" . $field->getName() . "', ";
 181              // The field PHP specs
 182              $result .= $field->getPHP(false);
 183              // The end of the line
 184              $result .= ');' . XMLDB_LINEFEED;
 185          }
 186          // Iterate over each key
 187          if ($keys = $table->getKeys()) {
 188              $result .= XMLDB_LINEFEED;
 189              $result .= '        // Adding keys to table ' . $table->getName() . '.' . XMLDB_LINEFEED;
 190              foreach ($keys as $key) {
 191                  // The key header, with name
 192                  $result .= '        $table->add_key(' . "'" . $key->getName() . "', ";
 193                  // The key PHP specs
 194                  $result .= $key->getPHP();
 195                  // The end of the line
 196                  $result .= ');' . XMLDB_LINEFEED;
 197              }
 198          }
 199          // Iterate over each index
 200          if ($indexes = $table->getIndexes()) {
 201              $result .= XMLDB_LINEFEED;
 202              $result .= '        // Adding indexes to table ' . $table->getName() . '.' . XMLDB_LINEFEED;
 203              foreach ($indexes as $index) {
 204                  // The index header, with name
 205                  $result .= '        $table->add_index(' . "'" . $index->getName() . "', ";
 206                  // The index PHP specs
 207                  $result .= $index->getPHP();
 208                  // The end of the line
 209                  $result .= ');' . XMLDB_LINEFEED;
 210              }
 211          }
 212  
 213          // Launch the proper DDL
 214          $result .= XMLDB_LINEFEED;
 215          $result .= '        // Conditionally launch create table for ' . $table->getName() . '.' . XMLDB_LINEFEED;
 216          $result .= '        if (!$dbman->table_exists($table)) {' . XMLDB_LINEFEED;
 217          $result .= '            $dbman->create_table($table);' . XMLDB_LINEFEED;
 218          $result .= '        }' . XMLDB_LINEFEED;
 219  
 220          // Add the proper upgrade_xxxx_savepoint call
 221          $result .= $this->upgrade_savepoint_php ($structure);
 222  
 223          // Add standard PHP footer
 224          $result .= XMLDB_PHP_FOOTER;
 225  
 226          return $result;
 227      }
 228  
 229      /**
 230       * This function will generate all the PHP code needed to
 231       * drop one table using XMLDB objects and functions
 232       *
 233       * @param xmldb_structure structure object containing all the info
 234       * @param string table table code to be dropped
 235       * @return string PHP code to be used to drop the table
 236       */
 237      function drop_table_php($structure, $table) {
 238  
 239          $result = '';
 240          // Validate if we can do it
 241          if (!$table = $structure->getTable($table)) {
 242              return false;
 243          }
 244          if ($table->getAllErrors()) {
 245              return false;
 246          }
 247  
 248          // Add the standard PHP header
 249          $result .= XMLDB_PHP_HEADER;
 250  
 251          // Add contents
 252          $result .= XMLDB_LINEFEED;
 253          $result .= '        // Define table ' . $table->getName() . ' to be dropped.' . XMLDB_LINEFEED;
 254          $result .= '        $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
 255  
 256          // Launch the proper DDL
 257          $result .= XMLDB_LINEFEED;
 258          $result .= '        // Conditionally launch drop table for ' . $table->getName() . '.' . XMLDB_LINEFEED;
 259          $result .= '        if ($dbman->table_exists($table)) {' . XMLDB_LINEFEED;
 260          $result .= '            $dbman->drop_table($table);' . XMLDB_LINEFEED;
 261          $result .= '        }' . XMLDB_LINEFEED;
 262  
 263          // Add the proper upgrade_xxxx_savepoint call
 264          $result .= $this->upgrade_savepoint_php ($structure);
 265  
 266          // Add standard PHP footer
 267          $result .= XMLDB_PHP_FOOTER;
 268  
 269          return $result;
 270      }
 271  
 272      /**
 273       * This function will generate all the PHP code needed to
 274       * rename one table using XMLDB objects and functions
 275       *
 276       * @param xmldb_structure structure object containing all the info
 277       * @param string table table code to be renamed
 278       * @return string PHP code to be used to rename the table
 279       */
 280      function rename_table_php($structure, $table) {
 281  
 282          $result = '';
 283          // Validate if we can do it
 284          if (!$table = $structure->getTable($table)) {
 285              return false;
 286          }
 287          if ($table->getAllErrors()) {
 288              return false;
 289          }
 290  
 291          // Add the standard PHP header
 292          $result .= XMLDB_PHP_HEADER;
 293  
 294          // Add contents
 295          $result .= XMLDB_LINEFEED;
 296          $result .= '        // Define table ' . $table->getName() . ' to be renamed to NEWNAMEGOESHERE.' . XMLDB_LINEFEED;
 297          $result .= '        $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
 298  
 299          // Launch the proper DDL
 300          $result .= XMLDB_LINEFEED;
 301          $result .= '        // Launch rename table for ' . $table->getName() . '.' . XMLDB_LINEFEED;
 302          $result .= '        $dbman->rename_table($table, ' . "'NEWNAMEGOESHERE'" . ');' . XMLDB_LINEFEED;
 303  
 304          // Add the proper upgrade_xxxx_savepoint call
 305          $result .= $this->upgrade_savepoint_php ($structure);
 306  
 307          // Add standard PHP footer
 308          $result .= XMLDB_PHP_FOOTER;
 309  
 310          return $result;
 311      }
 312  
 313  }
 314