xmldb MDL-24979 Made xmldb (a) not hide libxml errors permanently, (b) not incorrectl...
[moodle.git] / lib / xmldb / xmldb_file.php
CommitLineData
4a0e2e63 1<?php
8165877a 2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
46293bd7 10// Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com //
8165877a 11// (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com //
12// //
13// This program is free software; you can redistribute it and/or modify //
14// it under the terms of the GNU General Public License as published by //
15// the Free Software Foundation; either version 2 of the License, or //
16// (at your option) any later version. //
17// //
18// This program is distributed in the hope that it will be useful, //
19// but WITHOUT ANY WARRANTY; without even the implied warranty of //
20// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21// GNU General Public License for more details: //
22// //
23// http://www.gnu.org/copyleft/gpl.html //
24// //
25///////////////////////////////////////////////////////////////////////////
26
27/// This class represents an entire XMLDB file
28
46293bd7 29class xmldb_file extends xmldb_object {
8165877a 30
31 var $path;
776dee9c 32 var $schema;
33 var $dtd;
8165877a 34 var $xmldb_structure;
35
36 /**
46293bd7 37 * Constructor of the xmldb_file
8165877a 38 */
a8cb94f6 39 function __construct($path) {
46293bd7 40 parent::__construct($path);
8165877a 41 $this->path = $path;
42 $this->xmldb_structure = NULL;
43 }
44
45 /**
46 * Determine if the XML file exists
47 */
48 function fileExists() {
49 if (file_exists($this->path) && is_readable($this->path)) {
50 return true;
51 }
52 return false;
53 }
54
55 /**
56 * Determine if the XML is writeable
57 */
58 function fileWriteable() {
59 if (is_writeable(dirname($this->path))) {
60 return true;
61 }
62 return false;
63 }
64
65 function &getStructure() {
66 return $this->xmldb_structure;
67 }
68
776dee9c 69 /**
5884a8e6 70 * This function will check/validate the XML file for correctness
adc31ef5 71 * Dynamically if will use the best available checker/validator
776dee9c 72 * (expat syntax checker or DOM schema validator
73 */
74 function validateXMLStructure() {
75
844239d3
PS
76 /// Create and load XML file
77 $parser = new DOMDocument();
78 $contents = file_get_contents($this->path);
79 if (strpos($contents, '<STATEMENTS>')) {
80 //delete the removed STATEMENTS section, it would not validate
81 $contents = preg_replace('|<STATEMENTS>.*</STATEMENTS>|s', '', $contents);
82 }
86aae61e 83
d854dff9
SM
84 // Let's capture errors
85 $olderrormode = libxml_use_internal_errors(true);
86
87 // Clear XML error flag so that we don't incorrectly report failure
88 // when a previous xml parse failed
89 libxml_clear_errors();
90
844239d3
PS
91 $parser->loadXML($contents);
92 /// Only validate if we have a schema
93 if (!empty($this->schema) && file_exists($this->schema)) {
94 $parser->schemaValidate($this->schema);
776dee9c 95 }
844239d3
PS
96 /// Check for errors
97 $errors = libxml_get_errors();
98
d854dff9
SM
99 // Stop capturing errors
100 libxml_use_internal_errors($olderrormode);
101
844239d3
PS
102 /// Prepare errors
103 if (!empty($errors)) {
104 /// Create one structure to store errors
105 $structure = new xmldb_structure($this->path);
106 /// Add errors to structure
107 $structure->errormsg = 'XML Error: ';
108 foreach ($errors as $error) {
109 $structure->errormsg .= sprintf("%s at line %d. ",
110 trim($error->message, "\n\r\t ."),
111 $error->line);
776dee9c 112 }
844239d3
PS
113 /// Add structure to file
114 $this->xmldb_structure = $structure;
115 /// Check has failed
776dee9c 116 return false;
117 }
844239d3 118
776dee9c 119 return true;
120 }
121
8165877a 122 /**
123 * Load and the XMLDB structure from file
124 */
125 function loadXMLStructure() {
126 if ($this->fileExists()) {
776dee9c 127 /// Let's validate the XML file
128 if (!$this->validateXMLStructure()) {
129 return false;
130 }
844239d3
PS
131 $contents = file_get_contents($this->path);
132 if (strpos($contents, '<STATEMENTS>')) {
133 //delete the removed STATEMENTS section, it would not validate
134 $contents = preg_replace('|<STATEMENTS>.*</STATEMENTS>|s', '', $contents);
135 debugging('STATEMENTS section is not supported any more, please use db/install.php or db/log.php');
136 }
8165877a 137 /// File exists, so let's process it
138 /// Load everything to a big array
844239d3 139 $xmlarr = xmlize($contents);
8165877a 140 /// Convert array to xmldb structure
46293bd7 141 $this->xmldb_structure = $this->arr2xmldb_structure($xmlarr);
8165877a 142 /// Analize results
143 if ($this->xmldb_structure->isLoaded()) {
144 $this->loaded = true;
145 return true;
146 } else {
147 return false;
148 }
149 }
150 return true;
151 }
152
153 /**
46293bd7 154 * This function takes an xmlized array and put it into one xmldb_structure
8165877a 155 */
46293bd7 156 function arr2xmldb_structure ($xmlarr) {
157 $structure = new xmldb_structure($this->path);
158 $structure->arr2xmldb_structure($xmlarr);
8165877a 159 return $structure;
160 }
161
776dee9c 162 /**
163 * This function sets the DTD of the XML file
164 */
165 function setDTD($path) {
166 $this->dtd = $path;
167 }
168
169 /**
170 * This function sets the schema of the XML file
171 */
172 function setSchema($path) {
173 $this->schema = $path;
174 }
175
eef868d1 176 /**
46293bd7 177 * This function saves the whole xmldb_structure to its file
8165877a 178 */
179 function saveXMLFile() {
180
8165877a 181 $structure =& $this->getStructure();
182
183 $result = file_put_contents($this->path, $structure->xmlOutput());
184
185 return $result;
186 }
187}