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 ask and retrofit all the information from one
  25   * mysql table present in the Moodle DB to one xmldb_table structure
  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 new_table_from_mysql 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  
  41          // Get needed strings
  42          $this->loadStrings(array(
  43              'createtable' => 'tool_xmldb',
  44              'aftertable' => 'tool_xmldb',
  45              'create' => 'tool_xmldb',
  46              'back' => 'tool_xmldb'
  47          ));
  48      }
  49  
  50      /**
  51       * Invoke method, every class will have its own
  52       * returns true/false on completion, setting both
  53       * errormsg and output as necessary
  54       */
  55      function invoke() {
  56          parent::invoke();
  57  
  58          $result = true;
  59  
  60          // Set own core attributes
  61          $this->does_generate = ACTION_GENERATE_HTML;
  62  
  63          // These are always here
  64          global $CFG, $XMLDB, $DB, $OUTPUT;
  65  
  66          // Do the job, setting result as needed
  67          // Get the dir containing the file
  68          $dirpath = required_param('dir', PARAM_PATH);
  69          $dirpath = $CFG->dirroot . $dirpath;
  70  
  71          // Get the correct dirs
  72          if (!empty($XMLDB->dbdirs)) {
  73              $dbdir = $XMLDB->dbdirs[$dirpath];
  74          } else {
  75              return false;
  76          }
  77          if (!empty($XMLDB->editeddirs)) {
  78              $editeddir = $XMLDB->editeddirs[$dirpath];
  79              $structure = $editeddir->xml_file->getStructure();
  80          }
  81  
  82          $tableparam = optional_param('table', NULL, PARAM_CLEAN);
  83  
  84          // If no table, show form
  85          if (!$tableparam) {
  86              // No postaction here
  87              $this->postaction = NULL;
  88              // Get list of tables
  89              $dbtables = $DB->get_tables();
  90              $selecttables = array();
  91              foreach ($dbtables as $dbtable) {
  92                  $i = $structure->findTableInArray($dbtable);
  93                  if ($i === NULL) {
  94                      $selecttables[$dbtable] = $dbtable;
  95                  }
  96              }
  97              // Get list of after tables
  98              $aftertables = array();
  99              if ($tables = $structure->getTables()) {
 100                  foreach ($tables as $aftertable) {
 101                      $aftertables[$aftertable->getName()] = $aftertable->getName();
 102                  }
 103              }
 104              if (!$selecttables) {
 105                  $this->errormsg = 'No tables available to be retrofitted';
 106                  return false;
 107              }
 108              // Now build the form
 109              $o = '<form id="form" action="index.php" method="post">';
 110              $o .= '<div>';
 111              $o.= '    <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
 112              $o.= '    <input type="hidden" name ="action" value="new_table_from_mysql" />';
 113              $o.= '    <input type="hidden" name ="postaction" value="edit_table" />';
 114              $o.= '    <input type="hidden" name ="sesskey" value="' . sesskey() . '" />';
 115              $o.= '    <table id="formelements" class="boxaligncenter" cellpadding="5">';
 116              $o.= '      <tr><td><label for="menutable" accesskey="t">' . $this->str['createtable'] .' </label>' . html_writer::select($selecttables, 'table') . '<label for="menuafter" accesskey="a">' . $this->str['aftertable'] . ' </label>' .html_writer::select($aftertables, 'after') . '</td></tr>';
 117              $o.= '      <tr><td colspan="2" align="center"><input type="submit" value="' .$this->str['create'] . '" /></td></tr>';
 118              $o.= '      <tr><td colspan="2" align="center"><a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a></td></tr>';
 119              $o.= '    </table>';
 120              $o.= '</div></form>';
 121  
 122              $this->output = $o;
 123  
 124  
 125          // If table, retrofit information and, if everything works,
 126          // go to the table edit action
 127          } else {
 128              // Get some params (table is mandatory here)
 129              $tableparam = required_param('table', PARAM_CLEAN);
 130              $afterparam = required_param('after', PARAM_CLEAN);
 131  
 132              // Create one new xmldb_table
 133              $table = new xmldb_table(strtolower(trim($tableparam)));
 134              $table->setComment($table->getName() . ' table retrofitted from MySQL');
 135              // Get fields info from ADODb
 136              $dbfields = $DB->get_columns($tableparam);
 137              if ($dbfields) {
 138                  foreach ($dbfields as $dbfield) {
 139                      // Create new XMLDB field
 140                      $field = new xmldb_field($dbfield->name);
 141                      // Set field with info retrofitted
 142                      $field->setFromADOField($dbfield);
 143                      // Add field to the table
 144                      $table->addField($field);
 145                  }
 146              }
 147              // Get PK, UK and indexes info from ADODb
 148              $dbindexes = $DB->get_indexes($tableparam);
 149              if ($dbindexes) {
 150                  $lastkey = NULL; //To temp store the last key processed
 151                  foreach ($dbindexes as $indexname => $dbindex) {
 152                      // Add the indexname to the array
 153                      $dbindex['name'] = $indexname;
 154                      // We are handling one xmldb_key (primaries + uniques)
 155                      if ($dbindex['unique']) {
 156                          $key = new xmldb_key(strtolower($dbindex['name']));
 157                          // Set key with info retrofitted
 158                          $key->setFromADOKey($dbindex);
 159                          // Set default comment to PKs
 160                          if ($key->getType() == XMLDB_KEY_PRIMARY) {
 161                          }
 162                          // Add key to the table
 163                          $table->addKey($key);
 164  
 165                      // We are handling one xmldb_index (non-uniques)
 166                      } else {
 167                          $index = new xmldb_index(strtolower($dbindex['name']));
 168                          // Set index with info retrofitted
 169                          $index->setFromADOIndex($dbindex);
 170                          // Add index to the table
 171                          $table->addIndex($index);
 172                      }
 173                  }
 174              }
 175              // Finally, add the whole retroffited table to the structure
 176              // in the place specified
 177              $structure->addTable($table, $afterparam);
 178          }
 179  
 180          // Launch postaction if exists (leave this here!)
 181          if ($this->getPostAction() && $result) {
 182              return $this->launch($this->getPostAction());
 183          }
 184  
 185          // Return ok if arrived here
 186          return $result;
 187      }
 188  }
 189