/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; /// Set own core attributes $this->does_generate = ACTION_NONE; //$this->does_generate = ACTION_GENERATE_HTML; /// These are always here global $CFG, $XMLDB; /// Do the job, setting $result as needed /// Get the dir containing the file $dirpath = required_param('dir', PARAM_PATH); $dirpath = $CFG->dirroot . stripslashes_safe($dirpath); /// Get the correct dir if (!empty($XMLDB->dbdirs)) { $dbdir =& $XMLDB->dbdirs[$dirpath]; if ($dbdir) { /// Set some defaults $dbdir->xml_exists = false; $dbdir->xml_writeable = false; $dbdir->xml_loaded = false; ///Only if the directory exists if (!$dbdir->path_exists) { return false; } $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml'); ///Set the XML DTD and schema $xmldb_file->setDTD($CFG->dirroot . '/lib/xmldb/xmldb.dtd'); $xmldb_file->setSchema($CFG->dirroot . '/lib/xmldb/xmldb.xsd'); /// Set dbdir as necessary if ($xmldb_file->fileExists()) { $dbdir->xml_exists = true; } if ($xmldb_file->fileWriteable()) { $dbdir->xml_writeable = true; } /// Load the XML contents to structure $loaded = $xmldb_file->loadXMLStructure(); if ($loaded && $xmldb_file->isLoaded()) { $dbdir->xml_loaded = true; $dbdir->filemtime = filemtime($dbdir->path . '/install.xml'); } $dbdir->xml_file = $xmldb_file; } else { $this->errormsg = 'Wrong directory (' . $dirpath . ')'; $result = false; } } else { $this->errormsg = 'XMLDB structure not found'; $result = false; } /// Launch postaction if exists if ($this->getPostAction() && $result) { return $this->launch($this->getPostAction()); } return $result; }
/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; /// Set own core attributes $this->does_generate = ACTION_NONE; //$this->does_generate = ACTION_GENERATE_HTML; /// These are always here global $CFG, $XMLDB; /// Do the job, setting $result as needed /// Iterate over $XMLDB->dbdirs, loading their XML data to memory if ($XMLDB->dbdirs) { $dbdirs =& $XMLDB->dbdirs; foreach ($dbdirs as $dbdir) { /// Set some defaults $dbdir->xml_exists = false; $dbdir->xml_writeable = false; $dbdir->xml_loaded = false; ///Only if the directory exists if (!$dbdir->path_exists) { continue; } $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml'); /// Set dbdir as necessary if ($xmldb_file->fileExists()) { $dbdir->xml_exists = true; } if ($xmldb_file->fileWriteable()) { $dbdir->xml_writeable = true; } /// Load the XML contents to structure $loaded = $xmldb_file->loadXMLStructure(); if ($loaded && $xmldb_file->isLoaded()) { $dbdir->xml_loaded = true; } $dbdir->xml_file = $xmldb_file; } } return $result; }
/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; /// Set own core attributes $this->does_generate = ACTION_GENERATE_HTML; /// These are always here global $CFG, $XMLDB, $db; /// And we nedd some ddl suff require_once $CFG->libdir . '/ddllib.php'; /// Here we'll acummulate all the wrong fields found $wrong_fields = array(); /// Correct fields must be type bigint for MySQL and int8 for PostgreSQL switch ($CFG->dbfamily) { case 'mysql': $correct_type = 'bigint'; break; case 'postgres': $correct_type = 'int8'; break; default: $correct_type = NULL; } /// Do the job, setting $result as needed /// Get the confirmed to decide what to do $confirmed = optional_param('confirmed', false, PARAM_BOOL); /// If not confirmed, show confirmation box if (!$confirmed) { $o = '<table class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">'; $o .= ' <tr><td class="generalboxcontent">'; $o .= ' <p class="centerpara">' . $this->str['confirmcheckbigints'] . '</p>'; if ($CFG->dbfamily == 'mysql') { $o .= ' <p class="centerpara">' . $this->str['mysqlextracheckbigints'] . '</p>'; } $o .= ' <table class="boxaligncenter" cellpadding="20"><tr><td>'; $o .= ' <div class="singlebutton">'; $o .= ' <form action="index.php?action=check_bigints&sesskey=' . sesskey() . '&confirmed=yes" method="post"><fieldset class="invisiblefieldset">'; $o .= ' <input type="submit" value="' . $this->str['yes'] . '" /></fieldset></form></div>'; $o .= ' </td><td>'; $o .= ' <div class="singlebutton">'; $o .= ' <form action="index.php?action=main_view" method="post"><fieldset class="invisiblefieldset">'; $o .= ' <input type="submit" value="' . $this->str['no'] . '" /></fieldset></form></div>'; $o .= ' </td></tr>'; $o .= ' </table>'; $o .= ' </td></tr>'; $o .= '</table>'; $this->output = $o; } else { /// The back to edit table button $b = ' <p class="centerpara buttons">'; $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>'; $b .= '</p>'; /// Iterate over $XMLDB->dbdirs, loading their XML data to memory if ($XMLDB->dbdirs) { $dbdirs =& $XMLDB->dbdirs; $o = '<ul>'; foreach ($dbdirs as $dbdir) { /// Only if the directory exists if (!$dbdir->path_exists) { continue; } /// Load the XML file $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml'); /// Load the needed XMLDB generator $classname = 'XMLDB' . $CFG->dbtype; $generator = new $classname(); $generator->setPrefix($CFG->prefix); /// Only if the file exists if (!$xmldb_file->fileExists()) { continue; } /// Load the XML contents to structure $loaded = $xmldb_file->loadXMLStructure(); if (!$loaded || !$xmldb_file->isLoaded()) { notify('Errors found in XMLDB file: ' . $dbdir->path . '/install.xml'); continue; } /// Arriving here, everything is ok, get the XMLDB structure $structure = $xmldb_file->getStructure(); $o .= ' <li>' . str_replace($CFG->dirroot . '/', '', $dbdir->path . '/install.xml'); /// Getting tables if ($xmldb_tables = $structure->getTables()) { $o .= ' <ul>'; /// Foreach table, process its fields foreach ($xmldb_tables as $xmldb_table) { /// Skip table if not exists if (!table_exists($xmldb_table)) { continue; } /// Fetch metadata from phisical DB. All the columns info. if ($metacolumns = $db->MetaColumns($CFG->prefix . $xmldb_table->getName())) { $metacolumns = array_change_key_case($metacolumns, CASE_LOWER); } else { //// Skip table if no metacolumns is available for it continue; } /// Table processing starts here $o .= ' <li>' . $xmldb_table->getName(); /// Get and process XMLDB fields if ($xmldb_fields = $xmldb_table->getFields()) { $o .= ' <ul>'; foreach ($xmldb_fields as $xmldb_field) { /// If the field isn't integer(10), skip if ($xmldb_field->getType() != XMLDB_TYPE_INTEGER || $xmldb_field->getLength() != 10) { continue; } /// If the metadata for that column doesn't exist, skip if (!isset($metacolumns[$xmldb_field->getName()])) { continue; } /// To variable for better handling $metacolumn = $metacolumns[$xmldb_field->getName()]; /// Going to check this field in DB $o .= ' <li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' '; /// Detect if the phisical field is wrong and, under mysql, check for incorrect signed fields too if ($metacolumn->type != $correct_type || $CFG->dbfamily == 'mysql' && $xmldb_field->getUnsigned() && !$metacolumn->unsigned) { $o .= '<font color="red">' . $this->str['wrong'] . '</font>'; /// Add the wrong field to the list $obj = new object(); $obj->table = $xmldb_table; $obj->field = $xmldb_field; $wrong_fields[] = $obj; } else { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } $o .= '</li>'; } $o .= ' </ul>'; } $o .= ' </li>'; /// Give the script some more time (resetting to current if exists) if ($currenttl = @ini_get('max_execution_time')) { @ini_set('max_execution_time', $currenttl); } } $o .= ' </ul>'; } $o .= ' </li>'; } $o .= '</ul>'; } /// We have finished, let's show the results of the search $s = ''; $r = '<table class="generalbox boxaligncenter boxwidthwide" border="0" cellpadding="5" cellspacing="0" id="results">'; $r .= ' <tr><td class="generalboxcontent">'; $r .= ' <h2 class="main">' . $this->str['searchresults'] . '</h2>'; $r .= ' <p class="centerpara">' . $this->str['wrongints'] . ': ' . count($wrong_fields) . '</p>'; $r .= ' </td></tr>'; $r .= ' <tr><td class="generalboxcontent">'; /// If we have found wrong integers inform about them if (count($wrong_fields)) { $r .= ' <p class="centerpara">' . $this->str['yeswrongintsfound'] . '</p>'; $r .= ' <ul>'; foreach ($wrong_fields as $obj) { $xmldb_table = $obj->table; $xmldb_field = $obj->field; /// MySQL directly supports this if ($CFG->dbfamily == 'mysql') { $sqlarr = $xmldb_table->getAlterFieldSQL($CFG->dbtype, $CFG->prefix, $xmldb_field, true); /// PostgreSQL (XMLDB implementation) is a bit, er... imperfect. } else { if ($CFG->dbfamily == 'postgres') { $sqlarr = array('ALTER TABLE ' . $CFG->prefix . $xmldb_table->getName() . ' ALTER COLUMN ' . $xmldb_field->getName() . ' TYPE BIGINT;'); } } $r .= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' . $this->str['field'] . ': ' . $xmldb_field->getName() . '</li>'; /// Add to output if we have sentences if ($sqlarr) { $s .= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />'; } } $r .= ' </ul>'; /// Add the SQL statements (all together) $r .= '<hr />' . $s; } else { $r .= ' <p class="centerpara">' . $this->str['nowrongintsfound'] . '</p>'; } $r .= ' </td></tr>'; $r .= ' <tr><td class="generalboxcontent">'; /// Add the complete log message $r .= ' <p class="centerpara">' . $this->str['completelogbelow'] . '</p>'; $r .= ' </td></tr>'; $r .= '</table>'; $this->output = $b . $r . $o; } /// Launch postaction if exists (leave this here!) if ($this->getPostAction() && $result) { return $this->launch($this->getPostAction()); } /// Return ok if arrived here return $result; }
function hotpot_create_table($table) { global $CFG; static $sql; static $xmldb_file; // check table does not already exist if (hotpot_db_table_exists($table)) { return true; } if (!isset($xmldb_file)) { // first time only if (class_exists('XMLDBFile')) { $xmldb_file = new XMLDBFile("{$CFG->dirroot}/mod/hotpot/db/install.xml"); if (!$xmldb_file->fileExists() || !$xmldb_file->loadXMLStructure() || !$xmldb_file->isLoaded()) { unset($xmldb_file); } } if (empty($xmldb_file)) { $xmldb_file = false; } } if ($xmldb_file) { // Moodle 1.8 (and later) $ok = false; foreach ($xmldb_file->xmldb_structure->tables as $xmldb_table) { if ($xmldb_table->name == $table) { $ok = create_table($xmldb_table); break; } } return $ok; } // Moodle 1.7 (and earlier) if (!isset($sql)) { // first time only $sqlfilepath = "{$CFG->dirroot}/mod/hotpot/db/{$CFG->dbtype}.sql"; if (file_exists($sqlfilepath)) { if (function_exists('file_get_contents')) { $sql = file_get_contents($sqlfilepath); } else { // PHP < 4.3 $sql = file($sqlfilepath); if (is_array($sql)) { $sql = implode('', $sql); } } } if (empty($sql)) { $sql = ''; } } // extract and execute all CREATE statements relating to this table if (preg_match_all("/CREATE (TABLE|INDEX)(\\s[^;]*)? prefix_{$table}(\\s[^;]*)?;/s", $sql, $strings)) { $ok = true; foreach ($strings[0] as $string) { $ok = $ok && modify_database('', $string); } return $ok; } // table could not be created return false; }
/** * Invoke method, every class will have its own * returns true/false on completion, setting both * errormsg and output as necessary */ function invoke() { parent::invoke(); $result = true; /// Set own core attributes $this->does_generate = ACTION_GENERATE_HTML; /// These are always here global $CFG, $XMLDB; /// And we nedd some ddl suff require_once $CFG->libdir . '/ddllib.php'; /// Here we'll acummulate all the missing indexes found $missing_indexes = array(); /// Do the job, setting $result as needed /// Get the confirmed to decide what to do $confirmed = optional_param('confirmed', false, PARAM_BOOL); /// If not confirmed, show confirmation box if (!$confirmed) { $o = '<table class="generalbox" border="0" cellpadding="5" cellspacing="0" id="notice">'; $o .= ' <tr><td class="generalboxcontent">'; $o .= ' <p class="centerpara">' . $this->str['confirmcheckindexes'] . '</p>'; $o .= ' <table class="boxaligncenter" cellpadding="20"><tr><td>'; $o .= ' <div class="singlebutton">'; $o .= ' <form action="index.php?action=check_indexes&confirmed=yes" method="post"><fieldset class="invisiblefieldset">'; $o .= ' <input type="submit" value="' . $this->str['yes'] . '" /></fieldset></form></div>'; $o .= ' </td><td>'; $o .= ' <div class="singlebutton">'; $o .= ' <form action="index.php?action=main_view" method="post"><fieldset class="invisiblefieldset">'; $o .= ' <input type="submit" value="' . $this->str['no'] . '" /></fieldset></form></div>'; $o .= ' </td></tr>'; $o .= ' </table>'; $o .= ' </td></tr>'; $o .= '</table>'; $this->output = $o; } else { /// The back to edit table button $b = ' <p class="centerpara buttons">'; $b .= '<a href="index.php">[' . $this->str['back'] . ']</a>'; $b .= '</p>'; /// Iterate over $XMLDB->dbdirs, loading their XML data to memory if ($XMLDB->dbdirs) { $dbdirs =& $XMLDB->dbdirs; $o = '<ul>'; foreach ($dbdirs as $dbdir) { /// Only if the directory exists if (!$dbdir->path_exists) { continue; } /// Load the XML file $xmldb_file = new XMLDBFile($dbdir->path . '/install.xml'); /// Load the needed XMLDB generator $classname = 'XMLDB' . $CFG->dbtype; $generator = new $classname(); $generator->setPrefix($CFG->prefix); /// Only if the file exists if (!$xmldb_file->fileExists()) { continue; } /// Load the XML contents to structure $loaded = $xmldb_file->loadXMLStructure(); if (!$loaded || !$xmldb_file->isLoaded()) { notify('Errors found in XMLDB file: ' . $dbdir->path . '/install.xml'); continue; } /// Arriving here, everything is ok, get the XMLDB structure $structure = $xmldb_file->getStructure(); $o .= ' <li>' . str_replace($CFG->dirroot . '/', '', $dbdir->path . '/install.xml'); /// Getting tables if ($xmldb_tables = $structure->getTables()) { $o .= ' <ul>'; /// Foreach table, process its indexes and keys foreach ($xmldb_tables as $xmldb_table) { /// Skip table if not exists if (!table_exists($xmldb_table)) { continue; } $o .= ' <li>' . $xmldb_table->getName(); /// Keys if ($xmldb_keys = $xmldb_table->getKeys()) { $o .= ' <ul>'; foreach ($xmldb_keys as $xmldb_key) { $o .= ' <li>' . $this->str['key'] . ': ' . $xmldb_key->readableInfo() . ' '; /// Primaries are skipped if ($xmldb_key->getType() == XMLDB_KEY_PRIMARY) { $o .= '<font color="green">' . $this->str['ok'] . '</font></li>'; continue; } /// If we aren't creating the keys or the key is a XMLDB_KEY_FOREIGN (not underlying index generated /// automatically by the RDBMS) create the underlying (created by us) index (if doesn't exists) if (!$generator->getKeySQL($xmldb_table, $xmldb_key) || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) { /// Create the interim index $xmldb_index = new XMLDBIndex('anyname'); $xmldb_index->setFields($xmldb_key->getFields()); switch ($xmldb_key->getType()) { case XMLDB_KEY_UNIQUE: case XMLDB_KEY_FOREIGN_UNIQUE: $xmldb_index->setUnique(true); break; case XMLDB_KEY_FOREIGN: $xmldb_index->setUnique(false); break; } /// Check if the index exists in DB if (index_exists($xmldb_table, $xmldb_index)) { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } else { $o .= '<font color="red">' . $this->str['missing'] . '</font>'; /// Add the missing index to the list $obj = new object(); $obj->table = $xmldb_table; $obj->index = $xmldb_index; $missing_indexes[] = $obj; } } $o .= '</li>'; } $o .= ' </ul>'; } /// Indexes if ($xmldb_indexes = $xmldb_table->getIndexes()) { $o .= ' <ul>'; foreach ($xmldb_indexes as $xmldb_index) { $o .= ' <li>' . $this->str['index'] . ': ' . $xmldb_index->readableInfo() . ' '; /// Check if the index exists in DB if (index_exists($xmldb_table, $xmldb_index)) { $o .= '<font color="green">' . $this->str['ok'] . '</font>'; } else { $o .= '<font color="red">' . $this->str['missing'] . '</font>'; /// Add the missing index to the list $obj = new object(); $obj->table = $xmldb_table; $obj->index = $xmldb_index; $missing_indexes[] = $obj; } $o .= '</li>'; } $o .= ' </ul>'; } $o .= ' </li>'; } $o .= ' </ul>'; } $o .= ' </li>'; } $o .= '</ul>'; } /// We have finished, let's show the results of the search $s = ''; $r = '<table class="generalbox boxaligncenter boxwidthwide" border="0" cellpadding="5" cellspacing="0" id="results">'; $r .= ' <tr><td class="generalboxcontent">'; $r .= ' <h2 class="main">' . $this->str['searchresults'] . '</h2>'; $r .= ' <p class="centerpara">' . $this->str['missingindexes'] . ': ' . count($missing_indexes) . '</p>'; $r .= ' </td></tr>'; $r .= ' <tr><td class="generalboxcontent">'; /// If we have found missing indexes inform about them if (count($missing_indexes)) { $r .= ' <p class="centerpara">' . $this->str['yesmissingindexesfound'] . '</p>'; $r .= ' <ul>'; foreach ($missing_indexes as $obj) { $xmldb_table = $obj->table; $xmldb_index = $obj->index; $sqlarr = $xmldb_table->getAddIndexSQL($CFG->dbtype, $CFG->prefix, $xmldb_index, true); $r .= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' . $this->str['index'] . ': ' . $xmldb_index->readableInfo() . '</li>'; $s .= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />'; } $r .= ' </ul>'; /// Add the SQL statements (all together) $r .= '<hr />' . $s; } else { $r .= ' <p class="centerpara">' . $this->str['nomissingindexesfound'] . '</p>'; } $r .= ' </td></tr>'; $r .= ' <tr><td class="generalboxcontent">'; /// Add the complete log message $r .= ' <p class="centerpara">' . $this->str['completelogbelow'] . '</p>'; $r .= ' </td></tr>'; $r .= '</table>'; $this->output = $b . $r . $o; } /// Launch postaction if exists (leave this here!) if ($this->getPostAction() && $result) { return $this->launch($this->getPostAction()); } /// Return ok if arrived here return $result; }
/** * Returns names of all known tables == tables that moodle knowns about. * @return array of lowercase table names */ function get_used_table_names() { $table_names = array(); $dbdirs = get_db_directories(); foreach ($dbdirs as $dbdir) { $file = $dbdir . '/install.xml'; $xmldb_file = new XMLDBFile($file); if (!$xmldb_file->fileExists()) { continue; } $loaded = $xmldb_file->loadXMLStructure(); $structure =& $xmldb_file->getStructure(); if ($loaded and $tables = $structure->getTables()) { foreach ($tables as $table) { $table_names[] = strtolower($table->name); } } } return $table_names; }
/** * This function will load one entire XMLDB file, generating all the needed * SQL statements, specific for each RDBMS ($CFG->dbtype) and, finally, it * will execute all those statements against the DB. * * @uses $CFG, $db * @param $file full path to the XML file to be used * @return boolean (true on success, false on error) */ function install_from_xmldb_file($file) { global $CFG, $db; $status = true; $xmldb_file = new XMLDBFile($file); if (!$xmldb_file->fileExists()) { return false; } $loaded = $xmldb_file->loadXMLStructure(); if (!$loaded || !$xmldb_file->isLoaded()) { /// Show info about the error if we can find it if ($structure =& $xmldb_file->getStructure()) { if ($errors = $structure->getAllErrors()) { notify('Errors found in XMLDB file: ' . implode(', ', $errors)); } } return false; } $structure = $xmldb_file->getStructure(); if (!($sqlarr = $structure->getCreateStructureSQL($CFG->dbtype, $CFG->prefix, false))) { return true; //Empty array = nothing to do = no error } return execute_sql_arr($sqlarr); }
/** * Return structure info of tables from a xmldb file * * @param string $file * @return array(XMLDBTable) * @throws InstallationException */ function get_tables_from_xmldb_file($file) { global $CFG, $db; $status = true; $xmldb_file = new XMLDBFile($file); if (!$xmldb_file->fileExists()) { throw new InstallationException($xmldb_file->path . " doesn't exist."); } $loaded = $xmldb_file->loadXMLStructure(); if (!$loaded || !$xmldb_file->isLoaded()) { throw new InstallationException("Could not load " . $xmldb_file->path); } $structure = $xmldb_file->getStructure(); return array_reverse($structure->getTables()); }
function wiki_create_schema() { global $CFG; $wiki_tables = array(); $file = $CFG->dirroot . '/mod/wiki/db/install.xml'; $xmldb_file = new XMLDBFile($file); if (!$xmldb_file->fileExists()) { continue; } $loaded = $xmldb_file->loadXMLStructure(); $structure =& $xmldb_file->getStructure(); if ($loaded and $tables = $structure->getTables()) { foreach ($tables as $table) { $wiki_tables[$table->name] = $table; } } $wiki_tables['block_instance'] = null; return $wiki_tables; }
/** * This function will load one entire XMLDB file, generating all the needed * SQL statements, specific for each RDBMS ($CFG->dbtype) and, finally, it * will execute all those statements against the DB. * * @uses $CFG, $db * @param $file full path to the XML file to be used * @return boolean (true on success, false on error) */ function install_from_xmldb_file($file) { global $CFG, $db; $status = true; $xmldb_file = new XMLDBFile($file); if (!$xmldb_file->fileExists()) { throw new InstallationException($xmldb_file->path . " doesn't exist."); } $loaded = $xmldb_file->loadXMLStructure(); if (!$loaded || !$xmldb_file->isLoaded()) { throw new InstallationException("Could not load " . $xmldb_file->path); } $structure = $xmldb_file->getStructure(); if (!($sqlarr = $structure->getCreateStructureSQL($CFG->dbtype, $CFG->prefix, false))) { return true; //Empty array = nothing to do = no error } if (!execute_sql_arr($sqlarr)) { log_debug($sqlarr); throw new SQLException("Failed to install (check logs for xmldb errors)"); } return true; }