2 // This file is part of Moodle - http://moodle.org/
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 * This class represent one XMLDB file
21 * @copyright 1999 onwards Martin Dougiamas http://dougiamas.com
22 * 2001-3001 Eloy Lafuente (stronk7) http://contiento.com
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') ||
die();
29 class xmldb_file
extends xmldb_object
{
31 /** @var string path to file */
34 /** @var string path to schema */
37 /** @var string document dtd */
40 /** @var xmldb_structure the structure stored in file */
41 protected $xmldb_structure;
44 * Constructor of the xmldb_file
47 public function __construct($path) {
48 parent
::__construct($path);
50 $this->xmldb_structure
= null;
54 * Determine if the XML file exists
57 public function fileExists() {
58 if (file_exists($this->path
) && is_readable($this->path
)) {
65 * Determine if the XML is writeable
68 public function fileWriteable() {
69 if (is_writeable(dirname($this->path
))) {
75 public function getStructure() {
76 return $this->xmldb_structure
;
80 * This function will check/validate the XML file for correctness
81 * Dynamically if will use the best available checker/validator
82 * (expat syntax checker or DOM schema validator
85 public function validateXMLStructure() {
87 // Create and load XML file
88 $parser = new DOMDocument();
89 $contents = file_get_contents($this->path
);
90 if (strpos($contents, '<STATEMENTS>')) {
91 //delete the removed STATEMENTS section, it would not validate
92 $contents = preg_replace('|<STATEMENTS>.*</STATEMENTS>|s', '', $contents);
95 // Let's capture errors
96 $olderrormode = libxml_use_internal_errors(true);
98 // Clear XML error flag so that we don't incorrectly report failure
99 // when a previous xml parse failed
100 libxml_clear_errors();
102 $parser->loadXML($contents);
103 // Only validate if we have a schema
104 if (!empty($this->schema
) && file_exists($this->schema
)) {
105 $parser->schemaValidate($this->schema
);
108 $errors = libxml_get_errors();
110 // Stop capturing errors
111 libxml_use_internal_errors($olderrormode);
114 if (!empty($errors)) {
115 // Create one structure to store errors
116 $structure = new xmldb_structure($this->path
);
117 // Add errors to structure
118 $structure->errormsg
= 'XML Error: ';
119 foreach ($errors as $error) {
120 $structure->errormsg
.= sprintf("%s at line %d. ",
121 trim($error->message
, "\n\r\t ."),
124 // Add structure to file
125 $this->xmldb_structure
= $structure;
134 * Load and the XMLDB structure from file
137 public function loadXMLStructure() {
138 if ($this->fileExists()) {
139 // Let's validate the XML file
140 if (!$this->validateXMLStructure()) {
143 $contents = file_get_contents($this->path
);
144 if (strpos($contents, '<STATEMENTS>')) {
145 //delete the removed STATEMENTS section, it would not validate
146 $contents = preg_replace('|<STATEMENTS>.*</STATEMENTS>|s', '', $contents);
147 debugging('STATEMENTS section is not supported any more, please use db/install.php or db/log.php');
149 // File exists, so let's process it
150 // Load everything to a big array
151 $xmlarr = xmlize($contents);
152 // Convert array to xmldb structure
153 $this->xmldb_structure
= $this->arr2xmldb_structure($xmlarr);
155 if ($this->xmldb_structure
->isLoaded()) {
156 $this->loaded
= true;
166 * This function takes an xmlized array and put it into one xmldb_structure
167 * @param array $xmlarr
168 * @return xmldb_structure
170 public function arr2xmldb_structure ($xmlarr) {
171 $structure = new xmldb_structure($this->path
);
172 $structure->arr2xmldb_structure($xmlarr);
177 * This function sets the DTD of the XML file
180 public function setDTD($path) {
185 * This function sets the schema of the XML file
188 public function setSchema($path) {
189 $this->schema
= $path;
193 * This function saves the whole xmldb_structure to its file
194 * @return int|bool false on failure, number of written bytes on success
196 public function saveXMLFile() {
198 $structure = $this->getStructure();
200 $result = file_put_contents($this->path
, $structure->xmlOutput());