|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 00004 // // 00005 // NOTICE OF COPYRIGHT // 00006 // // 00007 // Moodle - Modular Object-Oriented Dynamic Learning Environment // 00008 // http://moodle.com // 00009 // // 00010 // Copyright (C) 1999 onwards Martin Dougiamas http://dougiamas.com // 00011 // (C) 2001-3001 Eloy Lafuente (stronk7) http://contiento.com // 00012 // // 00013 // This program is free software; you can redistribute it and/or modify // 00014 // it under the terms of the GNU General Public License as published by // 00015 // the Free Software Foundation; either version 2 of the License, or // 00016 // (at your option) any later version. // 00017 // // 00018 // This program is distributed in the hope that it will be useful, // 00019 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 00020 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 00021 // GNU General Public License for more details: // 00022 // // 00023 // http://www.gnu.org/copyleft/gpl.html // 00024 // // 00026 00028 00029 class xmldb_structure extends xmldb_object { 00030 00031 var $path; 00032 var $version; 00033 var $tables; 00034 00038 function __construct($name) { 00039 parent::__construct($name); 00040 $this->path = NULL; 00041 $this->version = NULL; 00042 $this->tables = array(); 00043 } 00044 00048 function getPath() { 00049 return $this->path; 00050 } 00051 00055 function getVersion() { 00056 return $this->version; 00057 } 00058 00062 function &getTable($tablename) { 00063 $i = $this->findTableInArray($tablename); 00064 if ($i !== NULL) { 00065 return $this->tables[$i]; 00066 } 00067 $null = NULL; 00068 return $null; 00069 } 00070 00074 function &findTableInArray($tablename) { 00075 foreach ($this->tables as $i => $table) { 00076 if ($tablename == $table->getName()) { 00077 return $i; 00078 } 00079 } 00080 $null = NULL; 00081 return $null; 00082 } 00083 00087 function orderTables() { 00088 $result = $this->orderElements($this->tables); 00089 if ($result) { 00090 $this->setTables($result); 00091 return true; 00092 } else { 00093 return false; 00094 } 00095 } 00096 00100 function &getTables() { 00101 return $this->tables; 00102 } 00103 00107 function setVersion($version) { 00108 $this->version = $version; 00109 } 00110 00115 function addTable(&$table, $after=NULL) { 00116 00118 $prevtable = NULL; 00119 $nexttable = NULL; 00120 00121 if (!$after) { 00122 $alltables =& $this->getTables(); 00123 if ($alltables) { 00124 end($alltables); 00125 $prevtable =& $alltables[key($alltables)]; 00126 } 00127 } else { 00128 $prevtable =& $this->getTable($after); 00129 } 00130 if ($prevtable && $prevtable->getNext()) { 00131 $nexttable =& $this->getTable($prevtable->getNext()); 00132 } 00133 00135 if ($prevtable) { 00136 $table->setPrevious($prevtable->getName()); 00137 $prevtable->setNext($table->getName()); 00138 } 00139 if ($nexttable) { 00140 $table->setNext($nexttable->getName()); 00141 $nexttable->setPrevious($table->getName()); 00142 } 00144 $table->setLoaded(true); 00145 $table->setChanged(true); 00147 $this->tables[] =& $table; 00149 $this->orderTables($this->tables); 00151 $this->calculateHash(true); 00153 $this->setVersion(userdate(time(), '%Y%m%d', 99, false)); 00154 $this->setChanged(true); 00155 } 00156 00160 function deleteTable($tablename) { 00161 00162 $table =& $this->getTable($tablename); 00163 if ($table) { 00164 $i = $this->findTableInArray($tablename); 00166 $prevtable =& $this->getTable($table->getPrevious()); 00167 $nexttable =& $this->getTable($table->getNext()); 00169 if ($prevtable) { 00170 $prevtable->setNext($table->getNext()); 00171 } 00172 if ($nexttable) { 00173 $nexttable->setPrevious($table->getPrevious()); 00174 } 00176 unset($this->tables[$i]); 00178 $this->orderTables($this->tables); 00180 $this->calculateHash(true); 00182 $this->setVersion(userdate(time(), '%Y%m%d', 99, false)); 00183 $this->setChanged(true); 00184 } 00185 } 00186 00190 function setTables(&$tables) { 00191 $this->tables = $tables; 00192 } 00193 00197 function arr2xmldb_structure($xmlarr) { 00198 00199 global $CFG; 00200 00201 $result = true; 00202 00207 00209 if (isset($xmlarr['XMLDB']['@']['PATH'])) { 00210 $this->path = trim($xmlarr['XMLDB']['@']['PATH']); 00211 } else { 00212 $this->errormsg = 'Missing PATH attribute'; 00213 $this->debug($this->errormsg); 00214 $result = false; 00215 } 00216 if (isset($xmlarr['XMLDB']['@']['VERSION'])) { 00217 $this->version = trim($xmlarr['XMLDB']['@']['VERSION']); 00218 } else { 00219 $this->errormsg = 'Missing VERSION attribute'; 00220 $this->debug($this->errormsg); 00221 $result = false; 00222 } 00223 if (isset($xmlarr['XMLDB']['@']['COMMENT'])) { 00224 $this->comment = trim($xmlarr['XMLDB']['@']['COMMENT']); 00225 } else if (!empty($CFG->xmldbdisablecommentchecking)) { 00226 $this->comment = ''; 00227 } else { 00228 $this->errormsg = 'Missing COMMENT attribute'; 00229 $this->debug($this->errormsg); 00230 $result = false; 00231 } 00232 00234 if (isset($xmlarr['XMLDB']['#']['TABLES']['0']['#']['TABLE'])) { 00235 foreach ($xmlarr['XMLDB']['#']['TABLES']['0']['#']['TABLE'] as $xmltable) { 00236 if (!$result) { //Skip on error 00237 continue; 00238 } 00239 $name = trim($xmltable['@']['NAME']); 00240 $table = new xmldb_table($name); 00241 $table->arr2xmldb_table($xmltable); 00242 $this->tables[] = $table; 00243 if (!$table->isLoaded()) { 00244 $this->errormsg = 'Problem loading table ' . $name; 00245 $this->debug($this->errormsg); 00246 $result = false; 00247 } 00248 } 00249 } else { 00250 $this->errormsg = 'Missing TABLES section'; 00251 $this->debug($this->errormsg); 00252 $result = false; 00253 } 00254 00256 if ($result && $this->tables) { 00258 if (!$this->checkNameValues($this->tables)) { 00259 $this->errormsg = 'Some TABLES name values are incorrect'; 00260 $this->debug($this->errormsg); 00261 $result = false; 00262 } 00264 $this->fixPrevNext($this->tables); 00265 if ($result && !$this->checkPreviousNextValues($this->tables)) { 00266 $this->errormsg = 'Some TABLES previous/next values are incorrect'; 00267 $this->debug($this->errormsg); 00268 $result = false; 00269 } 00271 if ($result && !$this->orderTables($this->tables)) { 00272 $this->errormsg = 'Error ordering the tables'; 00273 $this->debug($this->errormsg); 00274 $result = false; 00275 } 00276 } 00277 00279 if ($result) { 00280 $this->loaded = true; 00281 } 00282 $this->calculateHash(); 00283 return $result; 00284 } 00285 00289 function calculateHash($recursive = false) { 00290 if (!$this->loaded) { 00291 $this->hash = NULL; 00292 } else { 00293 $key = $this->name . $this->path . $this->comment; 00294 if ($this->tables) { 00295 foreach ($this->tables as $tbl) { 00296 $table =& $this->getTable($tbl->getName()); 00297 if ($recursive) { 00298 $table->calculateHash($recursive); 00299 } 00300 $key .= $table->getHash(); 00301 } 00302 } 00303 $this->hash = md5($key); 00304 } 00305 } 00306 00310 function xmlOutput() { 00311 $o = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n"; 00312 $o.= '<XMLDB PATH="' . $this->path . '"'; 00313 $o.= ' VERSION="' . $this->version . '"'; 00314 if ($this->comment) { 00315 $o.= ' COMMENT="' . htmlspecialchars($this->comment) . '"'."\n"; 00316 } 00317 $rel = array_fill(0, count(explode('/', $this->path)), '..'); 00318 $rel = implode('/', $rel); 00319 $o.= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'."\n"; 00320 $o.= ' xsi:noNamespaceSchemaLocation="'.$rel.'/lib/xmldb/xmldb.xsd"'."\n"; 00321 $o.= '>' . "\n"; 00323 if ($this->tables) { 00324 $o.= ' <TABLES>' . "\n"; 00325 foreach ($this->tables as $table) { 00326 $o.= $table->xmlOutput(); 00327 } 00328 $o.= ' </TABLES>' . "\n"; 00329 } 00330 $o.= '</XMLDB>'; 00331 00332 return $o; 00333 } 00334 00340 function getTableUses($tablename) { 00341 00342 $uses = array(); 00343 00346 $alltables = $this->getTables(); 00347 if ($alltables) { 00348 foreach ($alltables as $table) { 00349 $keys = $table->getKeys(); 00350 if ($keys) { 00351 foreach ($keys as $key) { 00352 if ($key->getType() == XMLDB_KEY_FOREIGN) { 00353 if ($tablename == $key->getRefTable()) { 00354 $uses[] = 'table ' . $table->getName() . ' key ' . $key->getName(); 00355 } 00356 } 00357 } 00358 } 00359 } 00360 } 00361 00363 if (!empty($uses)) { 00364 return $uses; 00365 } else { 00366 return false; 00367 } 00368 } 00369 00375 function getFieldUses($tablename, $fieldname) { 00376 00377 $uses = array(); 00378 00380 $table = $this->getTable($tablename); 00381 if ($keys = $table->getKeys()) { 00382 foreach ($keys as $key) { 00383 if (in_array($fieldname, $key->getFields()) || 00384 in_array($fieldname, $key->getRefFields())) { 00385 $uses[] = 'table ' . $table->getName() . ' key ' . $key->getName(); 00386 } 00387 } 00388 } 00390 $table = $this->getTable($tablename); 00391 if ($indexes = $table->getIndexes()) { 00392 foreach ($indexes as $index) { 00393 if (in_array($fieldname, $index->getFields())) { 00394 $uses[] = 'table ' . $table->getName() . ' index ' . $index->getName(); 00395 } 00396 } 00397 } 00400 $alltables = $this->getTables(); 00401 if ($alltables) { 00402 foreach ($alltables as $table) { 00403 $keys = $table->getKeys(); 00404 if ($keys) { 00405 foreach ($keys as $key) { 00406 if ($key->getType() == XMLDB_KEY_FOREIGN) { 00407 if ($tablename == $key->getRefTable()) { 00408 $reffieds = $key->getRefFields(); 00409 if (in_array($fieldname, $key->getRefFields())) { 00410 $uses[] = 'table ' . $table->getName() . ' key ' . $key->getName(); 00411 } 00412 } 00413 } 00414 } 00415 } 00416 } 00417 } 00418 00420 if (!empty($uses)) { 00421 return $uses; 00422 } else { 00423 return false; 00424 } 00425 } 00426 00432 function getKeyUses($tablename, $keyname) { 00433 00434 $uses = array(); 00435 00438 $mytable = $this->getTable($tablename); 00439 $mykey = $mytable->getKey($keyname); 00440 $alltables = $this->getTables(); 00441 if ($alltables && $mykey) { 00442 foreach ($alltables as $table) { 00443 $allkeys = $table->getKeys(); 00444 if ($allkeys) { 00445 foreach ($allkeys as $key) { 00446 if ($key->getType() != XMLDB_KEY_FOREIGN) { 00447 continue; 00448 } 00449 if ($key->getRefTable() == $tablename && 00450 implode(',', $key->getRefFields()) == implode(',', $mykey->getFields())) { 00451 $uses[] = 'table ' . $table->getName() . ' key ' . $key->getName(); 00452 } 00453 } 00454 } 00455 } 00456 } 00457 00459 if (!empty($uses)) { 00460 return $uses; 00461 } else { 00462 return false; 00463 } 00464 } 00465 00471 function getIndexUses($tablename, $indexname) { 00472 00473 $uses = array(); 00474 00477 00479 if (!empty($uses)) { 00480 return $uses; 00481 } else { 00482 return false; 00483 } 00484 } 00485 00491 function getAllErrors() { 00492 00493 $errors = array(); 00495 if ($this->getError()) { 00496 $errors[] = $this->getError(); 00497 } 00499 if ($tables = $this->getTables()) { 00500 foreach ($tables as $table) { 00501 if ($tableerrors = $table->getAllErrors()) { 00502 00503 } 00504 } 00506 if ($tableerrors) { 00507 $errors = array_merge($errors, $tableerrors); 00508 } 00509 } 00511 if (count($errors)) { 00512 return $errors; 00513 } else { 00514 return false; 00515 } 00516 } 00517 }