"MDL-12304, fix double text"
[moodle-linuxchix.git] / lib / xmldb / classes / XMLDBObject.class.php
blob4c31feedee72850ced27a32c3d3c626abc0acf74
1 <?php // $Id$
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 represent the XMLDB base class where all the common piezes
28 /// are defined
30 class XMLDBObject {
32 var $name;
33 var $comment;
34 var $previous;
35 var $next;
36 var $hash;
37 var $loaded;
38 var $changed;
39 var $errormsg;
41 /**
42 * Creates one new XMLDBObject
44 function XMLDBObject($name) {
45 $this->name = $name;
46 $this->comment = NULL;
47 $this->previous = NULL;
48 $this->next = NULL;
49 $this->hash = NULL;
50 $this->loaded = false;
51 $this->changed = false;
52 $this->errormsg = NULL;
55 /**
56 * This function returns true/false, if the XMLDBObject has been loaded
58 function isLoaded() {
59 return $this->loaded;
62 /**
63 * This function returns true/false, if the XMLDBObject has changed
65 function hasChanged() {
66 return $this->changed;
69 /**
70 * This function returns the comment of one XMLDBObject
72 function getComment() {
73 return $this->comment;
76 /**
77 * This function returns the hash of one XMLDBObject
79 function getHash() {
80 return $this->hash;
83 /**
84 * This function will return the name of the previous XMLDBObject
86 function getPrevious() {
87 return $this->previous;
90 /**
91 * This function will return the name of the next XMLDBObject
93 function getNext() {
94 return $this->next;
97 /**
98 * This function will return the name of the XMLDBObject
100 function getName() {
101 return $this->name;
105 * This function will return the error detected in the object
107 function getError() {
108 return $this->errormsg;
112 * This function will set the comment of the XMLDB object
114 function setComment($comment) {
115 $this->comment = $comment;
119 * This function will set the previous of the XMLDB object
121 function setPrevious($previous) {
122 $this->previous = $previous;
126 * This function will set the next of the XMLDB object
128 function setNext($next) {
129 $this->next = $next;
133 * This function will set the hash of the XMLDB object
135 function setHash($hash) {
136 $this->hash = $hash;
140 * This function will set the loaded field of the XMLDB object
142 function setLoaded($loaded = true) {
143 $this->loaded = $loaded;
147 * This function will set the changed field of the XMLDB object
149 function setChanged($changed = true) {
150 $this->changed = $changed;
153 * This function will set the name field of the XMLDB object
155 function setName($name) {
156 $this->name = $name;
161 * This function will check if one key name is ok or no (true/false)
162 * only lowercase a-z, 0-9 and _ are allowed
164 function checkName () {
165 $result = true;
167 if ($this->name != eregi_replace('[^a-z0-9_ -]', '', $this->name)) {
168 $result = false;
170 return $result;
174 * This function will check that all the elements in one array
175 * have a correct name [a-z0-9_]
177 function checkNameValues(&$arr) {
178 $result = true;
179 /// TODO: Perhaps, add support for reserved words
181 /// Check the name only contains valid chars
182 if ($arr) {
183 foreach($arr as $element) {
184 if (!$element->checkName()) {
185 $result = false;
189 return $result;
193 * Reconstruct previous/next attributes.
195 function fixPrevNext(&$arr) {
196 global $CFG;
198 if (empty($CFG->xmldbreconstructprevnext)) {
199 return false;
201 $tweaked = false;
203 $prev = null;
204 foreach ($arr as $key=>$el) {
205 $prev_value = $arr[$key]->previous;
206 $next_value = $arr[$key]->next;
208 $arr[$key]->next = null;
209 $arr[$key]->previous = null;
210 if ($prev !== null) {
211 $arr[$prev]->next = $arr[$key]->name;
212 $arr[$key]->previous = $arr[$prev]->name;
214 $prev = $key;
216 if ($prev_value != $arr[$key]->previous or $next_value != $arr[$key]->next) {
217 $tweaked = true;
221 return $tweaked;
225 * This function will check that all the elements in one array
226 * have a consistent info in their previous/next fields
228 function checkPreviousNextValues(&$arr) {
229 global $CFG;
230 if (!empty($CFG->xmldbdisablenextprevchecking)) {
231 return true;
233 $result = true;
234 /// Check that only one element has the previous not set
235 if ($arr) {
236 $counter = 0;
237 foreach($arr as $element) {
238 if (!$element->getPrevious()) {
239 $counter++;
242 if ($counter != 1) {
243 $result = false;
246 /// Check that only one element has the next not set
247 if ($result && $arr) {
248 $counter = 0;
249 foreach($arr as $element) {
250 if (!$element->getNext()) {
251 $counter++;
254 if ($counter != 1) {
255 $result = false;
258 /// Check that all the previous elements are existing elements
259 if ($result && $arr) {
260 foreach($arr as $element) {
261 if ($element->getPrevious()) {
262 $i = $this->findObjectInArray($element->getPrevious(), $arr);
263 if ($i === NULL) {
264 $result = false;
269 /// Check that all the next elements are existing elements
270 if ($result && $arr) {
271 foreach($arr as $element) {
272 if ($element->getNext()) {
273 $i = $this->findObjectInArray($element->getNext(), $arr);
274 if ($i === NULL) {
275 $result = false;
280 /// Check that there aren't duplicates in the previous values
281 if ($result && $arr) {
282 $existarr = array();
283 foreach($arr as $element) {
284 if (in_array($element->getPrevious(), $existarr)) {
285 $result = false;
286 } else {
287 $existarr[] = $element->getPrevious();
291 /// Check that there aren't duplicates in the next values
292 if ($result && $arr) {
293 $existarr = array();
294 foreach($arr as $element) {
295 if (in_array($element->getNext(), $existarr)) {
296 $result = false;
297 } else {
298 $existarr[] = $element->getNext();
302 return $result;
306 * This function will order all the elements in one array, following
307 * the previous/next rules
309 function orderElements($arr) {
310 global $CFG;
311 $result = true;
312 if (!empty($CFG->xmldbdisablenextprevchecking)) {
313 return $arr;
315 /// Create a new array
316 $newarr = array();
317 if (!empty($arr)) {
318 $currentelement = NULL;
319 /// Get the element without previous
320 foreach($arr as $key => $element) {
321 if (!$element->getPrevious()) {
322 $currentelement = $arr[$key];
323 $newarr[0] = $arr[$key];
326 if (!$currentelement) {
327 $result = false;
329 /// Follow the next rules
330 $counter = 1;
331 while ($result && $currentelement->getNext()) {
332 $i = $this->findObjectInArray($currentelement->getNext(), $arr);
333 $currentelement = $arr[$i];
334 $newarr[$counter] = $arr[$i];
335 $counter++;
337 /// Compare number of elements between original and new array
338 if ($result && count($arr) != count($newarr)) {
339 $result = false;
341 /// Check that previous/next is ok (redundant but...)
342 if ($this->checkPreviousNextValues($newarr)) {
343 $result = $newarr;
344 } else {
345 $result = false;
347 } else {
348 $result = array();
350 return $result;
354 * Returns the position of one object in the array.
356 function &findObjectInArray($objectname, $arr) {
357 foreach ($arr as $i => $object) {
358 if ($objectname == $object->getName()) {
359 return $i;
362 $null = NULL;
363 return $null;
367 * This function will display a readable info about the XMLDBObject
368 * (should be implemented inside each XMLDBxxx object)
370 function readableInfo() {
371 return get_class($this);
375 * This function will perform the central debug of all the XMLDB classes
376 * being called automatically every time one error is found. Apart from
377 * the main actions performed in it (XMLDB agnostic) it looks for one
378 * function called xmldb_debug() and invokes it, passing both the
379 * message code and the whole object.
380 * So, to perform custom debugging just add such function to your libs.
382 * Call to the external hook function can be disabled by request by
383 * defining XMLDB_SKIP_DEBUG_HOOK
385 function debug($message) {
387 /// Check for xmldb_debug($message, $xmldb_object)
388 $funcname = 'xmldb_debug';
389 /// If exists and XMLDB_SKIP_DEBUG_HOOK is undefined
390 if (function_exists($funcname) && !defined('XMLDB_SKIP_DEBUG_HOOK')) {
391 $funcname($message, $this);
396 * Returns one array of elements from one comma separated string,
397 * supporting quoted strings containing commas and concat function calls
399 function comma2array($string) {
401 $arr = array();
403 $foundquotes = array();
404 $foundconcats = array();
406 /// Extract all the concat elements from the string
407 preg_match_all("/(CONCAT\(.*?\))/is", $string, $matches);
408 foreach (array_unique($matches[0]) as $key=>$value) {
409 $foundconcats['<#'.$key.'#>'] = $value;
411 if (!empty($foundconcats)) {
412 $string = str_replace($foundconcats,array_keys($foundconcats),$string);
415 /// Extract all the quoted elements from the string (skipping
416 /// backslashed quotes that are part of the content.
417 preg_match_all("/('.*?[^\\\]')/is", $string, $matches);
418 foreach (array_unique($matches[0]) as $key=>$value) {
419 $foundquotes['<%'.$key.'%>'] = $value;
421 if (!empty($foundquotes)) {
422 $string = str_replace($foundquotes,array_keys($foundquotes),$string);
425 /// Explode safely the string
426 $arr = explode (',', $string);
428 /// Put the concat and quoted elements back again, triming every element
429 if ($arr) {
430 foreach ($arr as $key => $element) {
431 /// Clear some spaces
432 $element = trim($element);
433 /// Replace the quoted elements if exists
434 if (!empty($foundquotes)) {
435 $element = str_replace(array_keys($foundquotes), $foundquotes, $element);
437 /// Replace the concat elements if exists
438 if (!empty($foundconcats)) {
439 $element = str_replace(array_keys($foundconcats), $foundconcats, $element);
441 /// Delete any backslash used for quotes. XMLDB stuff will add them before insert
442 $arr[$key] = str_replace("\\'", "'", $element);
446 return $arr;