See Release Notes
Long Term Support Release
Differences Between: [Versions 401 and 402] [Versions 401 and 403]
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. 13 // 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/>. 16 17 /** 18 * This class represent the XMLDB base class where all the common pieces are defined 19 * 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 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 29 class xmldb_object { 30 31 /** @var string name of obejct */ 32 protected $name; 33 34 /** @var string comment on object */ 35 protected $comment; 36 37 /** @var xmldb_object */ 38 protected $previous; 39 40 /** @var xmldb_object */ 41 protected $next; 42 43 /** @var string hash of object */ 44 protected $hash; 45 46 /** @var bool is it loaded yet */ 47 protected $loaded; 48 49 /** @var bool was object changed */ 50 protected $changed; 51 52 /** @var string error message */ 53 protected $errormsg; 54 55 /** 56 * Creates one new xmldb_object 57 * @param string $name 58 */ 59 public function __construct($name) { 60 $this->name = $name; 61 $this->comment = null; 62 $this->previous = null; 63 $this->next = null; 64 $this->hash = null; 65 $this->loaded = false; 66 $this->changed = false; 67 $this->errormsg = null; 68 } 69 70 /** 71 * This function returns true/false, if the xmldb_object has been loaded 72 * @return bool 73 */ 74 public function isLoaded() { 75 return $this->loaded; 76 } 77 78 /** 79 * This function returns true/false, if the xmldb_object has changed 80 * @return bool 81 */ 82 public function hasChanged() { 83 return $this->changed; 84 } 85 86 /** 87 * This function returns the comment of one xmldb_object 88 * @return string 89 */ 90 public function getComment() { 91 return $this->comment; 92 } 93 94 /** 95 * This function returns the hash of one xmldb_object 96 * @return string 97 */ 98 public function getHash() { 99 return $this->hash; 100 } 101 102 /** 103 * This function will return the name of the previous xmldb_object 104 * @return xmldb_object 105 */ 106 public function getPrevious() { 107 return $this->previous; 108 } 109 110 /** 111 * This function will return the name of the next xmldb_object 112 * @return xmldb_object 113 */ 114 public function getNext() { 115 return $this->next; 116 } 117 118 /** 119 * This function will return the name of the xmldb_object 120 * @return string 121 */ 122 public function getName() { 123 return $this->name; 124 } 125 126 /** 127 * This function will return the error detected in the object 128 * @return string 129 */ 130 public function getError() { 131 return $this->errormsg; 132 } 133 134 /** 135 * This function will set the comment of the xmldb_object 136 * @param string $comment 137 */ 138 public function setComment($comment) { 139 $this->comment = $comment; 140 } 141 142 /** 143 * This function will set the previous of the xmldb_object 144 * @param xmldb_object $previous 145 */ 146 public function setPrevious($previous) { 147 $this->previous = $previous; 148 } 149 150 /** 151 * This function will set the next of the xmldb_object 152 * @param xmldb_object $next 153 */ 154 public function setNext($next) { 155 $this->next = $next; 156 } 157 158 /** 159 * This function will set the hash of the xmldb_object 160 * @param string $hash 161 */ 162 public function setHash($hash) { 163 $this->hash = $hash; 164 } 165 166 /** 167 * This function will set the loaded field of the xmldb_object 168 * @param bool $loaded 169 */ 170 public function setLoaded($loaded = true) { 171 $this->loaded = $loaded; 172 } 173 174 /** 175 * This function will set the changed field of the xmldb_object 176 * @param bool $changed 177 */ 178 public function setChanged($changed = true) { 179 $this->changed = $changed; 180 } 181 /** 182 * This function will set the name field of the xmldb_object 183 * @param string $name 184 */ 185 public function setName($name) { 186 $this->name = $name; 187 } 188 189 190 /** 191 * This function will check if one key name is ok or no (true/false) 192 * only lowercase a-z, 0-9 and _ are allowed 193 * @return bool 194 */ 195 public function checkName () { 196 $result = true; 197 198 if ($this->name != preg_replace('/[^a-z0-9_ -]/i', '', $this->name)) { 199 $result = false; 200 } 201 return $result; 202 } 203 204 /** 205 * This function will check that all the elements in one array 206 * have a correct name [a-z0-9_] 207 * @param array $arr 208 * @return bool 209 */ 210 public function checkNameValues($arr) { 211 $result = true; 212 // TODO: Perhaps, add support for reserved words 213 214 // Check the name only contains valid chars 215 if ($arr) { 216 foreach($arr as $element) { 217 if (!$element->checkName()) { 218 $result = false; 219 } 220 } 221 } 222 // Check there aren't duplicate names 223 if ($arr) { 224 $existing_fields = array(); 225 foreach($arr as $element) { 226 if (in_array($element->getName(), $existing_fields)) { 227 debugging('Object ' . $element->getName() . ' is duplicated!', DEBUG_DEVELOPER); 228 $result = false; 229 } 230 $existing_fields[] = $element->getName(); 231 } 232 } 233 return $result; 234 } 235 236 /** 237 * Reconstruct previous/next attributes. 238 * @param array $arr 239 * @return bool true if $arr modified 240 */ 241 public function fixPrevNext(&$arr) { 242 $tweaked = false; 243 244 $prev = null; 245 foreach ($arr as $key=>$el) { 246 $prev_value = $arr[$key]->previous; 247 $next_value = $arr[$key]->next; 248 249 $arr[$key]->next = null; 250 $arr[$key]->previous = null; 251 if ($prev !== null) { 252 $arr[$prev]->next = $arr[$key]->name; 253 $arr[$key]->previous = $arr[$prev]->name; 254 } 255 $prev = $key; 256 257 if ($prev_value != $arr[$key]->previous or $next_value != $arr[$key]->next) { 258 $tweaked = true; 259 } 260 } 261 262 return $tweaked; 263 } 264 265 /** 266 * This function will order all the elements in one array, following 267 * the previous/next rules 268 * @param array $arr 269 * @return array|bool 270 */ 271 public function orderElements($arr) { 272 $result = true; 273 274 // Create a new array 275 $newarr = array(); 276 if (!empty($arr)) { 277 $currentelement = null; 278 // Get the element without previous 279 foreach($arr as $key => $element) { 280 if (!$element->getPrevious()) { 281 $currentelement = $arr[$key]; 282 $newarr[0] = $arr[$key]; 283 } 284 } 285 if (!$currentelement) { 286 $result = false; 287 } 288 // Follow the next rules 289 $counter = 1; 290 while ($result && $currentelement->getNext()) { 291 $i = $this->findObjectInArray($currentelement->getNext(), $arr); 292 $currentelement = $arr[$i]; 293 $newarr[$counter] = $arr[$i]; 294 $counter++; 295 } 296 // Compare number of elements between original and new array 297 if ($result && count($arr) != count($newarr)) { 298 $result = false; 299 } else if ($newarr) { 300 $result = $newarr; 301 } else { 302 $result = false; 303 } 304 } else { 305 $result = array(); 306 } 307 return $result; 308 } 309 310 /** 311 * Returns the position of one object in the array. 312 * @param string $objectname 313 * @param array $arr 314 * @return mixed 315 */ 316 public function findObjectInArray($objectname, $arr) { 317 foreach ($arr as $i => $object) { 318 if ($objectname == $object->getName()) { 319 return $i; 320 } 321 } 322 return null; 323 } 324 325 /** 326 * This function will display a readable info about the xmldb_object 327 * (should be implemented inside each XMLDBxxx object) 328 * @return string 329 */ 330 public function readableInfo() { 331 return get_class($this); 332 } 333 334 /** 335 * This function will perform the central debug of all the XMLDB classes 336 * being called automatically every time one error is found. Apart from 337 * the main actions performed in it (XMLDB agnostic) it looks for one 338 * function called xmldb_debug() and invokes it, passing both the 339 * message code and the whole object. 340 * So, to perform custom debugging just add such function to your libs. 341 * 342 * Call to the external hook function can be disabled by request by 343 * defining XMLDB_SKIP_DEBUG_HOOK 344 * @param string $message 345 */ 346 public function debug($message) { 347 348 // Check for xmldb_debug($message, $xmldb_object) 349 $funcname = 'xmldb_debug'; 350 // If exists and XMLDB_SKIP_DEBUG_HOOK is undefined 351 if (function_exists($funcname) && !defined('XMLDB_SKIP_DEBUG_HOOK')) { 352 $funcname($message, $this); 353 } 354 } 355 356 /** 357 * Returns one array of elements from one comma separated string, 358 * supporting quoted strings containing commas and concat function calls 359 * @param string $string 360 * @return array 361 */ 362 public function comma2array($string) { 363 364 $foundquotes = array(); 365 $foundconcats = array(); 366 367 // Extract all the concat elements from the string 368 preg_match_all("/(CONCAT\(.*?\))/is", $string, $matches); 369 foreach (array_unique($matches[0]) as $key=>$value) { 370 $foundconcats['<#'.$key.'#>'] = $value; 371 } 372 if (!empty($foundconcats)) { 373 $string = str_replace($foundconcats,array_keys($foundconcats),$string); 374 } 375 376 // Extract all the quoted elements from the string (skipping 377 // backslashed quotes that are part of the content. 378 preg_match_all("/(''|'.*?[^\\\\]')/is", $string, $matches); 379 foreach (array_unique($matches[0]) as $key=>$value) { 380 $foundquotes['<%'.$key.'%>'] = $value; 381 } 382 if (!empty($foundquotes)) { 383 $string = str_replace($foundquotes,array_keys($foundquotes),$string); 384 } 385 386 // Explode safely the string 387 $arr = explode (',', $string); 388 389 // Put the concat and quoted elements back again, trimming every element 390 if ($arr) { 391 foreach ($arr as $key => $element) { 392 // Clear some spaces 393 $element = trim($element); 394 // Replace the quoted elements if exists 395 if (!empty($foundquotes)) { 396 $element = str_replace(array_keys($foundquotes), $foundquotes, $element); 397 } 398 // Replace the concat elements if exists 399 if (!empty($foundconcats)) { 400 $element = str_replace(array_keys($foundconcats), $foundconcats, $element); 401 } 402 // Delete any backslash used for quotes. XMLDB stuff will add them before insert 403 $arr[$key] = str_replace("\\'", "'", $element); 404 } 405 } 406 407 return $arr; 408 } 409 410 /** 411 * Validates the definition of objects and returns error message. 412 * 413 * The error message should not be localised because it is intended for developers, 414 * end users and admins should never see these problems! 415 * 416 * @param xmldb_table $xmldb_table optional when object is table 417 * @return string null if ok, error message if problem found 418 */ 419 public function validateDefinition(xmldb_table $xmldb_table=null) { 420 return null; 421 } 422 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body