See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 one XMLDB Key 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_key extends xmldb_object { 30 31 /** @var int type of key */ 32 protected $type; 33 34 /** @var array of fields */ 35 protected $fields; 36 37 /** @var string referenced table */ 38 protected $reftable; 39 40 /** @var array referenced fields */ 41 protected $reffields; 42 43 /** 44 * Creates one new xmldb_key 45 * @param string $name 46 * @param string $type XMLDB_KEY_[PRIMARY|UNIQUE|FOREIGN|FOREIGN_UNIQUE] 47 * @param array $fields an array of fieldnames to build the key over 48 * @param string $reftable name of the table the FK points to or null 49 * @param array $reffields an array of fieldnames in the FK table or null 50 */ 51 public function __construct($name, $type=null, $fields=array(), $reftable=null, $reffields=null) { 52 $this->type = null; 53 $this->fields = array(); 54 $this->reftable = null; 55 $this->reffields = array(); 56 parent::__construct($name); 57 $this->set_attributes($type, $fields, $reftable, $reffields); 58 } 59 60 /** 61 * Set all the attributes of one xmldb_key 62 * 63 * @param string $type XMLDB_KEY_[PRIMARY|UNIQUE|FOREIGN|FOREIGN_UNIQUE] 64 * @param array $fields an array of fieldnames to build the key over 65 * @param string $reftable name of the table the FK points to or null 66 * @param array $reffields an array of fieldnames in the FK table or null 67 */ 68 public function set_attributes($type, $fields, $reftable=null, $reffields=null) { 69 $this->type = $type; 70 $this->fields = $fields; 71 $this->reftable = $reftable; 72 $this->reffields = empty($reffields) ? array() : $reffields; 73 } 74 75 /** 76 * Get the key type 77 * @return int 78 */ 79 public function getType() { 80 return $this->type; 81 } 82 83 /** 84 * Set the key type 85 * @param int $type 86 */ 87 public function setType($type) { 88 $this->type = $type; 89 } 90 91 /** 92 * Set the key fields 93 * @param array $fields 94 */ 95 public function setFields($fields) { 96 $this->fields = $fields; 97 } 98 99 /** 100 * Set the key reftable 101 * @param string $reftable 102 */ 103 public function setRefTable($reftable) { 104 $this->reftable = $reftable; 105 } 106 107 /** 108 * Set the key reffields 109 * @param array $reffields 110 */ 111 public function setRefFields($reffields) { 112 $this->reffields = $reffields; 113 } 114 115 /** 116 * Get the key fields 117 * @return array 118 */ 119 public function getFields() { 120 return $this->fields; 121 } 122 123 /** 124 * Get the key reftable 125 * @return string 126 */ 127 public function getRefTable() { 128 return $this->reftable; 129 } 130 131 /** 132 * Get the key reffields 133 * @return array reference to ref fields 134 */ 135 public function getRefFields() { 136 return $this->reffields; 137 } 138 139 /** 140 * Load data from XML to the key 141 * @param array $xmlarr 142 * @return bool success 143 */ 144 public function arr2xmldb_key($xmlarr) { 145 146 $result = true; 147 148 // Debug the table 149 // traverse_xmlize($xmlarr); //Debug 150 // print_object ($GLOBALS['traverse_array']); //Debug 151 // $GLOBALS['traverse_array']=""; //Debug 152 153 // Process key attributes (name, type, fields, reftable, 154 // reffields, comment, previous, next) 155 if (isset($xmlarr['@']['NAME'])) { 156 $this->name = trim($xmlarr['@']['NAME']); 157 } else { 158 $this->errormsg = 'Missing NAME attribute'; 159 $this->debug($this->errormsg); 160 $result = false; 161 } 162 163 if (isset($xmlarr['@']['TYPE'])) { 164 // Check for valid type 165 $type = $this->getXMLDBKeyType(trim($xmlarr['@']['TYPE'])); 166 if ($type) { 167 $this->type = $type; 168 } else { 169 $this->errormsg = 'Invalid TYPE attribute'; 170 $this->debug($this->errormsg); 171 $result = false; 172 } 173 } else { 174 $this->errormsg = 'Missing TYPE attribute'; 175 $this->debug($this->errormsg); 176 $result = false; 177 } 178 179 if (isset($xmlarr['@']['FIELDS'])) { 180 $fields = strtolower(trim($xmlarr['@']['FIELDS'])); 181 if ($fields) { 182 $fieldsarr = explode(',',$fields); 183 if ($fieldsarr) { 184 foreach ($fieldsarr as $key => $element) { 185 $fieldsarr [$key] = trim($element); 186 } 187 } else { 188 $this->errormsg = 'Incorrect FIELDS attribute (comma separated of fields)'; 189 $this->debug($this->errormsg); 190 $result = false; 191 } 192 } else { 193 $this->errormsg = 'Empty FIELDS attribute'; 194 $this->debug($this->errormsg); 195 $result = false; 196 } 197 } else { 198 $this->errormsg = 'Missing FIELDS attribute'; 199 $this->debug($this->errormsg); 200 $result = false; 201 } 202 // Finally, set the array of fields 203 $this->fields = $fieldsarr; 204 205 if (isset($xmlarr['@']['REFTABLE'])) { 206 // Check we are in a FK 207 if ($this->type == XMLDB_KEY_FOREIGN || 208 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 209 $reftable = strtolower(trim($xmlarr['@']['REFTABLE'])); 210 if (!$reftable) { 211 $this->errormsg = 'Empty REFTABLE attribute'; 212 $this->debug($this->errormsg); 213 $result = false; 214 } 215 } else { 216 $this->errormsg = 'Wrong REFTABLE attribute (only FK can have it)'; 217 $this->debug($this->errormsg); 218 $result = false; 219 } 220 } else if ($this->type == XMLDB_KEY_FOREIGN || 221 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 222 $this->errormsg = 'Missing REFTABLE attribute'; 223 $this->debug($this->errormsg); 224 $result = false; 225 } 226 // Finally, set the reftable 227 if ($this->type == XMLDB_KEY_FOREIGN || 228 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 229 $this->reftable = $reftable; 230 } 231 232 if (isset($xmlarr['@']['REFFIELDS'])) { 233 // Check we are in a FK 234 if ($this->type == XMLDB_KEY_FOREIGN || 235 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 236 $reffields = strtolower(trim($xmlarr['@']['REFFIELDS'])); 237 if ($reffields) { 238 $reffieldsarr = explode(',',$reffields); 239 if ($reffieldsarr) { 240 foreach ($reffieldsarr as $key => $element) { 241 $reffieldsarr [$key] = trim($element); 242 } 243 } else { 244 $this->errormsg = 'Incorrect REFFIELDS attribute (comma separated of fields)'; 245 $this->debug($this->errormsg); 246 $result = false; 247 } 248 } else { 249 $this->errormsg = 'Empty REFFIELDS attribute'; 250 $this->debug($this->errormsg); 251 $result = false; 252 } 253 } else { 254 $this->errormsg = 'Wrong REFFIELDS attribute (only FK can have it)'; 255 $this->debug($this->errormsg); 256 $result = false; 257 } 258 } else if ($this->type == XMLDB_KEY_FOREIGN || 259 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 260 $this->errormsg = 'Missing REFFIELDS attribute'; 261 $this->debug($this->errormsg); 262 $result = false; 263 } 264 // Finally, set the array of reffields 265 if ($this->type == XMLDB_KEY_FOREIGN || 266 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 267 $this->reffields = $reffieldsarr; 268 } 269 270 if (isset($xmlarr['@']['COMMENT'])) { 271 $this->comment = trim($xmlarr['@']['COMMENT']); 272 } 273 274 // Set some attributes 275 if ($result) { 276 $this->loaded = true; 277 } 278 $this->calculateHash(); 279 return $result; 280 } 281 282 /** 283 * This function returns the correct XMLDB_KEY_XXX value for the 284 * string passed as argument 285 * @param string $type 286 * @return int 287 */ 288 public function getXMLDBKeyType($type) { 289 290 $result = XMLDB_KEY_INCORRECT; 291 292 switch (strtolower($type)) { 293 case 'primary': 294 $result = XMLDB_KEY_PRIMARY; 295 break; 296 case 'unique': 297 $result = XMLDB_KEY_UNIQUE; 298 break; 299 case 'foreign': 300 $result = XMLDB_KEY_FOREIGN; 301 break; 302 case 'foreign-unique': 303 $result = XMLDB_KEY_FOREIGN_UNIQUE; 304 break; 305 // case 'check': //Not supported 306 // $result = XMLDB_KEY_CHECK; 307 // break; 308 } 309 // Return the normalized XMLDB_KEY 310 return $result; 311 } 312 313 /** 314 * This function returns the correct name value for the 315 * XMLDB_KEY_XXX passed as argument 316 * @param int $type 317 * @return string 318 */ 319 public function getXMLDBKeyName($type) { 320 321 $result = ''; 322 323 switch ($type) { 324 case XMLDB_KEY_PRIMARY: 325 $result = 'primary'; 326 break; 327 case XMLDB_KEY_UNIQUE: 328 $result = 'unique'; 329 break; 330 case XMLDB_KEY_FOREIGN: 331 $result = 'foreign'; 332 break; 333 case XMLDB_KEY_FOREIGN_UNIQUE: 334 $result = 'foreign-unique'; 335 break; 336 // case XMLDB_KEY_CHECK: //Not supported 337 // $result = 'check'; 338 // break; 339 } 340 // Return the normalized name 341 return $result; 342 } 343 344 /** 345 * This function calculate and set the hash of one xmldb_key 346 * @param bool $recursive 347 */ 348 public function calculateHash($recursive = false) { 349 if (!$this->loaded) { 350 $this->hash = null; 351 } else { 352 $key = $this->type . implode(', ', $this->fields); 353 if ($this->type == XMLDB_KEY_FOREIGN || 354 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 355 $key .= $this->reftable . implode(', ', $this->reffields); 356 } 357 ; 358 $this->hash = md5($key); 359 } 360 } 361 362 /** 363 *This function will output the XML text for one key 364 * @return string 365 */ 366 public function xmlOutput() { 367 $o = ''; 368 $o.= ' <KEY NAME="' . $this->name . '"'; 369 $o.= ' TYPE="' . $this->getXMLDBKeyName($this->type) . '"'; 370 $o.= ' FIELDS="' . implode(', ', $this->fields) . '"'; 371 if ($this->type == XMLDB_KEY_FOREIGN || 372 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 373 $o.= ' REFTABLE="' . $this->reftable . '"'; 374 $o.= ' REFFIELDS="' . implode(', ', $this->reffields) . '"'; 375 } 376 if ($this->comment) { 377 $o.= ' COMMENT="' . htmlspecialchars($this->comment, ENT_COMPAT) . '"'; 378 } 379 $o.= '/>' . "\n"; 380 381 return $o; 382 } 383 384 /** 385 * This function will set all the attributes of the xmldb_key object 386 * based on information passed in one ADOkey 387 * @oaram array $adokey 388 */ 389 public function setFromADOKey($adokey) { 390 391 // Calculate the XMLDB_KEY 392 switch (strtolower($adokey['name'])) { 393 case 'primary': 394 $this->type = XMLDB_KEY_PRIMARY; 395 break; 396 default: 397 $this->type = XMLDB_KEY_UNIQUE; 398 } 399 // Set the fields, converting all them to lowercase 400 $fields = array_flip(array_change_key_case(array_flip($adokey['columns']))); 401 $this->fields = $fields; 402 // Some more fields 403 $this->loaded = true; 404 $this->changed = true; 405 } 406 407 /** 408 * Returns the PHP code needed to define one xmldb_key 409 * @return string 410 */ 411 public function getPHP() { 412 413 $result = ''; 414 415 // The type 416 switch ($this->getType()) { 417 case XMLDB_KEY_PRIMARY: 418 $result .= 'XMLDB_KEY_PRIMARY' . ', '; 419 break; 420 case XMLDB_KEY_UNIQUE: 421 $result .= 'XMLDB_KEY_UNIQUE' . ', '; 422 break; 423 case XMLDB_KEY_FOREIGN: 424 $result .= 'XMLDB_KEY_FOREIGN' . ', '; 425 break; 426 case XMLDB_KEY_FOREIGN_UNIQUE: 427 $result .= 'XMLDB_KEY_FOREIGN_UNIQUE' . ', '; 428 break; 429 } 430 // The fields 431 $keyfields = $this->getFields(); 432 if (!empty($keyfields)) { 433 $result .= "['". implode("', '", $keyfields) . "']"; 434 } else { 435 $result .= 'null'; 436 } 437 // The FKs attributes 438 if ($this->getType() == XMLDB_KEY_FOREIGN || 439 $this->getType() == XMLDB_KEY_FOREIGN_UNIQUE) { 440 // The reftable 441 $reftable = $this->getRefTable(); 442 if (!empty($reftable)) { 443 $result .= ", '" . $reftable . "', "; 444 } else { 445 $result .= 'null, '; 446 } 447 // The reffields 448 $reffields = $this->getRefFields(); 449 if (!empty($reffields)) { 450 $result .= "['". implode("', '", $reffields) . "']"; 451 } else { 452 $result .= 'null'; 453 } 454 } 455 // Return result 456 return $result; 457 } 458 459 /** 460 * Shows info in a readable format 461 * @return string 462 */ 463 public function readableInfo() { 464 $o = ''; 465 // type 466 $o .= $this->getXMLDBKeyName($this->type); 467 // fields 468 $o .= ' (' . implode(', ', $this->fields) . ')'; 469 // foreign key 470 if ($this->type == XMLDB_KEY_FOREIGN || 471 $this->type == XMLDB_KEY_FOREIGN_UNIQUE) { 472 $o .= ' references ' . $this->reftable . ' (' . implode(', ', $this->reffields) . ')'; 473 } 474 475 return $o; 476 } 477 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body