| [ Index ] |
|
Code source de LifeType 1.2.4 |
1 |<?php 2 3 if (!defined( "PLOG_CLASS_PATH" )) { 4 define( "PLOG_CLASS_PATH", dirname(__FILE__)."/"); 5 } 6 7 set_time_limit (5 * 3600); 8 9 // 10 // enable this for debugging purposes 11 // 12 define( "DB_WIZARD_DEBUG", false ); 13 14 // 15 // in case you're having problems with time outs while upgrading (probably too 16 // many records) lower this figure 17 // 18 define( "WIZARD_MAX_RECORDS_PER_STEP", 75 ); 19 20 // 21 // minimum php version required 22 // 23 define( "MIN_PHP_VERSION", "4.2.0" ); 24 25 // 26 // whether data transformers should fail on error by default 27 // It might be convenient to set this to 'false' if we're running 28 // the wizard on top of an already updated installation 29 // 30 define( "DATABASE_DATA_TRANSFORMER_FAIL_ON_ERROR_DEFAULT", true ); 31 32 // many hosts don't have this enabled and we, for the time being, need it... 33 ini_set("arg_seperator.output", "&"); 34 35 include_once ( PLOG_CLASS_PATH."class/bootstrap.php" ); 36 lt_include( PLOG_CLASS_PATH."class/controller/controller.class.php" ); 37 lt_include( PLOG_CLASS_PATH."class/template/templateservice.class.php" ); 38 lt_include( PLOG_CLASS_PATH."class/action/action.class.php" ); 39 lt_include( PLOG_CLASS_PATH."class/database/db.class.php" ); 40 lt_include( PLOG_CLASS_PATH."class/template/template.class.php" ); 41 lt_include( PLOG_CLASS_PATH."class/view/view.class.php" ); 42 lt_include( PLOG_CLASS_PATH."class/data/validator/usernamevalidator.class.php" ); 43 lt_include( PLOG_CLASS_PATH."class/data/validator/stringvalidator.class.php" ); 44 lt_include( PLOG_CLASS_PATH."class/data/validator/integervalidator.class.php" ); 45 lt_include( PLOG_CLASS_PATH."class/data/validator/emailvalidator.class.php" ); 46 lt_include( PLOG_CLASS_PATH."class/data/validator/passwordvalidator.class.php" ); 47 lt_include( PLOG_CLASS_PATH."class/data/timestamp.class.php" ); 48 lt_include( PLOG_CLASS_PATH."class/net/http/httpvars.class.php" ); 49 lt_include( PLOG_CLASS_PATH."class/misc/version.class.php" ); 50 lt_include( PLOG_CLASS_PATH."class/file/file.class.php" ); 51 lt_include( PLOG_CLASS_PATH."class/file/finder/filefinder.class.php" ); 52 lt_include( PLOG_CLASS_PATH."class/gallery/resizers/gddetector.class.php" ); 53 lt_include( PLOG_CLASS_PATH."class/config/configfilestorage.class.php" ); 54 lt_include( PLOG_CLASS_PATH."class/data/textfilter.class.php" ); 55 lt_include( PLOG_CLASS_PATH."class/locale/locales.class.php" ); 56 lt_include( PLOG_CLASS_PATH."class/locale/localefinder.class.php" ); 57 lt_include( PLOG_CLASS_PATH."class/template/templatesets/templatesets.class.php" ); 58 lt_include( PLOG_CLASS_PATH."class/dao/bloginfo.class.php" ); 59 lt_include( PLOG_CLASS_PATH."class/dao/users.class.php" ); 60 lt_include( PLOG_CLASS_PATH."class/dao/blogs.class.php" ); 61 lt_include( PLOG_CLASS_PATH."class/dao/articlecategories.class.php" ); 62 lt_include( PLOG_CLASS_PATH."class/dao/articles.class.php" ); 63 lt_include( PLOG_CLASS_PATH."class/dao/mylinkscategories.class.php" ); 64 lt_include( PLOG_CLASS_PATH."class/dao/userpermissions.class.php" ); 65 lt_include( PLOG_CLASS_PATH."class/dao/blogcategories.class.php" ); 66 lt_include( PLOG_CLASS_PATH."class/dao/globalarticlecategories.class.php" ); 67 lt_include( PLOG_CLASS_PATH."class/gallery/dao/galleryalbums.class.php" ); 68 lt_include( PLOG_CLASS_PATH."class/dao/permissions.class.php" ); 69 lt_include( PLOG_CLASS_PATH."class/dao/userpermissions.class.php" ); 70 lt_include( PLOG_CLASS_PATH."class/dao/permission.class.php" ); 71 lt_include( PLOG_CLASS_PATH."class/dao/userpermission.class.php" ); 72 lt_include( PLOG_CLASS_PATH."class/dao/userinfo.class.php" ); 73 lt_include( PLOG_CLASS_PATH."class/misc/integritychecker.class.php" ); 74 75 // table schemas 76 include ( PLOG_CLASS_PATH."install/dbschemas.properties.php" ); 77 // default configuration values for 1.1 78 include ( PLOG_CLASS_PATH."install/defaultconfig.properties.php" ); 79 80 define( "TEMP_FOLDER", "./tmp" ); 81 82 // maps used to map requests with actions 83 $_actionMap["Checks"] = "WizardChecks"; 84 $_actionMap["Default"] = "WizardChecks"; 85 $_actionMap["Intro"] = "WizardIntro"; 86 $_actionMap["Step1"] = "WizardStepOne"; 87 $_actionMap["Step2"] = "WizardStepTwo"; 88 $_actionMap["Step3"] = "WizardStepThree"; 89 $_actionMap["Step4"] = "WizardStepFour"; 90 $_actionMap["Step5"] = "WizardStepFive"; 91 $_actionMap["Update1"] = "UpdateStepOne"; 92 $_actionMap["Update2"] = "UpdateStepTwo"; 93 $_actionMap["Update3"] = "UpdateStepThree"; 94 $_actionMap["Fix120"] = "Fix120StepOne"; 95 96 97 /** 98 * Open a connection to the database 99 */ 100 function connectDb( $ignoreError = false , $selectDatabase = true ) 101 { 102 $config = new ConfigFileStorage(); 103 // open a connection to the database 104 //$db = NewADOConnection('mysql'); 105 $db = PDb::getDriver('mysql'); 106 107 if ( $selectDatabase ) { 108 $res = $db->Connect($config->getValue( "db_host" ), $config->getValue( "db_username" ), $config->getValue( "db_password" ), $config->getValue( "db_database" ), $config->getValue( "db_character_set" )); 109 } else { 110 $res = $db->Connect($config->getValue( "db_host" ), $config->getValue( "db_username" ), $config->getValue( "db_password" ), null, $config->getValue( "db_character_set" )); 111 } 112 113 if( DB_WIZARD_DEBUG ) 114 $db->debug = true; 115 116 // return error 117 if( $ignoreError ) 118 return $db; 119 120 if( !$res ) 121 return false; 122 123 return $db; 124 } 125 126 /** 127 * Returns the database prefix 128 */ 129 function getDbPrefix() 130 { 131 $config = new ConfigFileStorage(); 132 return $config->getValue( "db_prefix" ); 133 } 134 135 /** 136 * some useful little functions 137 */ 138 class WizardTools 139 { 140 /** 141 * returns true if plog has already been installed before or 142 * false otherwise 143 */ 144 function isNewInstallation() 145 { 146 $configFile = new ConfigFileStorage(); 147 // if plog hasn't been installed, this file will have empty settings 148 if( $configFile->getValue( "db_host") == "" && $configFile->getValue( "db_username") == "" && 149 $configFile->getValue( "db_database") == "" && $configFile->getValue( "db_prefix" ) == "" && 150 $configFile->getValue( "db_password" ) == "" ) 151 $isNew = true; 152 else 153 $isNew = false; 154 155 return( $isNew ); 156 } 157 158 /** 159 * Clean up the default temporary folder 160 */ 161 function cleanTmpFolder() 162 { 163 // remove the files recursively, but only files, do not do anything to directories 164 File::deleteDir( TEMP_FOLDER, true, true, array(".svn", ".htaccess") ); 165 } 166 } 167 168 /** 169 * Renders a template file. 170 */ 171 class WizardView extends View 172 { 173 174 var $_templateName; 175 176 function WizardView( $templateName ) 177 { 178 $this->View(); 179 $this->_templateName = $templateName; 180 } 181 182 function render() 183 { 184 // build the file name 185 $templateFileName = "wizard/".$this->_templateName.".template"; 186 187 //$t = new Template( $templateFileName, "" ); 188 $t = new Smarty(); 189 $v = new Version(); 190 $this->_params->setValue( "version", $v->getVersion()); 191 $this->_params->setValue( "projectPage", $v->getProjectPage()); 192 $this->_params->setValue( "safeMode", ini_get("safe_mode")); 193 $t->assign( $this->_params->getAsArray()); 194 $t->template_dir = "./templates"; 195 $t->compile_dir = TEMP_FOLDER; 196 $t->cache_dir = TEMP_FOLDER; 197 $t->use_sub_dirs = false; 198 $t->caching = false; 199 200 print $t->fetch( $templateFileName ); 201 } 202 } 203 204 class WizardAction extends Action 205 { 206 function WizardAction( $actionInfo, $request ) 207 { 208 $this->Action( $actionInfo, $request ); 209 } 210 } 211 212 class WizardValidator 213 { 214 var $_desc; 215 var $_critical; 216 var $_valid; 217 var $_solution; 218 219 function WizardValidator( $desc = "", $solution = "", $critical = true ) 220 { 221 $this->_desc = $desc; 222 $this->_critical = $critical; 223 $this->_valid = false; 224 $this->_solution = $solution; 225 } 226 227 function isCritical() 228 { 229 return( $this->_critical ); 230 } 231 232 function getDesc() 233 { 234 return( $this->_desc ); 235 } 236 237 function isValid() 238 { 239 return( $this->_valid ); 240 } 241 242 function getSolution() 243 { 244 return( $this->_solution ); 245 } 246 247 function validate() 248 { 249 return( $this->_valid ); 250 } 251 } 252 253 class WizardPhpVersionValidator extends WizardValidator 254 { 255 function WizardPhpVersionValidator( $minVersion = MIN_PHP_VERSION ) 256 { 257 $this->WizardValidator( "Checking if the installed <b>PHP</b> version is at least $minVersion", 258 "Please upgrade your version of PHP to $minVersion or newer", 259 true ); 260 $this->_minVersion = $minVersion; 261 } 262 263 function validate() 264 { 265 $this->_valid = version_compare( phpversion(), $this->_minVersion ) >= 0; 266 return( parent::validate()); 267 } 268 } 269 270 class WizardWritableFileValidator extends WizardValidator 271 { 272 var $_file; 273 274 function WizardWritableFileValidator( $file ) 275 { 276 $this->WizardValidator( "Checking if file/folder <b>$file</b> is writable", 277 "Please make sure that the file is writable by the web server", 278 true ); 279 $this->_file = $file; 280 } 281 282 function validate() 283 { 284 $this->_valid = File::isWritable( $this->_file ); 285 return( parent::validate()); 286 } 287 } 288 289 class WizardSessionFunctionsAvailableValidator extends WizardValidator 290 { 291 function WizardSessionFunctionsAvailableValidator() 292 { 293 $this->WizardValidator( "Checking if <b>session</b> functions are available", 294 "LifeType requires support for sessions to be part of your PHP installation", 295 true ); 296 } 297 298 function validate() 299 { 300 $this->_valid = function_exists( "session_start" ) && 301 function_exists( "session_destroy" ) && 302 function_exists( "session_cache_limiter" ) && 303 function_exists( "session_name" ) && 304 function_exists( "session_set_cookie_params" ) && 305 function_exists( "session_save_path" ); 306 return( parent::validate()); 307 } 308 } 309 310 class WizardSessionSettingsValidator extends WizardValidator 311 { 312 function WizardSessionSettingsValidator() 313 { 314 $this->WizardValidator( "Checking if <b>session.auto_start</b> is disabled", 315 "LifeType can only run when session.auto_start is disabled.", 316 true ); 317 } 318 319 function validate() 320 { 321 $this->_valid = (ini_get( "session.auto_start" ) == "0"); 322 return( parent::validate()); 323 } 324 } 325 326 class WizardMySQLFunctionsAvailableValidator extends WizardValidator 327 { 328 function WizardMySQLFunctionsAvailableValidator() 329 { 330 $this->WizardValidator( "Checking if <b>MySQL</b> functions are available", 331 "LifeType requires support for MySQL to be part of your PHP installation", 332 true ); 333 } 334 335 function validate() 336 { 337 $this->_valid = function_exists( "mysql_select_db" ) && 338 function_exists( "mysql_query" ) && 339 function_exists( "mysql_connect" ) && 340 function_exists( "mysql_fetch_assoc" ) && 341 function_exists( "mysql_num_rows" ) && 342 function_exists( "mysql_free_result" ); 343 return( parent::validate()); 344 } 345 } 346 347 class WizardXmlFunctionsAvailableValidator extends WizardValidator 348 { 349 function WizardXmlFunctionsAvailableValidator() 350 { 351 $this->WizardValidator( "Checking if <b>XML</b> functions are available", 352 "LifeType requires support for XML to be part of your PHP installation", 353 true ); 354 } 355 356 function validate() 357 { 358 $this->_valid = function_exists( "xml_set_object" ) && 359 function_exists( "xml_set_element_handler" ) && 360 function_exists( "xml_parser_create" ) && 361 function_exists( "xml_parser_set_option" ) && 362 function_exists( "xml_parse" ) && 363 function_exists( "xml_parser_free" ); 364 return( parent::validate()); 365 } 366 } 367 368 class WizardSafeModeValidator extends WizardValidator 369 { 370 function WizardSafeModeValidator() 371 { 372 $this->WizardValidator( "Checking if <b>safe mode</b> is disabled", 373 "LifeType can run when PHP's safe mode is enabled, but it may cause some problems.", 374 false ); 375 } 376 377 function validate() 378 { 379 $this->_valid = (ini_get( "safe_mode" ) == ""); 380 return( parent::validate()); 381 } 382 } 383 384 class WizardIconvFunctionsAvailableValidator extends WizardValidator 385 { 386 function WizardIconvFunctionsAvailableValidator() 387 { 388 $this->WizardValidator( "Checking if <b>iconv</b> functions are available", 389 "LifeType requires support for some resource metadata conversion and some LifeType plugins requires support for multi-byte language encoding/decoding.", 390 false ); 391 } 392 393 function validate() 394 { 395 $this->_valid = function_exists( "iconv" ); 396 return( parent::validate()); 397 } 398 } 399 400 class WizardMbstringFunctionsAvailableValidator extends WizardValidator 401 { 402 function WizardMbstringFunctionsAvailableValidator() 403 { 404 $this->WizardValidator( "Checking if <b>mbstring</b> functions are available", 405 "Some LifeType plugins requires support for multi-byte language encoding/decoding.", 406 false ); 407 } 408 409 function validate() 410 { 411 $this->_valid = function_exists( "mb_convert_encoding" ); 412 return( parent::validate()); 413 } 414 } 415 416 class WizardGdFunctionsAvailableValidator extends WizardValidator 417 { 418 function WizardGdFunctionsAvailableValidator() 419 { 420 $this->WizardValidator( "Checking if <b>gd</b> or <b>gd2</b> functions are available", 421 "LifeType requires support for generating image thumbnail.", 422 false ); 423 } 424 425 function validate() 426 { 427 $this->_valid = function_exists( "imagecopyresampled" ) && 428 function_exists( "imagecopyresized" ); 429 return( parent::validate()); 430 } 431 } 432 433 class WizardFileUploadsValidator extends WizardValidator 434 { 435 function WizardFileUploadsValidator() 436 { 437 $this->WizardValidator( "Checking if <b>file_uploads</b> is enabled", 438 "LifeType requires support for uploading resources.", 439 true ); 440 } 441 442 function validate() 443 { 444 $this->_valid = (ini_get( "file_uploads" ) == 1); 445 return( parent::validate()); 446 } 447 } 448 449 class WizardFileIntegrityValidator extends WizardValidator 450 { 451 function WizardFileIntegrityValidator() 452 { 453 $this->WizardValidator( "Checking that all files have been correctly uploaded", 454 "will be set later on...", 455 false ); 456 } 457 458 function validate() 459 { 460 include ( PLOG_CLASS_PATH."install/files.properties.php"); 461 462 $result = IntegrityChecker::checkIntegrity( 463 $data 464 ); 465 466 467 $this->_valid = ( count( $result ) == 0 ); 468 if( !$this->_valid ) { 469 /* let's modify a private attribute... */ 470 $fileList = implode( "<br/>", array_keys( $result )); 471 $this->_solution = "The current version of the following is not the expected one. Installation can proceed but please make sure that all files were uploaded correctly:"."<br/>".$fileList; 472 } 473 474 return( parent::validate()); 475 } 476 } 477 478 class WizardCtypeFunctionsAvailableValidator extends WizardValidator 479 { 480 function WizardCtypeFunctionsAvailableValidator() 481 { 482 $this->WizardValidator( "Checking if <b>ctype</b> functions are available", 483 "Some LifeType plugins requires support for variable type validation.", 484 false ); 485 } 486 487 function validate() 488 { 489 $this->_valid = function_exists( "ctype_digit" ); 490 return( parent::validate()); 491 } 492 } 493 494 class WizardChecks extends WizardAction 495 { 496 function perform() 497 { 498 // build the array with checks 499 $checkGroups['File checks'] = Array( 500 "writeConfigFile" => new WizardWritableFileValidator( "config/config.properties.php" ), 501 "writeTmpFolder" => new WizardWritableFileValidator( "tmp" ), 502 "writeGalleryFolder" => new WizardWritableFileValidator( "gallery" ), 503 "fileVersionCheck" => new WizardFileIntegrityValidator() 504 ); 505 506 $checkGroups['PHP version checking'] = Array( 507 "php" => new WizardPhpVersionValidator() 508 ); 509 510 $checkGroups['PHP configuration checking'] = Array( 511 "sessionSettings" => new WizardSessionSettingsValidator(), 512 "safemode" => new WizardSafeModeValidator(), 513 "fileUploads" => new WizardFileUploadsValidator() 514 ); 515 516 $checkGroups['PHP functions availability checking'] = Array( 517 "sessions" => new WizardSessionFunctionsAvailableValidator(), 518 "mysql" => new WizardMySQLFunctionsAvailableValidator(), 519 "xml" => new WizardXmlFunctionsAvailableValidator(), 520 "iconv" => new WizardIconvFunctionsAvailableValidator(), 521 "mbstring" => new WizardMbstringFunctionsAvailableValidator(), 522 "gd" => new WizardGdFunctionsAvailableValidator(), 523 "ctype" => new WizardCtypeFunctionsAvailableValidator() 524 ); 525 526 // run the checks 527 $ok = true; 528 foreach( $checkGroups as $checkGroup => $checks ) { 529 foreach( $checks as $id => $check ) { 530 $valid = $checkGroups[$checkGroup][$id]->validate(); 531 // if it doesn't validate but it's not critical, then we can proced too 532 if( !$checkGroups[$checkGroup][$id]->isCritical()) 533 $valid = true; 534 $ok = ($ok && $valid); 535 } 536 } 537 538 // create the view and pass the results 539 $this->_view = new WizardView( "checks" ); 540 $this->_view->setValue( "ok", $ok ); 541 $this->_view->setValue( "checkGroups", $checkGroups ); 542 543 if( WizardTools::isNewInstallation()) 544 $this->_view->setValue( "mode", "install" ); 545 else 546 $this->_view->setValue( "mode", "update" ); 547 548 return true; 549 } 550 } 551 552 class WizardPagedAction extends WizardAction 553 { 554 var $willRefresh; 555 556 function WizardPagedAction( $actionInfo, $request ) 557 { 558 $this->WizardAction( $actionInfo, $request ); 559 560 $this->willRefresh = false; 561 } 562 563 /** 564 * @private 565 */ 566 function getPageFromRequest() 567 { 568 lt_include( PLOG_CLASS_PATH."class/data/validator/integervalidator.class.php"); 569 // get the value from the request 570 $page = HttpVars::getRequestValue( "page" ); 571 // but first of all, validate it 572 $val = new IntegerValidator(); 573 if( !$val->validate( $page )) 574 $page = 1; 575 576 return $page; 577 } 578 579 /** 580 * @private 581 */ 582 function willRefresh() 583 { 584 return( $this->willRefresh ); 585 } 586 } 587 588 /** 589 * Gets the information about the database from the user. 590 */ 591 class WizardIntro extends WizardAction 592 { 593 function WizardIntro( $actionInfo, $request ) 594 { 595 $this->WizardAction( $actionInfo, $request ); 596 } 597 598 function perform() 599 { 600 // we can detect whether plog is already installed or not and direct users to the right 601 // place 602 if( WizardTools::isNewInstallation()) 603 $this->_view = new WizardView( "intro" ); 604 else { 605 Controller::setForwardAction( "Update1" ); 606 return false; 607 } 608 609 $this->setCommonData(); 610 return true; 611 } 612 } 613 614 /** 615 * 616 * Saves data to the configuration file 617 * 618 */ 619 class WizardStepOne extends WizardAction 620 { 621 622 var $_dbServer; 623 var $_dbUser; 624 var $_dbPassword; 625 var $_dbName; 626 var $_dbPrefix; 627 var $_connection; 628 629 function WizardStepOne( $actionInfo, $request ) 630 { 631 $this->WizardAction( $actionInfo, $request ); 632 633 // data validation 634 $this->registerFieldValidator( "dbServer", new StringValidator()); 635 $this->registerFieldValidator( "dbUser", new StringValidator()); 636 $this->registerFieldValidator( "dbPassword", new StringValidator(), true ); 637 $this->registerFieldValidator( "dbName", new StringValidator()); 638 $this->registerFieldValidator( "dbPrefix", new StringValidator(), true ); 639 $errorView = new WizardView( "intro" ); 640 $errorView->setErrorMessage( "Some data was incorrect or missing." ); 641 $this->setValidationErrorView( $errorView ); 642 } 643 644 function perform() 645 { 646 // fetch the data needed from the request 647 $this->_dbServer = $this->_request->getValue( "dbServer" ); 648 $this->_dbUser = $this->_request->getValue( "dbUser" ); 649 $this->_dbPassword = $this->_request->getValue( "dbPassword" ); 650 $this->_dbName = $this->_request->getValue( "dbName" ); 651 $this->_skipThis = $this->_request->getValue( "skipDbInfo" ); 652 $this->_dbPrefix = $this->_request->getValue( "dbPrefix", DEFAULT_DB_PREFIX ); 653 654 // we should now save the data to the configuration file, just before 655 // we read it 656 $configFile = new ConfigFileStorage(); 657 658 // we expect everything to be fine 659 $errors = false; 660 661 // before doing anything, we should check of the configuration file is 662 // writable by this script, or else, throw an error and bail out gracefully 663 $configFileName = $configFile->getConfigFileName(); 664 if( !File::exists( $configFileName )) { 665 if (! File::touch( $configFileName ) ) { 666 $this->_view = new WizardView( "intro" ); 667 $message = "Could not create the LifeType configuration file $configFileName. Please make sure 668 that the file can be created by the user running the webserver. It is needed to 669 store the database configuration settings."; 670 $this->_view->setErrorMessage( $message ); 671 $this->setCommonData( true ); 672 return false; 673 } else { 674 ConfigFileStorage::createConfigFile( $configFileName ); 675 } 676 } 677 if( File::exists( $configFileName ) && !File::isWritable( $configFileName )) { 678 $this->_view = new WizardView( "intro" ); 679 $message = "Please make sure that the file $configFileName can be written by this script during 680 the installation process. It is needed to store the database configuration settings. Once the 681 installation is complete, please revert the permissions to no writing possible."; 682 $this->_view->setErrorMessage( $message ); 683 $this->setCommonData( true ); 684 return false; 685 } 686 687 // continue if everything went fine 688 if( !$configFile->saveValue( "db_username", $this->_dbUser ) || 689 !$configFile->saveValue( "db_password", $this->_dbPassword ) || 690 !$configFile->saveValue( "db_host", $this->_dbServer ) || 691 !$configFile->saveValue( "db_database", $this->_dbName ) || 692 !$configFile->saveValue( "db_prefix", $this->_dbPrefix )) { 693 $errors = true; 694 } 695 696 if( $errors ) { 697 $message = "Could not save values to the configuration file. Please make sure it is available and 698 that has write permissions for the user under your web server is running."; 699 $this->_view = new WizardView( "intro" ); 700 $this->_view->setErrorMessage( $message ); 701 702 return( false ); 703 } 704 else { 705 $connectionEsablished = false; 706 707 $this->_connection = @mysql_connect( $this->_dbServer, $this->_dbUser, $this->_dbPassword ); 708 if( $this->_connection ) { 709 $connectionEsablished = true; 710 } else { 711 $connectionEsablished = false; 712 $message = "There was an error connecting to the database. Please check your settings."; 713 } 714 715 if ( !$connectionEsablished ) { 716 $this->_view = new WizardView( "step1" ); 717 $this->_view->setErrorMessage( $message ); 718 $this->setCommonData( true ); 719 return false; 720 } else { 721 $this->_view = new WizardView( "step1" ); 722 $availableCharacterSets = $this->getAvailableCharacterSets(); 723 $defaultCharacterSet = $this->getDatabaseCharacterSet(); 724 $createDatabase = false; 725 if( empty( $defaultCharacterSet ) ) 726 { 727 $defaultCharacterSet = $this->getServerCharacterSet(); 728 $createDatabase = true; 729 } 730 $this->_view->setValue( "availableCharacterSets", $availableCharacterSets ); 731 $this->_view->setValue( "defaultCharacterSet", $defaultCharacterSet ); 732 $this->_view->setValue( "createDatabase", $createDatabase ); 733 // now we better read the information from the config file to make sure that 734 // it has been correctly saved 735 $this->setCommonData( true ); 736 return true; 737 } 738 } 739 } 740 741 function getAvailableCharacterSets() 742 { 743 // check mysql version first. Version lower than 4.1 doesn't support utf8 744 $serverVersion = mysql_get_server_info( $this->_connection ); 745 $version = explode( '.', $serverVersion ); 746 if ( $version[0] < 4 ) return false; 747 if ( ( $version[0] == 4 ) && ( $version[1] == 0 ) ) return false; 748 749 // check if utf8 support was compiled in 750 $result = mysql_query( "SHOW CHARACTER SET", $this->_connection ); 751 if( $result ) 752 { 753 if( mysql_num_rows($result) > 0 ) { 754 // iterate through resultset 755 $availableCharacterSets = array(); 756 while( $row = mysql_fetch_array( $result, MYSQL_ASSOC ) ) 757 { 758 array_push( $availableCharacterSets, $row['Charset'] ); 759 } 760 return $availableCharacterSets; 761 } 762 } 763 return false; 764 } 765 766 function getDatabaseCharacterSet() 767 { 768 if( !@mysql_select_db( $this->_dbName, $this->_connection ) ) { 769 return false; 770 } 771 772 // We use a SHOW CREATE DATABASE command to show the original 773 // SQL character set when DB was created. 774 $result = mysql_query( "SHOW CREATE DATABASE `".$this->_dbName."`", $this->_connection ); 775 if( $result ) 776 { 777 if( mysql_num_rows( $result ) < 0 ) { 778 // The specified db name is wrong! 779 return false; 780 } 781 $dbInfo = mysql_fetch_row( $result ); 782 $pattern = '/40100 DEFAULT CHARACTER SET (\w+) /'; 783 if( ( preg_match( $pattern, $dbInfo[1], $match ) > 0 ) ) { 784 return $match[1]; 785 } 786 } 787 return false; 788 } 789 790 function getServerCharacterSet(){ 791 // We use a SHOW CREATE DATABASE command to show the original 792 // SQL character set when DB was created. 793 $result = mysql_query( "SHOW VARIABLES LIKE 'character_set_server'", $this->_connection ); 794 if( $result ) 795 { 796 if( mysql_num_rows( $result ) > 0 ) { 797 $row = mysql_fetch_array( $result, MYSQL_ASSOC ); 798 return $row['Value']; 799 } 800 } 801 return false; 802 } 803 } 804 805 /** 806 * 807 * Second step where we connect to the database and create the tables. 808 * 809 */ 810 class WizardStepTwo extends WizardAction 811 { 812 813 var $_db; 814 var $_database; 815 var $_dbCharacterSet; 816 var $_createDatabase; 817 818 function setDbConfigValues( &$view ) 819 { 820 $configFile = new ConfigFileStorage(); 821 $configFile->reload(); 822 $view->setValue( "dbUser", $configFile->getValue( "db_username" )); 823 $view->setValue( "dbPassword", $configFile->getValue( "db_password" )); 824 $view->setValue( "dbServer", $configFile->getValue( "db_host" )); 825 $view->setValue( "dbName", $configFile->getValue( "db_database" )); 826 $view->setValue( "dbPrefix", $configFile->getValue( "db_prefix" )); 827 $view->setValue( "dbCharacterSet", $configFile->getValue( "db_character_set" )); 828 return true; 829 } 830 831 function perform() 832 { 833 global $Tables; 834 global $Inserts; 835 836 $this->_dbCharacterSet = $this->_request->getValue( "dbCharacterSet" ); 837 $configFile = new ConfigFileStorage(); 838 $configFileName = $configFile->getConfigFileName(); 839 840 if( File::exists( $configFileName ) && !File::isWritable( $configFileName )) { 841 $this->_view = new WizardView( "step1" ); 842 $message = "Please make sure that the file $configFileName can be written by this script during 843 the installation process. It is needed to store the database configuration settings. Once the 844 installation is complete, please revert the permissions to no writing possible."; 845 $this->_view->setErrorMessage( $message ); 846 $this->setCommonData( true ); 847 return false; 848 } 849 850 // continue if everything went fine 851 if( !$configFile->saveValue( "db_character_set", $this->_dbCharacterSet ) ) { 852 $message = "Could not save values to the configuration file. Please make sure it is available and 853 that has write permissions for the user under your web server is running."; 854 $this->_view = new WizardView( "step1" ); 855 $this->_view->setErrorMessage( $message ); 856 857 return false; 858 } 859 860 $createDb = $this->_request->getValue( "createDatabase" ); 861 $message = ''; 862 863 // only check for errors in case the database table should already exist! 864 if( !$createDb ) { 865 $connectionEsablished = false; 866 867 // Lets check the 'everything is fine' case first.. 868 $this->_db = connectDb(); 869 if( $this->_db ) { 870 $connectionEsablished = true; 871 } else { 872 $connectionEsablished = false; 873 $message = "There was an error selecting the database. Please verify the database was already created or check the 'Create database' checkbox."; 874 } 875 876 // We were unable to connect to the db and select the right db.. lets try 877 // just to connect.. maybe the database needs to be created (even though the 878 // user did not check the appropriate box). 879 if ( !$connectionEsablished ) { 880 $this->_db = connectDb( true, false ); 881 if( !$this->_db ) { 882 $message = "There was an error connecting to the database. Please check your settings."; 883 } 884 } 885 886 if ( !$connectionEsablished ) { 887 $this->_view = new WizardView( "step1" ); 888 $this->setDbConfigValues( $this->_view ); 889 $this->_view->setErrorMessage( $message ); 890 $this->setCommonData( true ); 891 return false; 892 } 893 } 894 895 $config = new ConfigFileStorage(); 896 $this->_database = $config->getValue( "db_database" ); 897 $this->_dbPrefix = $config->getValue( "db_prefix" ); 898 899 // create the database 900 if( $createDb ) { 901 $this->_db = connectDb( false, false ); 902 if( !$this->_db ) { 903 $this->_view = new WizardView( "step1" ); 904 $this->setDbConfigValues( $this->_view ); 905 $this->_view->setErrorMessage( $message ); 906 $this->setCommonData( true ); 907 return false; 908 } 909 if( !$this->_db->Execute( "CREATE DATABASE ".$this->_database )) { 910 $message = "Error creating the database: ".$this->_db->ErrorMsg(); 911 $message .= "<br/><br/>If the database already exists, go back to Step 2 and use a new database name."; 912 $this->_view = new WizardView( "step1" ); 913 $this->setDbConfigValues( $this->_view ); 914 $this->_view->setErrorMessage( $message ); 915 $this->setCommonData( true ); 916 return false; 917 } else { 918 $message = "Database created successfully.<br/>"; 919 } 920 } 921 922 // reconnect using the new database. 923 $config = new ConfigFileStorage(); 924 $this->_db->Connect( $config->getValue( "db_host" ), 925 $config->getValue( "db_username" ), 926 $config->getValue( "db_password" ), 927 $config->getValue( "db_database" )); 928 929 // create a data dictionary to give us the right sql code needed to create the tables 930 $dict = NewPDbDataDictionary( $this->_db ); 931 932 // create the tables 933 $errors = false; 934 935 foreach( $Tables as $name => $table ) { 936 $upperName = $dict->upperName; 937 $tableSchema = $table["schema"]; 938 if ( isset( $table["options"] ) ) 939 { 940 $tableOptions = $table["options"]; 941 $options = array ( $upperName => $tableOptions ); 942 } else { 943 $options = array (); 944 } 945 $sqlarray = $dict->CreateTableSQL( $this->_dbPrefix.$name, $tableSchema, $options ); 946 947 // each table may need more than one sql query because of indexes, triggers, etc... 948 $ok = true; 949 foreach( $sqlarray as $sql ) { 950 $ok = ( $ok && $this->_db->Execute( $sql )); 951 } 952 953 if( $ok ) 954 $message .= "Table <strong>$name</strong> created successfully.<br/>"; 955 else { 956 $message .= "Error creating table $name: ".$this->_db->ErrorMsg()."<br/>"; 957 $errors = true; 958 } 959 } 960 961 if( $errors ) { 962 $message = "There was an error creating the tables in the database. Please make sure that the user chosen to connect to the database has enough permissions to create tables.<br/><br/>$message"; 963 $this->_view = new WizardView( "step1" ); 964 $this->_view->setErrorMessage( $message ); 965 $this->setDbConfigValues( $this->_view ); 966 $this->setCommonData(); 967 return false; 968 } 969 970 // try to guess the url where plog is running 971 $httpProtocol = (array_key_exists("HTTPS", $_SERVER) && $_SERVER["HTTPS"] == "on") ? "https://" : "http://"; 972 $httpHost = $_SERVER["HTTP_HOST"]; 973 $requestUrl = $_SERVER["REQUEST_URI"]; 974 $requestUrl = str_replace( "/wizard.php", "", $requestUrl ); 975 $plogUrl = $httpProtocol.$httpHost.$requestUrl; 976 977 // Find some of the tools we are going to need (last one is for os x, with fink installed) 978 // TBD: support for Windows specific directories 979 $folders = Array( "/bin/", "/usr/bin/", "/usr/local/bin/", "/sw/bin/" ); 980 $finder = new FileFinder(); 981 $pathToUnzip = $finder->findBinary( "unzip", $folders ); 982 $pathToTar = $finder->findBinary( "tar", $folders); 983 $pathToGzip = $finder->findBinary( "gzip", $folders); 984 $pathToBzip2 = $finder->findBinary( "bzip2", $folders); 985 $pathToConvert = $finder->findBinary( "convert", $folders); 986 987 // and execute some insert's 988 foreach( $Inserts as $insert ) { 989 $query = str_replace( "{dbprefix}", $this->_dbPrefix, $insert ); 990 $query = str_replace( "{plog_base_url}", $plogUrl, $query ); 991 // replace also the placeholders for the paths to the tools 992 $query = str_replace( "{path_to_tar}", $pathToTar, $query ); 993 $query = str_replace( "{path_to_unzip}", $pathToUnzip, $query ); 994 $query = str_replace( "{path_to_bz2}", $pathToBzip2, $query ); 995 $query = str_replace( "{path_to_gzip}", $pathToGzip, $query ); 996 $query = str_replace( "{path_to_convert}", $pathToConvert, $query ); 997 $query = str_replace( "{path_to_convert}", $pathToConvert, $query ); 998 if( !$this->_db->Execute( $query )) { 999 $message .= "Error executing code: ".$this->_db->ErrorMsg()."<br/>"; 1000 $errors = true; 1001 } 1002 } 1003 1004 // 1005 // show some information regarding the helper tools we're going to need 1006 // and wether they were found or not 1007 // 1008 $message .= "<br/><b>-- Helper tools --</b><br/>"; 1009 if( $pathToTar == "" ) 1010 $message .= "The helper tool 'tar' was not found<br/>"; 1011 else 1012 $message .= "The helper tool 'tar' was found in $pathToTar<br/>"; 1013 if( $pathToGzip == "" ) 1014 $message .= "The helper tool 'gzip' was not found<br/>"; 1015 else 1016 $message .= "The helper tool 'gzip' was found in $pathToGzip<br/>"; 1017 if( $pathToUnzip == "" ) 1018 $message .= "The helper tool 'unzip' was not found<br/>"; 1019 else 1020 $message .= "The helper tool 'unzip' was found in $pathToUnzip<br/>"; 1021 if( $pathToBzip2 == "" ) 1022 $message .= "The helper tool 'bzip2' was not found<br/>"; 1023 else 1024 $message .= "The helper tool 'bzip2' was found in $pathToTar<br/>"; 1025 if( $pathToConvert == "" ) 1026 $message .= "The helper tool 'convert' (from the ImageMagick package) was not found<br/>"; 1027 else 1028 $message .= "The helper tool 'convert' (from the ImageMagick package) was found in $pathToConvert<br/>"; 1029 1030 // Scan for locales 1031 $locales = new Locales(); 1032 // find all the new locales that we have not yet stored 1033 $f = new LocaleFinder(); 1034 $newLocaleCodes = $f->find(); 1035 1036 foreach( $newLocaleCodes as $newLocaleCode ) { 1037 $res = $locales->addLocale( $newLocaleCode ); 1038 } 1039 1040 // load the core permissions 1041 include ( PLOG_CLASS_PATH."install/corepermissions.properties.php" ); 1042 1043 // process permissions 1044 $total = 0; 1045 foreach( $permissions as $perm ) { 1046 // check if it already exists 1047 $query = "SELECT * FROM ".Db::getPrefix()."permissions WHERE permission = '".$perm[0]."'"; 1048 $result = $this->_db->Execute( $query ); 1049 if( !$result || $result->RowCount() < 1 ) { 1050 // permission needs to be added 1051 $corePerm = ( $perm[2] == true ? 1 : 0 ); 1052 $adminOnly = ( $perm[3] == true ? 1 : 0 ); 1053 1054 $query = "INSERT INTO ".Db::getPrefix()."permissions (permission,description,core_perm,admin_only) ". 1055 "VALUES ('".$perm[0]."','".$perm[1]."','".$corePerm."','".$adminOnly."')"; 1056 1057 $this->_db->Execute( $query ); 1058 $total++; 1059 } 1060 } 1061 1062 // show some feedback 1063 if( $errors ) { 1064 $this->_view = new WizardView( "step1" ); 1065 $this->setDbConfigValues( $this->_view ); 1066 $message = "There was an error initializing some of the tables. Please make sure that the user chosen to connect to the database has enough permissions to add records to the database.<br/><br/>$message"; 1067 $this->_view->setErrorMessage( $message ); 1068 $this->setCommonData(); 1069 } 1070 else { 1071 $this->_view = new WizardView( "step2" ); 1072 $this->_view->setValue( "message", $message ); 1073 } 1074 } 1075 } 1076 1077 /** 1078 * 1079 * this action only shows some feedback 1080 * 1081 */ 1082 class WizardStepThree extends WizardAction 1083 { 1084 function perform() 1085 { 1086 $this->_view = new WizardView( "step3" ); 1087 $this->setCommonData(); 1088 } 1089 } 1090 1091 /** 1092 * 1093 * Create the first user in the database 1094 * 1095 */ 1096 class WizardStepFour extends WizardAction 1097 { 1098 1099 var $_userName; 1100 var $_userPassword; 1101 var $_confirmPassword; 1102 var $_userEmail; 1103 var $_userFullName; 1104 1105 function WizardStepFour( $actionInfo, $request ) 1106 { 1107 $this->WizardAction( $actionInfo, $request ); 1108 1109 $this->registerFieldValidator( "userName", new UsernameValidator()); 1110 $this->registerFieldValidator( "userPassword", new PasswordValidator()); 1111 $this->registerFieldValidator( "userPasswordCheck", new PasswordValidator()); 1112 $this->registerFieldValidator( "userEmail", new EmailValidator()); 1113 $this->registerField( "userFullName" ); 1114 $view = new WizardView( "step3" ); 1115 $view->setErrorMessage( "Some data is missing or incorrect" ); 1116 $this->setValidationErrorView( $view ); 1117 } 1118 1119 // creates the user 1120 function perform() 1121 { 1122 $this->_userName = $this->_request->getValue( "userName" ); 1123 $this->_userPassword = $this->_request->getValue( "userPassword" ); 1124 $this->_confirmPassword = $this->_request->getValue( "userPasswordCheck" ); 1125 $this->_userEmail = $this->_request->getValue( "userEmail" ); 1126 $this->_userFullName = $this->_request->getValue( "userFullName" ); 1127 1128 $db = connectDb(); 1129 1130 if( !$db ) { 1131 $this->_view = new WizardView( "step3" ); 1132 $this->_view->setErrorMessage( "There was an error connecting to the database. Please check your settings." ); 1133 $this->setCommonData(); 1134 return false; 1135 } 1136 1137 if( $this->_confirmPassword != $this->_userPassword ) { 1138 $this->_view = new WizardView( "step3" ); 1139 $this->_form->setFieldValidationStatus( "userPasswordCheck", false ); 1140 $this->setCommonData( true ); 1141 return false; 1142 } 1143 1144 $dbPrefix = Db::getPrefix(); 1145 1146 $users = new Users(); 1147 $user = new UserInfo( $this->_userName, 1148 $this->_userPassword, 1149 $this->_userEmail, 1150 "", 1151 $this->_userFullName); 1152 // set the user as an administrator 1153 $user->setSiteAdmin( true ); 1154 // and add this record to the db 1155 $userId = $users->addUser( $user ); 1156 if( !$userId ) { 1157 $this->_view = new WizardView( "step3" ); 1158 $db =& Db::getDb(); 1159 $message = "There was an error adding the user. Make sure that the user does not already exist in the database (".$db->ErrorMsg().")"; 1160 $this->_view->setErrorMessage( $message ); 1161 $this->setCommonData(); 1162 return false; 1163 } 1164 1165 // since this user is an administrator, he must be granted all the administrator 1166 // permissions available 1167 $perms = new Permissions(); 1168 $userPerms = new UserPermissions(); 1169 foreach( $perms->getAllPermissions() as $perm ) { 1170 if( $perm->isAdminOnlyPermission()) { 1171 // if it's an admin permission, add it 1172 $p = new UserPermission( $userId, 0, $perm->getId()); 1173 $userPerms->grantPermission( $p ); 1174 //print("granting permission: ".$perm->getName()."<br/>"); 1175 } 1176 } 1177 1178 $this->_view = new Wizardview( "step4" ); 1179 $this->_view->setValue( "ownerid", $userId ); 1180 $this->_view->setValue( "siteLocales", Locales::getLocales()); 1181 $this->_view->setValue( "defaultLocale", Locales::getDefaultLocale()); 1182 $ts = new TemplateSets(); 1183 $this->_view->setValue( "siteTemplates", $ts->getGlobalTemplateSets()); 1184 $this->setCommonData(); 1185 return true; 1186 } 1187 1188 } 1189 1190 class WizardStepFive extends WizardAction 1191 { 1192 1193 var $_blogName; 1194 var $_ownerId; 1195 var $_blogProperties; 1196 1197 function WizardStepFive( $actionInfo, $request ) 1198 { 1199 $this->WizardAction( $actionInfo, $request ); 1200 1201 $this->registerFieldValidator( "blogName", new StringValidator()); 1202 $this->registerFieldValidator( "ownerid", new IntegerValidator()); 1203 $this->registerFieldValidator( "blogTemplate", new StringValidator()); 1204 $this->registerFieldValidator( "blogLocale", new StringValidator()); 1205 $view = new WizardView( "step4" ); 1206 $view->setErrorMessage( "Some data is missing or incorrect" ); 1207 $view->setValue( "siteLocales", Locales::getLocales()); 1208 $view->setValue( "defaultLocale", Locales::getDefaultLocale()); 1209 $ts = new TemplateSets(); 1210 $view->setValue( "siteTemplates", $ts->getGlobalTemplateSets()); 1211 $this->setValidationErrorView( $view ); 1212 } 1213 1214 function perform() 1215 { 1216 // Before we add a new blog, we need to add blog category and global article category first 1217 // add blog category 1218 $blogCategories = new BlogCategories(); 1219 $blogCategory = new BlogCategory( "General", "General" ); 1220 $blogCategoryId = $blogCategories->addBlogCategory( $blogCategory ); 1221 1222 // add global article category 1223 $globalArticleCategories = new GlobalArticleCategories(); 1224 $globalArticleCategory = new GlobalArticleCategory( "General", "General" ); 1225 $globalArticleCategoryId = $globalArticleCategories->addGlobalArticleCategory( $globalArticleCategory ); 1226 1227 // retrieve the values from the view 1228 $this->_blogName = $this->_request->getValue( "blogName" ); 1229 $this->_ownerId = $this->_request->getValue( "ownerid" ); 1230 $this->_blogProperties = $this->_request->getValue( "properties" ); 1231 $this->_blogTemplate = $this->_request->getValue( "blogTemplate" ); 1232 $this->_blogLocale = $this->_request->getValue( "blogLocale" ); 1233 1234 // configure the blog 1235 $blogs = new Blogs(); 1236 $blog = new BlogInfo( $this->_blogName, $this->_ownerId, "", "" ); 1237 // set the default BlogCategory id to blog 1238 $blog->setBlogCategoryId( $blogCategoryId ); 1239 $blog->setProperties( $this->_blogProperties ); 1240 $blog->setStatus( BLOG_STATUS_ACTIVE ); 1241 $blogSettings = $blog->getSettings(); 1242 $blogSettings->setValue( "locale", $this->_blogLocale ); 1243 $blogSettings->setValue( "template", $this->_blogTemplate ); 1244 $blog->setSettings( $blogSettings ); 1245 1246 // and now save it to the database 1247 $newblogId = $blogs->addBlog( $blog ); 1248 if( !$newblogId ) { 1249 $this->_view = new WizardView( "step4" ); 1250 $this->_view->setValue( "siteLocales", Locales::getLocales()); 1251 $ts = new TemplateSets(); 1252 $this->_view->setValue( "siteTemplates", $ts->getGlobalTemplateSets()); 1253 $this->_view->setErrorMessage( "There was an error creating the new blog" ); 1254 $this->setCommonData( true ); 1255 return false; 1256 } 1257 1258 // if the blog was created, we can add some basic information 1259 // add a category 1260 $articleCategories = new ArticleCategories(); 1261 $articleCategory = new ArticleCategory( "General", "General", $newblogId, true ); 1262 $catId = $articleCategories->addArticleCategory( $articleCategory ); 1263 1264 // load the right locale 1265 $locale =& Locales::getLocale( $this->_blogLocale ); 1266 // and load the right text 1267 $articleTopic = $locale->tr( "register_default_article_topic" ); 1268 $articleText = $locale->tr( "register_default_article_text" ); 1269 $article = new Article( $articleTopic, $articleText, Array( $catId ), $this->_ownerId, $newblogId, POST_STATUS_PUBLISHED, 0, Array(), "welcome" ); 1270 // set the default ArticleGlobalCategory id to article 1271 $article->setGlobalCategoryId( $globalArticleCategoryId ); 1272 // set the current time to article 1273 $t = new Timestamp(); 1274 $article->setDateObject( $t ); 1275 $articles = new Articles(); 1276 $articles->addArticle( $article ); 1277 1278 // add a new first album so that users can start uploading stuff right away 1279 $t = new Timestamp(); 1280 $album = new GalleryAlbum( $newblogId, 1281 "General", 1282 "General", 1283 GALLERY_RESOURCE_PREVIEW_AVAILABLE, 1284 0, 1285 $t->getTimestamp(), 1286 Array(), 1287 true ); 1288 $albums = new GalleryAlbums(); 1289 $albums->addAlbum( $album ); 1290 1291 // add a new default mylinkscategory 1292 $linksCategory = new MyLinksCategory( "General", $newblogId ); 1293 $linksCategories = new MyLinksCategories(); 1294 $linksCategories->addMyLinksCategory( $linksCategory ); 1295 1296 // save a few things in the default configuration 1297 $config =& Config::getConfig(); 1298 // default blog id 1299 $config->saveValue( "default_blog_id", (int)$newblogId ); 1300 // default locale 1301 $config->saveValue( "default_locale", $this->_blogLocale ); 1302 // and finally, the default template 1303 $config->saveValue( "default_template", $this->_blogTemplate ); 1304 1305 // 1306 // detect wether we have GD available and set the blog to use it 1307 // 1308 if( GdDetector::detectGd()) { 1309 $config->saveValue( "thumbnail_method", "gd" ); 1310 $message = "GD has been detected and set as the backend for dealing with images."; 1311 } 1312 else { 1313 $pathToConvert = $config->getValue( "path_to_convert" ); 1314 if( $pathToConvert ) { 1315 $config->saveValue( "thumbnail_method", "imagemagick" ); 1316 $message = "ImageMagick has been detected and set as the backend for dealing with images."; 1317 } 1318 else { 1319 // nothing was found, so we'll have to do away with the 'null' resizer... 1320 $config->saveValue( "thumbnail_method", "null" ); 1321 $message = "Neither GD nor ImageMagick have been detected in this host so it will not be possible to generate thumbnails from images."; 1322 } 1323 } 1324 1325 // clean the data cache to avoid problems when we're done 1326 lt_include( PLOG_CLASS_PATH."class/cache/cachemanager.class.php" ); 1327 $cache =& CacheManager::getCache(); 1328 $cache->clearCache(); 1329 1330 WizardTools::cleanTmpFolder(); 1331 1332 $this->_view = new WizardView( "step5" ); 1333 $this->_view->setValue( "message", $message ); 1334 return true; 1335 } 1336 } 1337 1338 class UpdateStepOne extends WizardAction 1339 { 1340 1341 function perform() 1342 { 1343 $this->_view = new WizardView( "update1" ); 1344 WizardStepTwo::setDbConfigValues( $this->_view ); 1345 $this->setCommonData(); 1346 } 1347 } 1348 1349 class UpdateStepTwo extends WizardAction 1350 { 1351 function perform() 1352 { 1353 lt_include( PLOG_CLASS_PATH."class/config/config.class.php" ); 1354 $config =& Config::getConfig(); 1355 $resourcesNamingRule = $config->getValue( "resources_naming_rule", "original_file_name" ); 1356 1357 $this->_view = new WizardView( "update2" ); 1358 $this->_view->setValue( "resourcesNamingRule", $resourcesNamingRule ); 1359 $this->setCommonData(); 1360 } 1361 } 1362 1363 /** 1364 * Generic class that performs data updates on the database 1365 */ 1366 class DatabaseDataTransformer extends Model 1367 { 1368 /** 1369 * @public 1370 * Public fields, may be accessed by other classes 1371 */ 1372 var $updatedRecords; 1373 var $message; 1374 var $errorRecords; 1375 var $notModifiedRecords; 1376 var $failOnError; 1377 var $page; 1378 var $itemsPerPage; 1379 var $dbPrefix; 1380 1381 function DatabaseDataTransformer( $page = -1, $itemsPerPage = WIZARD_MAX_RECORDS_PER_STEP ) 1382 { 1383 $this->Model(); 1384 1385 $this->updatedRecords = 0; 1386 $this->errorRecords = 0; 1387 $this->notModifiedRecords = 0; 1388 $this->addedRecords = 0; 1389 $this->deletedRecords = 0; 1390 $this->failOnError = DATABASE_DATA_TRANSFORMER_FAIL_ON_ERROR_DEFAULT; 1391 $this->message = ""; 1392 1393 $this->page = $page; 1394 $this->itemsPerPage = $itemsPerPage; 1395 1396 $this->dbPrefix = $this->getPrefix(); 1397 } 1398 1399 /** 1400 * Rerforms the transformation. Returns true if the step was successful or false otherwise. 1401 * Upon finalization, please check the $message string to get more information. Use the $updatedRecords, 1402 * $errorRecords, $notModifiedRecords, $addedRecords and $deletedRecords for some figures regarding the 1403 * previous step 1404 */ 1405 function perform() 1406 { 1407 // must be implemented by child classes 1408 return true; 1409 } 1410 1411 /** 1412 * Returns true if there is no more data for this transformer to upgrade, or false otherwise 1413 * 1414 * @return True if ready or false if not 1415 */ 1416 function isComplete() 1417 { 1418 return( $this->getNumSteps() <= $this->page ); 1419 } 1420 1421 /** 1422 * returns the number of steps needed to process this data 1423 */ 1424 function getNumSteps( $table = "" ) 1425 { 1426 // if there is a table name, we can take a shortcut or else we expect child 1427 // classes to reimplement this method 1428 if( $table ) { 1429 $numItems = $this->getNumItems( $this->getPrefix().$table ); 1430 1431 $numSteps = ceil( $numItems / $this->itemsPerPage ); 1432 } 1433 else { 1434 $numSteps = 0; 1435 } 1436 1437 return( $numSteps ); 1438 } 1439 1440 /** 1441 * returns the total number of records processed so far based on the current page and the 1442 * number of items per page 1443 */ 1444 function getTotalProcessedRecords() 1445 { 1446 return( $this->page * $this->itemsPerPage ); 1447 } 1448 1449 /** 1450 * returns an approximate percentage of records processed so far 1451 */ 1452 function getPercentProcessed() 1453 { 1454 $processed = $this->getTotalProcessedRecords(); 1455 return((int)($processed / ( $this->getNumSteps() * $this->itemsPerPage ) * 100 )); 1456 } 1457 } 1458 1459 /** 1460 * This step takes care of transforming the database schema, one 1461 * table at a time. 1462 */ 1463 class DatabaseSchemaDataTransformer extends DatabaseDataTransformer 1464 { 1465 function getNumSteps() 1466 { 1467 global $Tables; 1468 return( count( $Tables ) - 1); 1469 } 1470 1471 function perform() 1472 { 1473 global $Tables; 1474 1475 $tablesArray = array_keys( $Tables ); 1476 $curTable = $tablesArray[$this->page-1]; 1477 1478 $db =& Db::getDb(); 1479 $dict = NewPDbDataDictionary( $db ); 1480 $errors = false; 1481 1482 $this->message = "Performing changes to the dabase schema, please wait (step %s of %s)<br/>"; 1483 1484 $errorMessage = ""; 1485 $table_errors = false; 1486 $upperName = $dict->upperName; 1487 $tableSchema = $Tables[$curTable]["schema"]; 1488 if ( isset( $Tables[$curTable]["options"] )) { 1489 $tableOptions = $Tables[$curTable]["options"]; 1490 $options = array ( $upperName => $tableOptions ); 1491 } 1492 else { 1493 $options = array (); 1494 } 1495 1496 // generate the code with the changes for the table 1497 $sqlarray = $dict->ChangeTableSQL( $this->getPrefix().$curTable, $tableSchema, $options ); 1498 1499 foreach( $sqlarray as $sql ) { 1500 // and run the query 1501 //print( "sql: ".$sql."<br/>" ); 1502 if( !$this->Execute( $sql )) { 1503 $table_errors = true; 1504 $errors = true; 1505 $errorMessage .= $this->_db->ErrorMsg()."<br/>"; 1506 } 1507 } 1508 1509 if( !$table_errors ) { 1510 $this->message .= "Changes to table <strong>$curTable</strong> executed successfully.<br/>"; 1511 $result = true; 1512 } 1513 else { 1514 $this->message .= "Error modifying table $curTable: ".$errorMessage; 1515 $result = false; 1516 } 1517 1518 return( $result ); 1519 } 1520 } 1521 1522 /** 1523 * Processes all users and grants the appropriate permissions 1524 */ 1525 class UserPermissionsDataTransformer extends DatabaseDataTransformer 1526 { 1527 function getNumSteps() 1528 { 1529 return( parent::getNumSteps( "tmp_users_permissions" )); 1530 } 1531 1532 function perform() 1533 { 1534 $this->message = "Updating user permissions (step %s of %s)<br/>"; 1535 1536 $query3 = "SELECT * FROM ".Db::getPrefix()."tmp_users_permissions"; 1537 $res3 = $this->Execute( $query3, $this->page, $this->itemsPerPage ); 1538 if( $res3->RecordCount() == 0 ) { 1539 $this->message .= "No more records to process"; 1540 return( true ); 1541 } 1542 1543 $permissions = new Permissions(); 1544 $userPermissions = new UserPermissions(); 1545 $allPerms = $permissions->getAllPermissions(); 1546 $blogOwnerOnlyPerms = Array( "update_blog", 1547 "add_blog_user", 1548 "update_blog_user", 1549 "view_blog_users", 1550 "view_blog_stats", 1551 "add_blog_template", 1552 "view_blog_templates", 1553 "view_blog_stats" ); 1554 1555 while( $row = $res3->FetchRow()) { 1556 // grant all the non-admin permissions so that users can still access the blogs to where they still had permissions 1557 if( $row["permission_id"] != 3) { 1558 foreach( $allPerms as $perm ) { 1559 if( !$perm->isAdminOnlyPermission() && !in_array( $perm->getName(), $blogOwnerOnlyPerms )) { 1560 //print( "granting perm: ".$perm->getName()." - user: ".$row["user_id"]." - blog id: ".$row["blog_id"]."<br/>"); 1561 $perm = new UserPermission( $row["user_id"], $row["blog_id"], $perm->getId()); 1562 $userPermissions->grantPermission( $perm ); 1563 } 1564 } 1565 } 1566 } 1567 1568 $this->message .= "{$this->updatedRecords} users updated (".$this->getPercentProcessed()."%%)<br/>"; 1569 1570 $this->Execute("DROP TABLE ".Db::getPrefix()."tmp_users_permissions"); 1571 1572 return true; 1573 } 1574 } 1575 1576 class PermissionLoader extends DatabaseDataTransformer 1577 { 1578 1579 // 1580 // load the new list of permissions 1581 // 1582 function getNumSteps() 1583 { 1584 return( 0 ); 1585 } 1586 1587 function perform() 1588 { 1589 // initial message, no errors yet 1590 $this->message = "Loading new permissions (step %s of %s)<br/>"; 1591 $errors = false; 1592 1593 // load the core permissions 1594 include ( PLOG_CLASS_PATH."install/corepermissions.properties.php" ); 1595 1596 // process permissions 1597 $total = 0; 1598 foreach( $permissions as $perm ) { 1599 // check if it already exists 1600 $query = "SELECT * FROM ".$this->dbPrefix."permissions WHERE permission = '".$perm[0]."'"; 1601 $result = $this->Execute( $query ); 1602 if( !$result || $result->RowCount() < 1 ) { 1603 // permission needs to be added 1604 $corePerm = ( $perm[2] == true ? 1 : 0 ); 1605 $adminOnly = ( $perm[3] == true ? 1 : 0 ); 1606 $query = "INSERT INTO ".$this->dbPrefix."permissions (permission,description,core_perm,admin_only) ". 1607 "VALUES ('".$perm[0]."','".$perm[1]."','".$corePerm."','".$adminOnly."')"; 1608 $this->_db->Execute( $query ); 1609 $total++; 1610 } 1611 } 1612 1613 // 1614 // prepare the users_permissions table for the next step 1615 // 1616 1617 // make sure we are starting with an empty table 1618 $this->Execute("DELETE FROM ".Db::getPrefix()."tmp_users_permissions"); 1619 1620 if( !$this->Execute( "INSERT INTO ".$this->dbPrefix."tmp_users_permissions SELECT * FROM ".$this->dbPrefix."users_permissions WHERE blog_id != 0 AND permission_id != 1" )) { 1621 $this->message .= "Error preparing the users_permissions table for transformation"; 1622 $errors = true; 1623 } 1624 else { 1625 $this->Execute( "DELETE FROM ".$this->dbPrefix."users_permissions" ); 1626 $this->message .= count($permissions)." permissions successfully loaded"; 1627 $errors = false; 1628 } 1629 1630 return( !$errors ); 1631 } 1632 } 1633 1634 class ConfigDataTransformer extends DatabaseDataTransformer 1635 { 1636 function getNumSteps() 1637 { 1638 return( 0 ); 1639 } 1640 1641 function perform() 1642 { 1643 global $Inserts; 1644 1645 $this->message = "Adding new configuration parameters (step %s of %s)<br/>"; 1646 $errors = false; 1647 1648 // Find some of the tools we are going to need (last one is for os x, with fink installed), this will be needed later on 1649 $folders = Array( "/bin/", "/usr/bin/", "/usr/local/bin/", "/sw/bin/" ); 1650 $finder = new FileFinder(); 1651 $pathToUnzip = $finder->findBinary( "unzip", $folders ); 1652 $pathToTar = $finder->findBinary( "tar", $folders); 1653 $pathToGzip = $finder->findBinary( "gzip", $folders); 1654 $pathToBzip2 = $finder->findBinary( "bzip2", $folders); 1655 $pathToConvert = $finder->findBinary( "convert", $folders); 1656 1657 // check the configuration and add the new configuration settings that were added for 1.2 1658 foreach( $Inserts as $key => $insert ) { 1659 $checkKeyQuery = "SELECT * FROM ".$this->dbPrefix."config WHERE config_key ='".$key."';"; 1660 $result = $this->Execute($checkKeyQuery); 1661 if(!$result){ 1662 $this->message .= "Error executing code: ".$this->_db->ErrorMsg()."<br/>"; 1663 $errors = true; 1664 } 1665 else{ 1666 if ($result->RecordCount() == 0) { 1667 // replace the prefix 1668 $query = str_replace( "{dbprefix}", $this->dbPrefix, $insert ); 1669 // replace also the placeholders for the paths to the tools 1670 $query = str_replace( "{path_to_tar}", $pathToTar, $query ); 1671 $query = str_replace( "{path_to_unzip}", $pathToUnzip, $query ); 1672 $query = str_replace( "{path_to_bz2}", $pathToBzip2, $query ); 1673 $query = str_replace( "{path_to_gzip}", $pathToGzip, $query ); 1674 $query = str_replace( "{path_to_convert}", $pathToConvert, $query ); 1675 $query = str_replace( "{path_to_convert}", $pathToConvert, $query ); 1676 if( !$this->Execute( $query )) { 1677 $this->message .= "Error executing code: ".$this->_db->ErrorMsg()."<br/>"; 1678 $errors = true; 1679 } 1680 } 1681 $result->Close(); 1682 } 1683 } 1684 // check to see if we need to remove duplicates and the id index 1685 $query = "SELECT id FROM ".$this->dbPrefix."config LIMIT 1"; 1686 $result = $this->Execute($query); 1687 // if $result is false, id column has already been removed 1688 if($result){ 1689 $result->Close(); 1690 // remove all duplicates in plog_config table 1691 1692 // first create temp table without the duplicates 1693 $query = "CREATE TEMPORARY TABLE tmptable ". 1694 "SELECT * FROM ".$this->dbPrefix."config WHERE 1 GROUP BY config_key"; 1695 $result = $this->Execute($query); 1696 if($result){ 1697 //$result->Close(); 1698 // Now delete the old table 1699 $query = "DELETE FROM ".$this->dbPrefix."config"; 1700 $result = $this->Execute($query); 1701 if($result) { 1702 //$result->Close(); 1703 // Insert the unique rows into the old table 1704 $query = "INSERT INTO ".$this->dbPrefix."config SELECT * FROM tmptable"; 1705 $result = $this->Execute($query); 1706 } 1707 } 1708 /*if(!$result){ 1709 $this->message .= "Error removing duplicates in config table<br/>"; 1710 $errors = true; 1711 }*/ 1712 1713 if($result){ 1714 1715 // remove index id field, we don't need it any more! 1716 $query = "ALTER TABLE ".$this->dbPrefix."config DROP COLUMN id"; 1717 $result = $this->Execute($query); 1718 if(!$result){ 1719 $this->message .= "Error removing old id column from config table: ".$this->_db->ErrorMsg()."<br/>"; 1720 $errors = true; 1721 } 1722 } 1723 } 1724 1725 if( !$errors ) { 1726 $this->message .= "Configuration settings updated successfully"; 1727 } 1728 1729 return( !$errors ); 1730 } 1731 } 1732 1733 /** 1734 * Processes all admin users and grants the appropriate permissions 1735 */ 1736 class AdminUserPermissionsDataTransformer extends DatabaseDataTransformer 1737 { 1738 function getNumSteps() 1739 { 1740 return( parent::getNumSteps( "users" )); 1741 } 1742 1743 function perform() 1744 { 1745 $this->message = "Updating admin user permissions (step %s of %s)<br/>"; 1746 1747 // load each one of the categories and update them 1748 // list of categories 1749 /*$query3 = "SELECT id, site_admin FROM ".$this->dbPrefix."users"; 1750 $res3 = $this->Execute( $query3, $this->page, $this->itemsPerPage ); 1751 if( $res3->RecordCount() == 0 ) { 1752 $this->message .= "No more records to process"; 1753 return( true ); 1754 }*/ 1755 1756 $users = new Users(); 1757 $allUsers = $users->getAllUsers( USER_STATUS_ALL, "", "", $this->page, $this->itemsPerPage ); 1758 1759 $permissions = new Permissions(); 1760 $userPermissions = new UserPermissions(); 1761 $loginPerm = $permissions->getPermissionByName( "login_perm" ); 1762 $allPerms = $permissions->getAllPermissions(); 1763 1764 //while( $row = $res3->FetchRow()) { 1765 foreach( $allUsers as $user ) { 1766 print("Processing user: ".$user->getUsername()."<br/>"); 1767 //if( $row["site_admin"] > 0 ) { 1768 if( $user->isSiteAdmin()) { 1769 // it's an admin, let's grant all the appropriate permissions 1770 foreach( $allPerms as $perm ) { 1771 if( $perm->isAdminOnlyPermission() && $perm->getName() != "login_perm" ) { 1772 //$userPerm = new UserPermission( $row["id"], 0, $perm->getId()); 1773 $userPerm = new UserPermission( $user->getId(), 0, $perm->getId()); 1774 $userPermissions->grantPermission( $userPerm ); 1775 } 1776 } 1777 } 1778 // grant the login_perm permission or else users won't be able to log in 1779 $newPerm = new UserPermission( $user->getId(), 0, $loginPerm->getId()); 1780 $userPermissions->grantPermission( $newPerm ); 1781 1782 $this->updatedRecords++; 1783 } 1784 1785 $this->message .= "{$this->updatedRecords} users updated (".$this->getPercentProcessed()."%%)<br/>"; 1786 return true; 1787 } 1788 } 1789 1790 /** 1791 * processes all resource files and renames the files to their "real" names 1792 */ 1793 class ResourcesOriginalFileNameDataTransformer extends DatabaseDataTransformer 1794 { 1795 function getNumSteps() 1796 { 1797 return( parent::getNumSteps( "gallery_resources" )); 1798 } 1799 1800 function perform() 1801 { 1802 $this->message = "Updating resource files with original file naming rule (step %s of %s)<br/>"; 1803 1804 $query1 = "SELECT id, owner_id, file_name, resource_type, thumbnail_format FROM ".$this->dbPrefix."gallery_resources"; 1805 1806 $config =& Config::getConfig(); 1807 $galleryFolder = $config->getValue( "resources_folder" ); 1808 1809 // total number of comments 1810 $res1 = $this->Execute( $query1, $this->page, $this->itemsPerPage ); 1811 if( !$res1 ) { 1812 $this->message .= "Error performing loading resource data"; 1813 return false; 1814 } 1815 if( $res1->RecordCount() == 0 ) { 1816 $this->message .= "No more records to process"; 1817 return( true ); 1818 } 1819 $numComments = Array(); 1820 while( $row = $res1->FetchRow()) { 1821 // 1822 // process each one of the rows and rename the main file 1823 // 1824 1825 // get the file extension 1826 if(( $extPos = strrpos( $row["file_name"], "." )) !== false ) { 1827 $fileExt = substr( $row["file_name"], $extPos+1, strlen( $row["file_name"] )); 1828 } 1829 else { 1830 $fileExt = ""; 1831 } 1832 1833 $fileName = $galleryFolder.$row["owner_id"]."/".$row["owner_id"]."-".$row["id"].".".$fileExt; 1834 $destFileName = $galleryFolder.$row["owner_id"]."/".$row["file_name"]; 1835 1836 //print( "Renaming file: $fileName --- $destFileName<br/>" ); 1837 1838 // skip the rename if we already did it 1839 if( File::exists( $fileName )) { 1840 if( !File::exists( $destFileName)) { 1841 if( !File::rename( $fileName, $destFileName )) { 1842 $this->message .= "Error updating resource file with id ".$row["id"].", while attempting to rename file from $fileName to $destFileName<br/>"; 1843 } 1844 } 1845 } 1846 1847 // if it's an image, we also need to process the previews 1848 if( $row["resource_type"] == "1" ) { 1849 // calculate the extension of the preview file, depending on how it was saved 1850 if( $row["thumbnail_format"] == "same" ) { 1851 $previewExt = strtolower( $fileExt ); 1852 $destFileName = $row["file_name"]; 1853 } 1854 else { 1855 $previewExt = $row["thumbnail_format"]; 1856 // remove the old extension and put the new one in place 1857 //print("file name = ".$row["file_name"]." - file ext = $fileExt - previewExt = $previewExt" ); 1858 $destFileName = str_replace( $fileExt, $previewExt, $row["file_name"] ); 1859 } 1860 1861 // file names for the preview and medium preview 1862 $previewFileName = $galleryFolder.$row["owner_id"]."/previews/".$row["owner_id"]."-".$row["id"].".".$previewExt; 1863 $medPreviewFileName = $galleryFolder.$row["owner_id"]."/previews-med/".$row["owner_id"]."-".$row["id"].".".$previewExt; 1864 // destination file names for the preview and medium preview 1865 $destPreviewFileName = $galleryFolder.$row["owner_id"]."/previews/".$destFileName; 1866 $destMedPreviewFileName = $galleryFolder.$row["owner_id"]."/previews-med/".$destFileName; 1867 1868 //print(" -- renaming preview: $previewFileName -- $destPreviewFileName<br/>"); 1869 //print(" -- renaming medium preview: $medPreviewFileName -- $destMedPreviewFileName<br/>"); 1870 1871 if( File::exists( $previewFileName )) { 1872 if( !File::exists( $destPreviewFileName)) { 1873 File::rename( $previewFileName, $destPreviewFileName ); 1874 } 1875 } 1876 if( File::exists( $medPreviewFileName )) { 1877 if( !File::exists( $destMedPreviewFileName)) { 1878 File::rename( $medPreviewFileName, $destMedPreviewFileName ); 1879 } 1880 } 1881 } 1882 1883 $this->updatedRecords++; 1884 } 1885 $res1->Close(); 1886 $this->message .= "{$this->updatedRecords} resource files updated, ".$this->getTotalProcessedRecords()." processed so far (".$this->getPercentProcessed()."%%)<br/>"; 1887 return true; 1888 } 1889 } 1890 1891 /** 1892 * processes all resource files and renames the files to their "encoded" names 1893 */ 1894 class ResourcesEncodedFileNameDataTransformer extends DatabaseDataTransformer 1895 { 1896 function getNumSteps() 1897 { 1898 return( parent::getNumSteps( "gallery_resources" )); 1899 } 1900 1901 function perform() 1902 { 1903 $this->message = "Updating resource files with encoded file naming rule (step %s of %s)<br/>"; 1904 1905 $query1 = "SELECT id, owner_id, file_name, resource_type, thumbnail_format FROM ".$this->dbPrefix."gallery_resources"; 1906 1907 $config =& Config::getConfig(); 1908 $galleryFolder = $config->getValue( "resources_folder" ); 1909 1910 // total number of comments 1911 $res1 = $this->Execute( $query1, $this->page, $this->itemsPerPage ); 1912 if( !$res1 ) { 1913 $this->message .= "Error performing loading resource data"; 1914 return false; 1915 } 1916 if( $res1->RecordCount() == 0 ) { 1917 $this->message .= "No more records to process"; 1918 return( true ); 1919 } 1920 $numComments = Array(); 1921 while( $row = $res1->FetchRow()) { 1922 // 1923 // process each one of the rows and rename the main file 1924 // 1925 1926 // get the file extension 1927 if(( $extPos = strrpos( $row["file_name"], "." )) !== false ) { 1928 $fileExt = substr( $row["file_name"], $extPos+1, strlen( $row["file_name"] )); 1929 } 1930 else { 1931 $fileExt = ""; 1932 } 1933 1934 $fileName = $galleryFolder.$row["owner_id"]."/".$row["owner_id"]."-".$row["id"].".".$fileExt; 1935 $destFileName = $galleryFolder.$row["owner_id"]."/".$row["owner_id"]."-".$row["id"].".".strtolower($fileExt); 1936 1937 if( $fileName != $destFileName ) { 1938 if( File::exists( $fileName )) { 1939 if( !File::exists( $destFileName)) { 1940 if( !File::rename( $fileName, $destFileName )) { 1941 $this->message .= "Error updating resource file with id ".$row["id"].", while attempting to rename file from $fileName to $destFileName<br/>"; 1942 } 1943 } 1944 } 1945 } 1946 1947 $this->updatedRecords++; 1948 } 1949 $res1->Close(); 1950 $this->message .= "{$this->updatedRecords} resource files updated, ".$this->getTotalProcessedRecords()." processed so far (".$this->getPercentProcessed()."%%)<br/>"; 1951 return true; 1952 } 1953 } 1954 1955 /** 1956 * processes all resource files that we did not convert correctly in 1.2.0 1957 */ 1958 class ResourcesFix120FileNameDataTransformer extends DatabaseDataTransformer 1959 { 1960 function getNumSteps() 1961 { 1962 return( parent::getNumSteps( "gallery_resources" )); 1963 } 1964 1965 function perform() 1966 { 1967 $this->message = "Fixing resource files with original file naming rule (step %s of %s)<br/>"; 1968 1969 $query1 = "SELECT id, owner_id, file_name, resource_type, thumbnail_format FROM ".$this->dbPrefix."gallery_resources"; 1970 1971 $config =& Config::getConfig(); 1972 $galleryFolder = $config->getValue( "resources_folder" ); 1973 1974 // total number of comments 1975 $res1 = $this->Execute( $query1, $this->page, $this->itemsPerPage ); 1976 if( !$res1 ) { 1977 $this->message .= "Error performing loading resource data"; 1978 return false; 1979 } 1980 if( $res1->RecordCount() == 0 ) { 1981 $this->message .= "No more records to process"; 1982 return( true ); 1983 } 1984 $numComments = Array(); 1985 while( $row = $res1->FetchRow()) { 1986 // 1987 // process each one of the rows and rename the main file 1988 // 1989 1990 // get the file extension 1991 if(( $extPos = strrpos( $row["file_name"], "." )) !== false ) { 1992 $fileExt = substr( $row["file_name"], $extPos+1, strlen( $row["file_name"] )); 1993 } 1994 else { 1995 $fileExt = ""; 1996 } 1997 1998 // Only convert the preview file name if the file extension does not lower case 1999 if( strtolower( $fileExt ) != $fileExt ) { 2000 // if it's an image, we also need to process the previews 2001 if( $row["resource_type"] == "1" ) { 2002 // calculate the extension of the preview file, depending on how it was saved 2003 if( $row["thumbnail_format"] == "same" ) { 2004 $previewExt = strtolower( $fileExt ); 2005 $destFileName = $row["file_name"]; 2006 } 2007 else { 2008 $previewExt = $row["thumbnail_format"]; 2009 // remove the old extension and put the new one in place 2010 //print("file name = ".$row["file_name"]." - file ext = $fileExt - previewExt = $previewExt" ); 2011 $destFileName = str_replace( $fileExt, $previewExt, $row["file_name"] ); 2012 } 2013 2014 // file names for the preview and medium preview 2015 $previewFileName = $galleryFolder.$row["owner_id"]."/previews/".$row["owner_id"]."-".$row["id"].".".$previewExt; 2016 $medPreviewFileName = $galleryFolder.$row["owner_id"]."/previews-med/".$row["owner_id"]."-".$row["id"].".".$previewExt; 2017 // destination file names for the preview and medium preview 2018 $destPreviewFileName = $galleryFolder.$row["owner_id"]."/previews/".$destFileName; 2019 $destMedPreviewFileName = $galleryFolder.$row["owner_id"]."/previews-med/".$destFileName; 2020 2021 //print(" -- renaming preview: $previewFileName -- $destPreviewFileName<br/>"); 2022 //print(" -- renaming medium preview: $medPreviewFileName -- $destMedPreviewFileName<br/>"); 2023 2024 if( File::exists( $previewFileName )) { 2025 if( !File::exists( $destPreviewFileName)) { 2026 File::rename( $previewFileName, $destPreviewFileName ); 2027 } 2028 } 2029 if( File::exists( $medPreviewFileName )) { 2030 if( !File::exists( $destMedPreviewFileName)) { 2031 File::rename( $medPreviewFileName, $destMedPreviewFileName ); 2032 } 2033 } 2034 } 2035 } 2036 2037 $this->updatedRecords++; 2038 } 2039 $res1->Close(); 2040 $this->message .= "{$this->updatedRecords} resource files updated, ".$this->getTotalProcessedRecords()." processed so far (".$this->getPercentProcessed()."%%)<br/>"; 2041 return true; 2042 } 2043 } 2044 2045 // Dummy Transformer 2046 class DummyDataTransformer extends DatabaseDataTransformer 2047 { 2048 function getNumSteps() 2049 { 2050 return( 0 ); 2051 } 2052 2053 function perform() 2054 { 2055 return true; 2056 } 2057 } 2058 2059 /** 2060 * This class is basically now a "data transformer runner", because now it works 2061 * like class that executes data transformers, collects their results and refreshes 2062 * the page to execute the next step of the transformer. If the current transformer 2063 * reported that its processing is complete, this class will continue with the next 2064 * transformer unless there are no more transformer to run. 2065 * 2066 * In order to coordinate the current step and the current transformer, two parameters 2067 * are needed in each request: 2068 * 2069 * - page 2070 * - transformerId 2071 * 2072 * The 'page' parameter holds the current page, while 'transformerId' is the index of 2073 * the current transformer in the $this->transformers array. 2074 * 2075 * In order to add new transformers, follow these steps: 2076 * 2077 * - Create your own transfomer class by extending DatabaseDataTransformer and implementing 2078 * the methods DatabaseDataTransformer::perform() and DatabaseDataTransformer::getNumSteps(). The 2079 * first does the data processing while the second one returns the number of needed steps to the 2080 * class running the transformer. 2081 * - Add the name of the transformer class to the the UpdateStepThree::transformers array, 2082 * and the class will take care of everything else. 2083 */ 2084 class UpdateStepThree extends WizardPagedAction 2085 { 2086 var $resourcesNamingRule; 2087 var $message; 2088 var $currentTransformerId; 2089 var $totalTransformers; 2090 2091 function UpdateStepThree( $actionInfo, $httpRequest ) 2092 { 2093 $this->WizardPagedAction( $actionInfo, $httpRequest ); 2094 // data validation 2095 $this->registerFieldValidator( "resourcesNamingRule", new StringValidator()); 2096 $errorView = new WizardView( "update2" ); 2097 $errorView->setErrorMessage( "Some data was incorrect or missing." ); 2098 $this->setValidationErrorView( $errorView ); 2099 2100 /** 2101 * array with the data transformers that will be run 2102 */ 2103 $this->resourcesNamingRule = $this->_request->getValue( "resourcesNamingRule" ); 2104 if( $this->resourcesNamingRule == 'encoded_file_name' ) { 2105 $this->transformers = Array( 2106 "DatabaseSchemaDataTransformer", 2107 "PermissionLoader", 2108 "AdminUserPermissionsDataTransformer", 2109 "UserPermissionsDataTransformer", 2110 "ConfigDataTransformer", 2111 "ResourcesEncodedFileNameDataTransformer", 2112 "DummyDataTransformer" 2113 ); 2114 } 2115 else { 2116 $this->transformers = Array( 2117 "DatabaseSchemaDataTransformer", 2118 "PermissionLoader", 2119 "AdminUserPermissionsDataTransformer", 2120 "UserPermissionsDataTransformer", 2121 "ConfigDataTransformer", 2122 "ResourcesOriginalFileNameDataTransformer", 2123 "DummyDataTransformer" 2124 ); 2125 } 2126 2127 $this->currentTransformerId = $this->getTransformerIdFromRequest(); 2128 $this->totalTransformers = count( $this->transformers ) - 1; 2129 } 2130 2131 /** 2132 * gets the id of the transformer from the request. If it is not available, it 2133 * will return the id of the first transformer available (which is '0') 2134 * 2135 * @private 2136 */ 2137 function getTransformerIdFromRequest() 2138 { 2139 $id = HttpVars::getRequestValue( "transformerId" ); 2140 $val = new IntegerValidator(); 2141 if( !$val->validate( $id )) 2142 $id = 0; 2143 2144 return $id; 2145 } 2146 2147 function perform() 2148 { 2149 $step = $this->getPageFromRequest(); 2150 2151 // get the current transformer class so that we can continue where we left 2152 $transformerClass = $this->transformers[$this->currentTransformerId]; 2153 $transformer = new $transformerClass( $step ); 2154 $result = $transformer->perform(); 2155 $complete = $transformer->isComplete(); 2156 $message = $transformer->message; 2157 $message = sprintf( $message, $this->currentTransformerId + 1, $this->totalTransformers ); 2158 2159 //print("transformer = $transformerClass<br/>"); 2160 2161 // error during processing and the processor is configured 2162 // to fail on error 2163 if( !$result && $transformer->failOnError ) { 2164 //print("Error in step = $step<br/>"); 2165 $this->_view = new WizardView( "update3" ); 2166 $this->_view->setValue( "resourcesNamingRule", $this->resourcesNamingRule ); 2167 // current and next step 2168 $this->_view->setValue( "currentStep", $step ); 2169 $this->_view->setValue( "nextStep", $step+1 ); 2170 // whether this transformer is ready 2171 $this->_view->setValue( "complete", $complete ); 2172 // transformer id 2173 $this->_view->setValue( "transformerId", $this->currentTransformerId ); 2174 $this->_view->setValue( "error", true ); 2175 if( $transformer->DbError() != "" ) { 2176 $message .= "<br/>The database error message was: ".$transformer->DbError()."<br/>"; 2177 } 2178 2179 $this->_view->setErrorMessage( $message ); 2180 } 2181 else { 2182 if( !$complete ) { 2183 //print("it's not complete! step = $step<br/>"); 2184 $this->_view = new WizardView( "update3" ); 2185 $this->_view->setValue( "resourcesNamingRule", $this->resourcesNamingRule ); 2186 // current and next step 2187 $this->_view->setValue( "currentStep", $step ); 2188 $this->_view->setValue( "nextStep", $step+1 ); 2189 // whether this transformer is ready 2190 $this->_view->setValue( "complete", $complete ); 2191 // transformer id 2192 $this->_view->setValue( "transformerId", $this->currentTransformerId ); 2193 } 2194 else { 2195 // have we already been through all transformers? 2196 //print("transformer complete! - num transformers = ".count($this->transformers)."<br/>"); 2197 $moreTransformers = ( $this->currentTransformerId+1 < count( $this->transformers )); 2198 if( $moreTransformers ) { 2199 //print("Starting new transformer!<br/>"); 2200 $this->_view = new WizardView( "update3" ); 2201 $this->_view->setValue( "resourcesNamingRule", $this->resourcesNamingRule ); 2202 // current and next step 2203 $this->_view->setValue( "currentStep", 0 ); 2204 $this->_view->setValue( "nextStep", 1 ); 2205 // whether this transformer is ready 2206 $this->_view->setValue( "complete", false ); 2207 // transformer id 2208 $this->_view->setValue( "transformerId", $this->currentTransformerId+1 ); 2209 } 2210 else { 2211 // no more data to transform, we can finalize the installation! 2212 // delete the contents of the temporary folder 2213 lt_include( PLOG_CLASS_PATH."class/config/config.class.php" ); 2214 $config =& Config::getConfig(); 2215 $tmpFolder = $config->getValue( "temp_folder", TEMP_FOLDER ); 2216 WizardTools::cleanTmpFolder(); 2217 2218 // save the resources naming rule to config table 2219 $config->saveValue( "resources_naming_rule", $this->resourcesNamingRule ); 2220 2221 $this->_view = new WizardView( "update4" ); 2222 } 2223 } 2224 } 2225 2226 $this->_view->setValue( "message", $message ); 2227 2228 return true; 2229 } 2230 } 2231 2232 // Fix those resources that we did not convert correctly in 1.2.0 2233 class Fix120StepOne extends WizardPagedAction 2234 { 2235 var $message; 2236 var $currentTransformerId; 2237 var $totalTransformers; 2238 2239 function Fix120StepOne( $actionInfo, $httpRequest ) 2240 { 2241 $this->WizardPagedAction( $actionInfo, $httpRequest ); 2242 2243 /** 2244 * array with the data transformers that will be run 2245 */ 2246 $this->transformers = Array( 2247 "ResourcesFix120FileNameDataTransformer", 2248 "DummyDataTransformer" 2249 ); 2250 2251 $this->currentTransformerId = $this->getTransformerIdFromRequest(); 2252 $this->totalTransformers = count( $this->transformers ) - 1; 2253 } 2254 2255 /** 2256 * gets the id of the transformer from the request. If it is not available, it 2257 * will return the id of the first transformer available (which is '0') 2258 * 2259 * @private 2260 */ 2261 function getTransformerIdFromRequest() 2262 { 2263 $id = HttpVars::getRequestValue( "transformerId" ); 2264 $val = new IntegerValidator(); 2265 if( !$val->validate( $id )) 2266 $id = 0; 2267 2268 return $id; 2269 } 2270 2271 function perform() 2272 { 2273 $step = $this->getPageFromRequest(); 2274 2275 // get the current transformer class so that we can continue where we left 2276 $transformerClass = $this->transformers[$this->currentTransformerId]; 2277 $transformer = new $transformerClass( $step ); 2278 $result = $transformer->perform(); 2279 $complete = $transformer->isComplete(); 2280 $message = $transformer->message; 2281 $message = sprintf( $message, $this->currentTransformerId + 1, $this->totalTransformers ); 2282 2283 //print("transformer = $transformerClass<br/>"); 2284 2285 // error during processing and the processor is configured 2286 // to fail on error 2287 if( !$result && $transformer->failOnError ) { 2288 //print("Error in step = $step<br/>"); 2289 $this->_view = new WizardView( "update3" ); 2290 // current and next step 2291 $this->_view->setValue( "currentStep", $step ); 2292 $this->_view->setValue( "nextStep", $step+1 ); 2293 // whether this transformer is ready 2294 $this->_view->setValue( "complete", $complete ); 2295 // transformer id 2296 $this->_view->setValue( "transformerId", $this->currentTransformerId ); 2297 $this->_view->setValue( "error", true ); 2298 if( $transformer->DbError() != "" ) { 2299 $message .= "<br/>The database error message was: ".$transformer->DbError()."<br/>"; 2300 } 2301 2302 $this->_view->setErrorMessage( $message ); 2303 } 2304 else { 2305 if( !$complete ) { 2306 //print("it's not complete! step = $step<br/>"); 2307 $this->_view = new WizardView( "fix120" ); 2308 // current and next step 2309 $this->_view->setValue( "currentStep", $step ); 2310 $this->_view->setValue( "nextStep", $step+1 ); 2311 // whether this transformer is ready 2312 $this->_view->setValue( "complete", $complete ); 2313 // transformer id 2314 $this->_view->setValue( "transformerId", $this->currentTransformerId ); 2315 } 2316 else { 2317 // have we already been through all transformers? 2318 //print("transformer complete! - num transformers = ".count($this->transformers)."<br/>"); 2319 $moreTransformers = ( $this->currentTransformerId+1 < count( $this->transformers )); 2320 if( $moreTransformers ) { 2321 //print("Starting new transformer!<br/>"); 2322 $this->_view = new WizardView( "fix120" ); 2323 // current and next step 2324 $this->_view->setValue( "currentStep", 0 ); 2325 $this->_view->setValue( "nextStep", 1 ); 2326 // whether this transformer is ready 2327 $this->_view->setValue( "complete", false ); 2328 // transformer id 2329 $this->_view->setValue( "transformerId", $this->currentTransformerId+1 ); 2330 } 2331 else { 2332 // no more data to transform, we can finalize the installation! 2333 // delete the contents of the temporary folder 2334 lt_include( PLOG_CLASS_PATH."class/config/config.class.php" ); 2335 $config =& Config::getConfig(); 2336 $tmpFolder = $config->getValue( "temp_folder", TEMP_FOLDER ); 2337 WizardTools::cleanTmpFolder(); 2338 2339 // User upgrade LifeType from 1.1.x to 1.2.0, they have to use "original_file_name", 2340 // becasue there is no option for user to choose he want to use encoded file name 2341 // or original file name. 2342 // save the resources naming rule to config table 2343 $config->saveValue( "resources_naming_rule", "original_file_name" ); 2344 2345 $this->_view = new WizardView( "update4" ); 2346 } 2347 } 2348 } 2349 2350 $this->_view->setValue( "message", $message ); 2351 2352 return true; 2353 } 2354 } 2355 2356 // check if the "./tmp" folder is writable by us, otherwise 2357 // throw an error before the user gets countless errors 2358 // from Smarty 2359 if( !File::isWritable( TEMP_FOLDER ) || !File::isDir( TEMP_FOLDER )) { 2360 print("<span style=\"color:red; font-size: 14px;\">Error</span><br/><br/>This wizard needs the ".TEMP_FOLDER." folder to be writable by the web server user.<br/><br/>Please correct it and try again."); 2361 die(); 2362 } 2363 2364 //// main part //// 2365 $controller = new Controller( $_actionMap, "nextStep" ); 2366 $controller->process( HttpVars::getRequest()); 2367 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Mon Nov 26 21:04:15 2007 | par Balluche grâce à PHPXref 0.7 |
|