xmldb MDL-24979 Made xmldb (a) not hide libxml errors permanently, (b) not incorrectl...
[moodle.git] / lib / xmldb / xmldb_file.php
1 <?php
3 ///////////////////////////////////////////////////////////////////////////
4 //                                                                       //
5 // NOTICE OF COPYRIGHT                                                   //
6 //                                                                       //
7 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
8 //          http://moodle.com                                            //
9 //                                                                       //
10 // Copyright (C) 1999 onwards Martin Dougiamas     http://dougiamas.com  //
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 ///////////////////////////////////////////////////////////////////////////
27 /// This class represents an entire XMLDB file
29 class xmldb_file extends xmldb_object {
31     var $path;
32     var $schema;
33     var $dtd;
34     var $xmldb_structure;
36     /**
37      * Constructor of the xmldb_file
38      */
39     function __construct($path) {
40         parent::__construct($path);
41         $this->path = $path;
42         $this->xmldb_structure = NULL;
43     }
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     }
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     }
65     function &getStructure() {
66         return $this->xmldb_structure;
67     }
69     /**
70      * This function will check/validate the XML file for correctness
71      * Dynamically if will use the best available checker/validator
72      * (expat syntax checker or DOM schema validator
73      */
74     function validateXMLStructure() {
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         }
84         // Let's capture errors
85         $olderrormode = libxml_use_internal_errors(true);
87         // Clear XML error flag so that we don't incorrectly report failure
88         // when a previous xml parse failed
89         libxml_clear_errors();
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);
95         }
96     /// Check for errors
97         $errors = libxml_get_errors();
99         // Stop capturing errors
100         libxml_use_internal_errors($olderrormode);
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);
112             }
113         /// Add structure to file
114             $this->xmldb_structure = $structure;
115         /// Check has failed
116             return false;
117         }
119         return true;
120     }
122     /**
123      * Load and the XMLDB structure from file
124      */
125     function loadXMLStructure() {
126         if ($this->fileExists()) {
127         /// Let's validate the XML file
128             if (!$this->validateXMLStructure()) {
129                 return false;
130             }
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             }
137         /// File exists, so let's process it
138         /// Load everything to a big array
139             $xmlarr = xmlize($contents);
140         /// Convert array to xmldb structure
141             $this->xmldb_structure = $this->arr2xmldb_structure($xmlarr);
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     }
153     /**
154      * This function takes an xmlized array and put it into one xmldb_structure
155      */
156     function arr2xmldb_structure ($xmlarr) {
157         $structure = new xmldb_structure($this->path);
158         $structure->arr2xmldb_structure($xmlarr);
159         return $structure;
160     }
162     /**
163      * This function sets the DTD of the XML file
164      */
165     function setDTD($path) {
166         $this->dtd = $path;
167     }
169     /**
170      * This function sets the schema of the XML file
171      */
172     function setSchema($path) {
173         $this->schema = $path;
174     }
176     /**
177      * This function saves the whole xmldb_structure to its file
178      */
179     function saveXMLFile() {
181         $structure =& $this->getStructure();
183         $result = file_put_contents($this->path, $structure->xmlOutput());
185         return $result;
186     }