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
+165
View File
@@ -0,0 +1,165 @@
<?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/>.
/**
* General database export class
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Base class for database export operations. This class defines basic callbacks
* for export operations and implements the @see export_database and
* @export_table methods generic export processing. In general, subclasses will
* override callback methods to provide specific output and (optionally)
* @see export_database to add functionality.
* Between a single pair of calls to @see begin_database_export and
* @see finish_database_export, multiple non-overlapping pairs of calls may
* be made to @see begin_table_export and @see finish_database_export for
* different tables. Between one pair of calls to @see begin_table_export and
* @see finish_database_export multiple calls may be made to
* @see export_table_data for the same table.
*/
abstract class database_exporter {
/** @var moodle_database Connection to the source database (a @see moodle_database object). */
protected $mdb;
/** @var database_manager Database manager of the source database (a @see database_manager object). */
protected $manager;
/** @var xmldb_structure Source database schema in XMLDB format (a @see xmldb_structure object). */
protected $schema;
/**
* Boolean flag - whether or not to check that XML database schema matches
* the RDBMS database schema before exporting (used by
* @see export_database).
* @var bool
*/
protected $check_schema;
/**
* Object constructor.
*
* @param moodle_database $mdb Connection to the source database (a
* @see moodle_database object).
* @param boolean $check_schema - whether or not to check that XML database
* schema matches the RDBMS database schema before exporting (used by
* @see export_database).
*/
public function __construct(moodle_database $mdb, $check_schema=true) {
$this->mdb = $mdb;
$this->manager = $mdb->get_manager();
$this->schema = $this->manager->get_install_xml_schema();
$this->check_schema = $check_schema;
}
/**
* Callback function. Should be called only once database per export
* operation, before any other export operations. Subclasses should export
* basic database information (version and timestamp).
*
* @param float $version the version of the system which generating the data
* @param string $release moodle release info
* @param string $timestamp the timestamp of the data (in ISO 8601) format.
* @param string $description a user description of the data.
* @return void
*/
abstract public function begin_database_export($version, $release, $timestamp, $description);
/**
* Callback function. Should be called only once per table export operation,
* before any other table export operations. Subclasses should export
* basic database information (name and schema's hash).
*
* @param xmldb_table $table - XMLDB object for the exported table
* @return void
*/
abstract public function begin_table_export(xmldb_table $table);
/**
* Callback function. Should be called only once per table export operation,
* after all other table export operations.
*
* @param xmldb_table $table - XMLDB object for the exported table
*/
abstract public function finish_table_export(xmldb_table $table);
/**
* Callback function. Should be called only once database per export
* operation, after all database export operations.
*/
abstract public function finish_database_export();
/**
* Callback function. Should be called only once per record export operation,
* only between @see begin_table_export and @see finish_table_export calls.
* It will insert table data. Subclasses should export basic record
* information (data values).
*
* @param xmldb_table $table - XMLDB object of the table from which data was retrieved
* @param object $data - data object (fields and values from record)
* @return void
*/
abstract public function export_table_data(xmldb_table $table, $data);
/**
* Generic method to export the database. It checks the schema (if
* @see $check_schema is true), queries the database and calls
* appropriate callbacks.
*
* @throws dbtransfer_exception if any checking (e.g. database schema) fails
*
* @param string $description a user description of the data.
*/
public function export_database($description=null) {
global $CFG;
$options = [
'changedcolumns' => false, // Column types may be fixed by transfer.
'missingindexes' => false, // No need to worry about indexes for transfering data.
'extraindexes' => false
];
if ($this->check_schema and $errors = $this->manager->check_database_schema($this->schema, $options)) {
$details = '';
foreach ($errors as $table=>$items) {
$details .= '<div>'.get_string('tablex', 'dbtransfer', $table);
$details .= '<ul>';
foreach ($items as $item) {
$details .= '<li>'.$item.'</li>';
}
$details .= '</ul></div>';
}
throw new dbtransfer_exception('exportschemaexception', $details);
}
$tables = $this->schema->getTables();
$this->begin_database_export($CFG->version, $CFG->release, date('c'), $description);
foreach ($tables as $table) {
$rs = $this->mdb->export_table_recordset($table->getName());
if (!$rs) {
throw new ddl_table_missing_exception($table->getName());
}
$this->begin_table_export($table);
foreach ($rs as $row) {
$this->export_table_data($table, $row);
}
$this->finish_table_export($table);
$rs->close();
}
$this->finish_database_export();
}
}
+218
View File
@@ -0,0 +1,218 @@
<?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/>.
/**
* General database importer class
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Base class for database import operations. This class implements
* basic callbacks for import operations and defines the @see import_database
* method as a common method for all importers. In general, subclasses will
* override import_database and call other methods in appropriate moments.
* Between a single pair of calls to @see begin_database_import and
* @see finish_database_import, multiple non-overlapping pairs of calls may
* be made to @see begin_table_import and @see finish_database_import for
* different tables.
* Between one pair of calls to @see begin_table_import and
* @see finish_database_import multiple calls may be made to
* @see import_table_data for the same table.
* This class can be used directly, if the standard control flow (defined above)
* is respected.
*/
class database_importer {
/** @var moodle_database Connection to the target database (a @see moodle_database object). */
protected $mdb;
/** @var database_manager Database manager of the target database (a @see database_manager object). */
protected $manager;
/** @var xmldb_structure Target database schema in XMLDB format (a @see xmldb_structure object). */
protected $schema;
/**
* Boolean flag - whether or not to check that XML database schema matches
* the RDBMS database schema before importing (used by
* @see begin_database_import).
* @var bool
*/
protected $check_schema;
/** @var string How to use transactions. */
protected $transactionmode = 'allinone';
/** @var moodle_transaction Transaction object */
protected $transaction;
/**
* Object constructor.
*
* @param moodle_database $mdb Connection to the target database (a
* @see moodle_database object). Use null to use the current $DB connection.
* @param boolean $check_schema - whether or not to check that XML database
* schema matches the RDBMS database schema before importing (inside
* @see begin_database_import).
*/
public function __construct(moodle_database $mdb, $check_schema=true) {
$this->mdb = $mdb;
$this->manager = $mdb->get_manager();
$this->schema = $this->manager->get_install_xml_schema();
$this->check_schema = $check_schema;
}
/**
* How to use transactions during the import.
* @param string $mode 'pertable', 'allinone' or 'none'.
*/
public function set_transaction_mode($mode) {
if (!in_array($mode, array('pertable', 'allinone', 'none'))) {
throw new coding_exception('Unknown transaction mode', $mode);
}
$this->transactionmode = $mode;
}
/**
* Callback function. Should be called only once database per import
* operation, before any database changes are made. It will check the database
* schema if @see check_schema is true
*
* @throws dbtransfer_exception if any checking (e.g. database schema, Moodle
* version) fails
*
* @param float $version the version of the system which generated the data
* @param string $timestamp the timestamp of the data (in ISO 8601) format.
* @return void
*/
public function begin_database_import($version, $timestamp) {
global $CFG;
if (!$this->mdb->get_tables()) {
// No tables present yet, time to create all tables.
$this->manager->install_from_xmldb_structure($this->schema);
}
if (round($version, 2) !== round($CFG->version, 2)) { // version might be in decimal format too
$a = (object)array('schemaver'=>$version, 'currentver'=>$CFG->version);
throw new dbtransfer_exception('importversionmismatchexception', $a);
}
$options = [
'changedcolumns' => false, // Column types may be fixed by transfer.
'missingindexes' => false, // No need to worry about indexes for transfering data.
'extraindexes' => false
];
if ($this->check_schema and $errors = $this->manager->check_database_schema($this->schema, $options)) {
$details = '';
foreach ($errors as $table=>$items) {
$details .= '<div>'.get_string('table').' '.$table.':';
$details .= '<ul>';
foreach ($items as $item) {
$details .= '<li>'.$item.'</li>';
}
$details .= '</ul></div>';
}
throw new dbtransfer_exception('importschemaexception', $details);
}
if ($this->transactionmode == 'allinone') {
$this->transaction = $this->mdb->start_delegated_transaction();
}
}
/**
* Callback function. Should be called only once per table import operation,
* before any table changes are made. It will delete all table data.
*
* @throws dbtransfer_exception an unknown table import is attempted
* @throws ddl_table_missing_exception if the table is missing
*
* @param string $tablename - the name of the table that will be imported
* @param string $schemaHash - the hash of the xmldb_table schema of the table
* @return void
*/
public function begin_table_import($tablename, $schemaHash) {
if ($this->transactionmode == 'pertable') {
$this->transaction = $this->mdb->start_delegated_transaction();
}
if (!$table = $this->schema->getTable($tablename)) {
throw new dbtransfer_exception('unknowntableexception', $tablename);
}
if ($schemaHash != $table->getHash()) {
throw new dbtransfer_exception('differenttableexception', $tablename);
}
// this should not happen, unless someone drops tables after import started
if (!$this->manager->table_exists($table)) {
throw new ddl_table_missing_exception($tablename);
}
$this->mdb->delete_records($tablename);
}
/**
* Callback function. Should be called only once per table import operation,
* after all table changes are made. It will reset table sequences if any.
* @param string $tablename
* @return void
*/
public function finish_table_import($tablename) {
$table = $this->schema->getTable($tablename);
$fields = $table->getFields();
foreach ($fields as $field) {
if ($field->getSequence()) {
$this->manager->reset_sequence($tablename);
return;
}
}
if ($this->transactionmode == 'pertable') {
$this->transaction->allow_commit();
}
}
/**
* Callback function. Should be called only once database per import
* operation, after all database changes are made. It will commit changes.
* @return void
*/
public function finish_database_import() {
if ($this->transactionmode == 'allinone') {
$this->transaction->allow_commit();
}
}
/**
* Callback function. Should be called only once per record import operation, only
* between @see begin_table_import and @see finish_table_import calls.
* It will insert table data.
*
* @throws dml_exception if data insert operation failed
*
* @param string $tablename - the name of the table in which data will be
* imported
* @param object $data - data object (fields and values will be inserted
* into table)
* @return void
*/
public function import_table_data($tablename, $data) {
$this->mdb->import_record($tablename, $data);
}
/**
* Common import method
* @return void
*/
public function import_database() {
// implement in subclasses
}
}
+122
View File
@@ -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/>.
/**
* General database mover class
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
class database_mover extends database_exporter {
/** @var database_importer Importer object used to transfer data. */
protected $importer;
/** @var progress_trace Progress tracing object */
protected $feedback;
/**
* Object constructor.
*
* @param moodle_database $mdb_source Connection to the source database (a
* @see moodle_database object).
* @param moodle_database $mdb_target Connection to the target database (a
* @see moodle_database object).
* @param boolean $check_schema - whether or not to check that XML database
* schema matches the RDBMS database schema before exporting (used by
* @param progress_trace $feedback Progress tracing object
* @see export_database).
*/
public function __construct(moodle_database $mdb_source, moodle_database $mdb_target,
$check_schema = true, progress_trace $feedback = null) {
if (empty($feedback)) {
$this->feedback = new null_progress_trace();
} else {
$this->feedback = $feedback;
}
if ($check_schema) {
$this->feedback->output(get_string('checkingsourcetables', 'core_dbtransfer'));
}
parent::__construct($mdb_source, $check_schema);
$this->feedback->output(get_string('creatingtargettables', 'core_dbtransfer'));
$this->importer = new database_importer($mdb_target, $check_schema);
}
/**
* How to use transactions during the transfer.
* @param string $mode 'pertable', 'allinone' or 'none'.
*/
public function set_transaction_mode($mode) {
$this->importer->set_transaction_mode($mode);
}
/**
* Callback function. Calls importer's begin_database_import callback method.
*
* @param float $version the version of the system which generating the data
* @param string $release moodle release info
* @param string $timestamp the timestamp of the data (in ISO 8601) format.
* @param string $description a user description of the data.
* @return void
*/
public function begin_database_export($version, $release, $timestamp, $description) {
$this->feedback->output(get_string('copyingtables', 'core_dbtransfer'));
$this->importer->begin_database_import($version, $timestamp, $description);
}
/**
* Callback function. Calls importer's begin_table_import callback method.
*
* @param xmldb_table $table - XMLDB object for the exported table
* @return void
*/
public function begin_table_export(xmldb_table $table) {
$this->feedback->output(get_string('copyingtable', 'core_dbtransfer', $table->getName()), 1);
$this->importer->begin_table_import($table->getName(), $table->getHash());
}
/**
* Callback function. Calls importer's import_table_data callback method.
*
* @param xmldb_table $table - XMLDB object of the table from which data
* was retrieved
* @param object $data - data object (fields and values from record)
* @return void
*/
public function export_table_data(xmldb_table $table, $data) {
$this->importer->import_table_data($table->getName(), $data);
}
/**
* Callback function. Calls importer's finish_table_import callback method.
* @param xmldb_table $table - XMLDB object for the exported table
* @return void
*/
public function finish_table_export(xmldb_table $table) {
$this->feedback->output(get_string('done', 'core_dbtransfer', $table->getName()), 2);
$this->importer->finish_table_import($table->getName());
}
/**
* Callback function. Calls importer's finish_database_import callback method.
* @return void
*/
public function finish_database_export() {
$this->importer->finish_database_import();
}
}
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="moodle_database" type="databaseType" />
<xs:complexType name="databaseType">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="table"
type="tableType" />
</xs:sequence>
<xs:attribute name="version" type="xs:float" use="required" />
<xs:attribute name="release" type="xs:string"></xs:attribute>
<xs:attribute name="timestamp" type="xs:dateTime"
use="required" />
<xs:attribute name="comment" type="xs:string" />
</xs:complexType>
<xs:complexType name="tableType">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="record" type="recordType" />
</xs:sequence>
<xs:attribute name="name" type="xs:NCName" use="required" />
<xs:attribute name="schemaHash" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="recordType">
<xs:sequence>
<xs:element maxOccurs="unbounded" name="field" type="fieldType" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="fieldType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute default="content" name="value" use="optional">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="content" />
<xs:enumeration value="null" />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
+75
View File
@@ -0,0 +1,75 @@
<?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/>.
/**
* XML format exporter class to file storage
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* XML format exporter class to file storage.
*/
class file_xml_database_exporter extends xml_database_exporter {
/** @var string Path to the XML data file. */
protected $filepath;
/** @var resource File descriptor for the output file. */
protected $file;
/**
* Object constructor.
*
* @param string $filepath - path to the XML data file. Use 'php://output' for PHP
* output stream.
* @param moodle_database $mdb Connection to the source database
* @see xml_database_exporter::__construct()
* @param boolean $check_schema - whether or not to check that XML database
* @see xml_database_exporter::__construct()
*/
public function __construct($filepath, moodle_database $mdb, $check_schema=true) {
parent::__construct($mdb, $check_schema);
$this->filepath = $filepath;
}
/**
* Specific output method for the file XML sink.
* @param string $text
*/
protected function output($text) {
fwrite($this->file, $text);
}
/**
* Specific implementation for file exporting the database: it opens output stream, calls
* superclass @see database_exporter::export_database() and closes output stream.
*
* @throws dbtransfer_exception if any checking (e.g. database schema) fails
*
* @param string $description a user description of the data.
*/
public function export_database($description=null) {
global $CFG;
// TODO: add exception if file creation fails
$this->file = fopen($this->filepath, 'wb');
parent::export_database($description);
fclose($this->file);
@chmod($this->filepath, $CFG->filepermissions);
}
}
+65
View File
@@ -0,0 +1,65 @@
<?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/>.
/**
* XML format importer class from file storage
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* XML format importer class from file storage.
*/
class file_xml_database_importer extends xml_database_importer {
/** @var string Path to the XML data file. */
protected $filepath;
/**
* Object constructor.
*
* @param string $filepath - path to the XML data file. Use 'php://input' for PHP
* input stream.
* @param moodle_database $mdb Connection to the target database
* @see xml_database_importer::__construct()
* @param boolean $check_schema - whether or not to check that XML database
* @see xml_database_importer::__construct()
*/
public function __construct($filepath, moodle_database $mdb, $check_schema=true) {
$this->filepath = $filepath;
parent::__construct($mdb, $check_schema);
}
/**
* Common import method: it opens the file storage, creates the parser, feeds
* the XML parser with data, releases the parser and closes the file storage.
* @return void
*/
public function import_database() {
$file = fopen($this->filepath, 'r');
$parser = $this->get_parser();
while ($data = fread($file, 65536)) {
if (!xml_parse($parser, $data, feof($file))) {
throw new dbtransfer_exception('malformedxmlexception');
}
}
xml_parser_free($parser);
fclose($file);
}
}
+62
View File
@@ -0,0 +1,62 @@
<?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/>.
/**
* XML format exporter class to memory storage
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* XML format exporter class to memory storage (i.e. a string).
*/
class string_xml_database_exporter extends xml_database_exporter {
/** @var string String with XML data. */
protected $data;
/**
* Specific output method for the memory XML sink.
* @param string $text
*/
protected function output($text) {
$this->data .= $text;
}
/**
* Returns the output of the exporters
* @return string XML data from exporter
*/
public function get_output() {
return $this->data;
}
/**
* Specific implementation for memory exporting the database: it clear the buffer
* and calls superclass @see database_exporter::export_database().
*
* @throws dbtransfer_exception if any checking (e.g. database schema) fails
* @param string $description a user description of the data.
* @return void
*/
public function export_database($description=null) {
$this->data = '';
parent::export_database($description);
}
}
+60
View File
@@ -0,0 +1,60 @@
<?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/>.
/**
* XML format importer class from memory storage
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* XML format importer class from memory storage (i.e. string).
*/
class string_xml_database_importer extends xml_database_importer {
/** @var string String with XML data. */
protected $data;
/**
* Object constructor.
*
* @param string $data - string with XML data
* @param moodle_database $mdb Connection to the target database
* @see xml_database_importer::__construct()
* @param boolean $check_schema - whether or not to check that XML database
* @see xml_database_importer::__construct()
*/
public function __construct($data, moodle_database $mdb, $check_schema=true) {
parent::__construct($mdb, $check_schema);
$this->data = $data;
}
/**
* Common import method: it creates the parser, feeds the XML parser with
* data, releases the parser.
* @return void
*/
public function import_database() {
$parser = $this->get_parser();
if (!xml_parse($parser, $this->data, true)) {
throw new dbtransfer_exception('malformedxmlexception');
}
xml_parser_free($parser);
}
}
+98
View File
@@ -0,0 +1,98 @@
<?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/>.
/**
* XML format exporter class
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* XML format exporter class.
* Provides logic for writing XML tags and data inside appropriate callbacks.
* Subclasses should define XML data sinks.
*/
abstract class xml_database_exporter extends database_exporter {
/**
* Generic output method. Subclasses should implement it with code specific
* to the target XML sink.
*/
abstract protected function output($text);
/**
* Callback function. Outputs open XML PI and moodle_database opening tag.
*
* @param float $version the version of the system which generating the data
* @param string $release moodle release info
* @param string $timestamp the timestamp of the data (in ISO 8601) format.
* @param string $description a user description of the data.
* @return void
*/
public function begin_database_export($version, $release, $timestamp, $description) {
$this->output('<?xml version="1.0" encoding="utf-8"?>');
//TODO add xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" and schema information
$this->output('<moodle_database version="'.$version.'" release="'.$release.'" timestamp="'.$timestamp.'"'.(empty ($description) ? '' : ' comment="'.htmlspecialchars($description, ENT_QUOTES, 'UTF-8').'"').'>');
}
/**
* Callback function. Outputs table opening tag.
*
* @param xmldb_table $table - XMLDB object for the exported table
* @return void
*/
public function begin_table_export(xmldb_table $table) {
$this->output('<table name="'.$table->getName().'" schemaHash="'.$table->getHash().'">');
}
/**
* Callback function. Outputs table closing tag.
*
* @param xmldb_table $table - XMLDB object for the exported table
*/
public function finish_table_export(xmldb_table $table) {
$this->output('</table>');
}
/**
* Callback function. Outputs moodle_database closing tag.
*/
public function finish_database_export() {
$this->output('</moodle_database>');
}
/**
* Callback function. Outputs record tag with field subtags and data.
*
* @param xmldb_table $table - XMLDB object of the table from which data was retrieved
* @param object $data - data object (fields and values from record)
* @return void
*/
public function export_table_data(xmldb_table $table, $data) {
$this->output('<record>');
foreach ($data as $key => $value) {
if (is_null($value)) {
$this->output('<field name="'.$key.'" value="null" />');
} else {
$this->output('<field name="'.$key.'">'.htmlspecialchars($value, ENT_NOQUOTES, 'UTF-8').'</field>');
}
}
$this->output('</record>');
}
}
+155
View File
@@ -0,0 +1,155 @@
<?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/>.
/**
* XML format importer class
*
* @package core_dtl
* @copyright 2008 Andrei Bautu
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* XML format importer class (uses SAX for speed and low memory footprint).
* Provides logic for parsing XML data and calling appropriate callbacks.
* Subclasses should define XML data sources.
*/
abstract class xml_database_importer extends database_importer {
protected $current_table;
protected $current_row;
protected $current_field;
protected $current_data;
protected $current_data_is_null;
/**
* Creates and setups a SAX parser. Subclasses should use this method to
* create the XML parser.
*
* @return resource XML parser resource.
*/
protected function get_parser() {
$parser = xml_parser_create();
xml_set_object($parser, $this);
xml_set_element_handler($parser, 'tag_open', 'tag_close');
xml_set_character_data_handler($parser, 'cdata');
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false);
return $parser;
}
/**
* Callback function. Called by the XML parser for opening tags processing.
*
* @param resource $parser XML parser resource.
* @param string $tag name of opening tag
* @param array $attributes set of opening tag XML attributes
* @return void
*/
protected function tag_open($parser, $tag, $attributes) {
switch ($tag) {
case 'moodle_database' :
if (empty($attributes['version']) || empty($attributes['timestamp'])) {
throw new dbtransfer_exception('malformedxmlexception');
}
$this->begin_database_import($attributes['version'], $attributes['timestamp']);
break;
case 'table' :
if (isset($this->current_table)) {
throw new dbtransfer_exception('malformedxmlexception');
}
if (empty($attributes['name']) || empty($attributes['schemaHash'])) {
throw new dbtransfer_exception('malformedxmlexception');
}
$this->current_table = $attributes['name'];
$this->begin_table_import($this->current_table, $attributes['schemaHash']);
break;
case 'record' :
if (isset($this->current_row) || !isset($this->current_table)) {
throw new dbtransfer_exception('malformedxmlexception');
}
$this->current_row = new stdClass();
break;
case 'field' :
if (isset($this->current_field) || !isset($this->current_row)) {
throw new dbtransfer_exception('malformedxmlexception');
}
$this->current_field = $attributes['name'];
$this->current_data = '';
if (isset($attributes['value']) and $attributes['value'] === 'null') {
$this->current_data_is_null = true;
} else {
$this->current_data_is_null = false;
}
break;
default :
throw new dbtransfer_exception('malformedxmlexception');
}
}
/**
* Callback function. Called by the XML parser for closing tags processing.
*
* @param resource $parser XML parser resource.
* @param string $tag name of opening tag
* @return void
*/
protected function tag_close($parser, $tag) {
switch ($tag) {
case 'moodle_database' :
$this->finish_database_import();
break;
case 'table' :
$this->finish_table_import($this->current_table);
$this->current_table = null;
break;
case 'record' :
$this->import_table_data($this->current_table, $this->current_row);
$this->current_row = null;
break;
case 'field' :
$field = $this->current_field;
if ($this->current_data_is_null) {
$this->current_row->$field = null;
} else {
$this->current_row->$field = $this->current_data;
}
$this->current_field = null;
$this->current_data = null;
$this->current_data_is_null = null;
break;
default :
throw new dbtransfer_exception('malformedxmlexception');
}
}
/**
* Callback function. Called by the XML parser for character data processing.
*
* @param resource $parser XML parser resource.
* @param string $data character data to be processed
* @return void
*/
protected function cdata($parser, $data) {
if (isset($this->current_field)) {
$this->current_data .= $data;
}
}
}