first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+78
View File
@@ -0,0 +1,78 @@
XMLDB - Base classes and edition interface.
Complete Documentation:
http://docs.moodle.org/en/XMLDB_Defining_one_XML_structure
Ciao, Eloy Lafuente (stronk7)
========== ========== ========== ========== ==========
========== ========== HISTORY ========== ==========
========== ========== ========== ========== ==========
2006-08-07 - Editor working on production
The editor has been used succesfully to build
a bunch of install.xml files and everything
seems to be working properly.
========== ========== ========== ========== ==========
2006-07-11 - PHP4 compatible release
Now everything seems to be working under PHP 4. What
a horrible OOP implementation!
Note that write permissions to */db dirs are required.
Now working in the 3 missing forms, to manually edit
fields, keys and indexes.
Ciao, Eloy Lafuente (stronk7)
========== ========== ========== ========== ==========
2006-07-11 - Important notes
I've just discovered this some seconds ago, in order
to test properly the XMLDB classes and editor:
1.- PHP 5 required for now. Will change this soon.
2.- Perms to "apache" user needed in */db
dirs in order to allow the XMDBD interface
to write files.
Ciao, Eloy Lafuente (stronk7)
========== ========== ========== ========== ==========
2006-07-11 - Initial commit
This directory contains the XMLDB classes to be used
under Moodle > 1.7 to store all the DB info in a
neutral form (classes dir). Also it contains one simple
interface to edit all those structures.
To install and test it, simply copy the whole xmldb directory
under your moodle/admin dir and point your browser (as admin)
to http://your.server/moodle/admin/xmldb
The edition interface isn't completed yet (it laks 3 more forms
to edit fields, keys and indexes) and there isn't any lang file
(although I hope everything is really clear).
The edition interface includes one reverse-engineering tool that
provides an easy way to retroffit and to generate any table from
MySQL to the new XMLDB format.
Once the XMLDB format was approved, we'll be able to build all the
"generators" needed in order to use it to create Moodle DB structures
for each RDBMS flavour.
Once the interface was finished (2-3 days from now) related documentation
will be sent to http://docs.moodle.org/en/XML_database_schema in order
to comment/modify/approve the final XML format.
All the code is, obviously GPL, with its copyrights and so on...
Ciao, Eloy Lafuente (stronk7) :-)
@@ -0,0 +1,273 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Main xmldb action clasee
*
* Main xmldb action class. It implements all the basic
* functionalities to be shared by each action.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class XMLDBAction {
/** @var bool Type of value returned by the invoke method, ACTION_GENERATE_HTML have contents to show, set by each specialized invoke*/
protected $does_generate;
/** @var string Title of the Action (class name, by default), set by parent init automatically*/
protected $title;
/** @var string Strings used by the action set by each specialized init, calling loadStrings*/
protected $str;
/** @var string Output of the action, set by each specialized invoke, get with getOutput*/
protected $output;
/** @var string Last Error produced. Check when any invoke returns false, get with getError*/
protected $errormsg;
/** @var string Action to execute at the end of the invoke script*/
protected $postaction;
/** @var bool Actions must be protected by sesskey mechanism*/
protected $sesskey_protected;
/** @var mixed */
protected $subaction;
/** @var bool Set own core attributes. */
protected $can_subaction;
/**
* Constructor
*/
function __construct() {
$this->init();
}
/**
* Init method, every subclass will have its own,
* always calling the parent one
*/
function init() {
$this->does_generate = ACTION_NONE;
$this->title = strtolower(get_class($this));
$this->str = array();
$this->output = NULL;
$this->errormsg = NULL;
$this->subaction = NULL;
$this->sesskey_protected = true;
}
/**
* Returns the type of output of the file
* @return bool
*/
function getDoesGenerate() {
return $this->does_generate;
}
/**
* getError method, returns the last error string.
* Used if the invoke() methods returns false
* @return string
*/
function getError() {
return $this->errormsg;
}
/**
* getOutput method, returns the output generated by the action.
* Used after execution of the invoke() methods if they return true
* @return string
*/
function getOutput() {
return $this->output;
}
/**
* getPostAction method, returns the action to launch after executing
* another one
* @return string
*/
function getPostAction() {
return $this->postaction;
}
/**
* getTitle method returns the title of the action (that is part
* of the $str array attribute
* @return string
*/
function getTitle() {
return $this->str['title'];
}
/**
* loadStrings method, loads the required strings specified in the
* array parameter
* @param string[] $strings
*/
function loadStrings($strings) {
// Load some commonly used strings
if (get_string_manager()->string_exists($this->title, 'tool_xmldb')) {
$this->str['title'] = get_string($this->title, 'tool_xmldb');
} else {
$this->str['title'] = $this->title;
}
// Now process the $strings array loading it in the $str atribute
if ($strings) {
foreach ($strings as $key => $module) {
$this->str[$key] = get_string($key, $module);
}
}
}
/**
* main invoke method, it sets the postaction attribute
* if possible and checks sesskey_protected if needed
*/
function invoke() {
global $SESSION;
// Sesskey protection
if ($this->sesskey_protected) {
require_sesskey();
}
// If we are used any dir, save it in the lastused session object
// Some actions can use it to perform positioning
if ($lastused = optional_param ('dir', NULL, PARAM_PATH)) {
$SESSION->lastused = $lastused;
}
$this->postaction = optional_param ('postaction', NULL, PARAM_ALPHAEXT);
// Avoid being recursive
if ($this->title == $this->postaction) {
$this->postaction = NULL;
}
}
/**
* launch method, used to easily call invoke methods between actions
* @param string $action
* @return mixed
*/
function launch($action) {
global $CFG;
// Get the action path and invoke it
$actionsroot = "$CFG->dirroot/$CFG->admin/tool/xmldb/actions";
$actionclass = $action . '.class.php';
$actionpath = "$actionsroot/$action/$actionclass";
// Load and invoke the proper action
$result = false;
if (file_exists($actionpath) && is_readable($actionpath)) {
require_once($actionpath);
if ($xmldb_action = new $action) {
$result = $xmldb_action->invoke();
if ($result) {
if ($xmldb_action->does_generate != ACTION_NONE &&
$xmldb_action->getOutput()) {
$this->does_generate = $xmldb_action->does_generate;
$this->title = $xmldb_action->title;
$this->str = $xmldb_action->str;
$this->output .= $xmldb_action->getOutput();
}
} else {
$this->errormsg = $xmldb_action->getError();
}
} else {
$this->errormsg = "Error: cannot instantiate class (actions/$action/$actionclass)";
}
} else {
$this->errormsg = "Error: wrong action specified ($action)";
}
return $result;
}
/**
* This function will generate the PHP code needed to
* implement the upgrade_xxxx_savepoint() php calls in
* upgrade code generated from the editor. It's used by
* the view_structure_php and view_table_php actions
*
* @param xmldb_structure structure object containing all the info
* @return string PHP code to be used to mark a reached savepoint
*/
function upgrade_savepoint_php($structure) {
global $CFG;
// NOTE: $CFG->admin !== 'admin' is not supported in XMLDB editor, sorry.
$path = $structure->getPath();
$plugintype = 'error';
if ($path === 'lib/db') {
$plugintype = 'lib';
$pluginname = null;
} else {
$path = dirname($path);
$pluginname = basename($path);
$path = dirname($path);
$plugintypes = core_component::get_plugin_types();
foreach ($plugintypes as $type => $fulldir) {
if ($CFG->dirroot.'/'.$path === $fulldir) {
$plugintype = $type;
break;
}
}
}
$result = '';
switch ($plugintype ) {
case 'lib': // has own savepoint function
$result = XMLDB_LINEFEED .
' // Main savepoint reached.' . XMLDB_LINEFEED .
' upgrade_main_savepoint(true, XXXXXXXXXX);' . XMLDB_LINEFEED;
break;
case 'mod': // has own savepoint function
$result = XMLDB_LINEFEED .
' // ' . ucfirst($pluginname) . ' savepoint reached.' . XMLDB_LINEFEED .
' upgrade_mod_savepoint(true, XXXXXXXXXX, ' . "'$pluginname'" . ');' . XMLDB_LINEFEED;
break;
case 'block': // has own savepoint function
$result = XMLDB_LINEFEED .
' // ' . ucfirst($pluginname) . ' savepoint reached.' . XMLDB_LINEFEED .
' upgrade_block_savepoint(true, XXXXXXXXXX, ' . "'$pluginname'" . ');' . XMLDB_LINEFEED;
break;
default: // rest of plugins
$result = XMLDB_LINEFEED .
' // ' . ucfirst($pluginname) . ' savepoint reached.' . XMLDB_LINEFEED .
' upgrade_plugin_savepoint(true, XXXXXXXXXX, ' . "'$plugintype'" . ', ' . "'$pluginname'" . ');' . XMLDB_LINEFEED;
}
return $result;
}
}
@@ -0,0 +1,211 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2008 onwards Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This is a base class for the various actions that interate over all the
* tables and check some aspect of their definition.
*
* @package tool_xmldb
* @copyright 2008 onwards Tim Hunt
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class XMLDBCheckAction extends XMLDBAction {
/**
* @var string This string is displayed with a yes/no choice before the report is run.
* You must set this to the name of a lang string in xmldb.php before calling init.
*/
protected $introstr = '';
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own core attributes
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
$this->introstr => 'tool_xmldb',
'ok' => '',
'wrong' => 'tool_xmldb',
'table' => 'tool_xmldb',
'field' => 'tool_xmldb',
'searchresults' => 'tool_xmldb',
'completelogbelow' => 'tool_xmldb',
'yes' => '',
'no' => '',
'error' => '',
'back' => 'tool_xmldb'
));
}
/**
* 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, $OUTPUT;
// And we nedd some ddl suff
$dbman = $DB->get_manager();
// Here we'll acummulate all the wrong fields found
$problemsfound = 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="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str[$this->introstr] . '</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=' . $this->title . '&amp;confirmed=yes&amp;sesskey=' . sesskey() . '" 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 xmldb_file($dbdir->path . '/install.xml');
// 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()) {
echo $OUTPUT->notification('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 (!$dbman->table_exists($xmldb_table)) {
continue;
}
// Fetch metadata from physical DB. All the columns info.
if (!$metacolumns = $DB->get_columns($xmldb_table->getName(), false)) {
// / Skip table if no metacolumns is available for it
continue;
}
// Table processing starts here
$o.=' <li>' . $xmldb_table->getName();
// Do the specific check.
list($output, $newproblems) = $this->check_table($xmldb_table, $metacolumns);
$o.=$output;
$problemsfound = array_merge($problemsfound, $newproblems);
$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>';
}
// Create a report of the problems found.
$r = $this->display_results($problemsfound);
// Combine the various bits of output.
$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;
}
/**
* Do the checks necessary on one particular table.
*
* @param xmldb_table $xmldb_table the table definition from the install.xml file.
* @param array $metacolumns the column information read from the database.
* @return array an array with two elements: First, some additional progress output,
* for example a list (<ul>) of the things check each with an one work ok/not ok summary.
* Second, an array giving the details of any problems found. These arrays
* for all tables will be aggregated, and then passed to
*/
abstract protected function check_table(xmldb_table $xmldb_table, array $metacolumns);
/**
* Display a list of the problems found.
*
* @param array $problems_found an aggregation of all the problems found by
* all the check_table calls.
* @return string a display of all the problems found as HTML.
*/
abstract protected function display_results(array $problems_found);
}
@@ -0,0 +1,154 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Add the mandatory fields for persistent to the table.
*
* @package tool_xmldb
* @copyright 2019 Michael Aherne
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class add_persistent_mandatory extends XMLDBAction {
function init() {
parent::init();
// Get needed strings.
$this->loadStrings(array(
'addpersistent' => 'tool_xmldb',
'persistentfieldsconfirm' => 'tool_xmldb',
'persistentfieldscomplete' => 'tool_xmldb',
'persistentfieldsexist' => 'tool_xmldb',
'back' => 'core'
));
}
function getTitle() {
return $this->str['addpersistent'];
}
function invoke() {
parent::invoke();
$this->does_generate = ACTION_GENERATE_HTML;
global $CFG, $XMLDB, $OUTPUT;
$dir = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dir;
if (empty($XMLDB->dbdirs)) {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = required_param('table', PARAM_ALPHANUMEXT);
/** @var xmldb_table $table */
$table = $structure->getTable($tableparam);
$result = true;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
$confirm = optional_param('confirm', false, PARAM_BOOL);
$fields = ['usermodified', 'timecreated', 'timemodified'];
$existing = [];
foreach ($fields as $field) {
if ($table->getField($field)) {
$existing[] = $field;
}
}
$returnurl = new \moodle_url('/admin/tool/xmldb/index.php', [
'table' => $tableparam,
'dir' => $dir,
'action' => 'edit_table'
]);
$backbutton = html_writer::link($returnurl, '[' . $this->str['back'] . ']');
$actionbuttons = html_writer::tag('p', $backbutton, ['class' => 'centerpara buttons']);
if (!$confirm) {
if (!empty($existing)) {
$message = html_writer::span($this->str['persistentfieldsexist']);
$message .= html_writer::alist($existing);
$this->output .= $OUTPUT->notification($message);
if (count($existing) == count($fields)) {
$this->output .= $actionbuttons;
return true;
}
}
$confirmurl = new \moodle_url('/admin/tool/xmldb/index.php', [
'table' => $tableparam,
'dir' => $dir,
'action' => 'add_persistent_mandatory',
'sesskey' => sesskey(),
'confirm' => '1'
]);
$message = html_writer::span($this->str['persistentfieldsconfirm']);
$message .= html_writer::alist(array_diff($fields, $existing));
$this->output .= $OUTPUT->confirm($message, $confirmurl, $returnurl);
} else {
$fieldsadded = [];
foreach ($fields as $field) {
if (!in_array($field, $existing)) {
$fieldsadded[] = $field;
$table->add_field($field, XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, null, 0);
}
}
if (!$table->getKey('usermodified')) {
$table->add_key('usermodified', XMLDB_KEY_FOREIGN, ['usermodified'], 'user', ['id']);
}
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
$message = html_writer::span($this->str['persistentfieldscomplete']);
$message .= html_writer::alist(array_diff($fields, $existing));
$this->output .= $OUTPUT->notification($message, 'success');
$this->output .= $actionbuttons;
}
return $result;
}
}
@@ -0,0 +1,140 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* reporting about the ones not physically implemented as BIGINTs
* and providing one SQL script to fix all them. MDL-11038
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class check_bigints extends XMLDBCheckAction {
/**
* Init method, every subclass will have its own
*/
function init() {
global $DB;
$this->introstr = 'confirmcheckbigints';
parent::init();
// Set own core attributes
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'wrongints' => 'tool_xmldb',
'nowrongintsfound' => 'tool_xmldb',
'yeswrongintsfound' => 'tool_xmldb',
));
}
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) {
$o = '';
$wrong_fields = array();
// 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) {
continue;
}
// If the metadata for that column doesn't exist, skip
if (!isset($metacolumns[$xmldb_field->getName()])) {
continue;
}
$minlength = $xmldb_field->getLength();
if ($minlength > 18) {
// Anything above 18 is borked, just ignore it here.
$minlength = 18;
}
// 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 physical field is wrong
if (($metacolumn->meta_type != 'I' and $metacolumn->meta_type != 'R') or $metacolumn->max_length < $minlength) {
$o.='<font color="red">' . $this->str['wrong'] . '</font>';
// Add the wrong field to the list
$obj = new stdClass();
$obj->table = $xmldb_table;
$obj->field = $xmldb_field;
$wrong_fields[] = $obj;
} else {
$o.='<font color="green">' . $this->str['ok'] . '</font>';
}
$o.='</li>';
}
$o.=' </ul>';
}
return array($o, $wrong_fields);
}
protected function display_results(array $wrong_fields) {
global $DB;
$dbman = $DB->get_manager();
$s = '';
$r = '<table class="generaltable 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;
$sqlarr = $dbman->generator->getAlterFieldSQL($xmldb_table, $xmldb_field);
$r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
$this->str['field'] . ': ' . $xmldb_field->getName() . '</li>';
// Add to output if we have sentences
if ($sqlarr) {
$sqlarr = $dbman->generator->getEndedStatements($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>';
return $r;
}
}
@@ -0,0 +1,195 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* This class will check all the default values existing in the DB
* match those specified in the xml specs
* and providing one SQL script to fix all them.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class check_defaults extends XMLDBCheckAction {
/**
* Init method, every subclass will have its own
*/
public function init() {
$this->introstr = 'confirmcheckdefaults';
parent::init();
// Set own core attributes.
// Set own custom attributes.
// Get needed strings.
$this->loadStrings(array(
'wrongdefaults' => 'tool_xmldb',
'nowrongdefaultsfound' => 'tool_xmldb',
'yeswrongdefaultsfound' => 'tool_xmldb',
'expected' => 'tool_xmldb',
'actual' => 'tool_xmldb',
));
}
protected function check_table(xmldb_table $xmldbtable, array $metacolumns) {
$o = '';
$wrongfields = array();
// Get and process XMLDB fields.
if ($xmldbfields = $xmldbtable->getFields()) {
$o .= ' <ul>';
foreach ($xmldbfields as $xmldbfield) {
// Get the default value for the field.
$xmldbdefault = $xmldbfield->getDefault();
// Char fields with not null currently have default '' when actually installed.
if ($xmldbdefault === null && $xmldbfield->getType() === XMLDB_TYPE_CHAR &&
$xmldbfield->getNotNull()) {
$xmldbdefault = '';
}
if ($xmldbdefault !== null) {
$xmldbdefault = (string)$xmldbdefault;
}
// If the metadata for that column doesn't exist or 'id' field found, skip.
if (!isset($metacolumns[$xmldbfield->getName()]) or $xmldbfield->getName() == 'id') {
continue;
}
// To variable for better handling.
$metacolumn = $metacolumns[$xmldbfield->getName()];
// Going to check this field in DB.
$o .= ' <li>' . $this->str['field'] . ': ' . $xmldbfield->getName() . ' ';
// Get the value of the physical default (or blank if there isn't one).
if ($metacolumn->has_default == 1) {
$physicaldefault = $metacolumn->default_value;
} else {
$physicaldefault = null;
}
// For number fields there are issues with type differences, so let's convert
// everything to a float.
if ($xmldbfield->getType() === XMLDB_TYPE_NUMBER) {
if ($physicaldefault !== null) {
$physicaldefault = (float) $physicaldefault;
}
if ($xmldbdefault !== null) {
$xmldbdefault = (float) $xmldbdefault;
}
}
// There *is* a default and it's wrong.
if ($physicaldefault !== $xmldbdefault) {
$xmldbtext = self::display_default($xmldbdefault);
$physicaltext = self::display_default($physicaldefault);
$info = "({$this->str['expected']} {$xmldbtext}, {$this->str['actual']} {$physicaltext})";
$o .= '<font color="red">' . $this->str['wrong'] . " $info</font>";
// Add the wrong field to the list.
$obj = new stdClass();
$obj->table = $xmldbtable;
$obj->field = $xmldbfield;
$obj->physicaldefault = $physicaldefault;
$obj->xmldbdefault = $xmldbdefault;
$wrongfields[] = $obj;
} else {
$o .= '<font color="green">' . $this->str['ok'] . '</font>';
}
$o .= '</li>';
}
$o .= ' </ul>';
}
return array($o, $wrongfields);
}
/**
* Converts a default value suitable for display.
*
* @param string|null $defaultvalue Default value
* @return string Displayed version
*/
protected static function display_default($defaultvalue) {
if ($defaultvalue === null) {
return '-';
} else {
return "'" . s($defaultvalue) . "'";
}
}
protected function display_results(array $wrongfields) {
global $DB;
$dbman = $DB->get_manager();
$s = '';
$r = '<table class="generaltable 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['wrongdefaults'] . ': ' . count($wrongfields) . '</p>';
$r .= ' </td></tr>';
$r .= ' <tr><td class="generalboxcontent">';
// If we have found wrong defaults inform about them.
if (count($wrongfields)) {
$r .= ' <p class="centerpara">' . $this->str['yeswrongdefaultsfound'] . '</p>';
$r .= ' <ul>';
foreach ($wrongfields as $obj) {
$xmldbtable = $obj->table;
$xmldbfield = $obj->field;
$physicaltext = self::display_default($obj->physicaldefault);
$xmldbtext = self::display_default($obj->xmldbdefault);
// Get the alter table command.
$sqlarr = $dbman->generator->getAlterFieldSQL($xmldbtable, $xmldbfield);
$r .= ' <li>' . $this->str['table'] . ': ' . $xmldbtable->getName() . '. ' .
$this->str['field'] . ': ' . $xmldbfield->getName() . ', ' .
$this->str['expected'] . ' ' . $xmldbtext . ' ' .
$this->str['actual'] . ' ' . $physicaltext . '</li>';
// Add to output if we have sentences.
if ($sqlarr) {
$sqlarr = $dbman->generator->getEndedStatements($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['nowrongdefaultsfound'] . '</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>';
return $r;
}
}
@@ -0,0 +1,196 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will look for data in the database that violates the foreign
* key definitions found in the XMLDB definitions.
*
* Note that by default, this check does not complain about foreign key
* violations from, say, a userid column defined as NOT NULL DEFAULT '0'.
* Each 0 in that column will violate the foreign key, but we ignore them.
* If you want a strict check performed, then add &strict=1 to the URL.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class check_foreign_keys extends XMLDBCheckAction {
/**
* Init method, every subclass will have its own
*/
function init() {
$this->introstr = 'confirmcheckforeignkeys';
parent::init();
// Set own core attributes
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'key' => 'tool_xmldb',
'violatedforeignkeys' => 'tool_xmldb',
'noviolatedforeignkeysfound' => 'tool_xmldb',
'violatedforeignkeysfound' => 'tool_xmldb',
'violations' => 'tool_xmldb',
'unknowntable' => 'tool_xmldb',
'unknownfield' => 'tool_xmldb',
));
}
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) {
global $DB;
$dbman = $DB->get_manager();
$strictchecks = optional_param('strict', false, PARAM_BOOL);
$o = '';
$violatedkeys = array();
// Keys
if ($xmldb_keys = $xmldb_table->getKeys()) {
$o.=' <ul>';
foreach ($xmldb_keys as $xmldb_key) {
// We are only interested in foreign keys.
if (!in_array($xmldb_key->getType(), array(XMLDB_KEY_FOREIGN, XMLDB_KEY_FOREIGN_UNIQUE))) {
continue;
}
$o.=' <li>' . $this->str['key'] . ': ' . $xmldb_key->readableInfo() . ' ';
$reftable = $xmldb_key->getRefTable();
if (!$dbman->table_exists($reftable)) {
$o.='<font color="red">' . $this->str['unknowntable'] . '</font>';
// Add the missing index to the list
$violation = new stdClass();
$violation->string = 'fkunknowntable';
$violation->table = $xmldb_table;
$violation->key = $xmldb_key;
$violation->reftable = $reftable;
$violatedkeys[] = $violation;
continue;
}
// Work out the SQL to find key violations.
$keyfields = $xmldb_key->getFields();
$reffields = $xmldb_key->getRefFields();
$joinconditions = array();
$nullnessconditions = array();
$params = array();
foreach ($keyfields as $i => $field) {
if (!$dbman->field_exists($reftable, $reffields[$i])) {
$o.='<font color="red">' . $this->str['unknownfield'] . '</font>';
// Add the missing index to the list
$violation = new stdClass();
$violation->string = 'fkunknownfield';
$violation->table = $xmldb_table;
$violation->key = $xmldb_key;
$violation->reftable = $reftable;
$violation->reffield = $reffields[$i];
$violatedkeys[] = $violation;
continue 2;
}
$joinconditions[] = 't1.' . $field . ' = t2.' . $reffields[$i];
$xmldb_field = $xmldb_table->getField($field);
$default = $xmldb_field->getDefault();
if (!$xmldb_field->getNotNull()) {
$nullnessconditions[] = 't1.' . $field . ' IS NOT NULL';
} else if (!$strictchecks && ($default == '0' || !$default)) {
// We have a default of 0 or '' or something like that.
// These generate a lot of false-positives, so ignore them
// for now.
$nullnessconditions[] = 't1.' . $field . ' <> ?';
$params[] = $xmldb_field->getDefault();
}
}
$nullnessconditions[] = 't2.id IS NULL';
$sql = 'SELECT count(1) FROM {' . $xmldb_table->getName() .
'} t1 LEFT JOIN {' . $reftable . '} t2 ON ' .
implode(' AND ', $joinconditions) . ' WHERE ' .
implode(' AND ', $nullnessconditions);
// Check there are any problems in the database.
$violations = $DB->count_records_sql($sql, $params);
if ($violations == 0) {
$o.='<font color="green">' . $this->str['ok'] . '</font>';
} else {
$o.='<font color="red">' . $this->str['violations'] . '</font>';
// Add the missing index to the list
$violation = new stdClass;
$violation->string = 'fkviolationdetails';
$violation->table = $xmldb_table;
$violation->key = $xmldb_key;
$violation->numviolations = $violations;
$violation->numrows = $DB->count_records($xmldb_table->getName());
$violation->sql = str_replace('count(1)', '*', $sql);
if (!empty($params)) {
$violation->sqlparams = '(' . implode(', ', $params) . ')';
} else {
$violation->sqlparams = '';
}
$violatedkeys[] = $violation;
}
$o.='</li>';
}
$o.=' </ul>';
}
return array($o, $violatedkeys);
}
protected function display_results(array $violatedkeys) {
$r = '<table class="generaltable 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['violatedforeignkeys'] . ': ' . count($violatedkeys) . '</p>';
$r.= ' </td></tr>';
$r.= ' <tr><td class="generalboxcontent">';
// If we have found wrong integers inform about them
if (count($violatedkeys)) {
$r.= ' <p class="centerpara">' . $this->str['violatedforeignkeysfound'] . '</p>';
$r.= ' <ul>';
foreach ($violatedkeys as $violation) {
$violation->tablename = $violation->table->getName();
$violation->keyname = $violation->key->getName();
$r.= ' <li>' .get_string($violation->string, 'tool_xmldb', $violation);
if (!empty($violation->sql)) {
$r.= '<pre>' . s($violation->sql) . '; ' . s($violation->sqlparams) . '</pre>';
}
$r.= '</li>';
}
$r.= ' </ul>';
} else {
$r.= ' <p class="centerpara">' . $this->str['noviolatedforeignkeysfound'] . '</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>';
return $r;
}
}
@@ -0,0 +1,219 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will compare all the indexes found in the XMLDB definitions
* with the physical DB implementation, reporting about all the missing
* indexes to be created to be 100% ok.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class check_indexes extends XMLDBCheckAction {
/**
* Init method, every subclass will have its own
*/
function init() {
$this->introstr = 'confirmcheckindexes';
parent::init();
// Set own core attributes
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'extraindexesfound' => 'tool_xmldb',
'missing' => 'tool_xmldb',
'key' => 'tool_xmldb',
'index' => 'tool_xmldb',
'missingindexes' => 'tool_xmldb',
'nomissingorextraindexesfound' => 'tool_xmldb',
'yesextraindexesfound' => 'tool_xmldb',
'yesmissingindexesfound' => 'tool_xmldb',
));
}
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) {
global $DB;
$dbman = $DB->get_manager();
$o = '';
$dbindexes = $DB->get_indexes($xmldb_table->getName());
$missing_indexes = array();
// 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 (!$dbman->generator->getKeySQL($xmldb_table, $xmldb_key) || $xmldb_key->getType() == XMLDB_KEY_FOREIGN) {
// Create the interim index
$xmldb_index = new xmldb_index('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 ($dbman->index_exists($xmldb_table, $xmldb_index)) {
$o.='<font color="green">' . $this->str['ok'] . '</font>';
$this->remove_index_from_dbindex($dbindexes, $xmldb_index);
} else {
$o.='<font color="red">' . $this->str['missing'] . '</font>';
// Add the missing index to the list
$obj = new stdClass();
$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 ($dbman->index_exists($xmldb_table, $xmldb_index)) {
$o.='<font color="green">' . $this->str['ok'] . '</font>';
$this->remove_index_from_dbindex($dbindexes, $xmldb_index);
} else {
$o.='<font color="red">' . $this->str['missing'] . '</font>';
// Add the missing index to the list
$obj = new stdClass();
$obj->table = $xmldb_table;
$obj->index = $xmldb_index;
$missing_indexes[] = $obj;
}
$o.='</li>';
}
$o.=' </ul>';
}
// Hack - skip for table 'search_simpledb_index' as this plugin adds indexes dynamically on install
// which are not included in install.xml. See search/engine/simpledb/db/install.php.
if ($xmldb_table->getName() != 'search_simpledb_index') {
foreach ($dbindexes as $indexname => $index) {
$missing_indexes[] = $indexname;
}
}
return array($o, $missing_indexes);
}
protected function display_results(array $missing_indexes) {
global $DB;
$dbman = $DB->get_manager();
$missingindexes = [];
$extraindexes = [];
foreach ($missing_indexes as $missingindex) {
if (is_object($missingindex)) {
$missingindexes[] = $missingindex;
} else {
$extraindexes[] = $missingindex;
}
}
$s = '';
$r = '<table class="generaltable 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($missingindexes) . '</p>';
$r .= ' <p class="centerpara">' . $this->str['extraindexesfound'] . ': ' . count($extraindexes) . '</p>';
$r.= ' </td></tr>';
$r.= ' <tr><td class="generalboxcontent">';
// If we have found missing indexes or extra indexes inform the user about them.
if (!empty($missingindexes) || !empty($extraindexes)) {
if ($missingindexes) {
$r.= ' <p class="centerpara">' . $this->str['yesmissingindexesfound'] . '</p>';
$r.= ' <ul>';
foreach ($missingindexes as $obj) {
$xmldb_table = $obj->table;
$xmldb_index = $obj->index;
$sqlarr = $dbman->generator->getAddIndexSQL($xmldb_table, $xmldb_index);
$r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
$this->str['index'] . ': ' . $xmldb_index->readableInfo() . '</li>';
$sqlarr = $dbman->generator->getEndedStatements($sqlarr);
$s.= '<code>' . str_replace("\n", '<br />', implode('<br />', $sqlarr)) . '</code><br />';
}
$r.= ' </ul>';
// Add the SQL statements (all together)
$r.= '<hr />' . $s;
}
if ($extraindexes) {
$r .= '<p class="centerpara">' . $this->str['yesextraindexesfound'] . '</p>';
$r .= '<ul>';
foreach ($extraindexes as $ei) {
$r .= '<li>' . $ei . '</li>';
}
$r .= '</ul>';
$r .= '<hr />';
}
} else {
$r .= '<p class="centerpara">' . $this->str['nomissingorextraindexesfound'] . '</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>';
return $r;
}
/**
* Removes an index from the array $dbindexes if it is found.
*
* @param array $dbindexes
* @param xmldb_index $index
*/
private function remove_index_from_dbindex(array &$dbindexes, xmldb_index $index) {
foreach ($dbindexes as $key => $dbindex) {
if ($dbindex['columns'] == $index->getFields()) {
unset($dbindexes[$key]);
}
}
}
}
@@ -0,0 +1,153 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2011 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will check all the varchar2() columns
* in the Moodle installed DB, looking for incorrect (INT)
* length semanticas providing one SQL script to fix all
* them by changing to cross-db (CHAR) length semantics.
* See MDL-29322 for more details.
*
* @package tool_xmldb
* @copyright 2011 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class check_oracle_semantics extends XMLDBCheckAction {
/**
* Init method, every subclass will have its own
*/
function init() {
$this->introstr = 'confirmcheckoraclesemantics';
parent::init();
// Set own core attributes
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'wrongoraclesemantics' => 'tool_xmldb',
'nowrongoraclesemanticsfound' => 'tool_xmldb',
'yeswrongoraclesemanticsfound' => 'tool_xmldb',
'expected' => 'tool_xmldb',
'actual' => 'tool_xmldb',
));
}
protected function check_table(xmldb_table $xmldb_table, array $metacolumns) {
global $DB;
$o = '';
$wrong_fields = array();
// Get and process XMLDB fields
if ($xmldb_fields = $xmldb_table->getFields()) {
$o .= '<ul>';
foreach ($xmldb_fields as $xmldb_field) {
// Get the type of the column, we only will process CHAR (VARCHAR2) ones
if ($xmldb_field->getType() != XMLDB_TYPE_CHAR) {
continue;
}
$o.='<li>' . $this->str['field'] . ': ' . $xmldb_field->getName() . ' ';
// Get current semantic from dictionary, we only will process B (BYTE) ones
// suplying the SQL code to change them to C (CHAR) semantic
$params = array(
'table_name' => core_text::strtoupper($DB->get_prefix() . $xmldb_table->getName()),
'column_name' => core_text::strtoupper($xmldb_field->getName()),
'data_type' => 'VARCHAR2');
$currentsemantic = $DB->get_field_sql('
SELECT char_used
FROM user_tab_columns
WHERE table_name = :table_name
AND column_name = :column_name
AND data_type = :data_type', $params);
// If using byte semantics, we'll need to change them to char semantics
if ($currentsemantic == 'B') {
$info = '(' . $this->str['expected'] . " 'CHAR', " . $this->str['actual'] . " 'BYTE')";
$o .= '<font color="red">' . $this->str['wrong'] . " $info</font>";
// Add the wrong field to the list
$obj = new stdClass();
$obj->table = $xmldb_table;
$obj->field = $xmldb_field;
$wrong_fields[] = $obj;
} else {
$o .= '<font color="green">' . $this->str['ok'] . '</font>';
}
$o .= '</li>';
}
$o .= '</ul>';
}
return array($o, $wrong_fields);
}
protected function display_results(array $wrong_fields) {
global $DB;
$dbman = $DB->get_manager();
$s = '';
$r = '<table class="generaltable 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['wrongoraclesemantics'] . ': ' . count($wrong_fields) . '</p>';
$r.= ' </td></tr>';
$r.= ' <tr><td class="generalboxcontent">';
// If we have found wrong defaults inform about them
if (count($wrong_fields)) {
$r.= ' <p class="centerpara">' . $this->str['yeswrongoraclesemanticsfound'] . '</p>';
$r.= ' <ul>';
foreach ($wrong_fields as $obj) {
$xmldb_table = $obj->table;
$xmldb_field = $obj->field;
$r.= ' <li>' . $this->str['table'] . ': ' . $xmldb_table->getName() . '. ' .
$this->str['field'] . ': ' . $xmldb_field->getName() . ', ' .
$this->str['expected'] . ' ' . "'CHAR'" . ' ' .
$this->str['actual'] . ' ' . "'BYTE'" . '</li>';
$sql = 'ALTER TABLE ' . $DB->get_prefix() . $xmldb_table->getName() . ' MODIFY ' .
$xmldb_field->getName() . ' VARCHAR2(' . $xmldb_field->getLength() . ' CHAR)';
$sql = $dbman->generator->getEndedStatements($sql);
$s.= '<code>' . str_replace("\n", '<br />', $sql) . '</code><br />';
}
$r.= ' </ul>';
// Add the SQL statements (all together)
$r.= '<hr />' . $s;
} else {
$r.= ' <p class="centerpara">' . $this->str['nowrongoraclesemanticsfound'] . '</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>';
return $r;
}
}
@@ -0,0 +1,131 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class create_xml_file extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own core attributes
$this->can_subaction = ACTION_NONE;
//$this->can_subaction = ACTION_HAVE_SUBACTIONS;
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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);
$plugintype = $this->get_plugin_type($dirpath);
$dirpath = $CFG->dirroot . $dirpath;
$file = $dirpath . '/install.xml';
// Some variables
$xmlpath = dirname(str_replace($CFG->dirroot . '/', '', $file));
$xmlversion = userdate(time(), '%Y%m%d', 99, false);
$xmlcomment = 'XMLDB file for Moodle ' . dirname($xmlpath);
$xmltable = strtolower(basename(dirname($xmlpath)));
if ($plugintype && $plugintype != 'mod') {
$xmltable = $plugintype.'_'.$xmltable;
}
// Initial contents
$c = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
$c.= ' <XMLDB PATH="' . $xmlpath . '" VERSION="' . $xmlversion .'" COMMENT="' . $xmlcomment .'">' . "\n";
$c.= ' <TABLES>' . "\n";
$c.= ' <TABLE NAME="' . $xmltable . '" COMMENT="Default comment for ' . $xmltable .', please edit me">' . "\n";
$c.= ' <FIELDS>' . "\n";
$c.= ' <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />' . "\n";
$c.= ' </FIELDS>' . "\n";
$c.= ' <KEYS>' . "\n";
$c.= ' <KEY NAME="primary" TYPE="primary" FIELDS="id" />' . "\n";
$c.= ' </KEYS>' . "\n";
$c.= ' </TABLE>' . "\n";
$c.= ' </TABLES>' . "\n";
$c.= ' </XMLDB>' . "\n";
if (!file_put_contents($file, $c)) {
$errormsg = 'Error creando fichero ' . $file;
$result = false;
}
// Launch postaction if exists
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
/**
* From a given path, work out what type of plugin
* this belongs to
* @param string $dirpath Path to the db file for this plugin
* @return string the type of the plugin or null if not found
*/
function get_plugin_type($dirpath) {
global $CFG;
$dirpath = $CFG->dirroot.$dirpath;
// Reverse order so that we get subplugin matches.
$plugintypes = array_reverse(core_component::get_plugin_types());
foreach ($plugintypes as $plugintype => $pluginbasedir) {
if (substr($dirpath, 0, strlen($pluginbasedir)) == $pluginbasedir) {
return $plugintype;
}
}
return null;
}
}
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will delete completely one field
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_field extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'confirmdeletefield' => 'tool_xmldb',
'yes' => '',
'no' => ''
));
}
/**
* 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;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = required_param('table', PARAM_CLEAN);
$fieldparam = required_param('field', PARAM_CLEAN);
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// If not confirmed, show confirmation box
if (!$confirmed) {
$o = '<table width="60" class="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmdeletefield'] . '<br /><br />' . $fieldparam . '</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=delete_field&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;postaction=edit_table&amp;field=' . $fieldparam . '&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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 {
// Get the edited dir
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
$editeddir = $XMLDB->editeddirs[$dirpath];
if ($editeddir) {
$structure = $editeddir->xml_file->getStructure();
// Move adjacent fields prev and next attributes
$tables = $structure->getTables();
$table = $structure->getTable($tableparam);
$fields = $table->getFields();
$field = $table->getField($fieldparam);
if ($field->getPrevious()) {
$prev = $table->getField($field->getPrevious());
$prev->setNext($field->getNext());
}
if ($field->getNext()) {
$next = $table->getField($field->getNext());
$next->setPrevious($field->getPrevious());
}
// Remove the field
$table->deleteField($fieldparam);
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
}
}
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will delete completely one index
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_index extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'confirmdeleteindex' => 'tool_xmldb',
'yes' => '',
'no' => ''
));
}
/**
* 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;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = required_param('table', PARAM_PATH);
$indexparam = required_param('index', PARAM_PATH);
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// If not confirmed, show confirmation box
if (!$confirmed) {
$o = '<table width="60" class="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmdeleteindex'] . '<br /><br />' . $indexparam . '</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=delete_index&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;postaction=edit_table&amp;index=' . $indexparam . '&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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 {
// Get the edited dir
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
$editeddir = $XMLDB->editeddirs[$dirpath];
if ($editeddir) {
$structure = $editeddir->xml_file->getStructure();
// Move adjacent indexes prev and next attributes
$tables = $structure->getTables();
$table = $structure->getTable($tableparam);
$indexes = $table->getIndexes();
$index = $table->getIndex($indexparam);
if ($index->getPrevious()) {
$prev = $table->getIndex($index->getPrevious());
$prev->setNext($index->getNext());
}
if ($index->getNext()) {
$next = $table->getIndex($index->getNext());
$next->setPrevious($index->getPrevious());
}
// Remove the index
$table->deleteIndex($indexparam);
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
}
}
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will delete completely one key
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_key extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'confirmdeletekey' => 'tool_xmldb',
'yes' => '',
'no' => ''
));
}
/**
* 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;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = required_param('table', PARAM_PATH);
$keyparam = required_param('key', PARAM_PATH);
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// If not confirmed, show confirmation box
if (!$confirmed) {
$o = '<table width="60" class="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmdeletekey'] . '<br /><br />' . $keyparam . '</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=delete_key&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;postaction=edit_table&amp;key=' . $keyparam . '&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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 {
// Get the edited dir
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
$editeddir = $XMLDB->editeddirs[$dirpath];
if ($editeddir) {
$structure = $editeddir->xml_file->getStructure();
// Move adjacent keys prev and next attributes
$tables = $structure->getTables();
$table = $structure->getTable($tableparam);
$keys = $table->getKeys();
$key = $table->getKey($keyparam);
if ($key->getPrevious()) {
$prev = $table->getKey($key->getPrevious());
$prev->setNext($key->getNext());
}
if ($key->getNext()) {
$next = $table->getKey($key->getNext());
$next->setPrevious($key->getPrevious());
}
// Remove the key
$table->deleteKey($keyparam);
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
}
}
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,116 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will delete completely one table
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_table extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'confirmdeletetable' => 'tool_xmldb',
'yes' => '',
'no' => ''
));
}
/**
* 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;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = required_param('table', PARAM_CLEAN);
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// If not confirmed, show confirmation box
if (!$confirmed) {
$o = '<table width="60" class="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmdeletetable'] . '<br /><br />' . $tableparam . '</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=delete_table&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;postaction=edit_xml_file&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '" 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 {
// Get the edited dir
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
$editeddir = $XMLDB->editeddirs[$dirpath];
if ($editeddir) {
$structure = $editeddir->xml_file->getStructure();
// Remove the table
$structure->deleteTable($tableparam);
}
}
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,112 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will delete completely one XML file
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class delete_xml_file extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'confirmdeletexmlfile' => 'tool_xmldb',
'yes' => '',
'no' => ''
));
}
/**
* 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;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_CLEAN);
$dirpath = $CFG->dirroot . $dirpath;
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// If not confirmed, show confirmation box
if (!$confirmed) {
$o = '<table width="60" class="generaltable" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmdeletexmlfile'] . '<br /><br />' . $dirpath . '/install.php</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=delete_xml_file&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;postaction=main_view#lastused" 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#lastused" 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 {
// Get the original dir and delete the xml file
if (!empty($XMLDB->dbdirs)) {
if (isset($XMLDB->dbdirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
if ($dbdir) {
@unlink($dirpath . '/install.xml');
}
}
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,206 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will provide the interface for all the edit field actions
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_field extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'change' => 'tool_xmldb',
'float2numbernote' => 'tool_xmldb',
'vieworiginal' => 'tool_xmldb',
'viewedited' => 'tool_xmldb',
'yes' => '',
'no' => '',
'back' => 'tool_xmldb'
));
}
/**
* 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, $OUTPUT;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// Fetch request data
$tableparam = required_param('table', PARAM_CLEAN);
if (!$table = $structure->getTable($tableparam)) {
$this->errormsg = 'Wrong table specified: ' . $tableparam;
return false;
}
$fieldparam = required_param('field', PARAM_CLEAN);
if (!$field = $table->getField($fieldparam)) {
// Arriving here from a name change, looking for the new field name
$fieldparam = required_param('name', PARAM_CLEAN);
$field = $table->getField($fieldparam);
}
$dbdir = $XMLDB->dbdirs[$dirpath];
$origstructure = $dbdir->xml_file->getStructure();
$o = ''; // Output starts
// If field is XMLDB_TYPE_FLOAT, comment about to migrate it to XMLDB_TYPE_NUMBER
if ($field->getType() == XMLDB_TYPE_FLOAT) {
$o .= '<p>' . $this->str['float2numbernote'] . '</p>';
}
// Add the main form
$o.= '<form id="form" action="index.php" method="post">';
$o.= ' <div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="table" value="' . $tableparam .'" />';
$o.= ' <input type="hidden" name ="field" value="' . $fieldparam .'" />';
$o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />';
$o.= ' <input type="hidden" name ="action" value="edit_field_save" />';
$o.= ' <input type="hidden" name ="postaction" value="edit_table" />';
$o.= ' <table id="formelements" class="boxaligncenter">';
// XMLDB field name
// If the field has dependencies, we cannot change its name
$disabled = '';
if ($structure->getFieldUses($table->getName(), $field->getName())) {
$o.= ' <input type="hidden" name ="name" value="' . s($field->getName()) .'" />';
$o.= ' <tr valign="top"><td>Name:</td><td colspan="2">' . s($field->getName()) . '</td></tr>';
} else {
$o.= ' <tr valign="top"><td><label for="name" accesskey="n">Name:</label></td><td colspan="2"><input name="name" type="text" size="'.xmldb_field::NAME_MAX_LENGTH.'" maxlength="'.xmldb_field::NAME_MAX_LENGTH.'" id="name" value="' . s($field->getName()) . '" /></td></tr>';
}
// XMLDB field comment
$o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td colspan="2">
<textarea name="comment" rows="3" cols="80" id="comment" class="form-control">' .
s($field->getComment()) . '</textarea></td></tr>';
// xmldb_field Type
$typeoptions = array (XMLDB_TYPE_INTEGER => $field->getXMLDBTypeName(XMLDB_TYPE_INTEGER),
XMLDB_TYPE_NUMBER => $field->getXMLDBTypeName(XMLDB_TYPE_NUMBER),
XMLDB_TYPE_FLOAT => $field->getXMLDBTypeName(XMLDB_TYPE_FLOAT),
XMLDB_TYPE_DATETIME=> $field->getXMLDBTypeName(XMLDB_TYPE_DATETIME),
XMLDB_TYPE_CHAR => $field->getXMLDBTypeName(XMLDB_TYPE_CHAR),
XMLDB_TYPE_TEXT => $field->getXMLDBTypeName(XMLDB_TYPE_TEXT),
XMLDB_TYPE_BINARY => $field->getXMLDBTypeName(XMLDB_TYPE_BINARY));
// If current field isn't float, delete such column type to avoid its creation from the interface
// Note that float fields are supported completely but it's possible than in a next future
// we delete them completely from Moodle DB, using, exclusively, number(x,y) types
if ($field->getType() != XMLDB_TYPE_FLOAT) {
unset ($typeoptions[XMLDB_TYPE_FLOAT]);
}
// Also we hide datetimes. Only edition of them is allowed (and retrofit) but not new creation
if ($field->getType() != XMLDB_TYPE_DATETIME) {
unset ($typeoptions[XMLDB_TYPE_DATETIME]);
}
$select = html_writer::select($typeoptions, 'type', $field->getType(), false);
$o.= ' <tr valign="top"><td><label for="menutype" accesskey="t">Type:</label></td>';
$o.= ' <td colspan="2">' . $select . '</td></tr>';
// xmldb_field Length
$o.= ' <tr valign="top"><td><label for="length" accesskey="l">Length:</label></td>';
$o.= ' <td colspan="2"><input name="length" type="text" size="6" maxlength="6" id="length" value="' . s($field->getLength()) . '" /><span id="lengthtip"></span></td></tr>';
// xmldb_field Decimals
$o.= ' <tr valign="top"><td><label for="decimals" accesskey="d">Decimals:</label></td>';
$o.= ' <td colspan="2"><input name="decimals" type="text" size="6" maxlength="6" id="decimals" value="' . s($field->getDecimals()) . '" /><span id="decimalstip"></span></td></tr>';
// xmldb_field NotNull
$notnulloptions = array (0 => 'null', 'not null');
$select = html_writer::select($notnulloptions, 'notnull', $field->getNotNull(), false);
$o.= ' <tr valign="top"><td><label for="menunotnull" accesskey="n">Not Null:</label></td>';
$o.= ' <td colspan="2">' . $select . '</td></tr>';
// xmldb_field Sequence
$sequenceoptions = array (0 => $this->str['no'], 1 => 'auto-numbered');
$select = html_writer::select($sequenceoptions, 'sequence', $field->getSequence(), false);
$o.= ' <tr valign="top"><td><label for="menusequence" accesskey="s">Sequence:</label></td>';
$o.= ' <td colspan="2">' . $select . '</td></tr>';
// xmldb_field Default
$o.= ' <tr valign="top"><td><label for="default" accesskey="d">Default:</label></td>';
$o.= ' <td colspan="2"><input type="text" name="default" size="30" maxlength="80" id="default" value="' . s($field->getDefault()) . '" /></td></tr>';
// Change button
$o .= ' <tr valign="top"><td>&nbsp;</td><td colspan="2"><input type="submit" value="' . $this->str['change'] .
'" class="btn btn-secondary" /></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
// Calculate the buttons
$b = ' <p class="centerpara buttons">';
// The view original XML button
if ($table->getField($fieldparam)) {
$b .= '&nbsp;<a href="index.php?action=view_field_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original&amp;table=' . $tableparam . '&amp;field=' . $fieldparam . '">[' . $this->str['vieworiginal'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['vieworiginal'] . ']';
}
// The view edited XML button
if ($field->hasChanged()) {
$b .= '&nbsp;<a href="index.php?action=view_field_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited&amp;table=' . $tableparam . '&amp;field=' . $fieldparam . '">[' . $this->str['viewedited'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['viewedited'] . ']';
}
// The back to edit table button
$b .= '&nbsp;<a href="index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o .= $b;
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,136 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// Register the needed events
onload=function() {
// Adjust the form on load
transformForm();
// Get the required fields
var typeField = document.getElementById('menutype');
var sequenceField = document.getElementById('menusequence');
// Register the rest of events
if (typeField.addEventListener) {
// Standard
typeField.addEventListener('change', transformForm, false);
sequenceField.addEventListener('change', transformForm, false);
} else {
// IE 5.5
typeField.attachEvent('onchange', transformForm);
sequenceField.attachEvent('onchange', transformForm);
}
}
/**
* This function controls all modifications to perform when any field changes
*/
function transformForm(event) {
// Initialize all the needed variables
var typeField = document.getElementById('menutype');
var lengthField = document.getElementById('length');
var decimalsField = document.getElementById('decimals');
var notnullField = document.getElementById('menunotnull');
var sequenceField = document.getElementById('menusequence');
var defaultField = document.getElementById('default');
var lengthTip = document.getElementById('lengthtip');
var decimalsTip = document.getElementById('decimalstip');
// Initially, enable everything
decimalsField.disabled = false;
notnullField.disabled = false;
sequenceField.disabled = false;
defaultField.disabled = false;
// Based on sequence, disable some items
if (sequenceField.value == '1') {
notnullField.disabled = true;
notnullField.value = '1';
defaultField.disabled = true;
defaultField.value = '';
}
// Based on type, disable some items
switch (typeField.value) {
case '1': // XMLDB_TYPE_INTEGER
lengthTip.innerHTML = ' 1...20'; // Hardcoded xmldb_field::INTEGER_MAX_LENGTH, yes!
lengthField.disabled = false;
decimalsTip.innerHTML = '';
decimalsField.disabled = true;
decimalsField.value = '';
break;
case '2': // XMLDB_TYPE_NUMBER
lengthTip.innerHTML = ' 1...38'; // Hardcoded xmldb_field::NUMBER_MAX_LENGTH, yes!
lengthField.disabled = false;
decimalsTip.innerHTML = ' 0...length or empty';
break;
case '3': // XMLDB_TYPE_FLOAT
lengthTip.innerHTML = ' 1...20 or empty'; // Hardcoded xmldb_field::FLOAT_MAX_LENGTH, yes!
lengthField.disabled = false;
decimalsTip.innerHTML = ' 0...length or empty';
break;
case '4': // XMLDB_TYPE_CHAR
lengthTip.innerHTML = ' 1...1333'; // Hardcoded xmldb_field::CHAR_MAX_LENGTH, yes!
lengthField.disabled = false;
decimalsTip.innerHTML = '';
decimalsField.disabled = true;
decimalsField.value = '';
sequenceField.disabled = true;
sequenceField.value = '0';
break;
case '5': // XMLDB_TYPE_TEXT
lengthTip.innerHTML = '';
lengthField.disabled = true;
decimalsTip.innerHTML = '';
decimalsField.disabled = true;
decimalsField.value = '';
sequenceField.disabled = true;
sequenceField.value = '0';
defaultField.disabled = true;
defaultField.value = '';
break;
case '6': // XMLDB_TYPE_BINARY
lengthTip.innerHTML = '';
lengthField.disabled = true;
decimalsTip.innerHTML = '';
decimalsField.disabled = true;
decimalsField.value = '';
sequenceField.disabled = true;
sequenceField.value = '0';
defaultField.disabled = true;
defaultField.value = '';
break;
case '7': // XMLDB_TYPE_DATETIME
lengthTip.innerHTML = '';
lengthField.disabled = true;
lengthField.value = '';
decimalsTip.innerHTML = '';
decimalsField.disabled = true;
decimalsField.value = '';
sequenceField.disabled = true;
sequenceField.value = '0';
defaultField.disabled = true;
defaultField.value = '';
break;
}
}
@@ -0,0 +1,275 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class verifies all the data introduced when editing a field for correctness,
* performing changes / displaying errors depending of the results.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_field_save extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'fieldnameempty' => 'tool_xmldb',
'incorrectfieldname' => 'tool_xmldb',
'duplicatefieldname' => 'tool_xmldb',
'integerincorrectlength' => 'tool_xmldb',
'numberincorrectlength' => 'tool_xmldb',
'floatincorrectlength' => 'tool_xmldb',
'charincorrectlength' => 'tool_xmldb',
'numberincorrectdecimals' => 'tool_xmldb',
'numberincorrectwholepart' => 'tool_xmldb',
'floatincorrectdecimals' => 'tool_xmldb',
'defaultincorrect' => 'tool_xmldb',
'back' => 'tool_xmldb',
'administration' => ''
));
}
/**
* 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
if (!data_submitted()) { // Basic prevention
throw new \moodle_exception('wrongcall', 'error');
}
// Get parameters
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = strtolower(required_param('table', PARAM_PATH));
$fieldparam = strtolower(required_param('field', PARAM_PATH));
$name = substr(trim(strtolower(optional_param('name', $fieldparam, PARAM_PATH))),0,xmldb_field::NAME_MAX_LENGTH);
$comment = required_param('comment', PARAM_CLEAN);
$comment = trim($comment);
$type = required_param('type', PARAM_INT);
$length = optional_param('length', null, PARAM_INT);
$decimals = optional_param('decimals', NULL, PARAM_INT);
$notnull = optional_param('notnull', false, PARAM_BOOL);
$sequence = optional_param('sequence', false, PARAM_BOOL);
$default = optional_param('default', NULL, PARAM_PATH);
$default = is_null($default) ? $default : trim($default);
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
$table = $structure->getTable($tableparam);
$field = $table->getField($fieldparam);
$oldhash = $field->getHash();
$errors = array(); // To store all the errors found
// Perform some automatic assumptions
if ($sequence) {
$notnull = true;
$default = NULL;
}
if ($type != XMLDB_TYPE_NUMBER && $type != XMLDB_TYPE_FLOAT) {
$decimals = NULL;
}
if ($type == XMLDB_TYPE_BINARY) {
$default = NULL;
}
if ($default === '') {
$default = NULL;
}
// Perform some checks
// Check empty name
if (empty($name)) {
$errors[] = $this->str['fieldnameempty'];
}
// Check incorrect name
if ($name == 'changeme') {
$errors[] = $this->str['incorrectfieldname'];
}
// Check duplicate name
if ($fieldparam != $name && $table->getField($name)) {
$errors[] = $this->str['duplicatefieldname'];
}
// Integer checks
if ($type == XMLDB_TYPE_INTEGER) {
if (!(is_numeric($length) && !empty($length) && intval($length)==floatval($length) &&
$length > 0 && $length <= xmldb_field::INTEGER_MAX_LENGTH)) {
$errors[] = $this->str['integerincorrectlength'];
}
if (!(empty($default) || (is_numeric($default) &&
!empty($default) &&
intval($default)==floatval($default)))) {
$errors[] = $this->str['defaultincorrect'];
}
}
// Number checks
if ($type == XMLDB_TYPE_NUMBER) {
if (!(is_numeric($length) && !empty($length) && intval($length)==floatval($length) &&
$length > 0 && $length <= xmldb_field::NUMBER_MAX_LENGTH)) {
$errors[] = $this->str['numberincorrectlength'];
}
if (!(empty($decimals) || (is_numeric($decimals) &&
!empty($decimals) &&
intval($decimals)==floatval($decimals) &&
$decimals >= 0 &&
$decimals < $length))) {
$errors[] = $this->str['numberincorrectdecimals'];
}
if (!empty($decimals) && ($length - $decimals > xmldb_field::INTEGER_MAX_LENGTH)) {
$errors[] = $this->str['numberincorrectwholepart'];
}
if (!(empty($default) || (is_numeric($default) &&
!empty($default)))) {
$errors[] = $this->str['defaultincorrect'];
}
}
// Float checks
if ($type == XMLDB_TYPE_FLOAT) {
if (!(empty($length) || (is_numeric($length) &&
!empty($length) &&
intval($length)==floatval($length) &&
$length > 0 &&
$length <= xmldb_field::FLOAT_MAX_LENGTH))) {
$errors[] = $this->str['floatincorrectlength'];
}
if (!(empty($decimals) || (is_numeric($decimals) &&
!empty($decimals) &&
intval($decimals)==floatval($decimals) &&
$decimals >= 0 &&
$decimals < $length))) {
$errors[] = $this->str['floatincorrectdecimals'];
}
if (!(empty($default) || (is_numeric($default) &&
!empty($default)))) {
$errors[] = $this->str['defaultincorrect'];
}
}
// Char checks
if ($type == XMLDB_TYPE_CHAR) {
if (!(is_numeric($length) && !empty($length) && intval($length)==floatval($length) &&
$length > 0 && $length <= xmldb_field::CHAR_MAX_LENGTH)) {
$errors[] = $this->str['charincorrectlength'];
}
if ($default !== NULL && $default !== '') {
if (substr($default, 0, 1) == "'" ||
substr($default, -1, 1) == "'") {
$errors[] = $this->str['defaultincorrect'];
}
}
}
// No text checks
// No binary checks
if (!empty($errors)) {
$tempfield = new xmldb_field($name);
$tempfield->setType($type);
$tempfield->setLength($length);
$tempfield->setDecimals($decimals);
$tempfield->setNotNull($notnull);
$tempfield->setSequence($sequence);
$tempfield->setDefault($default);
// Prepare the output
$o = '<p>' .implode(', ', $errors) . '</p>
<p>' . $name . ': ' . $tempfield->readableInfo() . '</p>';
$o.= '<a href="index.php?action=edit_field&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() .
'&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$this->output = $o;
}
// Continue if we aren't under errors
if (empty($errors)) {
// If there is one name change, do it, changing the prev and next
// atributes of the adjacent fields
if ($fieldparam != $name) {
$field->setName($name);
if ($field->getPrevious()) {
$prev = $table->getField($field->getPrevious());
$prev->setNext($name);
$prev->setChanged(true);
}
if ($field->getNext()) {
$next = $table->getField($field->getNext());
$next->setPrevious($name);
$next->setChanged(true);
}
}
// Set comment
$field->setComment($comment);
// Set the rest of fields
$field->setType($type);
$field->setLength($length);
$field->setDecimals($decimals);
$field->setNotNull($notnull);
$field->setSequence($sequence);
$field->setDefault($default);
// If the hash has changed from the old one, change the version
// and mark the structure as changed
$field->calculateHash(true);
if ($oldhash != $field->getHash()) {
$field->setChanged(true);
$table->setChanged(true);
// Recalculate the structure hash
$structure->calculateHash(true);
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
// Mark as changed
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,168 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will provide the interface for all the edit index actions
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_index extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'change' => 'tool_xmldb',
'vieworiginal' => 'tool_xmldb',
'viewedited' => 'tool_xmldb',
'yes' => '',
'no' => '',
'back' => 'tool_xmldb'
));
}
/**
* 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, $OUTPUT;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// Fetch request data
$tableparam = required_param('table', PARAM_CLEAN);
if (!$table = $structure->getTable($tableparam)) {
$this->errormsg = 'Wrong table specified: ' . $tableparam;
return false;
}
$indexparam = required_param('index', PARAM_CLEAN);
if (!$index = $table->getIndex($indexparam)) {
// Arriving here from a name change, looking for the new key name
$indexparam = required_param('name', PARAM_CLEAN);
$index = $table->getIndex($indexparam);
}
$dbdir = $XMLDB->dbdirs[$dirpath];
$origstructure = $dbdir->xml_file->getStructure();
// Add the main form
$o = '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="table" value="' . $tableparam .'" />';
$o.= ' <input type="hidden" name ="index" value="' . $indexparam .'" />';
$o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />';
$o.= ' <input type="hidden" name ="action" value="edit_index_save" />';
$o.= ' <input type="hidden" name ="postaction" value="edit_table" />';
$o.= ' <table id="formelements" class="boxaligncenter">';
// XMLDB index name
// If the index has dependencies, we cannot change its name
$disabled = '';
if ($structure->getIndexUses($table->getName(), $index->getName())) {
$disabled = ' disabled="disabled " ';
}
$o.= ' <tr valign="top"><td><label for="name" accesskey="n">Name:</label></td><td colspan="2"><input name="name" type="text" size="'.xmldb_field::NAME_MAX_LENGTH.'" id="name"' . $disabled . ' value="' . s($index->getName()) . '" /></td></tr>';
// XMLDB key comment
$o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td colspan="2">
<textarea name="comment" rows="3" cols="80" id="comment" class="form-control">' .
s($index->getComment()) . '</textarea></td></tr>';
// xmldb_index Type
$typeoptions = array (0 => 'not unique',
1 => 'unique');
$o.= ' <tr valign="top"><td><label for="menuunique" accesskey="t">Type:</label></td>';
$select = html_writer::select($typeoptions, 'unique', $index->getUnique(), false);
$o.= ' <td colspan="2">' . $select . '</td></tr>';
// xmldb_index Fields
$o.= ' <tr valign="top"><td><label for="fields" accesskey="f">Fields:</label></td>';
$o.= ' <td colspan="2"><input name="fields" type="text" size="40" maxlength="80" id="fields" value="' . s(implode(', ', $index->getFields())) . '" /></td></tr>';
// xmldb_index hints
$o.= ' <tr valign="top"><td><label for="hints" accesskey="h">Hints:</label></td>';
$o.= ' <td colspan="2"><input name="hints" type="text" size="40" maxlength="80" id="hints" value="' . s(implode(', ', $index->getHints())) . '" /></td></tr>';
// Change button
$o .= ' <tr valign="top"><td>&nbsp;</td><td colspan="2"><input type="submit" value="' .
$this->str['change'] . '" class="btn btn-secondary"/></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
// Calculate the buttons
$b = ' <p class="centerpara buttons">';
// The view original XML button
if ($table->getIndex($indexparam)) {
$b .= '&nbsp;<a href="index.php?action=view_index_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original&amp;table=' . $tableparam . '&amp;index=' . $indexparam . '">[' . $this->str['vieworiginal'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['vieworiginal'] . ']';
}
// The view edited XML button
if ($index->hasChanged()) {
$b .= '&nbsp;<a href="index.php?action=view_index_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited&amp;table=' . $tableparam . '&amp;index=' . $indexparam . '">[' . $this->str['viewedited'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['viewedited'] . ']';
}
// The back to edit table button
$b .= '&nbsp;<a href="index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o .= $b;
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,236 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class verifies all the data introduced when editing an index for correctness,
* performing changes / displaying errors depending of the results.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_index_save extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'indexnameempty' => 'tool_xmldb',
'incorrectindexname' => 'tool_xmldb',
'duplicateindexname' => 'tool_xmldb',
'nofieldsspecified' => 'tool_xmldb',
'duplicatefieldsused' => 'tool_xmldb',
'fieldsnotintable' => 'tool_xmldb',
'fieldsusedinkey' => 'tool_xmldb',
'fieldsusedinindex' => 'tool_xmldb',
'back' => 'tool_xmldb',
'administration' => ''
));
}
/**
* 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
if (!data_submitted()) { // Basic prevention
throw new \moodle_exception('wrongcall', 'error');
}
// Get parameters
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = strtolower(required_param('table', PARAM_PATH));
$indexparam = strtolower(required_param('index', PARAM_PATH));
$name = trim(strtolower(optional_param('name', $indexparam, PARAM_PATH)));
$comment = required_param('comment', PARAM_CLEAN);
$comment = trim($comment);
$unique = required_param('unique', PARAM_INT);
$fields = required_param('fields', PARAM_CLEAN);
$fields = str_replace(' ', '', trim(strtolower($fields)));
$hints = required_param('hints', PARAM_CLEAN);
$hints = str_replace(' ', '', trim(strtolower($hints)));
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
$table = $structure->getTable($tableparam);
$index = $table->getIndex($indexparam);
$oldhash = $index->getHash();
$errors = array(); // To store all the errors found
// Perform some checks
// Check empty name
if (empty($name)) {
$errors[] = $this->str['indexnameempty'];
}
// Check incorrect name
if ($name == 'changeme') {
$errors[] = $this->str['incorrectindexname'];
}
// Check duplicate name
if ($indexparam != $name && $table->getIndex($name)) {
$errors[] = $this->str['duplicateindexname'];
}
$fieldsarr = explode(',', $fields);
// Check the fields isn't empty
if (empty($fieldsarr[0])) {
$errors[] = $this->str['nofieldsspecified'];
} else {
// Check that there aren't duplicate column names
$uniquearr = array_unique($fieldsarr);
if (count($fieldsarr) != count($uniquearr)) {
$errors[] = $this->str['duplicatefieldsused'];
}
// Check that all the fields in belong to the table
foreach ($fieldsarr as $field) {
if (!$table->getField($field)) {
$errors[] = $this->str['fieldsnotintable'];
break;
}
}
// Check that there isn't any key using exactly the same fields
$tablekeys = $table->getKeys();
if ($tablekeys) {
foreach ($tablekeys as $tablekey) {
$keyfieldsarr = $tablekey->getFields();
// Compare both arrays, looking for differences
$diferences = array_merge(array_diff($fieldsarr, $keyfieldsarr), array_diff($keyfieldsarr, $fieldsarr));
if (empty($diferences)) {
$errors[] = $this->str['fieldsusedinkey'];
break;
}
}
}
// Check that there isn't any index using exactly the same fields
$tableindexes = $table->getIndexes();
if ($tableindexes) {
foreach ($tableindexes as $tableindex) {
// Skip checking against itself
if ($indexparam == $tableindex->getName()) {
continue;
}
$indexfieldsarr = $tableindex->getFields();
// Compare both arrays, looking for differences
$diferences = array_merge(array_diff($fieldsarr, $indexfieldsarr), array_diff($indexfieldsarr, $fieldsarr));
if (empty($diferences)) {
$errors[] = $this->str['fieldsusedinindex'];
break;
}
}
}
}
$hintsarr = array();
foreach (explode(',', $hints) as $hint) {
$hint = preg_replace('/[^a-z]/', '', $hint);
if ($hint === '') {
continue;
}
$hintsarr[] = $hint;
}
if (!empty($errors)) {
$tempindex = new xmldb_index($name);
$tempindex->setUnique($unique);
$tempindex->setFields($fieldsarr);
$tempindex->setHints($hintsarr);
// Prepare the output
$o = '<p>' .implode(', ', $errors) . '</p>
<p>' . $tempindex->readableInfo() . '</p>';
$o.= '<a href="index.php?action=edit_index&amp;index=' .$index->getName() . '&amp;table=' . $table->getName() .
'&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$this->output = $o;
}
// Continue if we aren't under errors
if (empty($errors)) {
// If there is one name change, do it, changing the prev and next
// attributes of the adjacent fields
if ($indexparam != $name) {
$index->setName($name);
if ($index->getPrevious()) {
$prev = $table->getIndex($index->getPrevious());
$prev->setNext($name);
$prev->setChanged(true);
}
if ($index->getNext()) {
$next = $table->getIndex($index->getNext());
$next->setPrevious($name);
$next->setChanged(true);
}
}
// Set comment
$index->setComment($comment);
// Set the rest of fields
$index->setUnique($unique);
$index->setFields($fieldsarr);
$index->setHints($hintsarr);
// If the hash has changed from the old one, change the version
// and mark the structure as changed
$index->calculateHash(true);
if ($oldhash != $index->getHash()) {
$index->setChanged(true);
$table->setChanged(true);
// Recalculate the structure hash
$structure->calculateHash(true);
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
// Mark as changed
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,178 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will provide the interface for all the edit key actions
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_key extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'change' => 'tool_xmldb',
'vieworiginal' => 'tool_xmldb',
'viewedited' => 'tool_xmldb',
'yes' => '',
'no' => '',
'back' => 'tool_xmldb'
));
}
/**
* 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, $OUTPUT;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// Fetch request data
$tableparam = required_param('table', PARAM_CLEAN);
if (!$table = $structure->getTable($tableparam)) {
$this->errormsg = 'Wrong table specified: ' . $tableparam;
return false;
}
$keyparam = required_param('key', PARAM_CLEAN);
if (!$key = $table->getKey($keyparam)) {
// Arriving here from a name change, looking for the new key name
$keyparam = required_param('name', PARAM_CLEAN);
$key = $table->getKey($keyparam);
}
$dbdir = $XMLDB->dbdirs[$dirpath];
$origstructure = $dbdir->xml_file->getStructure();
// Add the main form
$o = '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="table" value="' . $tableparam .'" />';
$o.= ' <input type="hidden" name ="key" value="' . $keyparam .'" />';
$o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />';
$o.= ' <input type="hidden" name ="action" value="edit_key_save" />';
$o.= ' <input type="hidden" name ="postaction" value="edit_table" />';
$o.= ' <table id="formelements" class="boxaligncenter">';
// XMLDB key name
// If the key has dependencies, we cannot change its name
$disabled = '';
if ($structure->getKeyUses($table->getName(), $key->getName())) {
$disabled = ' disabled="disabled " ';
}
$o.= ' <tr valign="top"><td><label for="name" accesskey="n">Name:</label></td><td colspan="2"><input name="name" type="text" size="'.xmldb_field::NAME_MAX_LENGTH.'" id="name"' . $disabled . ' value="' . s($key->getName()) . '" /></td></tr>';
// XMLDB key comment
$o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td colspan="2">
<textarea name="comment" rows="3" cols="80" id="comment" class="form-control">' .
s($key->getComment()) . '</textarea></td></tr>';
// xmldb_key Type
$typeoptions = array (XMLDB_KEY_PRIMARY => $key->getXMLDBKeyName(XMLDB_KEY_PRIMARY),
XMLDB_KEY_UNIQUE => $key->getXMLDBKeyName(XMLDB_KEY_UNIQUE),
XMLDB_KEY_FOREIGN => $key->getXMLDBKeyName(XMLDB_KEY_FOREIGN),
XMLDB_KEY_FOREIGN_UNIQUE => $key->getXMLDBKeyName(XMLDB_KEY_FOREIGN_UNIQUE));
// Only show the XMLDB_KEY_FOREIGN_UNIQUE if the Key has that type
// if ($key->getType() != XMLDB_KEY_FOREIGN_UNIQUE) {
// unset ($typeoptions[XMLDB_KEY_FOREIGN_UNIQUE);
// }
$select = html_writer::select($typeoptions, 'type', $key->getType(), false);
$o.= ' <tr valign="top"><td><label for="menutype" accesskey="t">Type:</label></td>';
$o.= ' <td colspan="2">' . $select . '</td></tr>';
// xmldb_key Fields
$o.= ' <tr valign="top"><td><label for="fields" accesskey="f">Fields:</label></td>';
$o.= ' <td colspan="2"><input name="fields" type="text" size="40" maxlength="80" id="fields" value="' . s(implode(', ', $key->getFields())) . '" /></td></tr>';
// xmldb_key Reftable
$o.= ' <tr valign="top"><td><label for="reftable" accesskey="t">Reftable:</label></td>';
$o.= ' <td colspan="2"><input name="reftable" type="text" size="20" maxlength="40" id="reftable" value="' . s($key->getReftable()) . '" /></td></tr>';
// xmldb_key Reffields
$o.= ' <tr valign="top"><td><label for="reffields" accesskey="t">Reffields:</label></td>';
$o.= ' <td colspan="2"><input name="reffields" type="text" size="40" maxlength="80" id="reffields" value="' . s(implode(', ', $key->getRefFields())) . '" /></td></tr>';
// Change button
$o .= ' <tr valign="top"><td>&nbsp;</td><td colspan="2"><input type="submit" value="' .
$this->str['change'] . '" class="btn btn-secondary"/></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
// Calculate the buttons
$b = ' <p class="centerpara buttons">';
// The view original XML button
if ($table->getKey($keyparam)) {
$b .= '&nbsp;<a href="index.php?action=view_key_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original&amp;table=' . $tableparam . '&amp;key=' . $keyparam . '">[' . $this->str['vieworiginal'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['vieworiginal'] . ']';
}
// The view edited XML button
if ($key->hasChanged()) {
$b .= '&nbsp;<a href="index.php?action=view_key_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited&amp;table=' . $tableparam . '&amp;key=' . $keyparam . '">[' . $this->str['viewedited'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['viewedited'] . ']';
}
// The back to edit table button
$b .= '&nbsp;<a href="index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o .= $b;
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,70 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// Register the needed events
onload=function() {
// Adjust the form on load
transformForm();
// Get the required fields
var typeField = document.getElementById('menutype');
// Register the rest of events
if (typeField.addEventListener) {
// Standard
typeField.addEventListener('change', transformForm, false);
} else {
// IE 5.5
typeField.attachEvent('onchange', transformForm);
}
}
/**
* This function controls all modifications to perform when any field changes
*/
function transformForm(event) {
// Initialize all the needed variables
var typeField = document.getElementById('menutype');
var fieldsField = document.getElementById('fields');
var reftableField = document.getElementById('reftable');
var reffieldsField = document.getElementById('reffields');
// Initially, enable everything
typeField.disabled = false;
fieldsField.disabled = false;
reftableField.disabled = false;
reffieldsField.disabled = false;
// Based on type, disable some items
switch (typeField.value) {
case '1': // XMLDB_KEY_PRIMARY
case '2': // XMLDB_KEY_UNIQUE
reftableField.disabled = true;
reftableField.value = '';
reffieldsField.disabled = true;
reffieldsField.value = '';
break;
case '3': // XMLDB_KEY_FOREIGN
case '5': // XMLDB_KEY_FOREIGN_UNIQUE
break;
}
}
@@ -0,0 +1,305 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class verifies all the data introduced when editing a key for correctness,
* performing changes / displaying errors depending of the results.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_key_save extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'keynameempty' => 'tool_xmldb',
'incorrectkeyname' => 'tool_xmldb',
'duplicatekeyname' => 'tool_xmldb',
'nofieldsspecified' => 'tool_xmldb',
'duplicatefieldsused' => 'tool_xmldb',
'fieldsnotintable' => 'tool_xmldb',
'fieldsusedinkey' => 'tool_xmldb',
'fieldsusedinindex' => 'tool_xmldb',
'noreftablespecified' => 'tool_xmldb',
'wrongnumberofreffields' => 'tool_xmldb',
'noreffieldsspecified' => 'tool_xmldb',
'nomasterprimaryuniquefound' => 'tool_xmldb',
'masterprimaryuniqueordernomatch' => 'tool_xmldb',
'primarykeyonlyallownotnullfields' => 'tool_xmldb',
'back' => 'tool_xmldb',
'administration' => ''
));
}
/**
* 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
if (!data_submitted()) { // Basic prevention
throw new \moodle_exception('wrongcall', 'error');
}
// Get parameters
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = strtolower(required_param('table', PARAM_PATH));
$keyparam = strtolower(required_param('key', PARAM_PATH));
$name = trim(strtolower(optional_param('name', $keyparam, PARAM_PATH)));
$comment = required_param('comment', PARAM_CLEAN);
$comment = trim($comment);
$type = required_param('type', PARAM_INT);
$fields = required_param('fields', PARAM_CLEAN);
$fields = str_replace(' ', '', trim(strtolower($fields)));
if ($type == XMLDB_KEY_FOREIGN ||
$type == XMLDB_KEY_FOREIGN_UNIQUE) {
$reftable = trim(strtolower(required_param('reftable', PARAM_PATH)));
$reffields= required_param('reffields', PARAM_CLEAN);
$reffields = str_replace(' ', '', trim(strtolower($reffields)));
}
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
$table = $structure->getTable($tableparam);
$key = $table->getKey($keyparam);
$oldhash = $key->getHash();
$errors = array(); // To store all the errors found
// Perform some checks
// Check empty name
if (empty($name)) {
$errors[] = $this->str['keynameempty'];
}
// Check incorrect name
if ($name == 'changeme') {
$errors[] = $this->str['incorrectkeyname'];
}
// Check duplicate name
if ($keyparam != $name && $table->getKey($name)) {
$errors[] = $this->str['duplicatekeyname'];
}
$fieldsarr = explode(',', $fields);
// Check the fields isn't empty
if (empty($fieldsarr[0])) {
$errors[] = $this->str['nofieldsspecified'];
} else {
// Check that there aren't duplicate column names
$uniquearr = array_unique($fieldsarr);
if (count($fieldsarr) != count($uniquearr)) {
$errors[] = $this->str['duplicatefieldsused'];
}
// Check that all the fields in belong to the table
foreach ($fieldsarr as $field) {
if (!$table->getField($field)) {
$errors[] = $this->str['fieldsnotintable'];
break;
}
}
// If primary, check that all the fields are not null
if ($type == XMLDB_KEY_PRIMARY) {
foreach ($fieldsarr as $field) {
if ($fi = $table->getField($field)) {
if (!$fi->getNotNull()) {
$errors[] = $this->str['primarykeyonlyallownotnullfields'];
break;
}
}
}
}
// Check that there isn't any key using exactly the same fields
$tablekeys = $table->getKeys();
if ($tablekeys) {
foreach ($tablekeys as $tablekey) {
// Skip checking against itself
if ($keyparam == $tablekey->getName()) {
continue;
}
$keyfieldsarr = $tablekey->getFields();
// Compare both arrays, looking for diferences
$diferences = array_merge(array_diff($fieldsarr, $keyfieldsarr), array_diff($keyfieldsarr, $fieldsarr));
if (empty($diferences)) {
$errors[] = $this->str['fieldsusedinkey'];
break;
}
}
}
// Check that there isn't any index using exactlt the same fields
$tableindexes = $table->getIndexes();
if ($tableindexes) {
foreach ($tableindexes as $tableindex) {
$indexfieldsarr = $tableindex->getFields();
// Compare both arrays, looking for diferences
$diferences = array_merge(array_diff($fieldsarr, $indexfieldsarr), array_diff($indexfieldsarr, $fieldsarr));
if (empty($diferences)) {
$errors[] = $this->str['fieldsusedinindex'];
break;
}
}
}
// If foreign key
if ($type == XMLDB_KEY_FOREIGN ||
$type == XMLDB_KEY_FOREIGN_UNIQUE) {
$reffieldsarr = explode(',', $reffields);
// Check reftable is not empty
if (empty($reftable)) {
$errors[] = $this->str['noreftablespecified'];
} else
// Check reffields are not empty
if (empty($reffieldsarr[0])) {
$errors[] = $this->str['noreffieldsspecified'];
} else
// Check the number of fields is correct
if (count($fieldsarr) != count($reffieldsarr)) {
$errors[] = $this->str['wrongnumberofreffields'];
} else {
// Check, if pointing to one structure table, that there is one master key for this key
if ($rt = $structure->getTable($reftable)) {
$masterfound = false;
$reftablekeys = $rt->getKeys();
if ($reftablekeys) {
foreach ($reftablekeys as $reftablekey) {
// Only compare with primary and unique keys
if ($reftablekey->getType() != XMLDB_KEY_PRIMARY && $reftablekey->getType() != XMLDB_KEY_UNIQUE) {
continue;
}
$keyfieldsarr = $reftablekey->getFields();
// Compare both arrays, looking for diferences
$diferences = array_merge(array_diff($reffieldsarr, $keyfieldsarr), array_diff($keyfieldsarr, $reffieldsarr));
if (empty($diferences)) {
$masterfound = true;
break;
}
}
if (!$masterfound) {
$errors[] = $this->str['nomasterprimaryuniquefound'];
} else {
// Quick test of the order
if (implode(',', $reffieldsarr) != implode(',', $keyfieldsarr)) {
$errors[] = $this->str['masterprimaryuniqueordernomatch'];
}
}
}
}
}
}
}
if (!empty($errors)) {
$tempkey = new xmldb_key($name);
$tempkey->setType($type);
$tempkey->setFields($fieldsarr);
if ($type == XMLDB_KEY_FOREIGN ||
$type == XMLDB_KEY_FOREIGN_UNIQUE) {
$tempkey->setRefTable($reftable);
$tempkey->setRefFields($reffieldsarr);
}
// Prepare the output
$o = '<p>' .implode(', ', $errors) . '</p>
<p>' . $name . ': ' . $tempkey->readableInfo() . '</p>';
$o.= '<a href="index.php?action=edit_key&amp;key=' .$key->getName() . '&amp;table=' . $table->getName() .
'&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$this->output = $o;
}
// Continue if we aren't under errors
if (empty($errors)) {
// If there is one name change, do it, changing the prev and next
// attributes of the adjacent fields
if ($keyparam != $name) {
$key->setName($name);
if ($key->getPrevious()) {
$prev = $table->getKey($key->getPrevious());
$prev->setNext($name);
$prev->setChanged(true);
}
if ($key->getNext()) {
$next = $table->getKey($key->getNext());
$next->setPrevious($name);
$next->setChanged(true);
}
}
// Set comment
$key->setComment($comment);
// Set the rest of fields
$key->setType($type);
$key->setFields($fieldsarr);
if ($type == XMLDB_KEY_FOREIGN ||
$type == XMLDB_KEY_FOREIGN_UNIQUE) {
$key->setRefTable($reftable);
$key->setRefFields($reffieldsarr);
}
// If the hash has changed from the old one, change the version
// and mark the structure as changed
$key->calculateHash(true);
if ($oldhash != $key->getHash()) {
$key->setChanged(true);
$table->setChanged(true);
// Recalculate the structure hash
$structure->calculateHash(true);
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
// Mark as changed
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,350 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class provides the interface for all the edit table actions
*
* Main page of edit table actions, from here fields/indexes/keys edition
* can be invoked, plus links to PHP code generator, view SQL, rearrange
* elements and so on.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_table extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'addpersistent' => 'tool_xmldb',
'change' => 'tool_xmldb',
'vieworiginal' => 'tool_xmldb',
'viewedited' => 'tool_xmldb',
'viewsqlcode' => 'tool_xmldb',
'viewphpcode' => 'tool_xmldb',
'newfield' => 'tool_xmldb',
'newkey' => 'tool_xmldb',
'newindex' => 'tool_xmldb',
'fields' => 'tool_xmldb',
'keys' => 'tool_xmldb',
'indexes' => 'tool_xmldb',
'edit' => 'tool_xmldb',
'up' => 'tool_xmldb',
'down' => 'tool_xmldb',
'delete' => 'tool_xmldb',
'reserved' => 'tool_xmldb',
'back' => 'tool_xmldb',
'viewxml' => 'tool_xmldb',
'pendingchanges' => 'tool_xmldb',
'pendingchangescannotbesaved' => 'tool_xmldb',
'save' => 'tool_xmldb'
));
}
/**
* Invoke method, every class will have its own
* returns true/false on completion, setting both
* errormsg and output as necessary
*/
function invoke() {
global $OUTPUT, $PAGE;
parent::invoke();
$result = true;
// Set own core attributes
$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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
// Check if the dir exists and copy it from dbdirs
// (because we need straight load in case of saving from here)
if (!isset($XMLDB->editeddirs[$dirpath])) {
$XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir));
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = required_param('table', PARAM_CLEAN);
if (!$table = $structure->getTable($tableparam)) {
// Arriving here from a name change, looking for the new table name
$tableparam = required_param('name', PARAM_CLEAN);
$table = $structure->getTable($tableparam);
}
$dbdir = $XMLDB->dbdirs[$dirpath];
$origstructure = $dbdir->xml_file->getStructure();
// Add the main form
$o = '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="table" value="' . $tableparam .'" />';
$o.= ' <input type="hidden" name ="action" value="edit_table_save" />';
$o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />';
$o.= ' <input type="hidden" name ="postaction" value="edit_table" />';
$o .= ' <table id="formelements">';
// If the table is being used, we cannot rename it
if ($structure->getTableUses($table->getName())) {
$o.= ' <tr valign="top"><td>Name:</td><td><input type="hidden" name ="name" value="' . s($table->getName()) . '" />' . s($table->getName()) .'</td></tr>';
} else {
$o.= ' <tr valign="top"><td><label for="name" accesskey="p">Name:</label></td><td><input name="name" type="text" size="'.xmldb_table::NAME_MAX_LENGTH.'" maxlength="'.xmldb_table::NAME_MAX_LENGTH.'" id="name" value="' . s($table->getName()) . '" /></td></tr>';
}
$o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td>
<textarea name="comment" rows="3" cols="80" id="comment" class="form-control">' .
s($table->getComment()) . '</textarea></td></tr>';
$o .= ' <tr valign="top"><td>&nbsp;</td><td><input type="submit" value="' . $this->str['change'] .
'" class="btn btn-secondary"/></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
// Calculate the pending changes / save message
$e = '';
$cansavenow = false;
if ($structure->hasChanged()) {
if (!is_writeable($dirpath . '/install.xml') || !is_writeable($dirpath)) {
$e .= '<p class="centerpara error">' . $this->str['pendingchangescannotbesaved'] . '</p>';
} else {
$e .= '<p class="centerpara warning">' . $this->str['pendingchanges'] . '</p>';
$cansavenow = true;
}
}
// Calculate the buttons
$b = ' <p class="centerpara buttons">';
// The view original XML button
if ($origstructure->getTable($tableparam)) {
$b .= '&nbsp;<a href="index.php?action=view_table_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original&amp;table=' . $tableparam . '">[' . $this->str['vieworiginal'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['vieworiginal'] . ']';
}
// The view edited XML button
if ($table->hasChanged()) {
$b .= '&nbsp;<a href="index.php?action=view_table_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited&amp;table=' . $tableparam . '">[' . $this->str['viewedited'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['viewedited'] . ']';
}
// The new field button
$b .= '&nbsp;<a href="index.php?action=new_field&amp;sesskey=' . sesskey() . '&amp;postaction=edit_field&amp;table=' . $tableparam . '&amp;field=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newfield'] . ']</a>';
// The new key button
$b .= '&nbsp;<a href="index.php?action=new_key&amp;sesskey=' . sesskey() . '&amp;postaction=edit_key&amp;table=' . $tableparam . '&amp;key=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newkey'] . ']</a>';
// The new index button
$b .= '&nbsp;<a href="index.php?action=new_index&amp;sesskey=' . sesskey() . '&amp;postaction=edit_index&amp;table=' . $tableparam . '&amp;index=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newindex'] . ']</a>';
$b .= '</p>';
$b .= ' <p class="centerpara buttons">';
// The view sql code button
$b .= '<a href="index.php?action=view_table_sql&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' .$this->str['viewsqlcode'] . ']</a>';
// The view php code button
$b .= '&nbsp;<a href="index.php?action=view_table_php&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>';
// The add persistent fields button.
$url = new \moodle_url('/admin/tool/xmldb/index.php', [
'action' => 'add_persistent_mandatory',
'sesskey' => sesskey(),
'table' => $tableparam,
'dir'=> str_replace($CFG->dirroot, '', $dirpath)
]);
$b .= '&nbsp;' . \html_writer::link($url, '[' . $this->str['addpersistent'] . ']');
// The save button (if possible)
if ($cansavenow) {
$b .= '&nbsp;<a href="index.php?action=save_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;time=' . time() . '&amp;unload=false&amp;postaction=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['save'] . ']</a>';
}
// The back to edit xml file button
$b .= '&nbsp;<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o .= $e . $b;
require_once("$CFG->libdir/ddl/sql_generator.php");
$reserved_words = sql_generator::getAllReservedWords();
// Delete any 'changeme' field/key/index
$table->deleteField('changeme');
$table->deleteKey('changeme');
$table->deleteIndex('changeme');
// Add the fields list
$fields = $table->getFields();
if (!empty($fields)) {
$o .= '<h3 class="main">' . $this->str['fields'] . '</h3>';
$o .= '<table id="listfields" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
$row = 0;
foreach ($fields as $field) {
// Drag element up/down.
$move = (count($fields) > 1) ? html_writer::span($OUTPUT->render_from_template('core/drag_handle',
['movetitle' => get_string('movecontent', 'moodle', $field->getName())]), '',
['data-action' => 'move_updown_field', 'data-dir' => str_replace($CFG->dirroot, '', $dirpath),
'data-table' => $table->getName(), 'data-field' => $field->getName()]) : '';
// The field name (link to edit - if the field has no uses)
if (!$structure->getFieldUses($table->getName(), $field->getName())) {
$f = '<a href="index.php?action=edit_field&amp;field=' .$field->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $field->getName() . '</a>';
} else {
$f = $field->getName();
}
// Calculate buttons
$b = '</td><td class="button cell">';
// The edit button (if the field has no uses)
if (!$structure->getFieldUses($table->getName(), $field->getName())) {
$b .= '<a href="index.php?action=edit_field&amp;field=' .$field->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
} else {
$b .= '[' . $this->str['edit'] . ']';
}
$b .= '</td><td class="button cell">';
// The delete button (if we have more than one and it isn't used
if (count($fields) > 1 &&
!$structure->getFieldUses($table->getName(), $field->getName())) {
$b .= '<a href="index.php?action=delete_field&amp;sesskey=' . sesskey() . '&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
} else {
$b .= '[' . $this->str['delete'] . ']';
}
$b .= '</td><td class="button cell">';
// The view xml button
$b .= '<a href="index.php?action=view_field_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;field=' . $field->getName() . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
// Detect if the table name is a reserved word
if (array_key_exists($field->getName(), $reserved_words)) {
$b .= '&nbsp;<a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>';
}
// The readable info
$r = '</td><td class="readableinfo cell">' . $field->readableInfo() . '</td>';
// Print table row
$o .= '<tr class="r' . $row . '" data-name="' . s($field->getName()) . '"><td class="cell firstcol">' . $move .
$f . $b . $r . '</tr>';
$row = ($row + 1) % 2;
}
$o .= '</table>';
$PAGE->requires->js_call_amd('tool_xmldb/move', 'init', ['listfields', 'move_updown_field']);
}
// Add the keys list
$keys = $table->getKeys();
if (!empty($keys)) {
$o .= '<h3 class="main">' . $this->str['keys'] . '</h3>';
$o .= '<table id="listkeys" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
$row = 0;
foreach ($keys as $key) {
// Drag element up/down.
$move = (count($keys) > 1) ? html_writer::span($OUTPUT->render_from_template('core/drag_handle',
['movetitle' => get_string('movecontent', 'moodle', $key->getName())]), '',
['data-action' => 'move_updown_key', 'data-dir' => str_replace($CFG->dirroot, '', $dirpath),
'data-table' => $table->getName(), 'data-key' => $key->getName()]) : '';
// The key name (link to edit - if the key has no uses)
if (!$structure->getKeyUses($table->getName(), $key->getName())) {
$k = '<a href="index.php?action=edit_key&amp;key=' .$key->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $key->getName() . '</a>';
} else {
$k = $key->getName();
}
// Calculate buttons
$b = '</td><td class="button cell">';
// The edit button (if the key hasn't uses)
if (!$structure->getKeyUses($table->getName(), $key->getName())) {
$b .= '<a href="index.php?action=edit_key&amp;key=' .$key->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
} else {
$b .= '[' . $this->str['edit'] . ']';
}
$b .= '</td><td class="button cell">';
// The delete button (if the key hasn't uses)
if (!$structure->getKeyUses($table->getName(), $key->getName())) {
$b .= '<a href="index.php?action=delete_key&amp;sesskey=' . sesskey() . '&amp;key=' . $key->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
} else {
$b .= '[' . $this->str['delete'] . ']';
}
$b .= '</td><td class="button cell">';
// The view xml button
$b .= '<a href="index.php?action=view_key_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;key=' . $key->getName() . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
// The readable info
$r = '</td><td class="readableinfo cell">' . $key->readableInfo() . '</td>';
// Print table row
$o .= '<tr class="r' . $row . '" data-name="' . s($key->getName()) . '"><td class="cell firstcol">' .
$move . $k . $b . $r .'</tr>';
$row = ($row + 1) % 2;
}
$o .= '</table>';
$PAGE->requires->js_call_amd('tool_xmldb/move', 'init', ['listkeys', 'move_updown_key']);
}
// Add the indexes list
$indexes = $table->getIndexes();
if (!empty($indexes)) {
$o .= '<h3 class="main">' . $this->str['indexes'] . '</h3>';
$o .= '<table id="listindexes" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
$row = 0;
foreach ($indexes as $index) {
// Drag element up/down.
$move = (count($indexes) > 1) ? html_writer::span($OUTPUT->render_from_template('core/drag_handle',
['movetitle' => get_string('movecontent', 'moodle', $index->getName())]), '',
['data-action' => 'move_updown_index', 'data-dir' => str_replace($CFG->dirroot, '', $dirpath),
'data-table' => $table->getName(), 'data-index' => $index->getName()]) : '';
// The index name (link to edit)
$i = '<a href="index.php?action=edit_index&amp;index=' .$index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $index->getName() . '</a>';
// Calculate buttons
$b = '</td><td class="button cell">';
// The edit button
$b .= '<a href="index.php?action=edit_index&amp;index=' .$index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
$b .= '</td><td class="button cell">';
// The delete button
$b .= '<a href="index.php?action=delete_index&amp;sesskey=' . sesskey() . '&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
$b .= '</td><td class="button cell">';
// The view xml button
$b .= '<a href="index.php?action=view_index_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;index=' . $index->getName() . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
// The readable info
$r = '</td><td class="readableinfo cell">' . $index->readableInfo() . '</td>';
// Print table row
$o .= '<tr class="r' . $row . '" data-name="' . s($index->getName()) . '"><td class="cell firstcol">' .
$move . $i . $b . $r .'</tr>';
$row = ($row + 1) % 2;
}
$o .= '</table>';
$PAGE->requires->js_call_amd('tool_xmldb/move', 'init', ['listindexes', 'move_updown_index']);
}
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,162 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will save changes in table name and/or comments
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_table_save extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'tablenameempty' => 'tool_xmldb',
'incorrecttablename' => 'tool_xmldb',
'duplicatetablename' => 'tool_xmldb',
'back' => 'tool_xmldb',
'administration' => ''
));
}
/**
* 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
if (!data_submitted()) { // Basic prevention
throw new \moodle_exception('wrongcall', 'error');
}
// Get parameters
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$tableparam = strtolower(required_param('table', PARAM_PATH));
$name = substr(trim(strtolower(required_param('name', PARAM_PATH))),0,xmldb_table::NAME_MAX_LENGTH);
$comment = required_param('comment', PARAM_CLEAN);
$comment = $comment;
$dbdir = $XMLDB->dbdirs[$dirpath];
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
$table = $structure->getTable($tableparam);
$errors = array(); // To store all the errors found
// Perform some checks
// Check empty name
if (empty($name)) {
$errors[] = $this->str['tablenameempty'];
}
// Check incorrect name
if ($name == 'changeme') {
$errors[] = $this->str['incorrecttablename'];
}
// Check duplicatename
if ($tableparam != $name && $structure->getTable($name)) {
$errors[] = $this->str['duplicatetablename'];
}
if (!empty($errors)) {
$temptable = new xmldb_table($name);
// Prepare the output
$o = '<p>' .implode(', ', $errors) . '</p>
<p>' . $temptable->getName() . '</p>';
$o.= '<a href="index.php?action=edit_table&amp;table=' . $tableparam .
'&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$this->output = $o;
// Continue if we aren't under errors
} else if (empty($errors)) {
// If there is one name change, do it, changing the prev and next
// atributes of the adjacent tables
if ($tableparam != $name) {
$table->setName($name);
if ($table->getPrevious()) {
$prev = $structure->getTable($table->getPrevious());
$prev->setNext($name);
$prev->setChanged(true);
}
if ($table->getNext()) {
$next = $structure->getTable($table->getNext());
$next->setPrevious($name);
$next->setChanged(true);
}
// Table has changed
$table->setChanged(true);
}
// Set comment
if ($table->getComment() != $comment) {
$table->setComment($comment);
// Table has changed
$table->setChanged(true);
}
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,235 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will edit one loaded XML file
*
* Main page to start editing one XML file. From here it's possible to access
* to tables edition plus PHP code generation and other utilities
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_xml_file extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'change' => 'tool_xmldb',
'edit' => 'tool_xmldb',
'up' => 'tool_xmldb',
'down' => 'tool_xmldb',
'delete' => 'tool_xmldb',
'vieworiginal' => 'tool_xmldb',
'viewedited' => 'tool_xmldb',
'tables' => 'tool_xmldb',
'newtable' => 'tool_xmldb',
'newtablefrommysql' => 'tool_xmldb',
'viewsqlcode' => 'tool_xmldb',
'viewphpcode' => 'tool_xmldb',
'reserved' => 'tool_xmldb',
'backtomainview' => 'tool_xmldb',
'viewxml' => 'tool_xmldb',
'pendingchanges' => 'tool_xmldb',
'pendingchangescannotbesaved' => 'tool_xmldb',
'save' => 'tool_xmldb'
));
}
/**
* Invoke method, every class will have its own
* returns true/false on completion, setting both
* errormsg and output as necessary
*/
function invoke() {
global $OUTPUT, $PAGE;
parent::invoke();
$result = true;
// Set own core attributes
$this->does_generate = ACTION_GENERATE_HTML;
// These are always here
global $CFG, $XMLDB, $DB;
// Do the job, setting $result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dir
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
if ($dbdir) {
// Only if the directory exists and it has been loaded
if (!$dbdir->path_exists || !$dbdir->xml_loaded) {
return false;
}
// Check if the in-memory object exists and create it
if (empty($XMLDB->editeddirs)) {
$XMLDB->editeddirs = array();
}
// Check if the dir exists and copy it from dbdirs
if (!isset($XMLDB->editeddirs[$dirpath])) {
$XMLDB->editeddirs[$dirpath] = unserialize(serialize($dbdir));
}
// Get it
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
// Add the main form
$o = '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="action" value="edit_xml_file_save" />';
$o.= ' <input type="hidden" name ="postaction" value="edit_xml_file" />';
$o.= ' <input type="hidden" name ="path" value="' . s($structure->getPath()) .'" />';
$o.= ' <input type="hidden" name ="version" value="' . s($structure->getVersion()) .'" />';
$o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() .'" />';
$o .= ' <table id="formelements">';
$o.= ' <tr valign="top"><td>Path:</td><td>' . s($structure->getPath()) . '</td></tr>';
$o.= ' <tr valign="top"><td>Version:</td><td>' . s($structure->getVersion()) . '</td></tr>';
$o .= ' <tr valign="top"><td><label for="comment" accesskey="c">Comment:</label></td><td>
<textarea name="comment" rows="3" cols="80" id="comment" class="form-control">' .
$structure->getComment() . '</textarea></td></tr>';
$o .= ' <tr><td>&nbsp;</td><td><input type="submit" value="' . $this->str['change'] .
'"class="btn btn-secondary" /></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
// Calculate the pending changes / save message
$e = '';
$cansavenow = false;
if ($structure->hasChanged()) {
if (!is_writeable($dirpath . '/install.xml') || !is_writeable($dirpath)) {
$e .= '<p class="centerpara error">' . $this->str['pendingchangescannotbesaved'] . '</p>';
} else {
$e .= '<p class="centerpara warning">' . $this->str['pendingchanges'] . '</p>';
$cansavenow = true;
}
}
// Calculate the buttons
$b = ' <p class="centerpara buttons">';
// The view original XML button
$b .= '&nbsp;<a href="index.php?action=view_structure_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=original">[' . $this->str['vieworiginal'] . ']</a>';
// The view edited XML button
if ($structure->hasChanged()) {
$b .= '&nbsp;<a href="index.php?action=view_structure_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;select=edited">[' . $this->str['viewedited'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['viewedited'] . ']';
}
// The new table button
$b .= '&nbsp;<a href="index.php?action=new_table&amp;sesskey=' . sesskey() . '&amp;postaction=edit_table&amp;table=changeme&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtable'] . ']</a>';
// The new from MySQL button
if ($DB->get_dbfamily() == 'mysql') {
$b .= '&nbsp;<a href="index.php?action=new_table_from_mysql&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['newtablefrommysql'] . ']</a>';
} else {
$b .= '&nbsp;[' . $this->str['newtablefrommysql'] . ']';
}
// The view sql code button
$b .= '<a href="index.php?action=view_structure_sql&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' .$this->str['viewsqlcode'] . ']</a>';
// The view php code button
$b .= '&nbsp;<a href="index.php?action=view_structure_php&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['viewphpcode'] . ']</a>';
// The save button (if possible)
if ($cansavenow) {
$b .= '&nbsp;<a href="index.php?action=save_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;time=' . time() . '&amp;unload=false&amp;postaction=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['save'] . ']</a>';
}
// The back to main menu button
$b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
$b .= '</p>';
$o .= $e . $b;
// Join all the reserved words into one big array
// Calculate list of available SQL generators
require_once("$CFG->libdir/ddl/sql_generator.php");
$reserved_words = sql_generator::getAllReservedWords();
// Add the tables list
$tables = $structure->getTables();
if ($tables) {
$o .= '<h3 class="main">' . $this->str['tables'] . '</h3>';
$o .= '<table id="listtables" border="0" cellpadding="5" cellspacing="1" class="boxaligncenter flexible">';
$row = 0;
foreach ($tables as $table) {
// Drag element for sortorder.
$move = html_writer::span($OUTPUT->render_from_template('core/drag_handle',
['movetitle' => get_string('movecontent', 'moodle', $table->getName())]), '',
['data-action' => 'move_updown_table', 'data-dir' => str_replace($CFG->dirroot, '', $dirpath),
'data-table' => $table->getName()]);
// The table name (link to edit table)
$t = '<a href="index.php?action=edit_table&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">' . $table->getName() . '</a>';
// Calculate buttons
$b = '</td><td class="button cell">';
// The edit button
$b .= '<a href="index.php?action=edit_table&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['edit'] . ']</a>';
$b .= '</td><td class="button cell">';
// The delete button (if we have more than one and it isn't used)
if (count($tables) > 1 &&
!$structure->getTableUses($table->getName())) {
// !$structure->getTableUses($table->getName())) {
$b .= '<a href="index.php?action=delete_table&amp;sesskey=' . sesskey() . '&amp;table=' . $table->getName() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['delete'] . ']</a>';
} else {
$b .= '[' . $this->str['delete'] . ']';
}
$b .= '</td><td class="button cell">';
// The view xml button
$b .= '<a href="index.php?action=view_table_xml&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;table=' . $table->getName() . '&amp;select=edited">[' . $this->str['viewxml'] . ']</a>';
// Detect if the table name is a reserved word
if (array_key_exists($table->getName(), $reserved_words)) {
$b .= '&nbsp;<a href="index.php?action=view_reserved_words"><span class="error">' . $this->str['reserved'] . '</span></a>';
}
$b .= '</td>';
// Print table row
$o .= '<tr class="r' . $row . '" data-name="' . s($table->getName()) . '"><td class="cell firstcol">' .
(count($tables) > 1 ? $move : '') .
$t . $b . '</tr>';
$row = ($row + 1) % 2;
}
$o .= '</table>';
}
// Add the back to main.
$this->output = $o;
$PAGE->requires->js_call_amd('tool_xmldb/move', 'init', ['listtables', 'move_updown_table']);
}
}
// Launch postaction if exists (leave this unmodified)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
return $result;
}
}
@@ -0,0 +1,101 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will save the changes performed to the comment of one file
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class edit_xml_file_save extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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
if (!data_submitted()) { // Basic prevention
throw new \moodle_exception('wrongcall', 'error');
}
// Get parameters
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$comment = required_param('comment', PARAM_CLEAN);
$comment = $comment;
// Set comment and recalculate hash
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
$structure->setComment($comment);
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origdir = $XMLDB->dbdirs[$dirpath];
$origstructure = $origdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,124 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright (C) 2001-3001 Eloy Lafuente (stronk7) {@link http://contiento.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will produce the documentation for all the XMLDB files in the server,
* via XSL, performing the output in HTML format.
*
* @package tool_xmldb
* @copyright (C) 2001-3001 Eloy Lafuente (stronk7) {@link http://contiento.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class generate_all_documentation extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'backtomainview' => 'tool_xmldb',
'documentationintro' => 'tool_xmldb',
'docindex' => 'tool_xmldb'
));
}
/**
* 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;
// Do the job, setting $result as needed
// Add link back to home
$b = ' <p class="centerpara buttons">';
$b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
$b .= '</p>';
$this->output=$b;
$c = ' <p class="centerpara">';
$c .= $this->str['documentationintro'];
$c .= '</p>';
$this->output.=$c;
$docs = '';
if(class_exists('XSLTProcessor')) {
$doc = new DOMDocument();
$xsl = new XSLTProcessor();
$doc->load(__DIR__.'/../generate_documentation/xmldb.xsl');
$xsl->importStyleSheet($doc);
$dbdirs = get_db_directories();
sort($dbdirs);
$index = $this->str['docindex'] . ' ';
foreach ($dbdirs as $path) {
if (!file_exists($path . '/install.xml')) {
continue;
}
$dir = trim(dirname(str_replace($CFG->dirroot, '', $path)), '/');
$index .= '<a href="#file_' . str_replace('/', '_', $dir) . '">' . $dir . '</a>, ';
$docs .= '<div class="file" id="file_' . str_replace('/', '_', $dir) . '">';
$docs .= '<h2>' . $dir . '</h2>';
$doc->load($path . '/install.xml');
$docs .= $xsl->transformToXML($doc);
$docs .= '</div>';
}
$this->output .= '<div id="file_idex">' . trim($index, ' ,') . '</div>' . $docs;
$this->output.=$b;
} else {
$this->output.=get_string('extensionrequired','tool_xmldb','xsl');
}
// Launch postaction if exists (leave this unmodified)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
return $result;
}
}
@@ -0,0 +1,108 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will produce XSL documentation for the loaded XML file
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class generate_documentation extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'backtomainview' => 'tool_xmldb',
'documentationintro' => 'tool_xmldb'
));
}
/**
* 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;
// Do the job, setting $result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$path = $dirpath.'/install.xml';
if(!file_exists($path) || !is_readable($path)) {
return false;
}
// Add link back to home
$b = ' <p class="centerpara buttons">';
$b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
$b .= '</p>';
$this->output=$b;
$c = ' <p class="centerpara">';
$c .= $this->str['documentationintro'];
$c .= '</p>';
$this->output.=$c;
if(class_exists('XSLTProcessor')) {
// Transform XML file and display it
$doc = new DOMDocument();
$xsl = new XSLTProcessor();
$doc->load(__DIR__.'/xmldb.xsl');
$xsl->importStyleSheet($doc);
$doc->load($path);
$this->output.=$xsl->transformToXML($doc);
$this->output.=$b;
} else {
$this->output.=get_string('extensionrequired','tool_xmldb','xsl');
}
// Launch postaction if exists (leave this unmodified)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
return $result;
}
}
@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes"/>
<!-- Top level: disclaimer/intro -->
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<!-- Tables: heading, comment -->
<xsl:template match="TABLE">
<xsl:variable name="tableid">table_<xsl:value-of select="@NAME"/></xsl:variable>
<h3 id="{$tableid}" style="margin-top:3em"><xsl:value-of select="@NAME"/></h3>
<xsl:call-template name="display-comment"><xsl:with-param name="PARA">y</xsl:with-param></xsl:call-template>
<xsl:apply-templates>
<xsl:with-param name="tableid" select="$tableid" />
</xsl:apply-templates>
</xsl:template>
<!-- Fields (if any): table with field, type, comment -->
<xsl:template match="FIELDS[FIELD]">
<xsl:param name="tableid" />
<table class="generaltable boxaligncenter" style="margin:1em 0" cellspacing="1" cellpadding="5" width="100%">
<tr>
<th class="header c0" scope="col">Field</th>
<th class="header c1" scope="col">Type</th>
<th class="header c2 lastcol" scope="col">Description</th>
</tr>
<xsl:apply-templates>
<xsl:with-param name="tableid" select="$tableid" />
</xsl:apply-templates>
</table>
</xsl:template>
<!-- Each individual field -->
<xsl:template match="FIELD">
<xsl:param name="tableid" />
<xsl:variable name="fieldid"><xsl:value-of select="$tableid"/>_field_<xsl:value-of select="@NAME"/></xsl:variable>
<xsl:variable name="COUNT" select="count(preceding-sibling::*)"/>
<tr class="r{$COUNT}">
<td id="{$fieldid}" class="cell c0"><xsl:value-of select="@NAME"/></td>
<td class="cell c1" style="white-space: nowrap;">
<xsl:value-of select="@TYPE"/>
(<xsl:value-of select="@LENGTH"/><xsl:if test="@DECIMALS">, <xsl:value-of select="@DECIMALS"/></xsl:if>)
<xsl:if test="@NOTNULL='true'">not null </xsl:if>
<xsl:if test="@DEFAULT">
<xsl:choose>
<xsl:when test="@TYPE='char'">default '<xsl:value-of select="@DEFAULT"/>'</xsl:when>
<xsl:when test="@TYPE='text'">default '<xsl:value-of select="@DEFAULT"/>'</xsl:when>
<xsl:otherwise>default <xsl:value-of select="@DEFAULT"/></xsl:otherwise>
</xsl:choose>
</xsl:if>
<xsl:if test="@SEQUENCE='true'">seq</xsl:if>
</td>
<td class="cell c2 lastcol"><xsl:call-template name="display-comment"/></td>
</tr>
</xsl:template>
<!-- Keys (if any): table with key, type, field(s), reference, and comment -->
<xsl:template match="KEYS[KEY]">
<h4>Keys</h4>
<table class="generaltable boxaligncenter" cellspacing="1" cellpadding="5" width="100%">
<tr>
<th class="header c0" scope="col">Name</th>
<th class="header c1" scope="col">Type</th>
<th class="header c2" scope="col">Field(s)</th>
<th class="header c3" scope="col">Reference</th>
<!-- If no keys have comments (which is usually sensible since it's
completely obvious what they are) then the comment column is not
included -->
<xsl:if test="*[normalize-space(@COMMENT)!='']">
<th class="header c4 lastcol" scope="col">Description</th>
</xsl:if>
</tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<!-- Individual key -->
<xsl:template match="KEY">
<xsl:variable name="COUNT" select="count(preceding-sibling::*)"/>
<tr class="r{$COUNT}">
<td class="cell c0"><xsl:value-of select="@NAME"/></td>
<td class="cell c1"><xsl:value-of select="@TYPE"/></td>
<td class="cell c2"><xsl:value-of select="@FIELDS"/></td>
<td class="cell c3">
<xsl:if test="@REFTABLE">
<xsl:variable name="tableid">table_<xsl:value-of select="@REFTABLE"/></xsl:variable>
<a href="#{$tableid}"><xsl:value-of select="@REFTABLE"/></a> (<xsl:value-of select="@REFFIELDS"/>)
</xsl:if>
</td>
<xsl:if test="../*[normalize-space(@COMMENT)!='']">
<td class="cell c4 lastcol"><xsl:call-template name="display-comment"/></td>
</xsl:if>
</tr>
</xsl:template>
<!-- Indexes -->
<xsl:template match="INDEXES[INDEX]">
<h4>Indexes</h4>
<table class="generaltable boxaligncenter" cellspacing="1" cellpadding="5" width="100%">
<tr>
<th class="header c0" scope="col">Name</th>
<th class="header c1" scope="col">Type</th>
<th class="header c2" scope="col">Field(s)</th>
<xsl:if test="*[normalize-space(@COMMENT)!='']">
<th class="header c4 lastcol" scope="col">Description</th>
</xsl:if>
</tr>
<xsl:apply-templates/>
</table>
</xsl:template>
<!-- Individual index -->
<xsl:template match="INDEX">
<xsl:variable name="COUNT" select="count(preceding-sibling::*)"/>
<tr class="r{$COUNT}">
<td class="cell c0"><xsl:value-of select="@NAME"/></td>
<td class="cell c1">
<xsl:choose>
<xsl:when test="@UNIQUE='true'">Unique</xsl:when>
<xsl:otherwise>Not unique</xsl:otherwise>
</xsl:choose>
</td>
<td class="cell c2"><xsl:value-of select="@FIELDS"/></td>
<xsl:if test="../*[normalize-space(@COMMENT)!='']">
<td class="cell c4 lastcol"><xsl:call-template name="display-comment"/></td>
</xsl:if>
</tr>
</xsl:template>
<xsl:template name="display-comment">
<xsl:param name="PARA"/>
<xsl:if test="normalize-space(@COMMENT)!=''">
<xsl:choose>
<xsl:when test="$PARA">
<p class="xmldb_comment"><xsl:value-of select="@COMMENT"/></p>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@COMMENT"/>
</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
@@ -0,0 +1,94 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will will check all the db directories existing under the
* current Moodle installation, sending them to the SESSION->dbdirs array
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class get_db_directories extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own core attributes
$this->can_subaction = ACTION_NONE;
//$this->can_subaction = ACTION_HAVE_SUBACTIONS;
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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
// Lets go to add all the db directories available inside Moodle
// Create the array if it doesn't exists
if (!isset($XMLDB->dbdirs)) {
$XMLDB->dbdirs = array();
}
// get list of all dirs and create objects with status
$db_directories = get_db_directories();
foreach ($db_directories as $path) {
$dbdir = new stdClass;
$dbdir->path = $path;
if (!isset($XMLDB->dbdirs[$dbdir->path])) {
$XMLDB->dbdirs[$dbdir->path] = $dbdir;
}
$XMLDB->dbdirs[$dbdir->path]->path_exists = file_exists($dbdir->path); //Update status
}
// Sort by key
ksort($XMLDB->dbdirs);
// Return ok if arrived here
return true;
}
}
@@ -0,0 +1,116 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will load one XML file to memory if necessary
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class load_xml_file extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own core attributes
$this->can_subaction = ACTION_NONE;
//$this->can_subaction = ACTION_HAVE_SUBACTIONS;
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $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 xmldb_file($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;
}
}
@@ -0,0 +1,99 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will load every XML file to memory if necessary
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class load_xml_files extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own core attributes
$this->can_subaction = ACTION_NONE;
//$this->can_subaction = ACTION_HAVE_SUBACTIONS;
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 xmldb_file($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;
}
}
@@ -0,0 +1,312 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will show all the actions available under the XMLDB editor interface
*
* From here, files can be created, edited, saved and deleted, plus some
* extra utilities like displaying docs, xml info and performing various consistency tests
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class main_view extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'load' => 'tool_xmldb',
'create' => 'tool_xmldb',
'edit' => 'tool_xmldb',
'save' => 'tool_xmldb',
'revert' => 'tool_xmldb',
'unload' => 'tool_xmldb',
'delete' => 'tool_xmldb',
'reservedwords' => 'tool_xmldb',
'gotolastused' => 'tool_xmldb',
'checkindexes' => 'tool_xmldb',
'checkdefaults' => 'tool_xmldb',
'checkforeignkeys' => 'tool_xmldb',
'checkbigints' => 'tool_xmldb',
'checkoraclesemantics' => 'tool_xmldb',
'reconcilefiles' => 'tool_xmldb',
'doc' => 'tool_xmldb',
'filemodifiedoutfromeditor' => 'tool_xmldb',
'viewxml' => 'tool_xmldb',
'pendingchangescannotbesavedreload' => 'tool_xmldb'
));
}
/**
* 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, $SESSION, $DB;
// Get lastused
$o = '';
if (isset($SESSION->lastused)) {
if ($lastused = $SESSION->lastused) {
// Print link
$o .= '<p class="centerpara"><a href="#lastused">' . $this->str['gotolastused'] . '</a></p>';
}
} else {
$lastused = NULL;
}
// Calculate the buttons
$b = '<p class="centerpara buttons">';
// The reserved_words button
$b .= '&nbsp;<a href="index.php?action=view_reserved_words">[' . $this->str['reservedwords'] . ']</a>';
// The docs button
$b .= '&nbsp;<a href="index.php?action=generate_all_documentation">[' . $this->str['doc'] . ']</a>';
// The reconcile XMLDB files button.
$b .= '&nbsp;<a href="index.php?action=reconcile_files">[' . $this->str['reconcilefiles'] . ']</a>';
// The check indexes button
$b .= '&nbsp;<a href="index.php?action=check_indexes&amp;sesskey=' . sesskey() . '">[' . $this->str['checkindexes'] . ']</a>';
// The check defaults button
$b .= '&nbsp;<a href="index.php?action=check_defaults&amp;sesskey=' . sesskey() . '">[' . $this->str['checkdefaults'] . ']</a>';
// The check bigints button (only for MySQL and PostgreSQL) MDL-11038a
if ($DB->get_dbfamily() == 'mysql' || $DB->get_dbfamily() == 'postgres') {
$b .= '&nbsp;<a href="index.php?action=check_bigints&amp;sesskey=' . sesskey() . '">[' . $this->str['checkbigints'] . ']</a>';
}
// The check semantics button (only for Oracle) MDL-29416
if ($DB->get_dbfamily() == 'oracle') {
$b .= '&nbsp;<a href="index.php?action=check_oracle_semantics&amp;sesskey=' . sesskey() . '">[' . $this->str['checkoraclesemantics'] . ']</a>';
}
$b .= '&nbsp;<a href="index.php?action=check_foreign_keys&amp;sesskey=' . sesskey() . '">[' . $this->str['checkforeignkeys'] . ']</a>';
$b .= '</p>';
// Send buttons to output
$o .= $b;
// Do the job
// Get the list of DB directories
$result = $this->launch('get_db_directories');
// Display list of DB directories if everything is ok
if ($result && !empty($XMLDB->dbdirs)) {
$o .= '<table id="listdirectories" border="0" cellpadding="5" cellspacing="1"' .
' class="table-striped table-sm admintable generaltable">';
$row = 0;
foreach ($XMLDB->dbdirs as $key => $dbdir) {
// Detect if this is the lastused dir
$hithis = false;
if (str_replace($CFG->dirroot, '', $key) == $lastused) {
$hithis = true;
}
$elementtext = str_replace($CFG->dirroot . '/', '', $key);
// Calculate the dbdir has_changed field if needed
if (!isset($dbdir->has_changed) && isset($dbdir->xml_loaded)) {
$dbdir->xml_changed = false;
if (isset($XMLDB->editeddirs[$key])) {
$editeddir = $XMLDB->editeddirs[$key];
if (isset($editeddir->xml_file)) {
$structure = $editeddir->xml_file->getStructure();
if ($structure->hasChanged()) {
$dbdir->xml_changed = true;
$editeddir->xml_changed = true;
}
}
}
}
// The file name (link to edit if the file is loaded)
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
is_readable($key) &&
!empty($dbdir->xml_loaded)) {
$f = '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">' . $elementtext . '</a>';
} else {
$f = $elementtext;
}
// Calculate the buttons
$b = ' <td class="button cell">';
// The create button
if ($dbdir->path_exists &&
!file_exists($key . '/install.xml') &&
is_writeable($key)) {
$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>';
} else {
$b .= '[' . $this->str['create'] . ']';
}
$b .= '</td><td class="button cell">';
// The load button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
empty($dbdir->xml_loaded)) {
$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>';
} else {
$b .= '[' . $this->str['load'] . ']';
}
$b .= '</td><td class="button cell">';
// The edit button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
is_readable($key) &&
!empty($dbdir->xml_loaded)) {
$b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['edit'] . ']</a>';
} else {
$b .= '[' . $this->str['edit'] . ']';
}
$b .= '</td><td class="button cell">';
// The save button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_writeable($key . '/install.xml') &&
is_writeable($key) &&
!empty($dbdir->xml_loaded) &&
!empty($dbdir->xml_changed)) {
$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>';
// Check if the file has been manually edited while being modified in the editor
if ($dbdir->filemtime != filemtime($key . '/install.xml')) {
// File manually modified. Add to action error, will be displayed inline.
$this->errormsg = $this->str['filemodifiedoutfromeditor'];
}
} else {
$b .= '[' . $this->str['save'] . ']';
}
$b .= '</td><td class="button cell">';
// The document button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
is_readable($key)) {
$b .= '<a href="index.php?action=generate_documentation&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['doc'] . ']</a>';
} else {
$b .= '[' . $this->str['doc'] . ']';
}
$b .= '</td><td class="button cell">';
// The view xml button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml')) {
$b .= '<a href="index.php?action=view_xml&amp;file=' . urlencode(str_replace($CFG->dirroot, '', $key) . '/install.xml') . '">[' . $this->str['viewxml'] . ']</a>';
} else {
$b .= '[' . $this->str['viewxml'] . ']';
}
$b .= '</td><td class="button cell">';
// The revert button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
is_writeable($key) &&
!empty($dbdir->xml_loaded) &&
!empty($dbdir->xml_changed)) {
$b .= '<a href="index.php?action=revert_changes&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['revert'] . ']</a>';
} else {
$b .= '[' . $this->str['revert'] . ']';
}
$b .= '</td><td class="button cell">';
// The unload button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
!empty($dbdir->xml_loaded) &&
empty($dbdir->xml_changed)) {
$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>';
} else {
$b .= '[' . $this->str['unload'] . ']';
}
$b .= '</td><td class="button cell">';
// The delete button
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
is_readable($key . '/install.xml') &&
is_writeable($key) &&
empty($dbdir->xml_loaded)) {
$b .= '<a href="index.php?action=delete_xml_file&amp;sesskey=' . sesskey() . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $key)) . '">[' . $this->str['delete'] . ']</a>';
} else {
$b .= '[' . $this->str['delete'] . ']';
}
$b .= '</td>';
// include the higlight
if ($hithis) {
$o .= '<tr class="highlight"><td class="directory cell"><a name="lastused" />' . $f . '</td>' . $b . '</tr>';
} else {
$o .= '<tr class="r' . $row . '"><td class="directory cell">' . $f . '</td>' . $b . '</tr>';
}
$row = ($row + 1) % 2;
// show errors if they exist
if (isset($dbdir->xml_file)) {
if ($structure = $dbdir->xml_file->getStructure()) {
$errors = !empty($this->errormsg) ? array($this->errormsg) : array();
$structureerrors = $structure->getAllErrors();
if ($structureerrors) {
$errors = array_merge($errors, $structureerrors);
}
if (!empty($errors)) {
if ($hithis) {
$o .= '<tr class="highlight"><td class="error cell" colspan="10">' . implode (', ', $errors) . '</td></tr>';
} else {
$o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">' . implode (', ', $errors) . '</td></tr>';
}
}
}
}
// If there are changes pending to be saved, but the file cannot be written... inform here
if ($dbdir->path_exists &&
file_exists($key . '/install.xml') &&
!empty($dbdir->xml_loaded) &&
!empty($dbdir->xml_changed) &&
(!is_writeable($key . '/install.xml') || !is_writeable($key))) {
if ($hithis) {
$o .= '<tr class="highlight"><td class="error cell" colspan="10">';
} else {
$o .= '<tr class="r' . $row . '"><td class="error cell" colspan="10">';
}
$o .= $this->str['pendingchangescannotbesavedreload'];
$o .= '</td></tr>';
}
}
$o .= '</table>';
// Set the output
$this->output = $o;
}
// Finally, return result
return $result;
}
}
@@ -0,0 +1,147 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will will move one field up/down
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class move_updown_field extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$prev = NULL;
$next = NULL;
$tableparam = required_param('table', PARAM_CLEAN);
$fieldparam = required_param('field', PARAM_CLEAN);
$direction = required_param('direction', PARAM_ALPHA);
$tables = $structure->getTables();
$table = $structure->getTable($tableparam);
$fields = $table->getFields();
if ($direction == 'down') {
$field = $table->getField($fieldparam);
$swap = $table->getField($field->getNext());
} else {
$swap = $table->getField($fieldparam);
$field = $table->getField($swap->getPrevious());
}
// Change the field before the pair
if ($field->getPrevious()) {
$prev = $table->getField($field->getPrevious());
$prev->setNext($swap->getName());
$swap->setPrevious($prev->getName());
$prev->setChanged(true);
} else {
$swap->setPrevious(NULL);
}
// Change the field after the pair
if ($swap->getNext()) {
$next = $table->getField($swap->getNext());
$next->setPrevious($field->getName());
$field->setNext($next->getName());
$next->setChanged(true);
} else {
$field->setNext(NULL);
}
// Swap the fields
$field->setPrevious($swap->getName());
$swap->setNext($field->getName());
// Mark fields as changed
$field->setChanged(true);
$swap->setChanged(true);
// Table has changed
$table->setChanged(true);
// Reorder the fields
$table->orderFields();
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,147 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will will move one index up/down
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class move_updown_index extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$prev = NULL;
$next = NULL;
$tableparam = required_param('table', PARAM_CLEAN);
$indexparam = required_param('index', PARAM_CLEAN);
$direction = required_param('direction', PARAM_ALPHA);
$tables = $structure->getTables();
$table = $structure->getTable($tableparam);
$indexes = $table->getIndexes();
if ($direction == 'down') {
$index = $table->getIndex($indexparam);
$swap = $table->getIndex($index->getNext());
} else {
$swap = $table->getIndex($indexparam);
$index = $table->getIndex($swap->getPrevious());
}
// Change the index before the pair
if ($index->getPrevious()) {
$prev = $table->getIndex($index->getPrevious());
$prev->setNext($swap->getName());
$swap->setPrevious($prev->getName());
$prev->setChanged(true);
} else {
$swap->setPrevious(NULL);
}
// Change the field after the pair
if ($swap->getNext()) {
$next = $table->getIndex($swap->getNext());
$next->setPrevious($index->getName());
$index->setNext($next->getName());
$next->setChanged(true);
} else {
$index->setNext(NULL);
}
// Swap the indexes
$index->setPrevious($swap->getName());
$swap->setNext($index->getName());
// Mark indexes as changed
$index->setChanged(true);
$swap->setChanged(true);
// Table has changed
$table->setChanged(true);
// Reorder the indexes
$table->orderIndexes();
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,147 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will will move one key up/down
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class move_updown_key extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$prev = NULL;
$next = NULL;
$tableparam = required_param('table', PARAM_CLEAN);
$keyparam = required_param('key', PARAM_CLEAN);
$direction = required_param('direction', PARAM_ALPHA);
$tables = $structure->getTables();
$table = $structure->getTable($tableparam);
$keys = $table->getKeys();
if ($direction == 'down') {
$key = $table->getKey($keyparam);
$swap = $table->getKey($key->getNext());
} else {
$swap = $table->getKey($keyparam);
$key = $table->getKey($swap->getPrevious());
}
// Change the key before the pair
if ($key->getPrevious()) {
$prev = $table->getKey($key->getPrevious());
$prev->setNext($swap->getName());
$swap->setPrevious($prev->getName());
$prev->setChanged(true);
} else {
$swap->setPrevious(NULL);
}
// Change the key after the pair
if ($swap->getNext()) {
$next = $table->getKey($swap->getNext());
$next->setPrevious($key->getName());
$key->setNext($next->getName());
$next->setChanged(true);
} else {
$key->setNext(NULL);
}
// Swap the keys
$key->setPrevious($swap->getName());
$swap->setNext($key->getName());
// Mark keys as changed
$key->setChanged(true);
$swap->setChanged(true);
// Table has changed
$table->setChanged(true);
// Reorder the keys
$table->orderKeys();
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,140 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will will move table up/down
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class move_updown_table extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$prev = NULL;
$next = NULL;
$tableparam = required_param('table', PARAM_CLEAN);
$direction = required_param('direction', PARAM_ALPHA);
$tables = $structure->getTables();
if ($direction == 'down') {
$table = $structure->getTable($tableparam);
$swap = $structure->getTable($table->getNext());
} else {
$swap = $structure->getTable($tableparam);
$table = $structure->getTable($swap->getPrevious());
}
// Change the table before the pair
if ($table->getPrevious()) {
$prev = $structure->getTable($table->getPrevious());
$prev->setNext($swap->getName());
$swap->setPrevious($prev->getName());
$prev->setChanged(true);
} else {
$swap->setPrevious(NULL);
}
// Change the table after the pair
if ($swap->getNext()) {
$next = $structure->getTable($swap->getNext());
$next->setPrevious($table->getName());
$table->setNext($next->getName());
$next->setChanged(true);
} else {
$table->setNext(NULL);
}
// Swap the tables
$table->setPrevious($swap->getName());
$swap->setNext($table->getName());
// Table has changed
$table->setChanged(true);
// Reorder the structure
$structure->orderTables();
// Recalculate the hash
$structure->calculateHash(true);
// If the hash has changed from the original one, change the version
// and mark the structure as changed
$origstructure = $dbdir->xml_file->getStructure();
if ($structure->getHash() != $origstructure->getHash()) {
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,108 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will create a new default field to be edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class new_field extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = required_param('table', PARAM_CLEAN);
$table = $structure->getTable($tableparam);
// If the changeme field exists, just get it and continue
$changeme_exists = false;
if ($fields = $table->getFields()) {
if ($field = $table->getField('changeme')) {
$changeme_exists = true;
}
}
if (!$changeme_exists) { // Lets create the field
$field = new xmldb_field('changeme');
$table->addField($field);
// We have one new field, so the structure has changed
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will create a new default index to be edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class new_index extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = required_param('table', PARAM_CLEAN);
$table = $structure->getTable($tableparam);
// If the changeme index exists, just get it and continue
$changeme_exists = false;
if ($indexes = $table->getIndexes()) {
if ($index = $table->getIndex('changeme')) {
$changeme_exists = true;
}
}
if (!$changeme_exists) { // Lets create the Index
$index = new xmldb_index('changeme');
$table->addIndex($index);
// We have one new key, so the structure has changed
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will create a new default key to be edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class new_key extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = required_param('table', PARAM_CLEAN);
$table = $structure->getTable($tableparam);
// If the changeme key exists, just get it and continue
$changeme_exists = false;
if ($keys = $table->getKeys()) {
if ($key = $table->getKey('changeme')) {
$changeme_exists = true;
}
}
if (!$changeme_exists) { // Lets create the Key
$key = new xmldb_key('changeme');
$table->addKey($key);
// We have one new key, so the structure has changed
$structure->setVersion(userdate(time(), '%Y%m%d', 99, false));
$structure->setChanged(true);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,119 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will create a new default table to be edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class new_table extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// If the changeme table exists, just get it and continue
$changeme_exists = false;
if ($tables = $structure->getTables()) {
if ($table = $structure->getTable('changeme')) {
$changeme_exists = true;
}
}
if (!$changeme_exists) { // Lets create the table
$field = new xmldb_field('id');
$field->setType(XMLDB_TYPE_INTEGER);
$field->setLength(10);
$field->setNotNull(true);
$field->setSequence(true);
$field->setLoaded(true);
$field->setChanged(true);
$key = new xmldb_key('primary');
$key->setType(XMLDB_KEY_PRIMARY);
$key->setFields(array('id'));
$key->setLoaded(true);
$key->setChanged(true);
$table = new xmldb_table('changeme');
$table->setComment('Default comment for the table, please edit me');
$table->addField($field);
$table->addKey($key);
// Finally, add the whole retrofitted table to the structure
// in the place specified
$structure->addTable($table);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,191 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will ask and retrofit all the information from one
* mysql table present in the Moodle DB to one xmldb_table structure
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class new_table_from_mysql extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
global $DB;
if ($DB->get_dbfamily() !== 'mysql') {
throw new moodle_exception('DB family not supported');
}
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'createtable' => 'tool_xmldb',
'aftertable' => 'tool_xmldb',
'create' => 'tool_xmldb',
'back' => 'tool_xmldb'
));
}
/**
* Invoke method, every class will have its own
* returns true/false on completion, setting both
* errormsg and output as necessary
*/
function invoke() {
parent::invoke();
// Set own core attributes
$this->does_generate = ACTION_GENERATE_HTML;
// These are always here
global $CFG, $XMLDB, $DB, $OUTPUT;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = optional_param('table', NULL, PARAM_CLEAN);
// If no table, show form
if (!$tableparam) {
// No postaction here
$this->postaction = NULL;
// Get list of tables
$dbtables = $DB->get_tables();
$selecttables = array();
foreach ($dbtables as $dbtable) {
$i = $structure->findTableInArray($dbtable);
if ($i === NULL) {
$selecttables[$dbtable] = $dbtable;
}
}
// Get list of after tables
$aftertables = array();
if ($tables = $structure->getTables()) {
foreach ($tables as $aftertable) {
$aftertables[$aftertable->getName()] = $aftertable->getName();
}
}
if (!$selecttables) {
$this->errormsg = 'No tables available to be retrofitted';
return false;
}
// Now build the form
$o = '<form id="form" action="index.php" method="post">';
$o .= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="action" value="new_table_from_mysql" />';
$o.= ' <input type="hidden" name ="postaction" value="edit_table" />';
$o.= ' <input type="hidden" name ="sesskey" value="' . sesskey() . '" />';
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$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>';
$o.= ' <tr><td colspan="2" align="center"><input type="submit" value="' .$this->str['create'] . '" /></td></tr>';
$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>';
$o.= ' </table>';
$o.= '</div></form>';
$this->output = $o;
// If table, retrofit information and, if everything works,
// go to the table edit action
} else {
// Get some params (table is mandatory here).
$tableparam = required_param('table', PARAM_ALPHANUMEXT);
$afterparam = required_param('after', PARAM_ALPHANUMEXT);
if (empty($tableparam) || empty($afterparam)) {
throw new moodle_exception('Invalid param value detected.');
}
// Create one new xmldb_table.
$table = new xmldb_table(strtolower(trim($tableparam)));
$table->setComment($table->getName() . ' table retrofitted from MySQL');
// Get fields info from ADODb
$dbfields = $DB->get_columns($tableparam);
if ($dbfields) {
foreach ($dbfields as $dbfield) {
// Create new XMLDB field
$field = new xmldb_field($dbfield->name);
// Set field with info retrofitted
$field->setFromADOField($dbfield);
// Add field to the table
$table->addField($field);
}
}
// Get PK, UK and indexes info from ADODb
$dbindexes = $DB->get_indexes($tableparam);
if ($dbindexes) {
foreach ($dbindexes as $indexname => $dbindex) {
// Add the indexname to the array
$dbindex['name'] = $indexname;
// We are handling one xmldb_key (primaries + uniques)
if ($dbindex['unique']) {
$key = new xmldb_key(strtolower($dbindex['name']));
// Set key with info retrofitted
$key->setFromADOKey($dbindex);
// Add key to the table
$table->addKey($key);
// We are handling one xmldb_index (non-uniques)
} else {
$index = new xmldb_index(strtolower($dbindex['name']));
// Set index with info retrofitted
$index->setFromADOIndex($dbindex);
// Add index to the table
$table->addIndex($index);
}
}
}
// Finally, add the whole retrofitted table to the structure in the place specified.
$structure->addTable($table, $afterparam);
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction()) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return true;
}
}
@@ -0,0 +1,124 @@
<?php
// This file is part of Moodle - https://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <https://www.gnu.org/licenses/>.
/**
* List all the files needing reconcile because the definitions don't match the XML contents.
*
* @package tool_xmldb
* @copyright 2022 onwards Eloy Lafuente (stronk7) {@link https://stronk7.com}
* @license https://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class reconcile_files extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
public function init() {
parent::init();
// Set own custom attributes.
$this->sesskey_protected = false; // This action doesn't need sesskey protection.
// Get needed strings.
$this->loadStrings([
'backtomainview' => 'tool_xmldb',
'reconcile_files_intro' => 'tool_xmldb',
'reconcile_files_no' => 'tool_xmldb',
'reconcile_files_yes' => 'tool_xmldb',
'searchresults' => 'tool_xmldb',
]);
}
/**
* Invoke method, every class will have its own
* returns true/false on completion, setting both
* errormsg and output as necessary
*/
public function invoke() {
parent::invoke();
$result = true;
// Set own core attributes.
$this->does_generate = ACTION_GENERATE_HTML;
// These are always here.
global $CFG, $XMLDB;
// Do the job, setting $result as needed.
// Add link back to home.
$b = ' <p class="centerpara">';
$b .= '&nbsp;<a href="index.php?action=main_view#lastused">[' . $this->str['backtomainview'] . ']</a>';
$b .= '</p>';
$this->output .= $b;
$c = '<p class="centerpara">';
$c .= $this->str['reconcile_files_intro'];
$c .= '</p>';
$this->output .= $c;
// Get the list of DB directories.
$result = $this->launch('get_db_directories');
if ($result && !empty($XMLDB->dbdirs)) {
$needfix = [];
foreach ($XMLDB->dbdirs as $key => $dbdir) {
// Verify it exists.
if (!file_exists($key . '/install.xml') && !is_readable($key . '/install.xml')) {
continue;
}
// Read the raw contents of the file.
$rawcontents = file_get_contents($key . '/install.xml');
// Load the XMLDB file and its structure.
$xmldb = new xmldb_file($key . '/install.xml');
$xmldb->loadXMLStructure();
// Generate the XML contents from the loaded structure.
$xmlcontents = $xmldb->getStructure()->xmlOutput();
if ($rawcontents != $xmlcontents) {
$relpath = str_replace($CFG->dirroot . '/', '', $key) . '/install.xml';
$needfix[] = $relpath;
// Left here on purpose, as a quick way to fix problems. To be
// enabled and run by developers only, uncomment the next line:
// file_put_contents($key . '/install.xml', $xmlcontents);
// (this script won't ever do that officially).
}
}
}
$r = '<h3 class="main">' . $this->str['searchresults'] . '</h3>';
if ($needfix) {
$r .= '<h4 class="main">' . $this->str['reconcile_files_yes'] . count($needfix) . '</h4>';
$r .= '<ul><li>' . implode('</li><li>', $needfix) . '</li></ul>';
} else {
$r .= '<h4 class="main">' . $this->str['reconcile_files_no'] . '</h4>';
}
// Set the output.
$this->output .= $r;
// Launch postaction if exists (leave this unmodified).
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
return $result;
}
}
@@ -0,0 +1,118 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will revert changes (delete the editeddb)
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class revert_changes extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'confirmrevertchanges' => 'tool_xmldb',
'yes' => '',
'no' => ''
));
}
/**
* 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;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
$confirmed = optional_param('confirmed', false, PARAM_BOOL);
// If not confirmed, show confirmation box
if (!$confirmed) {
$o = '<table width="60" class="generaltable boxaligncenter" border="0" cellpadding="5" cellspacing="0" id="notice">';
$o.= ' <tr><td class="generalboxcontent">';
$o.= ' <p class="centerpara">' . $this->str['confirmrevertchanges'] . '<br /><br />' . $dirpath . '</p>';
$o.= ' <table class="boxaligncenter" cellpadding="20"><tr><td>';
$o.= ' <div class="singlebutton">';
$o.= ' <form action="index.php?action=revert_changes&amp;sesskey=' . sesskey() . '&amp;confirmed=yes&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;postaction=main_view#lastused" 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#lastused" 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 {
// Get the original dir and delete some elements
if (!empty($XMLDB->dbdirs)) {
if (isset($XMLDB->dbdirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
if ($dbdir) {
unset($dbdir->xml_changed);
}
}
}
// Get the edited dir and delete it completely
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
unset($XMLDB->editeddirs[$dirpath]);
}
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,125 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will save one edited xml file
*
* This class will save the in-session xml structure to its
* corresponding xml file, optionally reloading it if editing
* is going to continue (unload=false). Else (default) the
* file is unloaded once saved.
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class save_xml_file extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
'filenotwriteable' => 'tool_xmldb'
));
}
/**
* 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;
// 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 . $dirpath;
$unload = optional_param('unload', true, PARAM_BOOL);
// Get the edited dir
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
$editeddir = $XMLDB->editeddirs[$dirpath];
}
}
// Copy the edited dir over the original one
if (!empty($XMLDB->dbdirs)) {
if (isset($XMLDB->dbdirs[$dirpath])) {
$XMLDB->dbdirs[$dirpath] = unserialize(serialize($editeddir));
$dbdir = $XMLDB->dbdirs[$dirpath];
}
}
// Check for perms
if (!is_writeable($dirpath . '/install.xml')) {
$this->errormsg = $this->str['filenotwriteable'] . '(' . $dirpath . '/install.xml)';
return false;
}
// Save the original dir
$result = $dbdir->xml_file->saveXMLFile();
if ($result) {
// Delete the edited dir
unset ($XMLDB->editeddirs[$dirpath]);
// Unload de originaldir
unset($XMLDB->dbdirs[$dirpath]->xml_file);
unset($XMLDB->dbdirs[$dirpath]->xml_loaded);
unset($XMLDB->dbdirs[$dirpath]->xml_changed);
unset($XMLDB->dbdirs[$dirpath]->xml_exists);
unset($XMLDB->dbdirs[$dirpath]->xml_writeable);
} else {
$this->errormsg = 'Error saving XML file (' . $dirpath . ')';
return false;
}
// If unload has been disabled, simulate it by reloading the file now
if (!$unload) {
return $this->launch('load_xml_file');
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,89 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class template extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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 . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// ADD YOUR CODE HERE
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,95 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will unload one loaded file completely
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class unload_xml_file extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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;
// 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 . $dirpath;
// Get the original dir and delete some elements
if (!empty($XMLDB->dbdirs)) {
if (isset($XMLDB->dbdirs[$dirpath])) {
$dbdir = $XMLDB->dbdirs[$dirpath];
if ($dbdir) {
unset($dbdir->xml_file);
unset($dbdir->xml_loaded);
unset($dbdir->xml_changed);
unset($dbdir->xml_exists);
unset($dbdir->xml_writeable);
}
}
}
// Get the edited dir and delete it completely
if (!empty($XMLDB->editeddirs)) {
if (isset($XMLDB->editeddirs[$dirpath])) {
unset($XMLDB->editeddirs[$dirpath]);
}
}
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will display the XML for one field being edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_field_xml extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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_XML;
// These are always here
global $CFG, $XMLDB;
// Do the job, setting result as needed
// Get the file parameter
$field = required_param('field', PARAM_PATH);
$table = required_param('table', PARAM_PATH);
$select = required_param('select', PARAM_ALPHA); //original/edited
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dir
if ($select == 'original') {
if (!empty($XMLDB->dbdirs)) {
$base = $XMLDB->dbdirs[$dirpath];
}
} else if ($select == 'edited') {
if (!empty($XMLDB->editeddirs)) {
$base = $XMLDB->editeddirs[$dirpath];
}
} else {
$this->errormsg = 'Cannot access to ' . $select . ' info';
$result = false;
}
if ($base) {
// Only if the directory exists and it has been loaded
if (!$base->path_exists || !$base->xml_loaded) {
$this->errormsg = 'Directory ' . $dirpath . ' not loaded';
return false;
}
} else {
$this->errormsg = 'Problem handling ' . $select . ' files';
return false;
}
// Get the structure
if ($result) {
if (!$structure = $base->xml_file->getStructure()) {
$this->errormsg = 'Error retrieving ' . $select . ' structure';
$result = false;
}
}
// Get the tables
if ($result) {
if (!$tables = $structure->getTables()) {
$this->errormsg = 'Error retrieving ' . $select . ' tables';
$result = false;
}
}
// Get the table
if ($result && !$t = $structure->getTable($table)) {
$this->errormsg = 'Error retrieving ' . $table . ' table';
$result = false;
}
// Get the fields
if ($result) {
if (!$fields = $t->getFields()) {
$this->errormsg = 'Error retrieving ' . $select . ' fields';
$result = false;
}
}
// Get the field
if ($result && !$f = $t->getField($field)) {
$this->errormsg = 'Error retrieving ' . $field . ' field';
$result = false;
}
if ($result) {
// Everything is ok. Generate the XML output
$this->output = $f->xmlOutput();
} else {
// Switch to HTML and error
$this->does_generate = ACTION_GENERATE_HTML;
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will display the XML for one index being edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_index_xml extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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_XML;
// These are always here
global $CFG, $XMLDB;
// Do the job, setting result as needed
// Get the file parameter
$index = required_param('index', PARAM_PATH);
$table = required_param('table', PARAM_PATH);
$select = required_param('select', PARAM_ALPHA); //original/edited
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dir
if ($select == 'original') {
if (!empty($XMLDB->dbdirs)) {
$base = $XMLDB->dbdirs[$dirpath];
}
} else if ($select == 'edited') {
if (!empty($XMLDB->editeddirs)) {
$base = $XMLDB->editeddirs[$dirpath];
}
} else {
$this->errormsg = 'Cannot access to ' . $select . ' info';
$result = false;
}
if ($base) {
// Only if the directory exists and it has been loaded
if (!$base->path_exists || !$base->xml_loaded) {
$this->errormsg = 'Directory ' . $dirpath . ' not loaded';
return false;
}
} else {
$this->errormsg = 'Problem handling ' . $select . ' files';
return false;
}
// Get the structure
if ($result) {
if (!$structure = $base->xml_file->getStructure()) {
$this->errormsg = 'Error retrieving ' . $select . ' structure';
$result = false;
}
}
// Get the tables
if ($result) {
if (!$tables = $structure->getTables()) {
$this->errormsg = 'Error retrieving ' . $select . ' tables';
$result = false;
}
}
// Get the table
if ($result && !$t = $structure->getTable($table)) {
$this->errormsg = 'Error retrieving ' . $table . ' table';
$result = false;
}
// Get the indexes
if ($result) {
if (!$indexes = $t->getIndexes()) {
$this->errormsg = 'Error retrieving ' . $select . ' indexes';
$result = false;
}
}
// Get the index
if ($result && !$i = $t->getIndex($index)) {
$this->errormsg = 'Error retrieving ' . $index . ' index';
$result = false;
}
if ($result) {
// Everything is ok. Generate the XML output
$this->output = $i->xmlOutput();
} else {
// Switch to HTML and error
$this->does_generate = ACTION_GENERATE_HTML;
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,141 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will display the XML for one key being edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_key_xml extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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_XML;
// These are always here
global $CFG, $XMLDB;
// Do the job, setting result as needed
// Get the file parameter
$key = required_param('key', PARAM_PATH);
$table = required_param('table', PARAM_PATH);
$select = required_param('select', PARAM_ALPHA); //original/edited
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dir
if ($select == 'original') {
if (!empty($XMLDB->dbdirs)) {
$base = $XMLDB->dbdirs[$dirpath];
}
} else if ($select == 'edited') {
if (!empty($XMLDB->editeddirs)) {
$base = $XMLDB->editeddirs[$dirpath];
}
} else {
$this->errormsg = 'Cannot access to ' . $select . ' info';
$result = false;
}
if ($base) {
// Only if the directory exists and it has been loaded
if (!$base->path_exists || !$base->xml_loaded) {
$this->errormsg = 'Directory ' . $dirpath . ' not loaded';
return false;
}
} else {
$this->errormsg = 'Problem handling ' . $select . ' files';
return false;
}
// Get the structure
if ($result) {
if (!$structure = $base->xml_file->getStructure()) {
$this->errormsg = 'Error retrieving ' . $select . ' structure';
$result = false;
}
}
// Get the tables
if ($result) {
if (!$tables = $structure->getTables()) {
$this->errormsg = 'Error retrieving ' . $select . ' tables';
$result = false;
}
}
// Get the table
if ($result && !$t = $structure->getTable($table)) {
$this->errormsg = 'Error retrieving ' . $table . ' table';
$result = false;
}
// Get the keys
if ($result) {
if (!$keys = $t->getKeys()) {
$this->errormsg = 'Error retrieving ' . $select . ' keys';
$result = false;
}
}
// Get the key
if ($result && !$k = $t->getKey($key)) {
$this->errormsg = 'Error retrieving ' . $key . ' key';
$result = false;
}
if ($result) {
// Everything is ok. Generate the XML output
$this->output = $k->xmlOutput();
} else {
// Switch to HTML and error
$this->does_generate = ACTION_GENERATE_HTML;
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,133 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will show all the reserved words in a format suitable to
* be pasted to: http://docs.moodle.org/en/XMLDB_reserved_words and
* http://docs.moodle.org/en/Database_reserved_words
* Also, it introspects te DB looking for such words and informing about
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_reserved_words extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'listreservedwords' => 'tool_xmldb',
'wrongreservedwords' => 'tool_xmldb',
'table' => 'tool_xmldb',
'field' => 'tool_xmldb',
'back' => 'tool_xmldb'
));
}
/**
* 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;
// Calculate list of available SQL generators
require_once("$CFG->libdir/ddl/sql_generator.php");
$reserved_words = sql_generator::getAllReservedWords();
// Now, calculate, looking into current DB (with AdoDB Metadata), which fields are
// in the list of reserved words
$wronguses = array();
$dbtables = $DB->get_tables();
if ($dbtables) {
foreach ($dbtables as $table) {
if (array_key_exists($table, $reserved_words)) {
$wronguses[] = $this->str['table'] . ' - ' . $table . ' (' . implode(', ',$reserved_words[$table]) . ')';
}
$dbfields = $DB->get_columns($table);
if ($dbfields) {
foreach ($dbfields as $dbfield) {
if (array_key_exists($dbfield->name, $reserved_words)) {
$wronguses[] = $this->str['field'] . ' - ' . $table . '->' . $dbfield->name . ' (' . implode(', ',$reserved_words[$dbfield->name]) . ')';
}
}
}
}
}
// Sort the wrong uses
sort($wronguses);
// The back to edit table button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o = $b;
// The list of currently wrong field names
if ($wronguses) {
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$o.= ' <tr><td align="center"><font color="red">' . $this->str['wrongreservedwords'] . '</font></td></tr>';
$o.= ' <tr><td>';
$o.= ' <ul><li>' . implode('</li><li>', $wronguses) . '</li></ul>';
$o.= ' </td></tr>';
$o.= ' </table>';
}
// The textarea showing all the reserved words
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$o.= ' <tr><td align="center">' . $this->str['listreservedwords'].'</td></tr>';
$o .= ' <tr><td><textarea cols="80" rows="32" class="form-control">';
$o.= s(implode(', ', array_keys($reserved_words)));
$o.= '</textarea></td></tr>';
$o.= ' </table>';
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,314 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will show the PHP needed (upgrade block) to perform
* the desired DDL action with the specified table
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_structure_php extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'selectaction' => 'tool_xmldb',
'selecttable' => 'tool_xmldb',
'view' => 'tool_xmldb',
'back' => 'tool_xmldb'
));
}
/**
* 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, $OUTPUT;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tables = $structure->getTables();
$table = reset($tables);
$defaulttable = null;
if ($table) {
$defaulttable = $table->getName();
}
// Get parameters
$commandparam = optional_param('command', 'create_table', PARAM_PATH);
$tableparam = optional_param('table', $defaulttable, PARAM_PATH);
// The back to edit xml button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o = $b;
// Calculate the popup of commands
$commands = array('create_table',
'drop_table',
'rename_table');
foreach ($commands as $command) {
$popcommands[$command] = str_replace('_', ' ', $command);
}
// Calculate the popup of tables
foreach ($tables as $table) {
$poptables[$table->getName()] = $table->getName();
}
// Now build the form
$o.= '<form id="form" action="index.php" method="post">';
$o.='<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="action" value="view_structure_php" />';
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$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>';
$o.= ' <tr><td colspan="2" align="center"><input type="submit" value="' .$this->str['view'] . '" /></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
$o.= ' <table id="phpcode" class="boxaligncenter" cellpadding="5">';
$o .= ' <tr><td><textarea cols="80" rows="32" class="form-control">';
// Based on current params, call the needed function
switch ($commandparam) {
case 'create_table':
$o.= s($this->create_table_php($structure, $tableparam));
break;
case 'drop_table':
$o.= s($this->drop_table_php($structure, $tableparam));
break;
case 'rename_table':
$o.= s($this->rename_table_php($structure, $tableparam));
break;
}
$o.= '</textarea></td></tr>';
$o.= ' </table>';
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
/**
* This function will generate all the PHP code needed to
* create one table using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table code to be created
* @return string PHP code to be used to create the table
*/
function create_table_php($structure, $table) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define table ' . $table->getName() . ' to be created.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= XMLDB_LINEFEED;
$result .= ' // Adding fields to table ' . $table->getName() . '.' . XMLDB_LINEFEED;
// Iterate over each field
foreach ($table->getFields() as $field) {
// The field header, with name
$result .= ' $table->add_field(' . "'" . $field->getName() . "', ";
// The field PHP specs
$result .= $field->getPHP(false);
// The end of the line
$result .= ');' . XMLDB_LINEFEED;
}
// Iterate over each key
if ($keys = $table->getKeys()) {
$result .= XMLDB_LINEFEED;
$result .= ' // Adding keys to table ' . $table->getName() . '.' . XMLDB_LINEFEED;
foreach ($keys as $key) {
// The key header, with name
$result .= ' $table->add_key(' . "'" . $key->getName() . "', ";
// The key PHP specs
$result .= $key->getPHP();
// The end of the line
$result .= ');' . XMLDB_LINEFEED;
}
}
// Iterate over each index
if ($indexes = $table->getIndexes()) {
$result .= XMLDB_LINEFEED;
$result .= ' // Adding indexes to table ' . $table->getName() . '.' . XMLDB_LINEFEED;
foreach ($indexes as $index) {
// The index header, with name
$result .= ' $table->add_index(' . "'" . $index->getName() . "', ";
// The index PHP specs
$result .= $index->getPHP();
// The end of the line
$result .= ');' . XMLDB_LINEFEED;
}
}
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Conditionally launch create table for ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' if (!$dbman->table_exists($table)) {' . XMLDB_LINEFEED;
$result .= ' $dbman->create_table($table);' . XMLDB_LINEFEED;
$result .= ' }' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* drop one table using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table code to be dropped
* @return string PHP code to be used to drop the table
*/
function drop_table_php($structure, $table) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define table ' . $table->getName() . ' to be dropped.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Conditionally launch drop table for ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' if ($dbman->table_exists($table)) {' . XMLDB_LINEFEED;
$result .= ' $dbman->drop_table($table);' . XMLDB_LINEFEED;
$result .= ' }' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* rename one table using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table code to be renamed
* @return string PHP code to be used to rename the table
*/
function rename_table_php($structure, $table) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define table ' . $table->getName() . ' to be renamed to NEWNAMEGOESHERE.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch rename table for ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->rename_table($table, ' . "'NEWNAMEGOESHERE'" . ');' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
}
@@ -0,0 +1,114 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will show the SQL generated for the selected RDBMS for
* the entire XMLDB file
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_structure_sql extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'selectdb' => 'tool_xmldb',
'back' => 'tool_xmldb'
));
}
/**
* 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;
$dbman = $DB->get_manager();
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// The back to edit table button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php?action=edit_xml_file&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o = $b;
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$o .= ' <tr><td><textarea cols="80" rows="32" class="form-control">';
// Get an array of statements
if ($starr = $DB->get_manager()->generator->getCreateStructureSQL($structure)) {
$starr = $dbman->generator->getEndedStatements($starr);
$sqltext = '';
foreach ($starr as $st) {
$sqltext .= s($st) . "\n\n";
}
$sqltext = trim($sqltext);
$o.= $sqltext;
}
$o.= '</textarea></td></tr>';
$o.= ' </table>';
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,115 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will display the XML for one structure
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_structure_xml extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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_XML;
// These are always here
global $CFG, $XMLDB;
// Do the job, setting result as needed
// Get the file parameter
$select = required_param('select', PARAM_ALPHA); //original/edited
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dir
if ($select == 'original') {
if (!empty($XMLDB->dbdirs)) {
$base = $XMLDB->dbdirs[$dirpath];
}
} else if ($select == 'edited') {
if (!empty($XMLDB->editeddirs)) {
$base = $XMLDB->editeddirs[$dirpath];
}
} else {
$this->errormsg = 'Cannot access to ' . $select . ' info';
$result = false;
}
if ($base) {
// Only if the directory exists and it has been loaded
if (!$base->path_exists || !$base->xml_loaded) {
$this->errormsg = 'Directory ' . $dirpath . ' not loaded';
return false;
}
} else {
$this->errormsg = 'Problem handling ' . $select . ' files';
return false;
}
// Get the structure
if ($result) {
if (!$structure = $base->xml_file->getStructure()) {
$this->errormsg = 'Error retrieving ' . $select . ' structure';
$result = false;
}
}
if ($result) {
// Everything is ok. Generate the XML output
$this->output = $structure->xmlOutput();
} else {
// Switch to HTML and error
$this->does_generate = ACTION_GENERATE_HTML;
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,921 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will show the PHP needed (upgrade block) to perform
* the desired DDL action with the specified field/key/index
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_table_php extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'selectaction' => 'tool_xmldb',
'selectfieldkeyindex' => 'tool_xmldb',
'view' => 'tool_xmldb',
'table' => 'tool_xmldb',
'selectonecommand' => 'tool_xmldb',
'selectonefieldkeyindex' => 'tool_xmldb',
'mustselectonefield' => 'tool_xmldb',
'mustselectonekey' => 'tool_xmldb',
'mustselectoneindex' => 'tool_xmldb',
'back' => 'tool_xmldb'
));
}
/**
* 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, $OUTPUT;
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
$tableparam = required_param('table', PARAM_PATH);
$table = $structure->getTable($tableparam);
$fields = $table->getFields();
$field = reset($fields);
$defaultfieldkeyindex = null;
if ($field) {
$defaultfieldkeyindex = 'f#' . $field->getName();
}
$keys = $table->getKeys();
$indexes = $table->getIndexes();
// Get parameters
$commandparam = optional_param('command', 'add_field', PARAM_PATH);
$origfieldkeyindexparam = optional_param('fieldkeyindex', $defaultfieldkeyindex, PARAM_PATH);
$fieldkeyindexparam = preg_replace('/[fki]#/i', '', $origfieldkeyindexparam); // Strip the initials
$fieldkeyindexinitial = substr($origfieldkeyindexparam, 0, 1); //To know what we have selected
// The back to edit xml button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php?action=edit_table&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '&amp;table=' . $tableparam . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o = $b;
// The table currently being edited
$o .= '<h3 class="main">' . $this->str['table'] . ': ' . s($tableparam) . '</h3>';
// To indent the menu selections
$optionspacer = '&nbsp;&nbsp;&nbsp;';
// Calculate the popup of commands
$commands = array('Fields',
$optionspacer . 'add_field',
$optionspacer . 'drop_field',
$optionspacer . 'rename_field',
$optionspacer . 'change_field_type',
$optionspacer . 'change_field_precision',
$optionspacer . 'change_field_notnull',
$optionspacer . 'change_field_default',
'Keys',
$optionspacer . 'add_key',
$optionspacer . 'drop_key',
$optionspacer . 'rename_key',
'Indexes',
$optionspacer . 'add_index',
$optionspacer . 'drop_index',
$optionspacer . 'rename_index');
foreach ($commands as $command) {
$popcommands[str_replace($optionspacer, '', $command)] = str_replace('_', ' ', $command);
}
// Calculate the popup of fields/keys/indexes
if ($fields) {
$popfields['fieldshead'] = 'Fields';
foreach ($fields as $field) {
$popfields['f#' . $field->getName()] = $optionspacer . $field->getName();
}
}
if ($keys) {
$popfields['keyshead'] = 'Keys';
foreach ($keys as $key) {
$popfields['k#' . $key->getName()] = $optionspacer . $key->getName();
}
}
if ($indexes) {
$popfields['indexeshead'] = 'Indexes';
foreach ($indexes as $index) {
$popfields['i#' . $index->getName()] = $optionspacer . $index->getName();
}
}
// Now build the form
$o.= '<form id="form" action="index.php" method="post">';
$o.= '<div>';
$o.= ' <input type="hidden" name ="dir" value="' . str_replace($CFG->dirroot, '', $dirpath) . '" />';
$o.= ' <input type="hidden" name ="table" value="' . s($tableparam) . '" />';
$o.= ' <input type="hidden" name ="action" value="view_table_php" />';
$o .= ' <table id="formelements" cellpadding="5">';
$o.= ' <tr><td><label for="menucommand" accesskey="c">' . $this->str['selectaction'] .' </label>' . html_writer::select($popcommands, 'command', $commandparam, false) . '&nbsp;<label for="menufieldkeyindex" accesskey="f">' . $this->str['selectfieldkeyindex'] . ' </label>' .html_writer::select($popfields, 'fieldkeyindex', $origfieldkeyindexparam, false) . '</td></tr>';
$o.= ' <tr><td colspan="2" align="center"><input type="submit" value="' .$this->str['view'] . '" /></td></tr>';
$o.= ' </table>';
$o.= '</div></form>';
$o.= ' <table id="phpcode" class="boxaligncenter" cellpadding="5">';
$o .= ' <tr><td><textarea cols="80" rows="32" class="form-control">';
// Check we have selected some field/key/index from the popup
if ($fieldkeyindexparam == 'fieldshead' || $fieldkeyindexparam == 'keyshead' || $fieldkeyindexparam == 'indexeshead') {
$o.= s($this->str['selectonefieldkeyindex']);
// Check we have selected some command from the popup
} else if ($commandparam == 'Fields' || $commandparam == 'Keys' || $commandparam == 'Indexes') {
$o.= s($this->str['selectonecommand']);
} else {
// Based on current params, call the needed function
switch ($commandparam) {
case 'add_field':
if ($fieldkeyindexinitial == 'f') { //Only if we have got one field
$o.= s($this->add_field_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'drop_field':
if ($fieldkeyindexinitial == 'f') { //Only if we have got one field
$o.= s($this->drop_field_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'rename_field':
if ($fieldkeyindexinitial == 'f') { //Only if we have got one field
$o.= s($this->rename_field_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'change_field_type':
if ($fieldkeyindexinitial == 'f') { //Only if we have got one field
$o.= s($this->change_field_type_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'change_field_precision':
if ($fieldkeyindexinitial == 'f') { //Only if we have got one field
$o.= s($this->change_field_precision_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'change_field_notnull':
if ($fieldkeyindexinitial == 'f') { // Only if we have got one field
$o.= s($this->change_field_notnull_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'change_field_default':
if ($fieldkeyindexinitial == 'f') { // Only if we have got one field
$o.= s($this->change_field_default_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonefield'];
}
break;
case 'add_key':
if ($fieldkeyindexinitial == 'k') { // Only if we have got one key
$o.= s($this->add_key_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonekey'];
}
break;
case 'drop_key':
if ($fieldkeyindexinitial == 'k') { // Only if we have got one key
$o.= s($this->drop_key_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonekey'];
}
break;
case 'rename_key':
if ($fieldkeyindexinitial == 'k') { // Only if we have got one key
$o.= s($this->rename_key_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectonekey'];
}
break;
case 'add_index':
if ($fieldkeyindexinitial == 'i') { // Only if we have got one index
$o.= s($this->add_index_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectoneindex'];
}
break;
case 'drop_index':
if ($fieldkeyindexinitial == 'i') { // Only if we have got one index
$o.= s($this->drop_index_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectoneindex'];
}
break;
case 'rename_index':
if ($fieldkeyindexinitial == 'i') { // Only if we have got one index
$o.= s($this->rename_index_php($structure, $tableparam, $fieldkeyindexparam));
} else {
$o.= $this->str['mustselectoneindex'];
}
break;
}
}
$o.= '</textarea></td></tr>';
$o.= ' </table>';
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
/**
* This function will generate all the PHP code needed to
* create one field using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to be created
* @return string PHP code to be used to create the field
*/
function add_field_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define field ' . $field->getName() . ' to be added to ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "', " . $field->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Conditionally launch add field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' if (!$dbman->field_exists($table, $field)) {'. XMLDB_LINEFEED;
$result .= ' $dbman->add_field($table, $field);' . XMLDB_LINEFEED;
$result .= ' }'. XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* drop one field using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to be dropped
* @return string PHP code to be used to drop the field
*/
function drop_field_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define field ' . $field->getName() . ' to be dropped from ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "'" . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Conditionally launch drop field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' if ($dbman->field_exists($table, $field)) {' . XMLDB_LINEFEED;
$result .= ' $dbman->drop_field($table, $field);' . XMLDB_LINEFEED;
$result .= ' }' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* rename one field using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to be renamed
* @return string PHP code to be used to rename the field
*/
function rename_field_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Rename field ' . $field->getName() . ' on table ' . $table->getName() . ' to NEWNAMEGOESHERE.'. XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "', " . $field->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch rename field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->rename_field($table, $field, ' . "'" . 'NEWNAMEGOESHERE' . "'" . ');' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* change the type of one field using XMLDB objects and functions.
* Currently these conversions are supported:
* integer to char
* char to integer
* number to char
* char to number
* float to char
* char to float
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to change precision
*/
function change_field_type_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Calculate the type tip text
$type = $field->getXMLDBTypeName($field->getType());
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Changing type of field ' . $field->getName() . ' on table ' . $table->getName() . ' to ' . $type . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "', " . $field->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch change of type for field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->change_field_type($table, $field);' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* change the precision of one field using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to change precision
*/
function change_field_precision_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Calculate the precision tip text
$precision = '(' . $field->getLength();
if ($field->getDecimals()) {
$precision .= ', ' . $field->getDecimals();
}
$precision .= ')';
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Changing precision of field ' . $field->getName() . ' on table ' . $table->getName() . ' to ' . $precision . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "', " . $field->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch change of precision for field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->change_field_precision($table, $field);' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* change the nullability of one field using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to change null/not null
*/
function change_field_notnull_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Calculate the notnull tip text
$notnull = $field->getNotnull() ? 'not null' : 'null';
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Changing nullability of field ' . $field->getName() . ' on table ' . $table->getName() . ' to ' . $notnull . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "', " . $field->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch change of nullability for field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->change_field_notnull($table, $field);' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* change the default of one field using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string field field name to change null/not null
*/
function change_field_default_php($structure, $table, $field) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$field = $table->getField($field)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Calculate the default tip text
$default = $field->getDefault() === null ? 'drop it' : $field->getDefault();
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Changing the default of field ' . $field->getName() . ' on table ' . $table->getName() . ' to ' . $default . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $field = new xmldb_field(' . "'" . $field->getName() . "', " . $field->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch change of default for field ' . $field->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->change_field_default($table, $field);' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* create one key using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string key key name to be created
* @return string PHP code to be used to create the key
*/
function add_key_php($structure, $table, $key) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$key = $table->getKey($key)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define key ' . $key->getName() . ' ('. $key->getXMLDBKeyName($key->getType()) . ') to be added to ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $key = new xmldb_key(' . "'" . $key->getName() . "', " . $key->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch add key ' . $key->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->add_key($table, $key);' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* drop one key using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string key key name to be dropped
* @return string PHP code to be used to drop the key
*/
function drop_key_php($structure, $table, $key) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$key = $table->getKey($key)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define key ' . $key->getName() . ' ('. $key->getXMLDBKeyName($key->getType()) . ') to be dropped form ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $key = new xmldb_key(' . "'" . $key->getName() . "', " . $key->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch drop key ' . $key->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->drop_key($table, $key);' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* rename one key using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string key key name to be renamed
* @return string PHP code to be used to rename the key
*/
function rename_key_php($structure, $table, $key) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$key = $table->getKey($key)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Prepend warning. This function isn't usable!
$result .= 'DON\'T USE THIS FUNCTION (IT\'S ONLY EXPERIMENTAL). SOME DBs DON\'T SUPPORT IT!' . XMLDB_LINEFEED . XMLDB_LINEFEED;
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define key ' . $key->getName() . ' ('. $key->getXMLDBKeyName($key->getType()) . ') to be renamed to NEWNAMEGOESHERE.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $key = new xmldb_key(' . "'" . $key->getName() . "', " . $key->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch rename key ' . $key->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->rename_key($table, $key, ' . "'" . 'NEWNAMEGOESHERE' . "'" . ');' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* create one index using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string index index name to be created
* @return string PHP code to be used to create the index
*/
function add_index_php($structure, $table, $index) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$index = $table->getIndex($index)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define index ' . $index->getName() . ' ('. ($index->getUnique() ? 'unique' : 'not unique') . ') to be added to ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $index = new xmldb_index(' . "'" . $index->getName() . "', " . $index->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Conditionally launch add index ' . $index->getName() . '.' . XMLDB_LINEFEED;
$result .= ' if (!$dbman->index_exists($table, $index)) {' . XMLDB_LINEFEED;
$result .= ' $dbman->add_index($table, $index);' . XMLDB_LINEFEED;
$result .= ' }' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* drop one index using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string index index name to be dropped
* @return string PHP code to be used to drop the index
*/
function drop_index_php($structure, $table, $index) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$index = $table->getIndex($index)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define index ' . $index->getName() . ' ('. ($index->getUnique() ? 'unique' : 'not unique') . ') to be dropped form ' . $table->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $index = new xmldb_index(' . "'" . $index->getName() . "', " . $index->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Conditionally launch drop index ' . $index->getName() . '.' . XMLDB_LINEFEED;
$result .= ' if ($dbman->index_exists($table, $index)) {' . XMLDB_LINEFEED;
$result .= ' $dbman->drop_index($table, $index);' . XMLDB_LINEFEED;
$result .= ' }' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
/**
* This function will generate all the PHP code needed to
* rename one index using XMLDB objects and functions
*
* @param xmldb_structure structure object containing all the info
* @param string table table name
* @param string index index name to be renamed
* @return string PHP code to be used to rename the index
*/
function rename_index_php($structure, $table, $index) {
$result = '';
// Validate if we can do it
if (!$table = $structure->getTable($table)) {
return false;
}
if (!$index = $table->getIndex($index)) {
return false;
}
if ($table->getAllErrors()) {
return false;
}
// Prepend warning. This function isn't usable!
$result .= 'DON\'T USE THIS FUNCTION (IT\'S ONLY EXPERIMENTAL). SOME DBs DON\'T SUPPORT IT!' . XMLDB_LINEFEED . XMLDB_LINEFEED;
// Add the standard PHP header
$result .= XMLDB_PHP_HEADER;
// Add contents
$result .= XMLDB_LINEFEED;
$result .= ' // Define index ' . $index->getName() . ' ('. ($index->getUnique() ? 'unique' : 'not unique') . ') to be renamed to NEWNAMEGOESHERE.' . XMLDB_LINEFEED;
$result .= ' $table = new xmldb_table(' . "'" . $table->getName() . "'" . ');' . XMLDB_LINEFEED;
$result .= ' $index = new xmldb_index(' . "'" . $index->getName() . "', " . $index->getPHP(true) . ');' . XMLDB_LINEFEED;
// Launch the proper DDL
$result .= XMLDB_LINEFEED;
$result .= ' // Launch rename index ' . $index->getName() . '.' . XMLDB_LINEFEED;
$result .= ' $dbman->rename_index($table, $index, ' . "'" . 'NEWNAMEGOESHERE' . "'" . ');' . XMLDB_LINEFEED;
// Add the proper upgrade_xxxx_savepoint call
$result .= $this->upgrade_savepoint_php ($structure);
// Add standard PHP footer
$result .= XMLDB_PHP_FOOTER;
return $result;
}
}
@@ -0,0 +1,48 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
// Register the needed events
onload=function() {
// Adjust the form on load
disablePopupHeads();
}
/**
* This function disables some elements from the command and from the fields/keys/indexes drop downs
*/
function disablePopupHeads() {
var popup = document.getElementById("menucommand");
var i = popup.length;
while (i--) {
option = popup[i];
if (option.value == "Fields" || option.value == "Keys" || option.value == "Indexes") {
popup[i].disabled = true;
}
}
popup = document.getElementById("menufieldkeyindex");
i = popup.length;
while (i--) {
option = popup[i];
if (option.value == "fieldshead" || option.value == "keyshead" || option.value == "indexeshead") {
popup[i].disabled = true;
}
}
}
@@ -0,0 +1,122 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will show the SQL generated for the selected RDBMS for
* one table
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_table_sql extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
'selectdb' => 'tool_xmldb',
'back' => 'tool_xmldb'
));
}
/**
* 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;
$dbman = $DB->get_manager();
// Do the job, setting result as needed
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dirs
if (!empty($XMLDB->dbdirs)) {
$dbdir = $XMLDB->dbdirs[$dirpath];
} else {
return false;
}
if (!empty($XMLDB->editeddirs)) {
$editeddir = $XMLDB->editeddirs[$dirpath];
$structure = $editeddir->xml_file->getStructure();
}
// Get parameters
$tableparam = required_param('table', PARAM_PATH);
if (!$table = $structure->getTable($tableparam)) {
$this->errormsg = 'Wrong table specified: ' . $tableparam;
return false;
}
// The back to edit table button
$b = ' <p class="centerpara buttons">';
$b .= '<a href="index.php?action=edit_table&amp;table=' . $tableparam . '&amp;dir=' . urlencode(str_replace($CFG->dirroot, '', $dirpath)) . '">[' . $this->str['back'] . ']</a>';
$b .= '</p>';
$o = $b;
$o.= ' <table id="formelements" class="boxaligncenter" cellpadding="5">';
$o .= ' <tr><td><textarea cols="80" rows="32" class="form-control">';
// Get an array of statements
if ($starr = $DB->get_manager()->generator->getCreateTableSQL($table)) {
$starr = $dbman->generator->getEndedStatements($starr);
$sqltext = '';
foreach ($starr as $st) {
$sqltext .= s($st) . "\n\n";
}
$sqltext = trim($sqltext);
$o.= $sqltext;
}
$o.= '</textarea></td></tr>';
$o.= ' </table>';
$this->output = $o;
// Launch postaction if exists (leave this here!)
if ($this->getPostAction() && $result) {
return $this->launch($this->getPostAction());
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,128 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will display the XML for one table being edited
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_table_xml extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* 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_XML;
// These are always here
global $CFG, $XMLDB;
// Do the job, setting result as needed
// Get the file parameter
$table = required_param('table', PARAM_CLEAN);
$select = required_param('select', PARAM_ALPHA); //original/edited
// Get the dir containing the file
$dirpath = required_param('dir', PARAM_PATH);
$dirpath = $CFG->dirroot . $dirpath;
// Get the correct dir
if ($select == 'original') {
if (!empty($XMLDB->dbdirs)) {
$base = $XMLDB->dbdirs[$dirpath];
}
} else if ($select == 'edited') {
if (!empty($XMLDB->editeddirs)) {
$base = $XMLDB->editeddirs[$dirpath];
}
} else {
$this->errormsg = 'Cannot access to ' . $select . ' info';
$result = false;
}
if ($base) {
// Only if the directory exists and it has been loaded
if (!$base->path_exists || !$base->xml_loaded) {
$this->errormsg = 'Directory ' . $dirpath . ' not loaded';
return false;
}
} else {
$this->errormsg = 'Problem handling ' . $select . ' files';
return false;
}
// Get the structure
if ($result) {
if (!$structure = $base->xml_file->getStructure()) {
$this->errormsg = 'Error retrieving ' . $select . ' structure';
$result = false;
}
}
// Get the tables
if ($result) {
if (!$tables = $structure->getTables()) {
$this->errormsg = 'Error retrieving ' . $select . ' tables';
$result = false;
}
}
// Get the table
if ($result && !$t = $structure->getTable($table)) {
$this->errormsg = 'Error retrieving ' . $table . ' table';
$result = false;
}
if ($result) {
// Everything is ok. Generate the XML output
$this->output = $t->xmlOutput();
} else {
// Switch to HTML and error
$this->does_generate = ACTION_GENERATE_HTML;
}
// Return ok if arrived here
return $result;
}
}
@@ -0,0 +1,89 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* This class will display one XML file
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class view_xml extends XMLDBAction {
/**
* Init method, every subclass will have its own
*/
function init() {
parent::init();
// Set own core attributes
$this->can_subaction = ACTION_NONE;
//$this->can_subaction = ACTION_HAVE_SUBACTIONS;
// Set own custom attributes
$this->sesskey_protected = false; // This action doesn't need sesskey protection
// Get needed strings
$this->loadStrings(array(
// 'key' => 'module',
));
}
/**
* Invoke method, every class will have its own
* returns true/false on completion, setting both
* errormsg and output as necessary
* @return mixed
*/
function invoke() {
parent::invoke();
$result = true;
// Set own core attributes
$this->does_generate = ACTION_GENERATE_XML;
// These are always here
global $CFG, $XMLDB;
// Do the job, setting result as needed
// Get the file parameter
$file = required_param('file', PARAM_PATH);
$fullpath = $CFG->dirroot . $file;
// File param must start with / and end with /db/install.xml to be safe.
if (substr($file, 0, 1) == '/' &&
substr($file, -15, 15) == '/db/install.xml') {
// Everything is ok. Load the file to memory
$this->output = file_get_contents($fullpath);
} else {
// Switch to HTML and error
$this->does_generate = ACTION_GENERATE_HTML;
$this->errormsg = 'File not viewable (' . $file .')';
$result = false;
}
// Return ok if arrived here
return $result;
}
}
+3
View File
@@ -0,0 +1,3 @@
define("tool_xmldb/move",["jquery","core/sortable_list","core/ajax","core/notification"],(function($,SortableList,Ajax,Notification){return{init:function(tableid,moveaction){var origIndex;new SortableList("#"+tableid+" tbody").getElementName=function(element){return $.Deferred().resolve(element.attr("data-name"))},$("#"+tableid+" tbody tr").on(SortableList.EVENTS.DRAGSTART,(function(_,info){origIndex=info.sourceList.children().index(info.element),setTimeout((function(){$(".sortable-list-is-dragged").width(info.element.width())}),501)})).on(SortableList.EVENTS.DROP,(function(_,info){var newIndex=info.targetList.children().index(info.element),t=info.element.find("[data-action="+moveaction+"]");if(info.positionChanged&&t.length){var request={methodname:"tool_xmldb_invoke_move_action",args:{action:moveaction,dir:t.attr("data-dir"),table:t.attr("data-table"),field:t.attr("data-field"),key:t.attr("data-key"),index:t.attr("data-index"),position:newIndex-origIndex}};Ajax.call([request])[0].fail(Notification.exception)}}))}}}));
//# sourceMappingURL=move.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"move.min.js","sources":["../src/move.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\ndefine(['jquery', 'core/sortable_list', 'core/ajax', 'core/notification'], function($, SortableList, Ajax, Notification) {\n return {\n init: function(tableid, moveaction) {\n // Initialise sortable for the given list.\n var sort = new SortableList('#' + tableid + ' tbody');\n sort.getElementName = function(element) {\n return $.Deferred().resolve(element.attr('data-name'));\n };\n var origIndex;\n $('#' + tableid + ' tbody tr').on(SortableList.EVENTS.DRAGSTART, function(_, info) {\n // Remember position of the element in the beginning of dragging.\n origIndex = info.sourceList.children().index(info.element);\n // Resize the \"proxy\" element to be the same width as the main element.\n setTimeout(function() {\n $('.sortable-list-is-dragged').width(info.element.width());\n }, 501);\n }).on(SortableList.EVENTS.DROP, function(_, info) {\n // When a list element was moved send AJAX request to the server.\n var newIndex = info.targetList.children().index(info.element);\n var t = info.element.find('[data-action=' + moveaction + ']');\n if (info.positionChanged && t.length) {\n var request = {\n methodname: 'tool_xmldb_invoke_move_action',\n args: {\n action: moveaction,\n dir: t.attr('data-dir'),\n table: t.attr('data-table'),\n field: t.attr('data-field'),\n key: t.attr('data-key'),\n index: t.attr('data-index'),\n position: newIndex - origIndex\n }\n };\n Ajax.call([request])[0].fail(Notification.exception);\n }\n });\n }\n };\n});\n"],"names":["define","$","SortableList","Ajax","Notification","init","tableid","moveaction","origIndex","getElementName","element","Deferred","resolve","attr","on","EVENTS","DRAGSTART","_","info","sourceList","children","index","setTimeout","width","DROP","newIndex","targetList","t","find","positionChanged","length","request","methodname","args","action","dir","table","field","key","position","call","fail","exception"],"mappings":"AAeAA,yBAAO,CAAC,SAAU,qBAAsB,YAAa,sBAAsB,SAASC,EAAGC,aAAcC,KAAMC,oBAChG,CACHC,KAAM,SAASC,QAASC,gBAMhBC,UAJO,IAAIN,aAAa,IAAMI,QAAU,UACvCG,eAAiB,SAASC,gBACpBT,EAAEU,WAAWC,QAAQF,QAAQG,KAAK,eAG7CZ,EAAE,IAAMK,QAAU,aAAaQ,GAAGZ,aAAaa,OAAOC,WAAW,SAASC,EAAGC,MAEzEV,UAAYU,KAAKC,WAAWC,WAAWC,MAAMH,KAAKR,SAElDY,YAAW,WACPrB,EAAE,6BAA6BsB,MAAML,KAAKR,QAAQa,WACnD,QACJT,GAAGZ,aAAaa,OAAOS,MAAM,SAASP,EAAGC,UAEpCO,SAAWP,KAAKQ,WAAWN,WAAWC,MAAMH,KAAKR,SACjDiB,EAAIT,KAAKR,QAAQkB,KAAK,gBAAkBrB,WAAa,QACrDW,KAAKW,iBAAmBF,EAAEG,OAAQ,KAC9BC,QAAU,CACVC,WAAY,gCACZC,KAAM,CACFC,OAAQ3B,WACR4B,IAAKR,EAAEd,KAAK,YACZuB,MAAOT,EAAEd,KAAK,cACdwB,MAAOV,EAAEd,KAAK,cACdyB,IAAKX,EAAEd,KAAK,YACZQ,MAAOM,EAAEd,KAAK,cACd0B,SAAUd,SAAWjB,YAG7BL,KAAKqC,KAAK,CAACT,UAAU,GAAGU,KAAKrC,aAAasC"}
+54
View File
@@ -0,0 +1,54 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
define(['jquery', 'core/sortable_list', 'core/ajax', 'core/notification'], function($, SortableList, Ajax, Notification) {
return {
init: function(tableid, moveaction) {
// Initialise sortable for the given list.
var sort = new SortableList('#' + tableid + ' tbody');
sort.getElementName = function(element) {
return $.Deferred().resolve(element.attr('data-name'));
};
var origIndex;
$('#' + tableid + ' tbody tr').on(SortableList.EVENTS.DRAGSTART, function(_, info) {
// Remember position of the element in the beginning of dragging.
origIndex = info.sourceList.children().index(info.element);
// Resize the "proxy" element to be the same width as the main element.
setTimeout(function() {
$('.sortable-list-is-dragged').width(info.element.width());
}, 501);
}).on(SortableList.EVENTS.DROP, function(_, info) {
// When a list element was moved send AJAX request to the server.
var newIndex = info.targetList.children().index(info.element);
var t = info.element.find('[data-action=' + moveaction + ']');
if (info.positionChanged && t.length) {
var request = {
methodname: 'tool_xmldb_invoke_move_action',
args: {
action: moveaction,
dir: t.attr('data-dir'),
table: t.attr('data-table'),
field: t.attr('data-field'),
key: t.attr('data-key'),
index: t.attr('data-index'),
position: newIndex - origIndex
}
};
Ajax.call([request])[0].fail(Notification.exception);
}
});
}
};
});
+119
View File
@@ -0,0 +1,119 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_value;
/**
* tool_xmldb external function
*
* @package tool_xmldb
* @copyright 2018 Moodle
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class tool_xmldb_external extends external_api {
/**
* Parameters for the 'tool_xmldb_invoke_move_action' WS
* @return external_function_parameters
*/
public static function invoke_move_action_parameters() {
return new external_function_parameters([
'action' => new external_value(PARAM_ALPHAEXT, 'Action'),
'dir' => new external_value(PARAM_PATH, 'Plugin that is being edited'),
'table' => new external_value(PARAM_NOTAGS, 'Table name'),
'field' => new external_value(PARAM_NOTAGS, 'Field name', VALUE_DEFAULT, ''),
'key' => new external_value(PARAM_NOTAGS, 'Key name', VALUE_DEFAULT, ''),
'index' => new external_value(PARAM_NOTAGS, 'Index name', VALUE_DEFAULT, ''),
'position' => new external_value(PARAM_INT, 'How many positions to move by (negative - up, positive - down)'),
]);
}
/**
* WS 'tool_xmldb_invoke_move_action' that invokes a move action
*
* @param string $action
* @param string $dir
* @param string $table
* @param string $field
* @param string $key
* @param string $index
* @param int $position
* @throws coding_exception
*/
public static function invoke_move_action($action, $dir, $table, $field, $key, $index, $position) {
global $CFG, $XMLDB, $SESSION;
require_once($CFG->libdir.'/ddllib.php');
require_once("$CFG->dirroot/$CFG->admin/tool/xmldb/actions/XMLDBAction.class.php");
require_once("$CFG->dirroot/$CFG->admin/tool/xmldb/actions/XMLDBCheckAction.class.php");
$params = self::validate_parameters(self::invoke_move_action_parameters(), [
'action' => $action,
'dir' => $dir,
'table' => $table,
'field' => $field,
'key' => $key,
'index' => $index,
'position' => $position
]);
self::validate_context(context_system::instance());
require_capability('moodle/site:config', context_system::instance());
if (!in_array($action, ['move_updown_table', 'move_updown_field', 'move_updown_key', 'move_updown_index'])) {
throw new coding_exception('Unsupported action');
}
$action = $params['action'];
$actionsroot = "$CFG->dirroot/$CFG->admin/tool/xmldb/actions";
$actionclass = $action . '.class.php';
$actionpath = "$actionsroot/$action/$actionclass";
if (file_exists($actionpath) && is_readable($actionpath)) {
require_once($actionpath);
}
if (!class_exists($action)) {
throw new coding_exception('Action class not found');
}
if (!isset($SESSION->xmldb)) {
$XMLDB = new stdClass;
} else {
$XMLDB = unserialize($SESSION->xmldb);
}
$_POST['dir'] = $params['dir'];
$_POST['table'] = $params['table'];
$_POST['field'] = $params['field'];
$_POST['key'] = $params['key'];
$_POST['index'] = $params['index'];
$_POST['direction'] = ($params['position'] > 0) ? 'down' : 'up';
for ($i = 0; $i < abs($params['position']); $i++) {
$a = new $action();
$a->invoke();
}
$SESSION->xmldb = serialize($XMLDB);
}
/**
* Return structure for the 'tool_xmldb_invoke_move_action' WS
* @return null
*/
public static function invoke_move_action_returns() {
return null;
}
}
@@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for tool_xmldb.
*
* @package tool_xmldb
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace tool_xmldb\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* Privacy Subsystem for tool_xmldb implementing null_provider.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Tool xmldb external functions and service definitions.
*
* @package tool_xmldb
* @copyright 2018 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
$functions = [
'tool_xmldb_invoke_move_action' => [
'classname' => tool_xmldb_external::class,
'methodname' => 'invoke_move_action',
'description' => 'moves element up/down',
'type' => 'write',
'ajax' => true,
]
];
+123
View File
@@ -0,0 +1,123 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This is the main script for the complete XMLDB interface. From here
* all the actions supported will be launched.
*
* @package tool_xmldb
* @copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com,
* (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../../config.php');
require_once($CFG->libdir.'/adminlib.php');
require_once($CFG->libdir.'/ddllib.php');
// Add required XMLDB action classes
require_once('actions/XMLDBAction.class.php');
require_once('actions/XMLDBCheckAction.class.php');
admin_externalpage_setup('toolxmld');
// Add other used libraries
require_once($CFG->libdir . '/xmlize.php');
// Handle session data
global $XMLDB;
// State is stored in session - we have to serialise it because the classes are not loaded when creating session
if (!isset($SESSION->xmldb)) {
$XMLDB = new stdClass;
} else {
$XMLDB = unserialize($SESSION->xmldb);
}
// Some previous checks
$site = get_site();
// Body of the script, based on action, we delegate the work
$action = optional_param ('action', 'main_view', PARAM_ALPHAEXT);
// Get the action path and invoke it
$actionsroot = "$CFG->dirroot/$CFG->admin/tool/xmldb/actions";
$actionclass = $action . '.class.php';
$actionpath = "$actionsroot/$action/$actionclass";
// Load and invoke the proper action
if (file_exists($actionpath) && is_readable($actionpath)) {
require_once($actionpath);
if ($xmldb_action = new $action) {
// Invoke it
$result = $xmldb_action->invoke();
// store the result in session
$SESSION->xmldb = serialize($XMLDB);
if ($result) {
// Based on getDoesGenerate()
switch ($xmldb_action->getDoesGenerate()) {
case ACTION_GENERATE_HTML:
$action = optional_param('action', '', PARAM_ALPHAEXT);
$postaction = optional_param('postaction', '', PARAM_ALPHAEXT);
// If the js exists, load it
if ($action) {
$script = $CFG->admin . '/tool/xmldb/actions/' . $action . '/' . $action . '.js';
$file = $CFG->dirroot . '/' . $script;
if (file_exists($file) && is_readable($file)) {
$PAGE->requires->js('/'.$script);
} else if ($postaction) {
// Try to load the postaction javascript if exists
$script = $CFG->admin . '/tool/xmldb/actions/' . $postaction . '/' . $postaction . '.js';
$file = $CFG->dirroot . '/' . $script;
if (file_exists($file) && is_readable($file)) {
$PAGE->requires->js('/'.$script);
}
}
}
// Go with standard admin header
echo $OUTPUT->header();
echo $OUTPUT->heading($xmldb_action->getTitle());
echo $xmldb_action->getOutput();
echo $OUTPUT->footer();
break;
case ACTION_GENERATE_XML:
header('Content-type: application/xhtml+xml; charset=utf-8');
echo $xmldb_action->getOutput();
break;
}
} else {
// TODO: need more detailed error info
throw new \moodle_exception('xmldberror');
}
} else {
$a = new stdClass();
$a->action = $action;
$a->actionclass = $actionclass;
throw new \moodle_exception('cannotinstantiateclass', 'tool_xmldb', '', $a);
}
} else {
throw new \moodle_exception('invalidaction');
}
if ($xmldb_action->getDoesGenerate() != ACTION_GENERATE_XML) {
if (debugging()) {
// print_object($XMLDB);
}
}
+235
View File
@@ -0,0 +1,235 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'tool_xmldb', language 'en', branch 'MOODLE_22_STABLE'
*
* @package tool_xmldb
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['actual'] = 'Actual';
$string['addpersistent'] = 'Add mandatory persistent fields';
$string['aftertable'] = 'After table:';
$string['back'] = 'Back';
$string['backtomainview'] = 'Back to main';
$string['cannotuseidfield'] = 'Cannot insert the "id" field. It is an autonumeric column';
$string['completelogbelow'] = '(see the complete log of the search below)';
$string['confirmdeletefield'] = 'Are you absolutely sure that you want to delete the field:';
$string['confirmdeleteindex'] = 'Are you absolutely sure that you want to delete the index:';
$string['confirmdeletekey'] = 'Are you absolutely sure that you want to delete the key:';
$string['confirmdeletetable'] = 'Are you absolutely sure that you want to delete the table:';
$string['confirmdeletexmlfile'] = 'Are you absolutely sure that you want to delete the file:';
$string['confirmcheckbigints'] = 'This functionality will search for <a href="https://tracker.moodle.org/browse/MDL-11038">potential wrong integer fields</a> in your Moodle server, generating (but not executing!) automatically the needed SQL statements to have all the integers in your DB properly defined.
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of wrong integers.
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
$string['confirmcheckdefaults'] = 'This functionality will search for inconsistent default values in your Moodle server, generating (but not executing!) the needed SQL statements to have all the default values properly defined.
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of inconsistent default values.
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
$string['confirmcheckforeignkeys'] = 'This functionality will search for potential violations of the foreign keys defined in the install.xml definitions. (Moodle does not currently generate actual foreign key constraints in the database, which is why invalid data may be present.)
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search for potential violations of the foreign keys.
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
$string['confirmcheckindexes'] = 'This functionality will search for potential missing indexes in your Moodle server, generating (but not executing!) automatically the needed SQL statements to keep everything updated.
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of missing indexes.
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
$string['confirmcheckoraclesemantics'] = 'This functionality will search for <a href="https://tracker.moodle.org/browse/MDL-29322">Oracle varchar2 columns using BYTE semantics</a> in your Moodle server, generating (but not executing!) automatically the needed SQL statements to have all the columns converted to use CHAR semantics instead (better for cross-db compatibility and increased contents max. length).
Once generated you can copy such statements and execute them safely with your favourite SQL interface (don\'t forget to backup your data before doing that).
It\'s highly recommended to be running the latest (+ version) available of your Moodle release before executing the search of BYTE semantics.
This functionality doesn\'t perform any action against the DB (just reads from it), so can be safely executed at any moment.';
$string['confirmrevertchanges'] = 'Are you absolutely sure that you want to revert changes performed over:';
$string['create'] = 'Create';
$string['createtable'] = 'Create table:';
$string['defaultincorrect'] = 'Incorrect default';
$string['delete'] = 'Delete';
$string['delete_field'] = 'Delete field';
$string['delete_index'] = 'Delete index';
$string['delete_key'] = 'Delete key';
$string['delete_table'] = 'Delete table';
$string['delete_xml_file'] = 'Delete XML file';
$string['doc'] = 'Doc';
$string['docindex'] = 'Documentation index:';
$string['documentationintro'] = 'This documentation is generated automatically from the XMLDB database definition. It is available only in English.';
$string['down'] = 'Down';
$string['duplicate'] = 'Duplicate';
$string['duplicatefieldname'] = 'Another field with that name exists';
$string['duplicatefieldsused'] = 'Duplicate fields used';
$string['duplicatekeyname'] = 'Another key with that name exists';
$string['duplicatetablename'] = 'Another table with that name exists';
$string['edit'] = 'Edit';
$string['edit_field'] = 'Edit field';
$string['edit_field_save'] = 'Save field';
$string['edit_index'] = 'Edit index';
$string['edit_index_save'] = 'Save index';
$string['edit_key'] = 'Edit key';
$string['edit_key_save'] = 'Save key';
$string['edit_table'] = 'Edit table';
$string['edit_table_save'] = 'Save table';
$string['edit_xml_file'] = 'Edit XML file';
$string['enumvaluesincorrect'] = 'Incorrect values for enum field';
$string['expected'] = 'Expected';
$string['extensionrequired'] = 'Sorry - the PHP extension \'{$a}\' is required for this action. Please install the extension if you want to use this feature.';
$string['extraindexesfound'] = 'Extra indexes found';
$string['field'] = 'Field';
$string['fieldnameempty'] = 'Name field empty';
$string['fields'] = 'Fields';
$string['fieldsnotintable'] = 'Field doesn\'t exist in table';
$string['fieldsusedinindex'] = 'This field is used as index';
$string['fieldsusedinkey'] = 'This field is used as key.';
$string['filemodifiedoutfromeditor'] = 'Warning: File locally modified while using the XMLDB Editor. Saving will overwrite local changes.';
$string['filenotwriteable'] = 'File not writeable';
$string['fkunknownfield'] = 'Foreign key {$a->keyname} on table {$a->tablename} points to a non-existent field {$a->reffield} in referenced table {$a->reftable}.';
$string['fkunknowntable'] = 'Foreign key {$a->keyname} on table {$a->tablename} points to a non-existent table {$a->reftable}.';
$string['fkviolationdetails'] = 'Foreign key {$a->keyname} on table {$a->tablename} is violated by {$a->numviolations} out of {$a->numrows} rows.';
$string['floatincorrectdecimals'] = 'Incorrect number of decimals for float field';
$string['floatincorrectlength'] = 'Incorrect length for float field';
$string['float2numbernote'] = 'Notice: Although "float" fields are 100% supported by XMLDB, it\'s recommended to migrate to "number" fields instead.';
$string['generate_all_documentation'] = 'All the documentation';
$string['generate_documentation'] = 'Documentation';
$string['gotolastused'] = 'Go to last used file';
$string['change'] = 'Change';
$string['charincorrectlength'] = 'Incorrect length for char field';
$string['checkbigints'] = 'Check integers';
$string['check_bigints'] = 'Look for incorrect DB integers';
$string['checkdefaults'] = 'Check defaults';
$string['check_defaults'] = 'Look for inconsistent default values';
$string['checkforeignkeys'] = 'Check foreign keys';
$string['check_foreign_keys'] = 'Look for foreign key violations';
$string['checkindexes'] = 'Check indexes';
$string['check_indexes'] = 'Look for missing DB indexes';
$string['checkoraclesemantics'] = 'Check semantics';
$string['check_oracle_semantics'] = 'Look for incorrect length semantics';
$string['duplicateindexname'] = 'Duplicate index name';
$string['incorrectfieldname'] = 'Incorrect name';
$string['index'] = 'Index';
$string['indexes'] = 'Indexes';
$string['indexnameempty'] = 'Index name is empty';
$string['integerincorrectlength'] = 'Incorrect length for integer field';
$string['incorrectindexname'] = 'Incorrect index name';
$string['incorrectkeyname'] = 'Incorrect key name';
$string['incorrecttablename'] = 'Incorrect table name';
$string['key'] = 'Key';
$string['keynameempty'] = 'The key name cannot be empty';
$string['keys'] = 'Keys';
$string['listreservedwords'] = 'List of reserved words<br />(used to keep <a href="https://docs.moodle.org/en/XMLDB_reserved_words" target="_blank">XMLDB reserved words</a> updated)';
$string['load'] = 'Load';
$string['main_view'] = 'Main view';
$string['masterprimaryuniqueordernomatch'] = 'The fields in your foreign key must be listed in the same order as they are listed in the UNIQUE KEY on the referenced table.';
$string['missing'] = 'Missing';
$string['missingindexes'] = 'Missing indexes found';
$string['mustselectonefield'] = 'You must select one field to see field related actions!';
$string['mustselectoneindex'] = 'You must select one index to see index related actions!';
$string['mustselectonekey'] = 'You must select one key to see key related actions!';
$string['newfield'] = 'New field';
$string['newindex'] = 'New index';
$string['newkey'] = 'New key';
$string['newtable'] = 'New table';
$string['newtablefrommysql'] = 'New table from MySQL';
$string['new_table_from_mysql'] = 'New table from MySQL';
$string['nofieldsspecified'] = 'No fields specified';
$string['nomasterprimaryuniquefound'] = 'The column(s) that your foreign key references must be included in a primary or unique KEY in the referenced table. Note that the column being in a UNIQUE INDEX is not good enough.';
$string['nomissingorextraindexesfound'] = 'No missing or extra indexes have been found, so no further action is required.';
$string['noreffieldsspecified'] = 'No reference fields specified';
$string['noreftablespecified'] = 'Specified reference table not found';
$string['noviolatedforeignkeysfound'] = 'No violated foreign keys found';
$string['nowrongdefaultsfound'] = 'No inconsistent default values have been found, your DB does not need further actions.';
$string['nowrongintsfound'] = 'No wrong integers have been found, your DB doesn\'t need further actions.';
$string['nowrongoraclesemanticsfound'] = 'No Oracle columns using BYTE semantics have been found, your DB doesn\'t need further actions.';
$string['numberincorrectdecimals'] = 'Incorrect number of decimals for number field';
$string['numberincorrectlength'] = 'Incorrect length for number field';
$string['numberincorrectwholepart'] = 'Too big whole number part for number field';
$string['pendingchanges'] = 'Note: You have performed changes to this file. They can be saved at any moment.';
$string['pendingchangescannotbesaved'] = 'There are changes in this file but they cannot be saved! Please verify that both the directory and the "install.xml" within it have write permissions for the web server.';
$string['pendingchangescannotbesavedreload'] = 'There are changes in this file but they cannot be saved! Please verify that both the directory and the "install.xml" within it have write permissions for the web server. Then reload this page and you should be able to save those changes.';
$string['persistentfieldsconfirm'] = 'Do you want to add the following fields: ';
$string['persistentfieldscomplete'] = 'The following fields have been added: ';
$string['persistentfieldsexist'] = 'The following fields already exist: ';
$string['pluginname'] = 'XMLDB editor';
$string['primarykeyonlyallownotnullfields'] = 'Primary keys cannot be null';
$string['reconcilefiles'] = 'Reconcile XMLDB files';
$string['reconcile_files'] = 'Look for XMLDB files needing reconciling';
$string['reconcile_files_intro'] = 'This functionality looks though the contents of all XMLDB files to verify that they match the results of generating them from the XMLDB editor.
A list of files needing to be reconciled (regenerated) will be displayed and the XMLDB editor can be used to fix them.';
$string['reconcile_files_no'] = 'All files are OK. No reconciling is needed.';
$string['reconcile_files_yes'] = 'Found files to reconcile: ';
$string['reserved'] = 'Reserved';
$string['reservedwords'] = 'Reserved words';
$string['revert'] = 'Revert';
$string['revert_changes'] = 'Revert changes';
$string['save'] = 'Save';
$string['searchresults'] = 'Search results';
$string['selectaction'] = 'Select action:';
$string['selectdb'] = 'Select database:';
$string['selectfieldkeyindex'] = 'Select field/key/index:';
$string['selectonecommand'] = 'Please select one action from the list to view PHP code';
$string['selectonefieldkeyindex'] = 'Please select one field/key/index from the list to view the PHP code';
$string['selecttable'] = 'Select table:';
$string['table'] = 'Table';
$string['tablenameempty'] = 'The table name cannot be empty';
$string['tables'] = 'Tables';
$string['unknownfield'] = 'Refers to an unknown field';
$string['unknowntable'] = 'Refers to an unknown table';
$string['unload'] = 'Unload';
$string['up'] = 'Up';
$string['view'] = 'View';
$string['viewedited'] = 'View edited';
$string['vieworiginal'] = 'View original';
$string['viewphpcode'] = 'View PHP code';
$string['view_reserved_words'] = 'View reserved words';
$string['viewsqlcode'] = 'View SQL code';
$string['view_structure_php'] = 'View structure PHP';
$string['view_structure_sql'] = 'View structure SQL';
$string['view_table_php'] = 'View table PHP';
$string['view_table_sql'] = 'View table SQL';
$string['viewxml'] = 'XML';
$string['violatedforeignkeys'] = 'Violated foreign keys';
$string['violatedforeignkeysfound'] = 'Violated foreign keys found';
$string['violations'] = 'Violations';
$string['wrong'] = 'Wrong';
$string['wrongdefaults'] = 'Wrong defaults found';
$string['wrongints'] = 'Wrong integers found';
$string['wronglengthforenum'] = 'Incorrect length for enum field';
$string['wrongnumberofreffields'] = 'Wrong number of reference fields';
$string['wrongreservedwords'] = 'Currently used reserved words<br />(note that table names aren\'t important if using $CFG->prefix)';
$string['wrongoraclesemantics'] = 'Wrong Oracle BYTE semantics found';
$string['yesextraindexesfound'] = 'The following additional indexes were found.';
$string['yesmissingindexesfound'] = '<p>Some missing indexes have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to create all of them. Remember to backup your data first!</p>
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more missing indexes are found.</p>';
$string['yeswrongdefaultsfound'] = '<p>Some inconsistent defaults have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to fix them all. Remember to backup your data first!</p>
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more inconsistent defaults are found.</p>';
$string['yeswrongintsfound'] = '<p>Some wrong integers have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to fix them. Remember to backup your data first!</p>
<p>After fixing them, it is highly recommended to execute this utility again to check that no more wrong integers are found.</p>';
$string['yeswrongoraclesemanticsfound'] = '<p>Some Oracle columns using BYTE semantics have been found in your DB. Here are their details and the needed SQL statements to be executed with your favourite SQL interface to convert them all. Remember to backup your data first!</p>
<p>After doing that, it\'s highly recommended to execute this utility again to check that no more wrong semantics are found.</p>';
$string['privacy:metadata'] = 'The XMLDB editor plugin does not store any personal data.';
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Link to xmldb editor
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($hassiteconfig) {
$ADMIN->add('development', new admin_externalpage('toolxmld', get_string('pluginname', 'tool_xmldb'), "$CFG->wwwroot/$CFG->admin/tool/xmldb/"));
}
+3
View File
@@ -0,0 +1,3 @@
.path-admin-tool-xmldb a[name="lastused"] {
padding-top: 50px;
}
@@ -0,0 +1,3 @@
.path-admin-tool-xmldb a[name="lastused"] {
padding-top: 50px;
}
@@ -0,0 +1,71 @@
@tool @tool_xmldb
Feature: Adding mandatory persistent fields to tables
In order for me to be able to create database tables for a persistent class
As a developer
I need to be able to add fields that are mandatory for the persistent class that I am developing
Background:
Given I log in as "admin"
And I navigate to "Development > XMLDB editor" in site administration
And I click on "Load" "link" in the "admin/tool/cohortroles/db" "table_row"
And I follow "admin/tool/cohortroles/db"
And I follow "New table"
Scenario: Cancel adding of mandatory persistent fields
Given I follow "Add mandatory persistent fields"
And I should see "usermodified"
And I should see "timecreated"
And I should see "timemodified"
When I press "Cancel"
Then I should see "Edit table"
And I should not see "usermodified"
And I should not see "timecreated"
And I should not see "timemodified"
Scenario: Creating mandatory persistent fields
Given I follow "Add mandatory persistent fields"
And I should see "usermodified"
And I should see "timecreated"
And I should see "timemodified"
When I press "Continue"
Then I should see "The following fields have been added:"
And I should see "usermodified" in the ".alert ul" "css_element"
And I should see "timecreated" in the ".alert ul" "css_element"
And I should see "timemodified" in the ".alert ul" "css_element"
And I follow "Back"
And I should see "usermodified" in the "listfields" "table"
And I should see "timecreated" in the "listfields" "table"
And I should see "timemodified" in the "listfields" "table"
And I should see "usermodified" in the "listkeys" "table"
Scenario: Partial creation of mandatory persistent fields
Given I follow "Add mandatory persistent fields"
And I press "Continue"
And I follow "Back"
And I click on "Delete" "link" in the "timecreated" "table_row"
And I press "Yes"
When I follow "Add mandatory persistent fields"
Then I should see "The following fields already exist:"
And I should see "usermodified" in the ".alert ul" "css_element"
And I should see "timemodified" in the ".alert ul" "css_element"
But I should not see "timecreated" in the ".alert ul" "css_element"
And I should see "Do you want to add the following fields:"
And I should see "timecreated" in the ".modal ul" "css_element"
And I press "Continue"
And I should see "The following fields have been added:"
And I should see "timecreated" in the ".alert ul" "css_element"
And I should not see "timemodified" in the ".alert ul" "css_element"
And I should not see "usermodified" in the ".alert ul" "css_element"
And I follow "Back"
And I should see "timecreated" in the "listfields" "table"
Scenario: Trying to create mandatory persistent fields that have all been added
Given I follow "Add mandatory persistent fields"
And I press "Continue"
And I follow "Back"
When I follow "Add mandatory persistent fields"
Then I should see "The following fields already exist:"
And I should see "usermodified" in the ".alert ul" "css_element"
And I should see "timecreated" in the ".alert ul" "css_element"
And I should see "timemodified" in the ".alert ul" "css_element"
And I should not see "Do you want to add the following fields:"
@@ -0,0 +1,12 @@
@tool @tool_xmldb
Feature: The Reconcile XMLDB files report works and all the files are ok
In order to ensure that all the XMLDB Editor xml files are generated properly
As a developer
I need to be able to run the Reconcile XMLDB files report and verify that everything is ok
Scenario: The Reconcile XMLDB files reports that all files are ok
Given I log in as "admin"
And I navigate to "Development > XMLDB editor" in site administration
When I follow "[Reconcile XMLDB files]"
Then I should see "Look for XMLDB files needing reconciling"
And I should see "All files are OK. No reconciling is needed."
+30
View File
@@ -0,0 +1,30 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Plugin version info
*
* @package tool_xmldb
* @copyright 2003 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'tool_xmldb'; // Full name of the plugin (used for diagnostics)