MDL-78324 core: Convert core/tag to esm
[moodle.git] / lib / xmldb / xmldb_file.php
blob67acce0538125a955a22642b490a8978d632fa3c
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
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/>.
17 /**
18 * This class represent one XMLDB file
20 * @package core_xmldb
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 */
32 protected $path;
34 /** @var string path to schema */
35 protected $schema;
37 /** @var string document dtd */
38 protected $dtd;
40 /** @var xmldb_structure the structure stored in file */
41 protected $xmldb_structure;
43 /**
44 * Constructor of the xmldb_file
45 * @param string $path
47 public function __construct($path) {
48 parent::__construct($path);
49 $this->path = $path;
50 $this->xmldb_structure = null;
53 /**
54 * Determine if the XML file exists
55 * @return bool
57 public function fileExists() {
58 if (file_exists($this->path) && is_readable($this->path)) {
59 return true;
61 return false;
64 /**
65 * Determine if the XML is writeable
66 * @return bool
68 public function fileWriteable() {
69 if (is_writeable(dirname($this->path))) {
70 return true;
72 return false;
75 public function getStructure() {
76 return $this->xmldb_structure;
79 /**
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
83 * @return true
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);
107 // Check for errors
108 $errors = libxml_get_errors();
110 // Stop capturing errors
111 libxml_use_internal_errors($olderrormode);
113 // Prepare errors
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 ."),
122 $error->line);
124 // Add structure to file
125 $this->xmldb_structure = $structure;
126 // Check has failed
127 return false;
130 return true;
134 * Load and the XMLDB structure from file
135 * @return true
137 public function loadXMLStructure() {
138 if ($this->fileExists()) {
139 // Let's validate the XML file
140 if (!$this->validateXMLStructure()) {
141 return false;
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);
154 // Analyze results
155 if ($this->xmldb_structure->isLoaded()) {
156 $this->loaded = true;
157 return true;
158 } else {
159 return false;
162 return 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);
173 return $structure;
177 * This function sets the DTD of the XML file
178 * @param string
180 public function setDTD($path) {
181 $this->dtd = $path;
185 * This function sets the schema of the XML file
186 * @param string
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());
202 return $result;