[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 /**************************************************************************\ 3 * eGroupWare - Setup * 4 * http://www.egroupware.org * 5 * -------------------------------------------- * 6 * This file written by Miles Lott <milos@groupwhere.org> * 7 * Originally written for phpGroupWare. * 8 * (C) 2001-2004 Miles Lott * 9 * Upgrade process rewritten by <RalfBecker@outdoor-training.de> to no * 10 * longer require tables_baseline files and delta-upgrades * 11 * -------------------------------------------- * 12 * This program is free software; you can redistribute it and/or modify it * 13 * under the terms of the GNU General Public License as published by the * 14 * Free Software Foundation; either version 2 of the License, or (at your * 15 * option) any later version. * 16 \**************************************************************************/ 17 /* $Id: class.setup_process.inc.php 21308 2006-04-09 10:59:54Z ralfbecker $ */ 18 19 /* app status values: 20 U Upgrade required/available 21 R upgrade in pRogress 22 C upgrade Completed successfully 23 D Dependency failure 24 F upgrade Failed 25 V Version mismatch at end of upgrade (Not used, proposed only) 26 M Missing files at start of upgrade (Not used, proposed only) 27 */ 28 29 class setup_process 30 { 31 var $oProc; 32 var $tables; 33 var $updateincluded = array(); 34 var $translation; 35 36 function setup_process() 37 { 38 $this->translation =& CreateObject('setup.setup_translation'); 39 } 40 41 /** 42 * create schema_proc object 43 * 44 * @param none 45 */ 46 function init_process() 47 { 48 $GLOBALS['egw_setup']->oProc =& CreateObject('phpgwapi.schema_proc'); 49 } 50 51 /** 52 * the mother of all multipass upgrade parental loop functions 53 * 54 * @param array $setup_info array of application info from setup.inc.php files 55 * @param string $type='new' defaults to new(install), could also be 'upgrade' 56 * @param boolean $DEBUG=false print debugging info 57 * @param boolean $force_en=false install english language files 58 * @param string $system_charset=null charset to use 59 */ 60 function pass($setup_info,$method='new',$DEBUG=False,$force_en=False) 61 { 62 if(!$method) 63 { 64 return False; 65 } 66 // Place api first 67 $pass['phpgwapi'] = $setup_info['phpgwapi']; 68 $pass['admin'] = $setup_info['admin']; 69 $pass['preferences'] = $setup_info['preferences']; 70 @reset($setup_info); 71 $setup_info = $GLOBALS['egw_setup']->detection->get_versions($setup_info); 72 @reset($setup_info); 73 74 $i = 1; 75 $passed = array(); 76 $passing = array(); 77 $pass_string = implode (':', $pass); 78 $passing_string = implode (':', $passing); 79 $do_langs = false; 80 while($pass_string != $passing_string) 81 { 82 $passing = array(); 83 if($DEBUG) { echo '<br>process->pass(): #' . $i . ' for ' . $method . ' processing' . "\n"; } 84 /* Check current versions and dependencies */ 85 $setup_info = $GLOBALS['egw_setup']->detection->get_db_versions($setup_info); 86 $setup_info = $GLOBALS['egw_setup']->detection->compare_versions($setup_info); 87 //_debug_array($setup_info);exit; 88 $setup_info = $GLOBALS['egw_setup']->detection->check_depends($setup_info); 89 //if($i==2) { _debug_array($passed);exit; } 90 91 /* stuff the rest of the apps, but only those with available upgrades */ 92 while(list($key,$value) = @each($setup_info)) 93 { 94 if (isset($value['only_db']) && ( 95 is_array($value['only_db']) && !in_array($GLOBALS['egw_setup']->db->Type,$value['only_db']) || 96 !is_array($value['only_db']) && $GLOBALS['egw_setup']->db->Type != $value['only_db'])) 97 { 98 continue; // app does not support this db-type, dont try installing it 99 } 100 if(($value['name'] != 'phpgwapi') && ($value['status'] == 'U')) 101 { 102 if(($passed[$value['name']]['status'] != 'F') && ($passed[$value['name']]['status'] != 'C')) 103 { 104 $pass[$value['name']] = $setup_info[$value['name']]; 105 } 106 } 107 /* 108 Now if we are on the 2nd or more passes, add api in 109 if (!$pass['phpgwapi']) 110 { 111 $pass['phpgwapi'] = $setup_info['phpgwapi']; 112 } 113 */ 114 } 115 116 switch($method) 117 { 118 case 'new': 119 /* Create tables and insert new records for each app in this list */ 120 $passing = $this->current($pass,$DEBUG); 121 $this->save_minimal_config(); 122 $passing = $this->default_records($passing,$DEBUG); 123 $do_langs = true; // just do it once at the end of all passes 124 break; 125 case 'upgrade': 126 /* Run upgrade scripts on each app in the list */ 127 $passing = $this->upgrade($pass,$DEBUG); 128 $do_langs = true; // just do it once at the end of all passes 129 //_debug_array($pass);exit; 130 break; 131 default: 132 /* What the heck are you doing? */ 133 return False; 134 break; 135 } 136 137 $pass = array(); 138 @reset($passing); 139 while(list($key,$value) = @each($passing)) 140 { 141 if($value['status'] == 'C') 142 { 143 $passed[$value['name']] = $passing[$value['name']]; 144 if($DEBUG) { echo '<br>process->pass(): '.$passed[$value['name']]['name'] . ' install completed'."\n"; } 145 } 146 elseif($value['status'] == 'F') 147 { 148 $setup_info[$value['name']] = $passing[$value['name']]; 149 if($DEBUG) { echo '<br>process->pass(): '.$setup_info[$value['name']]['name'] . ' install failed'."\n"; } 150 } 151 elseif($value['status'] == 'D') 152 { 153 $pass[$value['name']] = $setup_info[$value['name']]; 154 if($DEBUG) { echo '<br>process->pass(): '.$pass[$value['name']]['name'] . ' fails dependency check on this pass'."\n"; } 155 } 156 else 157 { 158 $tmp = $passing[$value['name']]['name']; 159 if($DEBUG) { echo '<br>process->pass(): '.$tmp . ' skipped on this pass'."\n"; } 160 } 161 } 162 163 $i++; 164 if($i == 20) /* Then oops it broke */ 165 { 166 echo '<br>Setup failure: excess looping in process->pass():'."\n"; 167 echo '<br>Pass:<br>'."\n"; 168 _debug_array($pass); 169 echo '<br>Passed:<br>'."\n"; 170 _debug_array($passed); 171 exit; 172 } 173 $pass_string = implode (':', $pass); 174 $passing_string = implode (':', $passing); 175 } 176 if ($do_langs) // just do it once at the end of all passes 177 { 178 $langs = false; 179 if ($method == 'new') 180 { 181 $langs[] = ($own_lang = get_var('ConfigLang',Array('POST','COOKIE'))); 182 if ($own_lang != 'en') $langs[] = 'en'; 183 } 184 $this->translation->drop_add_all_langs($langs); 185 } 186 /* now return the list */ 187 return $setup_info = array_merge($setup_info,$passed); 188 } 189 190 /** 191 * saves a minimal default config, so you get a running install without entering and saveing Step #2 config 192 * 193 */ 194 function save_minimal_config() 195 { 196 $is_windows = strtoupper(substr(PHP_OS,0,3)) == 'WIN'; 197 198 $GLOBALS['current_config']['site_title'] = 'eGroupWare'; 199 $GLOBALS['current_config']['hostname'] = $_SERVER['HTTP_HOST']; 200 201 // guessing the phpGW url 202 $parts = explode('/',$_SERVER['PHP_SELF']); 203 array_pop($parts); // remove config.php 204 array_pop($parts); // remove setup 205 $GLOBALS['current_config']['webserver_url'] = implode('/',$parts); 206 $egroupwareDirName = end($parts); 207 208 if(!$is_windows) { 209 if(@is_dir('/tmp')) { 210 $GLOBALS['current_config']['temp_dir'] = '/tmp'; 211 } else { 212 $GLOBALS['current_config']['temp_dir'] = '/path/to/temp/dir'; 213 } 214 $GLOBALS['current_config']['files_dir'] = '/var/lib/'.$egroupwareDirName.'/'.$GLOBALS['egw_setup']->ConfigDomain.'/files'; 215 $GLOBALS['current_config']['backup_dir'] = '/var/lib/'.$egroupwareDirName.'/'.$GLOBALS['egw_setup']->ConfigDomain.'/backup'; 216 } else { 217 if(@is_dir('c:\\windows\\temp')) { 218 $GLOBALS['current_config']['temp_dir'] = 'c:\\windows\\temp'; 219 } else { 220 $GLOBALS['current_config']['temp_dir'] = 'c:\\path\\to\\temp\\dir'; 221 } 222 $GLOBALS['current_config']['files_dir'] = 'c:\\Program files\\'.$egroupwareDirName.'\\'.$GLOBALS['egw_setup']->ConfigDomain.'\\files'; 223 $GLOBALS['current_config']['backup_dir'] = 'c:\\Program files\\'.$egroupwareDirName.'\\'.$GLOBALS['egw_setup']->ConfigDomain.'\\backup'; 224 } 225 $datetime =& CreateObject('phpgwapi.datetime'); 226 $GLOBALS['current_config']['tz_offset'] = $datetime->getbestguess(); 227 unset($datetime); 228 229 // RalfBecker: php.net recommend this for security reasons, it should be our default too 230 $GLOBALS['current_config']['usecookies'] = 'True'; 231 232 if ($GLOBALS['egw_setup']->system_charset) 233 { 234 $GLOBALS['current_config']['system_charset'] = $GLOBALS['egw_setup']->system_charset; 235 } 236 237 foreach($GLOBALS['current_config'] as $name => $value) 238 { 239 $GLOBALS['egw_setup']->db->insert($GLOBALS['egw_setup']->config_table,array( 240 'config_value' => $value, 241 ),array( 242 'config_app' => 'phpgwapi', 243 'config_name' => $name, 244 ),__FILE__,__LINE__); 245 } 246 } 247 248 /** 249 * drop tables per application, check that they are in the db first 250 * 251 * @param $setup_info array of application info from setup.inc.php files, etc. 252 */ 253 function droptables($setup_info,$DEBUG=False) 254 { 255 if(!@$GLOBALS['egw_setup']->oProc) 256 { 257 $this->init_process(); 258 } 259 /* The following is built so below we won't try to drop a table that isn't there. */ 260 $tablenames = $GLOBALS['egw_setup']->db->table_names(); 261 if (!is_array($setup_info) || !is_array($tablenames)) 262 { 263 return $setup_info; // nothing to do 264 } 265 $tables = array(); 266 foreach($tablenames as $data) 267 { 268 $tables[] = $data['table_name']; 269 } 270 271 if (!is_array($setup_info)) 272 { 273 return $setup_info; 274 } 275 foreach($setup_info as $app_name => $data) 276 { 277 if(is_array($data['tables'])) 278 { 279 foreach($data['tables'] as $table) 280 { 281 //echo $table; 282 if(in_array($table,$tables)) 283 { 284 if($DEBUG){ echo '<br>process->droptables(): Dropping :'. $app_name . ' table: ' . $table; } 285 $GLOBALS['egw_setup']->oProc->DropTable($table); 286 // Update the array values for return below 287 $setup_info[$app_name]['status'] = 'U'; 288 } 289 } 290 } 291 } 292 293 /* Done, return current status */ 294 return $setup_info; 295 } 296 297 /** 298 * process current table setup in each application/setup dir 299 * 300 * @param array $setup_info array of application info from setup.inc.php files, etc. 301 * @param boolean $DEBUG=false 302 */ 303 function current($setup_info,$DEBUG=False) 304 { 305 if(!@$GLOBALS['egw_setup']->oProc) 306 { 307 $this->init_process(); 308 } 309 @reset($setup_info); 310 while(list($key,$null) = @each($setup_info)) 311 { 312 $enabled = False; 313 $appname = $setup_info[$key]['name']; 314 $apptitle = $setup_info[$key]['title']; 315 316 if($DEBUG) { echo '<br>process->current(): Incoming status: ' . $appname . ',status: '. $setup_info[$key]['status']; } 317 318 $appdir = EGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; 319 320 if($setup_info[$key]['tables'] && file_exists($appdir.'tables_current.inc.php')) 321 { 322 if($DEBUG) { echo '<br>process->current(): Including: ' . $appdir.'tables_current.inc.php'; } 323 include ($appdir.'tables_current.inc.php'); 324 $ret = $this->post_process($phpgw_baseline,$DEBUG); 325 if($ret) 326 { 327 if($GLOBALS['egw_setup']->app_registered($appname)) 328 { 329 $GLOBALS['egw_setup']->update_app($appname); 330 $GLOBALS['egw_setup']->update_hooks($appname); 331 } 332 else 333 { 334 $GLOBALS['egw_setup']->register_app($appname); 335 $GLOBALS['egw_setup']->register_hooks($appname); 336 } 337 // Update the array values for return below 338 $setup_info[$key]['status'] = 'C'; 339 } 340 else 341 { 342 /* script processing failed */ 343 if($DEBUG) { echo '<br>process->current(): Failed for ' . $appname . ',status: '. $setup_info[$key]['status']; } 344 $setup_info[$key]['status'] = 'F'; 345 } 346 } 347 else 348 { 349 if($DEBUG) { echo '<br>process->current(): No current tables for ' . $apptitle . "\n"; } 350 /* 351 Add the app, but disable it if it has tables defined. 352 A manual sql script install is needed, but we do add the hooks 353 */ 354 $enabled = 99; 355 if($setup_info[$key]['tables'][0] != '') 356 { 357 $enabled = False; 358 } 359 if($GLOBALS['egw_setup']->app_registered($appname)) 360 { 361 $GLOBALS['egw_setup']->update_app($appname); 362 $GLOBALS['egw_setup']->update_hooks($appname); 363 } 364 else 365 { 366 $GLOBALS['egw_setup']->register_app($appname,$enabled); 367 $GLOBALS['egw_setup']->register_hooks($appname); 368 } 369 $setup_info[$key]['status'] = 'C'; 370 } 371 if($DEBUG) { echo '<br>process->current(): Outgoing status: ' . $appname . ',status: '. $setup_info[$key]['status']; } 372 } 373 374 /* Done, return current status */ 375 return ($setup_info); 376 } 377 378 /** 379 * process default_records.inc.php in each application/setup dir 380 * 381 * @param $setup_info array of application info from setup.inc.php files, etc. 382 */ 383 function default_records($setup_info,$DEBUG=False) 384 { 385 if(!@$GLOBALS['egw_setup']->oProc) 386 { 387 $this->init_process(); 388 } 389 @reset($setup_info); 390 while(list($key,$null) = @each($setup_info)) 391 { 392 $appname = $setup_info[$key]['name']; 393 $appdir = EGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; 394 395 if($setup_info[$key]['tables'] && file_exists($appdir.'default_records.inc.php')) 396 { 397 if($DEBUG) 398 { 399 echo '<br>process->default_records(): Including default records for ' . $appname . "\n"; 400 } 401 $GLOBALS['egw_setup']->oProc->m_odb->transaction_begin(); 402 $oProc = &$GLOBALS['egw_setup']->oProc; // to be compatible with old apps 403 include ($appdir.'default_records.inc.php'); 404 $GLOBALS['egw_setup']->oProc->m_odb->transaction_commit(); 405 } 406 /* $setup_info[$key]['status'] = 'C'; */ 407 } 408 409 /* Done, return current status */ 410 return ($setup_info); 411 } 412 413 /** 414 * process test_data.inc.php in each application/setup dir for developer tests 415 * 416 * This data should work with the baseline tables 417 * @param $setup_info array of application info from setup.inc.php files, etc. 418 */ 419 function test_data($setup_info,$DEBUG=False) 420 { 421 if(!@$GLOBALS['egw_setup']->oProc) 422 { 423 $this->init_process(); 424 } 425 @reset($setup_info); 426 while(list($key,$null) = @each($setup_info)) 427 { 428 $appname = $setup_info[$key]['name']; 429 $appdir = EGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; 430 431 if(file_exists($appdir.'test_data.inc.php')) 432 { 433 if($DEBUG) 434 { 435 echo '<br>process->test_data(): Including baseline test data for ' . $appname . "\n"; 436 } 437 $GLOBALS['egw_setup']->oProc->m_odb->transaction_begin(); 438 include ($appdir.'test_data.inc.php'); 439 $GLOBALS['egw_setup']->oProc->m_odb->transaction_commit(); 440 } 441 } 442 443 /* Done, return current status */ 444 return ($setup_info); 445 } 446 447 /** 448 * process baseline table setup in each application/setup dir 449 * 450 * @param $appinfo array of application info from setup.inc.php files, etc. 451 */ 452 function baseline($setup_info,$DEBUG=False) 453 { 454 if(!@$GLOBALS['egw_setup']->oProc) 455 { 456 $this->init_process(); 457 } 458 459 @reset($setup_info); 460 while(list($key,$null) = @each($setup_info)) 461 { 462 $appname = $setup_info[$key]['name']; 463 $appdir = EGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; 464 465 if(file_exists($appdir.'tables_baseline.inc.php')) 466 { 467 if($DEBUG) 468 { 469 echo '<br>process->baseline(): Including baseline tables for ' . $appname . "\n"; 470 } 471 include ($appdir.'tables_baseline.inc.php'); 472 $GLOBALS['egw_setup']->oProc->GenerateScripts($phpgw_baseline, $DEBUG); 473 $this->post_process($phpgw_baseline,$DEBUG); 474 475 /* Update the array values for return below */ 476 /* $setup_info[$key]['status'] = 'R'; */ 477 } 478 else 479 { 480 if($DEBUG) 481 { 482 echo '<br>process->baseline(): No baseline tables for ' . $appname . "\n"; 483 } 484 //$setup_info[$key]['status'] = 'C'; 485 } 486 } 487 488 /* Done, return current status */ 489 return ($setup_info); 490 } 491 492 /** 493 * process available upgrades in each application/setup dir 494 * 495 * @param $appinfo array of application info from setup.inc.php files, etc. 496 */ 497 function upgrade($setup_info,$DEBUG=False) 498 { 499 if(!@$GLOBALS['egw_setup']->oProc) 500 { 501 $this->init_process(); 502 } 503 $GLOBALS['egw_setup']->oProc->m_odb->HaltOnError = 'yes'; 504 505 foreach($setup_info as $key => $appdata) 506 { 507 $appname = $appdata['name']; 508 /* Don't try to upgrade an app that is not installed */ 509 if(!$GLOBALS['egw_setup']->app_registered($appname)) 510 { 511 if($DEBUG) 512 { 513 echo "<p>process->upgrade(): Application not installed: $appname</p>\n"; 514 } 515 unset($setup_info[$appname]); 516 continue; 517 } 518 519 /* if upgrade required, or if we are running again after an upgrade or dependency failure */ 520 if($DEBUG) 521 { 522 echo '<div style="text-align: left; border: thin dashed black; margin-top: 5px;">'."process->upgrade(): Incoming : appname: $appname, version: $appdata[currentver], status: $appdata[status]\n"; 523 } 524 if($appdata['status'] == 'U' || $appdata['status'] == 'D' ||$appdata['status'] == 'V' || $appdata['status'] == '') // TODO this is not getting set for api upgrade, sometimes ??? 525 { 526 $currentver = $appdata['currentver']; 527 $targetver = $appdata['version']; // The version we need to match when done 528 $appdir = EGW_SERVER_ROOT . SEP . $appname . SEP . 'setup' . SEP; 529 530 if(file_exists($appdir . 'tables_update.inc.php') && !@$this->updateincluded[$appname]) 531 { 532 include ($appdir . 'tables_update.inc.php'); 533 $this->updateincluded[$appname] = True; 534 535 while ($currentver && $currentver != $targetver && 536 function_exists($function = $appname . '_upgrade' . str_replace('.','_',$currentver))) 537 { 538 if($DEBUG) 539 { 540 echo "<br>process->upgrade(): $appname($currentver --> $targetver): running $function()\n"; 541 } 542 if (!($currentver = $function())) 543 { 544 if($DEBUG) 545 { 546 echo "<b>failed!!!</b>\n"; 547 } 548 $appstatus = 'F'; 549 } 550 else 551 { 552 if($DEBUG) 553 { 554 echo "--> $currentver\n"; 555 } 556 } 557 } 558 if ($currentver == $targetver) // upgrades succesful 559 { 560 if($DEBUG) 561 { 562 echo "<br>process->upgrade(): Upgrade of $appname to $targetver is completed.\n"; 563 } 564 $appstatus = 'C'; 565 } 566 elseif ($currentver) 567 { 568 if($DEBUG) 569 { 570 echo "<br><b>process->upgrade(): No table upgrade available for appname: $appname, version: $currentver</b>\n"; 571 } 572 $setup_info[$key]['currentver'] = $targetver; 573 $appstatus = 'F'; 574 } 575 } 576 else 577 { 578 if($DEBUG) 579 { 580 echo "<br>process->upgrade(): No table upgrade required/availible for $appname\n"; 581 } 582 $appstatus = 'C'; 583 } 584 if ($appstatus == 'C') // update successful completed 585 { 586 $setup_info[$key]['currentver'] = $targetver; 587 588 if($GLOBALS['egw_setup']->app_registered($appname)) 589 { 590 $GLOBALS['egw_setup']->update_app($appname); 591 $GLOBALS['egw_setup']->update_hooks($appname); 592 } 593 else 594 { 595 $GLOBALS['egw_setup']->register_app($appname); 596 $GLOBALS['egw_setup']->register_hooks($appname); 597 } 598 } 599 600 } 601 else 602 { 603 if($DEBUG) 604 { 605 echo "<br>process->upgrade(): No upgrade required for $appname\n"; 606 } 607 $appstatus = 'C'; 608 } 609 /* Done with this app, update status */ 610 if($DEBUG) 611 { 612 echo "<br>process->upgrade(): Outgoing : appname: $appname, status: $appstatus</div>\n"; 613 } 614 $setup_info[$key]['status'] = $appstatus; 615 } 616 617 /* Done, return current status */ 618 return ($setup_info); 619 } 620 621 /** 622 * commit above processing to the db 623 * 624 */ 625 function post_process($tables,$DEBUG=False) 626 { 627 if(!$tables) 628 { 629 return False; 630 } 631 632 return $GLOBALS['egw_setup']->oProc->ExecuteScripts($tables,$DEBUG); 633 } 634 635 /** 636 * send this a table name, returns printable column spec and keys for the table from schema_proc 637 * 638 * @param $tablename table whose array you want to see 639 */ 640 function sql_to_array($tablename='') 641 { 642 if(!$tablename) 643 { 644 return False; 645 } 646 647 if(!$GLOBALS['egw_setup']->oProc) 648 { 649 $this->init_process(); 650 } 651 652 $GLOBALS['egw_setup']->oProc->m_oTranslator->_GetColumns($GLOBALS['egw_setup']->oProc, $tablename, $sColumns, $sColumnName); 653 654 while(list($key,$tbldata) = each($GLOBALS['egw_setup']->oProc->m_oTranslator->sCol)) 655 { 656 $arr .= $tbldata; 657 } 658 $pk = $GLOBALS['egw_setup']->oProc->m_oTranslator->pk; 659 $fk = $GLOBALS['egw_setup']->oProc->m_oTranslator->fk; 660 $ix = $GLOBALS['egw_setup']->oProc->m_oTranslator->ix; 661 $uc = $GLOBALS['egw_setup']->oProc->m_oTranslator->uc; 662 663 return array($arr,$pk,$fk,$ix,$uc); 664 } 665 } 666 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |