[ Index ]
 

Code source de LifeType 1.2.4

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/ -> wizard.php (source)

   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", "&amp;");
  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  ?>


Généré le : Mon Nov 26 21:04:15 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics