[ PHPXref.com ] [ Generated: Sun Jul 20 17:51:59 2008 ] [ Flyspray 0.9.8 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/setup/ -> index.php (source)

   1  <?php
   2  // +----------------------------------------------------------------------
   3  // | PHP Source
   4  // +----------------------------------------------------------------------
   5  // | Copyright (C) 2005 by Jeffery Fernandez <developer@jefferyfernandez.id.au>
   6  // +----------------------------------------------------------------------
   7  // |
   8  // | Copyright: See COPYING file that comes with this distribution
   9  // +----------------------------------------------------------------------
  10  //
  11  // http://www.phpinfo.net/articles/article_php-coding-standard.html
  12  
  13  session_start();
  14  
  15  error_reporting(0);
  16  
  17  if (file_exists('../flyspray.conf.php') && (count($config = parse_ini_file('../flyspray.conf.php', true)) > 0) )
  18  {
  19     die('Flyspray Already Installed. Delete the contents of flyspray.conf.php to run setup.');
  20  }
  21  
  22  // ---------------------------------------------------------------------
  23  // Application information
  24  // ---------------------------------------------------------------------
  25  define('VALID_FLYSPRAY', 1 );
  26  define('APPLICATION_NAME', 'Flyspray');
  27  
  28  // ---------------------------------------------------------------------
  29  // Application Web locations
  30  // ---------------------------------------------------------------------
  31  define('SERVER_WEB_ROOT', 'http://'.$_SERVER['SERVER_NAME']);
  32  define('APPLICATION_SETUP_FOLDER', dirname($_SERVER['PHP_SELF']));
  33  define('APPLICATION_SETUP_INDEX', SERVER_WEB_ROOT . APPLICATION_SETUP_FOLDER);
  34  define('APPLICATION_WEB_ROOT', str_replace('setup',"",APPLICATION_SETUP_INDEX));
  35  
  36  // ---------------------------------------------------------------------
  37  // Application file system locations
  38  // ---------------------------------------------------------------------
  39  define('APPLICATION_PATH', realpath('../') );
  40  define('OBJECTS_PATH', realpath('../includes') );
  41  define('TEMPLATE_FOLDER', realpath('templates/'));
  42  
  43  require_once (OBJECTS_PATH . '/template.php');
  44  require_once (OBJECTS_PATH . '/functions.inc.php');
  45  require_once (OBJECTS_PATH . '/version.php');
  46  
  47  class Setup extends Flyspray
  48  {
  49     var $mPhpRequired;
  50     var $mSupportedDatabases;
  51     var $mAvailableDatabases;
  52  
  53     var $mProceed;
  54     var $mPhpVersionStatus;
  55     var $mAdodbStatus;
  56     var $mDatabaseStatus;
  57     var $mConfigFileStatus;
  58     var $mConfigText;
  59     var $mHtaccessText;
  60     var $mCacheFolderStatus;
  61  
  62     var $mDbConnection;
  63     var $mProductName;
  64     var $mUnixName;
  65     var $mAuthor;
  66  
  67     /**
  68      * @var string To store the data filter type
  69      */
  70     var $mDataFilter;
  71  
  72     /**
  73      * @var array To store the type of database setup (install or Upgrade).
  74      */
  75     var $mDatabaseSetup;
  76  
  77     var $mPreferencesTable;
  78     var $mUsersTable;
  79     var $mAttachmentsTable;
  80     var $mCommentsTable;
  81  
  82     var $mServerSoftware;
  83     var $mMinPasswordLength;
  84     var $mAdminUsername;
  85     var $mAdminPassword;
  86     var $mCompleteAction;
  87     var $mPhpCliStatus;
  88  
  89     function Setup()
  90     {
  91        // Call parent constructor
  92        //$this->Flyspray();
  93  
  94        // Initialise Application values
  95        $mApplication                = & new Version();
  96        $this->mProductName            = $mApplication->mProductName;
  97        $this->mVersion                = $mApplication->mVersion;
  98        $this->mCopyright            = $mApplication->mCopyright;
  99        $this->mUnixName            = $mApplication->mUnixName;
 100        $this->mAuthor                = $mApplication->mAuthor;
 101  
 102        $this->mPreferencesTable    = 'flyspray_prefs';
 103        $this->mUsersTable            = 'flyspray_users';
 104        $this->mMinPasswordLength    = 8;
 105  
 106        // Initialise flag for proceeding to next step.
 107        $this->mProceed                = FALSE;
 108        $this->mPhpRequired            = '4.3';
 109  
 110        // If the database is supported in Flyspray, the function to check in PHP.
 111        $this->mSupportedDatabases    =
 112                             array(
 113                                   'MySQL' => array(TRUE, 'mysql_connect', 'mysql'),
 114                                   'Postgres' => array(TRUE, 'pg_connect', 'pgsql'),
 115                                );
 116        $this->mAvailableDatabases    = array();
 117  
 118        // Array of information to setup the appropriate tables for installation
 119        // or upgrade of flyspray.
 120        $this->mDatabaseSetup        = array (
 121                                      1 => array ('Install 0.9.8' => '/sql/flyspray-0.9.8', 'dependency' => '', 'function' => 'InstallPointNineEight'),
 122                                      2 => array ('Upgrade 0.9.7 - 0.9.8' => '/sql/upgrade_0.9.7_to_0.9.8', 'dependency' => '3', 'function' => 'UpgradePointNineSeven'),
 123                                      // Only for testing3 => array ('Install 0.9.7' => '/sql/flyspray-0.9.7', 'dependency' => '', 'function' => 'InstallPointNineSeven'),
 124                                   ); 
 125  
 126        $this->mServerSoftware        = (strstr($_SERVER['SERVER_SOFTWARE'], 'Apache'))
 127                             ? 'apache'
 128                             : (
 129                                (strstr($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS'))
 130                                ? 'iis'
 131                                : 'unknown'
 132                               );
 133  
 134        // Process the page actions
 135        $this->ProcessActions();
 136     }
 137  
 138     /**
 139     * Function to scan include path and any additional paths for files
 140     * @param string $includeFile Name of file to scan for
 141     * @param string $additionalPath An additional path to scan for. eg Application path
 142     * @return boolean/string FALSE/actual path of file
 143     */
 144     function ScanIncludePath($includeFile, $additionalPath = '')
 145     {
 146        $where_path = '';
 147  
 148        // Add the optional application path to the include_path
 149        if (!empty($additionalPath))
 150        {
 151           ini_set('include_path', $additionalPath . PATH_SEPARATOR . ini_get('include_path'));
 152        }
 153  
 154  
 155        // Get the current include path settings from php config file
 156        $paths = explode(PATH_SEPARATOR, ini_get('include_path'));
 157  
 158  
 159        // Loop through the array of paths
 160        foreach($paths as $path)
 161        {
 162           // Check to see if the last character of the path is a "directory separator"
 163           if (substr($path, -1, 1) == DIRECTORY_SEPARATOR)
 164           {
 165              // If file exists, transfer the values and quit the foreach loop
 166              if (file_exists($path . $includeFile))
 167              {
 168                 $where_path = $path . $includeFile;
 169                 break;
 170              }
 171           }
 172           else
 173           {
 174              // Include the "directory separator" in the scan
 175              if (file_exists($path . DIRECTORY_SEPARATOR . $includeFile))
 176              {
 177                 $where_path = $path . DIRECTORY_SEPARATOR . $includeFile;
 178                 break;
 179              }
 180           }
 181        }
 182        // Return success of scan
 183        return ($where_path) ? $where_path : FALSE;
 184     }
 185  
 186     /**
 187     * Function to check the availability of ADOdb libraries. It calls another
 188     * function to scan the inlcude paths and you can include the application path
 189     * to be scanned as well.
 190     * @return string HTML formatted status
 191     */
 192     function CheckAdodbLibrary()
 193     {
 194        // Get the ADOdb library path. If not found it will be FALSE
 195        $this->mAdodbPath = $this->ScanIncludePath('adodb.inc.php', realpath('../adodb'));
 196  
 197        // Update the status of the library
 198        $this->mAdodbStatus = ($this->mAdodbPath) ? TRUE : FALSE;
 199  
 200        // Return an html formated availabe/missing string
 201        return $this->ReturnStatus($this->mAdodbStatus, $type = 'available');
 202     }
 203  
 204     /**
 205     * Function to check the permission of the config file
 206     * @param void
 207     * @return string An html formatted boolean answer
 208     */
 209     function CheckConfigFile()
 210     {
 211        // Get the full path to the file
 212        $file = realpath('../flyspray.conf.php');
 213  
 214        // Update the status of the Config file
 215        $this->mConfigFileStatus = $this->IsWriteable($file);
 216  
 217        // Return an html formated writeable/un-writeable string
 218        return $this->ReturnStatus($this->mConfigFileStatus, $type = 'writeable');
 219     }
 220  
 221     /**
 222     * Function to check the permission of the cache folder
 223     * @param void
 224     * @return string An html formatted boolean answer
 225     */
 226     function CheckCacheFolder()
 227     {
 228        // Get the full path to the file
 229        $file = realpath('../cache');
 230  
 231        // Update the status of the Cache folder
 232        $this->mCacheFolderStatus = $this->IsWriteable($file);
 233  
 234        // Return an html formated writeable/un-writeable string
 235        return $this->ReturnStatus($this->mCacheFolderStatus, $type = 'writeable');
 236     }
 237  
 238  
 239     /**
 240     * Function to check the availability of the Database support
 241     * @param void
 242     * @return void
 243     */
 244     function CheckDatabaseSupport()
 245     {
 246        $status = array();
 247  
 248        foreach ($this->mSupportedDatabases as $which => $database)
 249        {
 250        // Checking if the database has libraries built into PHP. Returns TRUE/FALSE
 251        $this->mAvailableDatabases[$which]['status'] = function_exists($database[1]);
 252  
 253        // If the Application(Flyspray) supports the available database supported in PHP
 254        $this->mAvailableDatabases[$which]['supported'] = ($database[0] === $this->mAvailableDatabases[$which]['status'])
 255           ?  $this->mAvailableDatabases[$which]['status']
 256           :  FALSE;
 257  
 258        // Just transferring the value for ease of veryfying Database support.
 259        $status[] = $this->mAvailableDatabases[$which]['supported'];
 260  
 261        // Generating the output to be displayed
 262        $this->mAvailableDatabases[$which]['status_output'] =
 263           $this->ReturnStatus($this->mAvailableDatabases[$which]['status'], $type = 'available');
 264        }
 265  
 266        //print_r($this->mAvailableDatabases);
 267  
 268        // Check if any one database support exists.
 269        // Update the status of database availability
 270        $this->mDatabaseStatus = (in_array('1', $status)) ? TRUE : FALSE;
 271     }
 272  
 273  
 274     function CheckPreStatus()
 275     {
 276        $this->mProceed =
 277        ($this->mAdodbStatus && $this->mDatabaseStatus && $this->mPhpVersionStatus)
 278        ?  TRUE
 279        :  FALSE;
 280  
 281        return $this->mProceed;
 282     }
 283  
 284  
 285     /**
 286     * Function to check the version of PHP available compared to the
 287     * Applications requirements
 288     * @param void
 289     * @return string An html formatted boolean answer
 290     */
 291     function CheckPhpCompatibility()
 292     {
 293        // Check the PHP version. Recommended version is 4.3 and above
 294        $this->mPhpVersionStatus = (phpversion() >= $this->mPhpRequired) ? TRUE : FALSE;
 295  
 296        // Return an html formated Yes/No string
 297        return $this->ReturnStatus($this->mPhpVersionStatus, $type = 'yes');
 298     }
 299     
 300     function CheckPhpCli()
 301     {
 302          exec("php -v", $output, $php_cli);
 303          if ($php_cli && $output)
 304          {
 305              $this->mPhpCliStatus = TRUE;
 306              return $this->mPhpCliStatus;
 307          }
 308          else
 309          {
 310              return FALSE;
 311          }
 312     }
 313  
 314     /**
 315     * Function to check the posted data from forms.
 316     * @param array $expectedFields Array of field names which needs processing
 317     * If the array of filed names don't exist in the Posted data, then this function
 318     * will accumulate error messages in the $_SESSION[PASS_PHRASE]['page_message'] array.
 319     * return boolean/array $data will be returned if successful
 320     */
 321     function CheckPostedData($expectedFields = array(), $pageHeading)
 322     {
 323        // Add slashes to the post array
 324        $this->FilterGpc('add', 'post');
 325  
 326        // Grab the posted data and trim it.
 327        $data = array_filter($_POST, array($this, "TrimArgs"));
 328  
 329  
 330        // Loop through the required values and check data
 331        foreach($expectedFields as $key => $value)
 332        {
 333  
 334           // If the data is Required and is empty or not set
 335           if (!isset($data[$key]) || empty($data[$key]))
 336           {
 337              if ($expectedFields[$key][2] == TRUE)
 338              {
 339                 // Acumulate error messages
 340                 $_SESSION['page_message'][] = "<strong>{$expectedFields[$key][0]}</strong>  is required";
 341              }
 342           }
 343           // Check for variable types
 344           elseif (!$this->VerifyVariableTypes($expectedFields[$key][1], $data[$key]))
 345           {
 346              $_SESSION['page_message'][] = "<strong>{$expectedFields[$key][0]}</strong> has to be a {$expectedFields[$key][1]}";
 347           }
 348        }
 349  
 350        // If there were messages, return false
 351        if (isset($_SESSION['page_message']))
 352        {
 353           $_SESSION['page_heading'] = $pageHeading;
 354           return FALSE;
 355        }
 356        else
 357        {
 358           return $data;
 359        }
 360     }
 361  
 362     function DisplayAdministration()
 363     {
 364        // Strip any slashes in GPC if magic_quotes is turned ON
 365        $this->FilterGpc('strip', 'post');
 366  
 367        // Trim the empty values in the $_POST array
 368        $data = array_filter($_POST, array($this, "TrimArgs"));
 369  
 370        $templates =
 371        array(
 372              'admin_body' => array(
 373                          'path' => TEMPLATE_FOLDER,
 374                          'template' => 'administration.tpl.php',
 375                          'vars' => array(
 376                                      'product_name' => $this->mProductName,
 377                                      'message' => $this->GetPageMessage(),
 378                                      'site_url' => APPLICATION_WEB_ROOT,
 379                                      'absolute_path' => realpath(APPLICATION_PATH),
 380                                      'admin_email' => $this->GetAdminInput('admin_email', $this->GetParamValue($data, 'admin_email', ''), 'Admin Email'),
 381                                      'pass_phrase' => $this->GetParamValue($data, 'pass_phrase', ''),
 382                                      'admin_username' => $this->GetAdminInput('admin_username', $this->GetParamValue($data, 'admin_username', ''), 'Admin Username'),
 383                                      'admin_password' => $this->GetAdminInput('admin_password', $this->GetParamValue($data, 'admin_password', $this->MakePassword($this->mMinPasswordLength)), 'Admin Password'),
 384                                      'db_type' => $this->GetParamValue($data, 'db_type', ''),
 385                                      'db_hostname' => $this->GetParamValue($data, 'db_hostname', ''),
 386                                      'db_username' => $this->GetParamValue($data, 'db_username', ''),
 387                                      'db_password' => $this->GetParamValue($data, 'db_password', ''),
 388                                      'db_name' => $this->GetParamValue($data, 'db_name', ''),
 389                                      'db_prefix' => $this->GetParamValue($data, 'db_prefix', ''),
 390                                      'db_setup_options' => $this->GetParamValue($data, 'db_setup_options', ''),
 391                                      'daemonise' => $this->GetReminderDaemonSelection($this->GetParamValue($data, 'reminder_daemon', '1')),
 392                                   ),
 393                       ),
 394  
 395              'structure' =>  array(
 396                             'path' => TEMPLATE_FOLDER,
 397                             'template' => 'structure.tpl.php',
 398                             'vars' => array(
 399                                         'title' => 'Administration setup for',
 400                                         'headers' => '',
 401                                         'index' => APPLICATION_SETUP_INDEX,
 402                                         'version' => $this->mVersion,
 403                                         'copyright' => $this->mCopyright,
 404                                         ),
 405                             'block' => array('body' => 'admin_body')
 406                             )
 407           );
 408  
 409        // Output the final template.
 410        $this->OutputPage($templates);
 411     }
 412  
 413  
 414     function DisplayCompletion()
 415     {
 416        // Strip any slashes in GPC if magic_quotes is turned ON
 417        $this->FilterGpc('strip', 'post');
 418  
 419        // Trim the empty values in the $_POST array
 420        $data = array_filter($_POST, array($this, "TrimArgs"));
 421  
 422        $templates =
 423        array(
 424              'complete_body' => array(
 425                          'path' => TEMPLATE_FOLDER,
 426                          'template' => 'complete_install.tpl.php',
 427                          'vars' => array(
 428                                      'product_name' => $this->mProductName,
 429                                      'message' => $this->GetPageMessage(),
 430                                      'config_writeable' => $this->mConfigFileStatus,
 431                                      'config_text' => $this->mConfigText,
 432                                      'admin_username' => $this->mAdminUsername,
 433                                      'admin_password' => $this->mAdminPassword,
 434                                      'site_index' => $data['site_url'],
 435                                      'complete_action' => $this->mCompleteAction,
 436                                      'daemonise' => $this->CheckPhpCli(),
 437                                   ),
 438                       ),
 439  
 440              'structure' =>  array(
 441                             'path' => TEMPLATE_FOLDER,
 442                             'template' => 'structure.tpl.php',
 443                             'vars' => array(
 444                                         'title' => 'Setup confirmation for',
 445                                         'headers' => '',
 446                                         'index' => APPLICATION_SETUP_INDEX,
 447                                         'version' => $this->mVersion,
 448                                         'copyright' => $this->mCopyright,
 449                                         ),
 450                             'block' => array('body' => 'complete_body')
 451                             )
 452           );
 453  
 454        // Output the final template.
 455        $this->OutputPage($templates);
 456     }
 457  
 458     function DisplayDatabaseSetup()
 459     {
 460        // Strip any slashes in GPC if magic_quotes is turned ON
 461        $this->FilterGpc('strip', 'post');
 462  
 463        // Trim the empty values in the $_POST array
 464        $data = array_filter($_POST, array($this, "TrimArgs"));
 465  
 466        $templates =
 467        array(
 468              'database_body' => array(
 469                                'path' => TEMPLATE_FOLDER,
 470                                'template' => 'database.tpl.php',
 471                                'vars' => array(
 472                                            'product_name' => $this->mProductName,
 473                                            'message' => $this->GetPageMessage(),
 474                                            'databases' => $this->mSupportedDatabases,
 475                                            'db_type' => $this->GetParamValue($data, 'db_type', ''),
 476                                            'db_hostname' => $this->GetParamValue($data, 'db_hostname', 'localhost'),
 477                                            'db_username' => $this->GetParamValue($data, 'db_username', ''),
 478                                            'db_password' => $this->GetParamValue($data, 'db_password', ''),
 479                                            'db_name' => $this->GetParamValue($data, 'db_name', $this->mUnixName),
 480                                            'db_prefix' => $this->GetParamValue($data, 'db_prefix', 'flyspray_'),
 481                                            'db_delete' => (isset($data['db_delete'])) ? 1 : 0,
 482                                            'db_backup' => (isset($data['db_backup'])) ? 1 : 0,
 483                                            'db_setup_options' => $this->GetSetupOptions()
 484                                         ),
 485                             ),
 486              'structure' =>  array(
 487                             'path' => TEMPLATE_FOLDER,
 488                             'template' => 'structure.tpl.php',
 489                             'vars' => array(
 490                                         'title' => 'Database setup for',
 491                                         'headers' => '',
 492                                         'index' => APPLICATION_SETUP_INDEX,
 493                                         'version' => $this->mVersion,
 494                                         'copyright' => $this->mCopyright,
 495                                         ),
 496                             'block' => array('body' => 'database_body')
 497                             )
 498           );
 499  
 500        // Output the final template.
 501        $this->OutputPage($templates);
 502     }
 503  
 504     /**
 505     * Function to prepare template output
 506     *
 507     *
 508     */
 509     function DisplayPreInstall()
 510     {
 511        // Check the Database support on the server.
 512        $this->CheckDatabaseSupport();
 513  
 514        $templates =
 515        array(
 516              'index_body' => array(
 517                          'path' => TEMPLATE_FOLDER,
 518                          'template' => 'pre_install.tpl.php',
 519                          'vars' => array(
 520                                      'product_name' => $this->mProductName,
 521                                      'required_php' => $this->mPhpRequired,
 522                                      'php_output' => $this->CheckPhpCompatibility(),
 523                                      'database_output' => $this->GetDatabaseOutput(),
 524                                      'adodb_output' => $this->CheckAdodbLibrary(),
 525                                      'adodb_status' => $this->mAdodbStatus,
 526                                      'config_output' => $this->CheckConfigFile(),
 527                                      'config_status' => $this->mConfigFileStatus,
 528                                      //'cache_output' => $this->CheckCacheFolder(),
 529                                      //'cache_status' => $this->mCacheFolderStatus,
 530                                      'php_settings' => $this->GetPhpSettings(),
 531                                      'status' => $this->CheckPreStatus(),
 532                                      'message' => $this->GetPageMessage(),
 533                                   ),
 534                       ),
 535  
 536              'structure' =>  array(
 537                             'path' => TEMPLATE_FOLDER,
 538                             'template' => 'structure.tpl.php',
 539                             'vars' => array(
 540                                         'title' => 'Pre-Installation Check for',
 541                                         'headers' => '',
 542                                         'index' => APPLICATION_SETUP_INDEX,
 543                                         'version' => $this->mVersion,
 544                                         'copyright' => $this->mCopyright,
 545                                         ),
 546                             'block' => array('body' => 'index_body')
 547                             )
 548           );
 549  
 550        // Output the final template.
 551        $this->OutputPage($templates);
 552     }
 553  
 554     function DisplayLicense()
 555     {
 556        $templates =
 557        array(
 558              'license_body' => array(
 559                          'path' => TEMPLATE_FOLDER,
 560                          'template' => 'license.tpl.php',
 561                          'vars' => array(
 562                                      'product_name' => $this->mProductName,
 563                                      'message' => $this->GetPageMessage(),
 564                                   ),
 565                       ),
 566  
 567              'structure' =>  array(
 568                             'path' => TEMPLATE_FOLDER,
 569                             'template' => 'structure.tpl.php',
 570                             'vars' => array(
 571                                         'title' => 'Licence Agreement for',
 572                                         'headers' => '',
 573                                         'index' => APPLICATION_SETUP_INDEX,
 574                                         'version' => $this->mVersion,
 575                                         'copyright' => $this->mCopyright,
 576                                         ),
 577                             'block' => array('body' => 'license_body')
 578                             )
 579           );
 580  
 581        // Output the final template.
 582        $this->OutputPage($templates);
 583     }
 584  
 585  
 586     function FetchThroughCurl($url, $downloadTo)
 587     {
 588        if (function_exists('curl_init'))
 589        {
 590           // Initialize a CURL session
 591           $ch = curl_init($url);
 592  
 593           // Get the file name of the download
 594           $filename = basename($url);
 595  
 596           // Open the file for writing
 597           $fp = fopen("$downloadTo/$filename", 'w');
 598  
 599           // Set an option for a CURL transfer
 600           curl_setopt($ch, CURLOPT_FILE, $fp);
 601           // Supress the cURL response headers
 602           curl_setopt($ch, CURLOPT_HEADER, 0);
 603  
 604           // Ge the status of the execution
 605           $result = curl_exec($ch);
 606  
 607           // close cURL resource and file handle
 608           curl_close($ch);
 609           fclose($fp);
 610  
 611           return ($result) ? TRUE : FALSE;
 612        }
 613        else
 614        {
 615           return FALSE;
 616        }
 617     }
 618  
 619     /**
 620     * To add/strip slashes depending on the status of magic_quotes_gpc
 621     * @param string $filter The type of filter to execute addslashes()
 622     *                         or stripcslashes()
 623     * @param string $what The Super global type to filter. It could be
 624     *                         of type gpc, get, post or cookie
 625     * @return void
 626     *
 627     * @todo Need to incorporate ordinary array filters
 628     */
 629     function FilterGpc($filter = 'strip', $what = 'gpc')
 630     {
 631        // Setup the allowed filter types.
 632        $filter_types        = array('strip', 'add');
 633        // Check for filter types.
 634        if (!in_array($filter, $filter_types)) die("Filter '$filter' not allowed");
 635        $this->mDataFilter    = $filter;
 636  
 637        // Check magic quotes status and filter
 638        if ( ((!get_magic_quotes_gpc()) && ($this->mDataFilter == 'add')) ||
 639              ((get_magic_quotes_gpc())  && ($this->mDataFilter == 'strip'))
 640           )
 641        {
 642           switch ($what)
 643           {
 644              case 'get':
 645                 // Process the $_GET super global
 646                 $_GET        = array_map(array(& $this, 'DataSlasher'), $_GET);
 647              break;
 648  
 649              case 'post':
 650                 // Process the $_POST super global
 651                 $_POST        = array_map(array(& $this, 'DataSlasher'), $_POST);
 652              break;
 653  
 654              case 'cookie':
 655                 // Process the $_COOKIE super global
 656                 $_COOKIE    = array_map(array(& $this, 'DataSlasher'), $_COOKIE);
 657              break;
 658  
 659              default:
 660                 // Process the GPC super globals with the call-back function
 661                 $_GET        = array_map(array(& $this, 'DataSlasher'), $_GET);
 662                 $_POST        = array_map(array(& $this, 'DataSlasher'), $_POST);
 663                 $_COOKIE    = array_map(array(& $this, 'DataSlasher'), $_COOKIE);
 664              break;
 665           }
 666  
 667        }
 668     }
 669  
 670     /**
 671     * To filter the data ie. to slash/unslash
 672     *
 673     * This is a function which may be called recursively depending on the
 674     * variable type. If it is an array it recurses back to this same function.
 675     *
 676     * @param string $gpcData the string which needs to be filtered
 677     * @return string $data the string after being filtered
 678     */
 679     function DataSlasher($rawData)
 680     {
 681        // If it is an array, map it back to this same function using array_map
 682        if (is_array($rawData))
 683        {
 684           array_map(array($this,'DataSlasher'), $rawData);
 685        }
 686        else
 687        {
 688           // Filter the data depending on the filter criteria.
 689           $data    = ($this->mDataFilter == 'add')
 690                 ? addslashes($rawData)
 691                 : stripslashes($rawData);
 692  
 693           // Convert to html entities ... Do we need to ???
 694           //$data    = htmlentities($data, ENT_QUOTES);
 695        }
 696        return $data;
 697     }
 698  
 699     /**
 700     * Function to download a file from a remote server and store it to flyspray server
 701     * @param string $url The URL of the file to download
 702     * @param string $downloadTo The destination folder to where the file will be saved on the server.
 703     *                            The destination folder needs to be world writeable.
 704     * @return boolean TRUE if success else error message
 705     */
 706     function DownloadFileToServer($url, $downloadTo, $alternate_url = '')
 707     {
 708        // If the download to folder is writeable
 709        if ($this->IsWriteable($downloadTo))
 710        {
 711  
 712          // Get the file name of the download
 713          $filename = basename($url);
 714      
 715          // Set time-out for 15 minutes
 716          set_time_limit(900);
 717      
 718          // Grab the file contents
 719          $contents = file_get_contents($url);
 720      
 721          // If successful in getting file contents
 722          if ($contents)
 723          {
 724              // If was able to open a handle to write to the file stream
 725              if ($handle = fopen("$downloadTo/$filename", 'w'))
 726              {
 727                  // If the contents was not written to file
 728                  if (fwrite($handle, $contents) === FALSE)
 729                  {
 730                      $_SESSION['page_message'][] = 'Could not write data to file';
 731                      return FALSE;
 732                  }
 733                  else
 734                  {
 735                      // Closes the open file pointer and return success
 736                      fclose($handle);
 737                      return TRUE;
 738                  }
 739              }
 740              else
 741              {
 742                  $_SESSION['page_message'][] = "Cannot open file ($filename) for writing. Please make $filename writeable before continuing.";
 743                  return FALSE;
 744              }
 745          }
 746          elseif ($this->FetchThroughCurl($url, $downloadTo))
 747          {
 748              return TRUE;
 749          }
 750          else
 751          {
 752              // Taking care of broken links or PHP URL restrictions
 753              $_SESSION['page_message'][] = "The file <strong>$url</strong> could not be downloaded for installation. " .
 754              (
 755                  $alternate = (!empty($alternate_url))
 756                  ? "Please download the libraries from <a href=\"$alternate_url\" title=\"$alternate_url\">$alternate_url</a> and extract to <strong>$downloadTo</strong>"
 757                  : ''
 758              );
 759              return FALSE;
 760          }
 761        }
 762        else
 763        {
 764          $_SESSION['page_message'][] = "Please make folder <strong>$downloadTo</strong> writeable by the web-server user or world writeable.";
 765          $_SESSION['page_message'][] = "On a Unix/Linux platform, its as easy as executing <strong><i>chmod 777 $downloadTo</i></strong> to make it world writeable.";
 766          $_SESSION['page_message'][] = 'It is advised to revert these permissions once you have finished the application setup.';
 767          return FALSE;
 768        }
 769     }
 770     
 771  
 772     function GetAdminInput($field, $value, $label)
 773     {
 774        $input_field = '';
 775        // If its a fresh install show the admin input fields
 776        if ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == '')
 777        {
 778           $input_field    = "
 779           <tr>
 780              <td align=\"right\">$label</td>
 781              <td align=\"center\"><input class=\"inputbox\" type=\"text\" name=\"$field\" value=\"$value\" size=\"30\" /></td>
 782           </tr>";
 783        }
 784        return $input_field;
 785     }
 786  
 787  
 788     function GetDatabaseOutput()
 789     {
 790        //print_r($this->mAvailableDatabases);
 791  
 792        $output = '';
 793        // Loop through the supported databases array
 794        foreach ($this->mSupportedDatabases as $which => $database)
 795        {
 796        $output .= "
 797        <tr>
 798           <td> - $which support</td>
 799           <td align=\"left\"><strong>{$this->mAvailableDatabases[$which]['status_output']}</strong></td>
 800           <td align=\"center\"><strong>". $this->ReturnStatus($this->mAvailableDatabases[$which]['supported'], $type = 'support')  . "</strong></td>
 801        </tr>";
 802  
 803        }
 804        // Return the html formatted results
 805        return $output;
 806     }
 807  
 808  
 809  
 810     /**
 811     * Function to get the php ini config values
 812     * @param string $option The ini setting name to check the status for
 813     * @return string The status of the setting either "On" or "OFF"
 814     */
 815     function GetIniSetting($option)
 816     {
 817        return (ini_get($option) == '1' ? 'ON' : 'OFF');
 818     }
 819  
 820     /**
 821     * Function to get the error messages and generate an error output for the template
 822     * @string $heading The value for the Error message heading
 823     *                  The error message is stored in the $_SESSION Global array
 824     *                  $_SESSION[PASS_PHRASE]['page_message']. If there is no value in
 825     *                  this array, then there will be no error message outputed.
 826     * @return string $message The message which needs outputting
 827     */
 828     function GetPageMessage()
 829     {
 830        // If there is an error
 831        if (isset($_SESSION['page_message']) && isset($_SESSION['page_heading']))
 832        {
 833           // Get an html formated list
 834           $page_message = $this->OutputHtmlList($_SESSION['page_message'],'ul');
 835  
 836           $message =
 837           '<h1 class="error">' . $_SESSION['page_heading'] . '</h1>
 838           <div class="box">
 839           <div class="shade">'.
 840              $page_message . '
 841           </div>
 842           </div>';
 843  
 844           // Destroy the session value
 845           unset($_SESSION['page_heading']);
 846           unset($_SESSION['page_message']);
 847  
 848           return $message;
 849        }
 850        else
 851        {
 852           return '';
 853        }
 854     }
 855  
 856  
 857     /**
 858     * Utility function to return a value from a named array or a specified default
 859     * @param array &$arr The array to get the values from
 860     * @param string $name The name of the key to check the value for
 861     * @param string $default The default value if the value is not set with the array
 862     * @return string $value The value to be returned
 863     */
 864     function GetParamValue(&$arr, $name, $default=null )
 865     {
 866        $value = isset($arr[$name]) ? $arr[$name] : $default;
 867        return $value;
 868     }
 869  
 870     /**
 871     * Function to get a listing of recommended and actual settings
 872     * for php.
 873     * @param void
 874     * @return string $output HTML formatted string.
 875     */
 876     function GetPhpSettings()
 877     {
 878        // Array of the setting name, php ini name and the recommended value
 879        $test_settings =
 880        array(
 881              array ('Safe Mode','safe_mode','OFF'),
 882              array ('Display Errors','display_errors','ON'),
 883              array ('File Uploads','file_uploads','ON'),
 884              array ('Magic Quotes GPC','magic_quotes_gpc','ON'),
 885              array ('Magic Quotes Runtime','magic_quotes_runtime','OFF'),
 886              array ('Register Globals','register_globals','OFF'),
 887              array ('Output Buffering','output_buffering','OFF'),
 888              array ('Session auto start','session.auto_start','OFF'),
 889              );
 890  
 891        $output = '';
 892  
 893        foreach ($test_settings as $recommended)
 894        {
 895        $actual_setting = $this->GetIniSetting($recommended[1]);
 896  
 897        $result = ($actual_setting == $recommended[2] )
 898           ?  '<span class="green"><strong>' . $recommended[2] . '</strong></span>'
 899           :  '<span class="red"><strong>' . $actual_setting . '</strong></span>';
 900  
 901        $output .=
 902        "
 903        <tr>
 904           <td>{$recommended[0]}</td><td align=\"center\"><strong>{$recommended[2]}</strong></td><td align=\"center\">{$result}</td>
 905        </tr>
 906        ";
 907        }
 908        return $output;
 909     }
 910     
 911     
 912  	function GetReminderDaemonSelection($value)
 913      {
 914          $selection    = '';
 915          if ($this->CheckPhpCli())
 916          {
 917              if ($value == 1)
 918              {
 919                  $selection .= '<input type="radio" name="reminder_daemon" value="1" checked="checked" /> Enable';
 920                  $selection .= '<input type="radio" name="reminder_daemon" value="0" /> Disable';
 921              }
 922              else
 923              {
 924                  $selection .= '<input type="radio" name="reminder_daemon" value="1" /> Enable';
 925                  $selection .= '<input type="radio" name="reminder_daemon" value="0" checked="checked" /> Disable';
 926              }
 927              return $selection;
 928          }
 929          else
 930          {
 931              return FALSE;
 932          }
 933      }
 934  
 935  
 936     function GetSetupOptions()
 937     {
 938        //print_r($this->mDatabaseSetup);
 939        $setup_array    = array();
 940        $setup_procedure = '<select name="db_setup_options">';
 941        foreach ($this->mDatabaseSetup as $key_array => $key_data)
 942        {
 943           foreach ($key_data as $install_type => $details)
 944           {
 945              //echo $key_array."<br />";
 946              //$setup_array[]        = $install_type;
 947              $selected            = ( (isset($_POST['db_setup_options'])) && ($_POST['db_setup_options'] == $key_array) )
 948                             ? 'selected="selected"'
 949                             : '';
 950              $setup_procedure    .= "<option value=\"$key_array\" $selected>$install_type</option>";
 951  
 952              break;
 953           }
 954        }
 955        $setup_procedure .= '</select>';
 956        return $setup_procedure;
 957     }
 958  
 959     /**
 960     * Function to install ADOdb library
 961     *
 962     *
 963     */
 964     function InstallAdodb()
 965     {
 966        $_SESSION['page_heading'] = 'ADOdb Installation';
 967  
 968          // where to download the libraries
 969          $download_to = realpath('../adodb');
 970          if (file_exists($download_to) && is_dir($download_to))
 971          {
 972              // Setup the Download URL's
 973              $url ='http://dl.sourceforge.net/sourceforge/adodb/adodb465.tgz';
 974              $alternate_url = 'http://sourceforge.net/project/showfiles.php?group_id=42718';
 975              
 976              // If the libraries were downloaded successfully
 977              if ( ($adodb_message = $this->DownloadFileToServer($url, $download_to, $alternate_url)) === TRUE)
 978              {
 979                  // Specify locations to fetch file and un-compress archive to
 980                  $from_location = $download_to;
 981                  $uncompress_to = "$download_to/../";
 982              
 983                  // If able to uncompress the archive. It will un-compress to the download location
 984                  if ( ($adodb_message = $this->UncompressFile($from_location, basename($url), $uncompress_to)) === TRUE )
 985                  {
 986                      $_SESSION['page_message'][] =  "Successfully installed ADOdb library into <strong>$download_to</strong>";
 987                      return TRUE;
 988                  }
 989              }
 990          }
 991          else
 992          {
 993              $_SESSION['page_message'][] = "Please create the adodb folder in the root of your $this->mProductName installation.";
 994              $_SESSION['page_message'][] = "After creating the folder, make it writeable by the webserver user or world writeable.";
 995              $_SESSION['page_message'][] = "On a Unix/Linux platform, its as easy as executing <strong><i>chmod 777 adodb</i></strong> to make it world writeable.";
 996              $_SESSION['page_message'][] = 'It is advised to revert these permissions once you have finished the application setup.';
 997              return FALSE;
 998          }
 999     }
1000  
1001  
1002     function InstallPointNineEight($data)
1003     {
1004        return TRUE;
1005     }
1006  
1007     function InstallPointNineSeven($data)
1008     {
1009        return TRUE;
1010     }
1011  
1012  
1013  
1014  
1015     /**
1016     * Function to check if a particular folder/file is writeable.
1017     * @param string $fileSystem Path to check
1018     * $return boolean TRUE/FALSE
1019     */
1020     function IsWriteable($fileSystem)
1021     {
1022        // Clear the cache
1023        clearstatcache();
1024  
1025        // Return the status of the permission
1026        return (file_exists($fileSystem) && is_writable($fileSystem))
1027        ? TRUE
1028        : FALSE;
1029     }
1030  
1031     function MakePassword($passwordLength)
1032     {
1033        $salt = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
1034        $length = strlen($salt);
1035        $password = '';
1036        mt_srand(10000000*(double)microtime());
1037  
1038        for ($i = 0; $i < $passwordLength; $i++)
1039        {
1040           $password .= $salt[mt_rand(0, $length - 1)];
1041        }
1042  
1043        return $password;
1044     }
1045  
1046  
1047     /**
1048     * Function to Output an Ordered/Un-ordered list from an array. Default list type is un-ordered.
1049     * @param array() $list_array An array list of data to be made into a list.
1050     * @return string $list An HTML list
1051     */
1052     function OutputHtmlList($list_array = array(), $list_type = 'ul')
1053     {
1054        $list = "<$list_type>";
1055        foreach ($list_array as $list_item)
1056        {
1057           $list .= "<li>$list_item</li>";
1058        }
1059        $list .= "</$list_type>";
1060  
1061        return $list;
1062     }
1063  
1064  
1065     /**
1066     * Function to act on all the actions during Flyspray Setup
1067     * The Post variables are extracted for deciding which function to call.
1068     */
1069     function ProcessActions()
1070     {
1071        $action = 'index';
1072        $what = '';
1073  
1074        extract($_POST);
1075  
1076        switch($action)
1077        {
1078           case 'index':
1079              if ($what == 'adodb')
1080              {
1081                 // Install the ADOdb library
1082                 $this->InstallAdodb();
1083                 // To prevent the user from getting a "Resend post request" warning if they refresh the page
1084                 header('Location: ' . APPLICATION_SETUP_INDEX);
1085                 exit;
1086              }
1087              $this->DisplayPreInstall();
1088           break;
1089  
1090           case 'licence':
1091              $this->DisplayLicense();
1092           break;
1093  
1094           case 'database':
1095              // Prepare the required data
1096              $required_data =
1097              array(
1098                    'agreecheck' => array(
1099                                   'Licence Agreement', 'string', TRUE
1100                                   )
1101                 );
1102  
1103              if ($this->CheckPostedData($required_data, $message = 'Accept Licence'))
1104              {
1105                 $this->DisplayDatabaseSetup();
1106              }
1107              else
1108              {
1109                 $_POST['action'] = 'licence';
1110                 $this->DisplayLicense();
1111              }
1112           break;
1113  
1114           case 'administration':
1115              // Prepare the required data
1116              $required_data =
1117              array(
1118                    'db_hostname' => array('Database hostname', 'string', TRUE),
1119                    'db_type' =>  array('Database type', 'string', TRUE),
1120                    'db_username' => array('Database username', 'string', TRUE),
1121                    'db_password' => array('Database password', 'string', TRUE),
1122                    'db_name' => array('Database name', 'string', TRUE),
1123                    'db_prefix' => array('Table prefix', 'string', TRUE),
1124                    'db_delete' => array('Delete tables checkbox', 'string', FALSE),
1125                    'db_backup' => array('Database backup checkbox', 'string', FALSE),
1126                    'db_setup_options' => array('Database Setup Options', 'number', TRUE)
1127                 );
1128              if ($data = $this->CheckPostedData($required_data, $message = 'Configuration Error'))
1129              {
1130                 // Set a page heading in case of errors.
1131                 $_SESSION['page_heading'] = 'Database Processing';
1132                 // Process the database checks and install tables
1133                 if ($this->ProcessDatabaseSetup($data))
1134                 {
1135                    // Proceed to Administration part
1136                    $this->DisplayAdministration();
1137                 }
1138                 else
1139                 {
1140                    $_POST['action'] = 'database';
1141                    $this->DisplayDatabaseSetup();
1142                 }
1143              }
1144              else
1145              {
1146                 $_POST['action'] = 'database';
1147                 $this->DisplayDatabaseSetup();
1148              }
1149           break;
1150  
1151           case 'complete':
1152              // Prepare the required data
1153              $required_data =
1154              array(
1155                 'db_hostname' => array('Database hostname', 'string', TRUE),
1156                 'db_type' =>  array('Database type', 'string', TRUE),
1157                 'db_username' => array('Database username', 'string', TRUE),
1158                 'db_password' => array('Database password', 'string', TRUE),
1159                 'db_name' => array('Database name', 'string', TRUE),
1160                 'db_prefix' => array('Table prefix', 'string', TRUE),
1161                 'db_setup_options' =>  array('Database type', 'number', TRUE),
1162                 'site_url' => array($this->mProductName . ' URL location', 'string', TRUE),
1163                 'absolute_path' => array($this->mProductName . ' Absolute path must exist and', 'folder', TRUE),
1164                 'admin_username' => array('Administrator\'s username', 'string', ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == '')),
1165                 'admin_password' => array("Administrator's Password must be minimum {$this->mMinPasswordLength} characters long and", 'password', ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == '')),
1166                 'admin_email' => array('Administrator\'s email address', 'email address', ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == '')),
1167                 'reminder_daemon' => array('Reminder Daemon', 'option', FALSE),
1168                 );
1169              if ($data = $this->CheckPostedData($required_data, $message = 'Missing config values'))
1170              {
1171                 // Set a page heading in case of errors.
1172                 $_SESSION['page_heading'] = 'Administration Processing';
1173  
1174                 if ($this->ProcessAdminConfig($data))
1175                 {
1176                    $this->DisplayCompletion($data);
1177                 }
1178                 else
1179                 {
1180                    $_POST['action'] = 'administration';
1181                    $this->DisplayAdministration();
1182                 }
1183              }
1184              else
1185              {
1186                 $_POST['action'] = 'administration';
1187                 $this->DisplayAdministration();
1188              }
1189           break;
1190  
1191           default:
1192              $this->DisplayPreInstall();
1193           break;
1194        }
1195     }
1196  
1197  
1198  
1199     function ProcessAdminConfig($data)
1200     {
1201        // Extract the varibales to local namespace
1202        extract($data);
1203  
1204        $this->CheckAdodbLibrary();
1205        if (!$this->mAdodbPath)
1206        {
1207           $_SESSION['page_heading'][]    = 'ADOdb Libraries not found';
1208           return FALSE;
1209        }
1210  
1211  
1212        $config_intro    =
1213        "; <?php die( 'Do not access this page directly.' ); ?>
1214  
1215        ; This is the Flysplay configuration file. It contains the basic settings
1216        ; needed for Flyspray to operate. All other preferences are stored in the
1217        ; database itself and are managed directly within the Flyspray admin interface.
1218        ; You should consider putting this file somewhere that isn't accessible using
1219        ; a web browser, and editing header.php to point to wherever you put this file.\n";
1220        $config_intro    = str_replace("\t", "", $config_intro);
1221  
1222        // Create a random cookie salt
1223        $cookiesalt = substr(md5(microtime()), 0, 2);
1224  
1225        // Check to see if running apache software and mod_rewrite is enabled (Can only check in PHP 4.3.2 and above)
1226        $re_writing    = 0;
1227        if ($this->mServerSoftware == 'apache' && function_exists('apache_get_modules'))
1228        {
1229              $apache_modules    = apache_get_modules();
1230              if ( ($apache_modules) && (in_array('mod_rewrite', $apache_modules)) )
1231              {
1232                  $re_writing = 1;
1233              }
1234        }
1235  
1236        // check to see if to enable the Reminder Daemon.
1237        $daemonise    = ( (isset($data['reminder_daemon'])) && ($data['reminder_daemon'] == 1) )
1238                      ? 1
1239                      : 0;
1240                      
1241        // Double check the urls and paths slashes.
1242        $site_url            .= (substr($site_url, -1, 1) != '/') ? '/' : '';
1243        $absolute_path    = (substr($absolute_path, -1, 1) == DIRECTORY_SEPARATOR) 
1244                            ? substr($absolute_path, 0, (strlen($absolute_path)-1) ) : $absolute_path;
1245  
1246        $config    = array();
1247        $config[] = "[database]";
1248        $config[] = "dbtype = \"$db_type\"                    ; Type of database (\"mysql\" or \"pgsql\" are currently supported)";
1249        $config[] = "dbhost = \"$db_hostname\"                ; Name or IP of your database server";
1250        $config[] = "dbname = \"$db_name\"                    ; The name of the database";
1251        $config[] = "dbuser = \"$db_username\"                ; The user to access the database";
1252        $config[] = "dbpass = \"$db_password\"                ; The password to go with that username above";
1253        $config[] = "dbprefix = \"$db_prefix\"                ; The prefix to the {$this->mProductName} tables";
1254        $config[] = "\n";
1255        $config[] = '[general]';
1256        $config[] = "basedir = \"$absolute_path\"        ; Location of your {$this->mProductName} installation";
1257        $config[] = "cookiesalt = \"$cookiesalt\"            ; Randomisation value for cookie encoding";
1258        $config[] = "adodbpath = \"{$this->mAdodbPath}\"    ; Path to the main ADODB include file";
1259        $config[] = 'output_buffering = "on"                ; Available options: "on" or "gzip"';
1260        $config[] = "passwdcrypt = \"md5\"                    ; Available options: \"crypt\", \"md5\", \"sha1\"";
1261        $config[] = "baseurl = \"{$site_url}\"                ; URL that points to {$this->mProductName}'s root";
1262        $config[] = "address_rewriting = \"$re_writing\"    ; Boolean. 0 = off, 1 = on.";
1263        $config[] = "reminder_daemon = \"$daemonise\"        ; Boolean. 0 = off, 1 = on.";
1264        $config[] = "\n";
1265  
1266        $config_text = $config_intro . implode( "\n", $config );
1267  
1268        if (is_writable('../flyspray.conf.php') && ($fp = fopen('../flyspray.conf.php', "w")))
1269        {
1270           fputs($fp, $config_text, strlen($config_text));
1271           fclose($fp);
1272           $this->mConfigFileStatus = TRUE;
1273        }
1274        else
1275        {
1276           $this->mConfigText = $config_text;
1277           $this->mConfigFileStatus = FALSE;
1278        }
1279  
1280  
1281        // Setting the database for the ADODB connection
1282        require_once($this->mAdodbPath);
1283        $this->mDbConnection =& NewADOConnection(strtolower($db_type));
1284        $this->mDbConnection->Connect($db_hostname, $db_username, $db_password, $db_name);
1285  
1286        // Get the users table name.
1287        $users_table    = ($db_prefix != '')
1288                    ? str_replace("{$this->mUnixName}_", $db_prefix, $this->mUsersTable )
1289                    : $this->mUsersTable;
1290        $sql    = "SELECT * FROM $users_table WHERE user_id = '1'";
1291  
1292        // Check if we already have an Admin user.
1293        $result = $this->mDbConnection->Execute($sql);
1294        if ($result)
1295        {
1296           // If the record exists, we update it.
1297           $row = $result->FetchRow();
1298           $this->mAdminUsername = $row['user_name'];
1299           $this->mAdminPassword = $row['user_pass'];
1300        }
1301  
1302  
1303        // If the admin inputs have been posted.. Only for fresh install
1304        if (isset($admin_username) && isset($admin_password) && isset($admin_email))
1305        {
1306           $md5_password    = md5($admin_password);
1307           $update_user    = "
1308           UPDATE
1309              $users_table
1310           SET
1311              user_name = '$admin_username',
1312              user_pass = '$md5_password',
1313              email_address = '$admin_email'
1314           WHERE
1315              user_id = '1'";
1316           $result = $this->mDbConnection->Execute($update_user);
1317           if (!$result)
1318           {
1319              $_SESSION['page_heading'][]    = 'Failed to update Admin users details.';
1320              return FALSE;
1321           }
1322           else
1323           {
1324              $this->mAdminUsername = $admin_username;
1325              $this->mAdminPassword = $admin_password;
1326           }
1327           $this->mCompleteAction    = 'do=authenticate';
1328        }
1329        else
1330        {
1331           $this->mAdminUsername = '';
1332           $this->mAdminPassword = '';
1333           $this->mCompleteAction    = 'do=myprofile';
1334           $this->SetUpgradeLogin($data, $cookiesalt);
1335        }
1336        return TRUE;
1337     }
1338  
1339  
1340     function ProcessDatabaseSetup($data)
1341     {
1342        // Look for ADOdb
1343        $this->mAdodbPath = $this->ScanIncludePath('adodb.inc.php', realpath('../adodb'));
1344        require_once($this->mAdodbPath);
1345  
1346        // Perform a number of fatality checks, then die gracefully
1347        if (!defined('_ADODB_LAYER'))
1348        {
1349           trigger_error('ADODB Libraries missing or not correct version');
1350        }
1351  
1352        // Setting the database type for the ADODB connection
1353        $this->mDbConnection =& NewADOConnection(strtolower($data['db_type']));
1354  
1355        // Setting debugging for ADODB
1356        $this->mDbConnection->debug = FALSE;
1357  
1358        /* check hostname/username/password */
1359        if (!$this->mDbConnection->Connect($data['db_hostname'], $data['db_username'], $data['db_password'], $data['db_name']))
1360        {
1361           switch($error_number = $this->mDbConnection->MetaError())
1362           {
1363              case '-1':
1364              // We are using the unknown error code(-1) because ADOdb library may not have the error defined.
1365              // It could be totally some weird error.
1366              $_SESSION['page_message'][] = $this->mDbConnection->ErrorMsg();
1367              return FALSE;
1368              break;
1369  
1370              case '-24':
1371              // Could not connect to database with the hostname provided
1372              $_SESSION['page_message'][] = 'Database ' . ucfirst($this->mDbConnection->MetaErrorMsg($error_number));
1373              $_SESSION['page_message'][] = 'Usually the database host name is "localhost". In some occassions, it maybe an internal ip-address or another host name to your webserver.';
1374              $_SESSION['page_message'][] = 'Double check with your hosting provider or System Administrator.';
1375              return FALSE;
1376              break;
1377  
1378              case '-26':
1379              // Username passwords don't match for the hostname provided
1380              $_SESSION['page_message'][] = ucfirst($this->mDbConnection->MetaErrorMsg($error_number));
1381              $_SESSION['page_message'][] = "Obviously you haven't set up the right permissions for the database hostname provided.";
1382              $_SESSION['page_message'][] = 'Double check the provided credentials or contact your System Administrator for further assistance.';
1383              return FALSE;
1384              break;
1385  
1386              default:
1387              $_SESSION['page_message'][] = 'Please verify your username/password/database details.';
1388              return FALSE;
1389              break;
1390           }
1391        }
1392        else
1393        {
1394           // Test to see if the database exists
1395           //$this->mDbConnection->Execute("SHOW TABLES FROM DATABASE {$data['db_name']}");
1396  
1397           //select * from pg_database where datname = 'jeffery_flyspray'
1398  
1399           //switch ($error_number = $this->mDbConnection->MetaError())
1400           //{
1401              //case '-5':
1402              // Can't create database. It already exists. Means now we have to do a check if we want to backup/drop database
1403              // Now we connect to the database and do the processing since we know it exists.
1404              //if ($this->mDbConnection->PConnect($data['db_hostname'], $data['db_username'], $data['db_password'], $data['db_name']))
1405              //{
1406                 // Setting the Fetch mode of the database connection.
1407                 $this->mDbConnection->SetFetchMode(ADODB_FETCH_BOTH);
1408  
1409                 // Backup and delete tables if requested
1410                 if ($this->BackupDeleteTables($data))
1411                 {
1412                    if ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == '')
1413                    {
1414                       // Populate the database with the new tables and return the result (boolean)
1415                       if (!$this->PopulateDb($data))
1416                       {
1417                          return FALSE;
1418                       }
1419                    }
1420                    else
1421                    {
1422                       // Call the dependency function
1423                       if (method_exists($this, $this->mDatabaseSetup[$_POST['db_setup_options']]['function']))
1424                       {
1425                          // Call the Upgrade function.
1426                          if (!$this->{$this->mDatabaseSetup[$_POST['db_setup_options']]['function']}($data))
1427                          {
1428                             return FALSE;
1429                          }
1430                       }
1431                       else
1432                       {
1433                          $_SESSION['page_message'][]    = "Function {$this->mDatabaseSetup[$_POST['db_setup_options']]['function']}() not defined!";
1434                          return FALSE;
1435                       }
1436                    }
1437                 }
1438                 else
1439                 {
1440                    return FALSE;
1441                 }
1442              //}
1443              //else
1444              //{
1445                 // Don't know why it woudn't work... just in case
1446              //    $_SESSION['page_message'][] = $this->mDbConnection->ErrorMsg();
1447              //    return FALSE;
1448              //}
1449              //break;
1450        /*
1451              case '-1':
1452              // We are using the unknown error code(-1) because ADOdb library may not have the error defined.
1453              $_SESSION['page_message'][] = $this->mDbConnection->ErrorMsg();
1454              return FALSE;
1455              break;
1456  
1457              default:
1458              $_SESSION['page_message'][] = $this->mDbConnection->ErrorMsg() . ': ' . $this->mDbConnection->ErrorNo();
1459              $_SESSION['page_message'][] = 'Unknown error, please notify Developer quoting the error number';
1460              return FALSE;
1461              break;*/
1462           //}
1463        }
1464        return TRUE;
1465     }
1466  
1467  
1468     function BackupTables($data, $table_list)
1469     {
1470        // Extract the data to local namespace
1471        extract($data);
1472  
1473        //Get the date value to rename tables with the date+time prefix if the backup option was ticked
1474        $date_time = date("YmdHis");
1475        $db_bu_prefix  = $date_time . '_' . $db_prefix;
1476  
1477        // Loop through the tables array
1478        foreach ($table_list as $table)
1479        {
1480           // Giving the backup table a new prefix based on the date & time of action
1481           $bu_table = str_replace($db_prefix, $db_bu_prefix, $table);
1482  
1483           // Query to copy the existing table into a table with the new prefix
1484           switch (strtolower($db_type))
1485           {
1486              case 'mysql':
1487                 $sql    = "CREATE TABLE $bu_table AS SELECT * FROM $table";
1488              break;
1489  
1490              case 'postgres':
1491                 $sql    = "CREATE TABLE \"$bu_table\" AS SELECT * FROM $table";
1492              break;
1493           }
1494  
1495           $this->mDbConnection->Execute($sql);
1496  
1497           // If any errors, record the error message in the array
1498           if ($error_number = $this->mDbConnection->MetaError())
1499           {
1500              $_SESSION['page_message'][] =  ucfirst($this->mDbConnection->MetaErrorMsg($error_number)) . ' Table backup error: ' . $sql;
1501           }
1502        }
1503        // Check for any error messages.
1504        if (isset($_SESSION['page_message']) && count($_SESSION['page_message']) > 0)
1505        {
1506           return FALSE;
1507        }
1508        else
1509        {
1510           return TRUE;
1511        }
1512     }
1513  
1514     function DeleteTables($data, $table_list)
1515     {
1516        extract($data);
1517        
1518        // Loop through the tables array
1519        foreach ($table_list as $table)
1520        {
1521           $db_type    = strtolower($db_type);
1522           // Prepare the query to drop the existing tables
1523       switch ($db_type)
1524       {
1525         case 'mysql':
1526           $sql = "DROP TABLE $table";
1527           break;
1528         case 'postgres':
1529           $sql = "DROP TABLE $table cascade";
1530           break;
1531       }
1532           $this->mDbConnection->Execute($sql);
1533           // If any errors, record the error message in the array
1534           if ($error_number = $this->mDbConnection->MetaError())
1535           {
1536              $_SESSION['page_message'][] =  ucfirst($this->mDbConnection->MetaErrorMsg($error_number)) . " Error deleting: $sql";
1537              return FALSE;
1538           }
1539        }
1540        return TRUE;
1541     }
1542  
1543     
1544     function DeleteSequences($data)
1545     {
1546        extract($data);
1547        $db_type    = strtolower($db_type);
1548        
1549        if ($db_type != 'postgres') {
1550      return TRUE;
1551        }
1552        $sql = "SELECT c.relname
1553      FROM pg_catalog.pg_class c
1554      LEFT JOIN pg_catalog.pg_user u ON u.usesysid = c.relowner
1555      LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
1556      WHERE c.relkind = 'S'
1557      AND n.nspname NOT IN ('pg_catalog', 'pg_toast')
1558      AND pg_catalog.pg_table_is_visible(c.oid)";
1559  
1560        $result = $this->mDbConnection->Execute($sql);
1561        $sequence_list = array();
1562        if ($result)
1563        {
1564      while ($row = $result->FetchRow())
1565      {
1566        $sequence_list[] = $row[0];
1567      }
1568        }
1569  
1570        foreach ($sequence_list as $sequence) {
1571      $sql = "DROP SEQUENCE $sequence";
1572      $this->mDbConnection->Execute($sql);
1573      // If any errors, record the error message in the array
1574      if ($error_number = $this->mDbConnection->MetaError())
1575      {
1576        $_SESSION['page_message'][] =  ucfirst($this->mDbConnection->MetaErrorMsg($error_number));
1577        return FALSE;
1578      }
1579        }
1580  
1581        return TRUE;
1582     }
1583  
1584  
1585     function BackupDeleteTables($data)
1586     {
1587        // Extract the data to local namespace
1588        extract($data);
1589  
1590        if ((isset($db_delete)) || (isset($db_backup)))
1591        {
1592           $db_type    = strtolower($db_type);
1593           // Query to get a list of tables in the database
1594           switch ($db_type)
1595           {
1596              case 'mysql':
1597                 $sql    = "SHOW TABLES FROM $db_name";
1598              break;
1599  
1600              case 'postgres':
1601                 $sql    = "SELECT tablename from pg_tables where tableowner = '$db_username'";
1602              break;
1603           }
1604  
1605           $result = $this->mDbConnection->Execute($sql);
1606           $table_list = array();
1607           if ($result)
1608           {
1609              while ($row = $result->FetchRow())
1610              {
1611                 $table_list[] = $row[0];
1612              }
1613           }
1614  
1615           // Filter the tables we want to work with ..... relating it to the table prefix.
1616           // If the prefix given is the same as the prefix we have in the database
1617           // If the prefix does not match.. we can't delete or backup the intended tables
1618           $filtered_tables    = array();
1619           foreach ($table_list as $table)
1620           {
1621              if (strpos($table, $db_prefix) == 0)
1622              {
1623                 $filtered_tables[]    = $table;
1624              }
1625           }
1626  
1627           // If it was requested to delete existing tables.
1628           if (isset($db_delete))
1629           {
1630              // If we are deleting, backup NEEDS to be done.
1631              if ((isset($db_delete)) && (isset($db_backup)))
1632              {
1633                 if (!count($filtered_tables) > 0)
1634                 {
1635                    // If there were no tables at all in the database.
1636                    $_SESSION['page_message'][] =  'Tables with provided prefix not found in database.';
1637                    $_SESSION['page_message'][] =  'Make sure you have the right table prefix for the database tables you intend to backup/delete';
1638                    $_SESSION['page_message'][] =  'You are safe to proceed into the setup without dropping tables as tables with the provided prefix don\'t exist!';
1639                    return FALSE;
1640                 }
1641  
1642                 // Drop/backup tables only if there are no dependancies. eg. Fresh Install
1643                 if ( ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == ''))
1644                 {
1645                    // Return error if Backup was not successful.
1646                    if (!$this->BackupTables($data, $filtered_tables))
1647                    {
1648                       return FALSE;
1649                    }
1650                 }
1651                 else
1652                 {
1653                    $_SESSION['page_message'][] =  'Tables where not dropped because you are performing an UPGRADE.';
1654                    $_SESSION['page_message'][] =  'Unckeck the "delete" checkbox to proceed into the setup.';
1655                    return FALSE;
1656                 }
1657  
1658  
1659                 // Drop tables only if there are no dependancies. eg. Fresh Install
1660              if ( ($this->mDatabaseSetup[$_POST['db_setup_options']]['dependency'] == ''))
1661                 {
1662                    // Return the status of deleting the tables if it was not successful.
1663           if (!$this->DeleteTables($data, $filtered_tables))
1664           {
1665             return FALSE;
1666           }
1667           if (!$this->DeleteSequences($data)) {
1668             return FALSE;
1669           }
1670                 }
1671                 else
1672                 {
1673                    $_SESSION['page_message'][] =  'Tables where not dropped because you are performing an UPGRADE.';
1674                    $_SESSION['page_message'][] =  'Unckeck the "delete backup" checkbox to proceed into the setup.';
1675                    return FALSE;
1676                 }
1677              }
1678              else
1679              {
1680                 // Not dropping the tables unless the backup option is checked.
1681                 $_SESSION['page_message'][] =  'Please select the "backup tables" checkbox in order to drop existing tables.';
1682                 return FALSE;
1683              }
1684              return TRUE;
1685           }
1686  
1687  
1688           // Perform actions if only the backup was selected.
1689           if (isset($db_backup))
1690           {
1691              if (!count($filtered_tables) > 0)
1692              {
1693                 // If there were no tables at all in the database.
1694                 $_SESSION['page_message'][] =  'Tables with provided prefix not found in database.';
1695                 $_SESSION['page_message'][] =  'Make sure you have the right table prefix for the database tables you intend to backup';
1696                 $_SESSION['page_message'][] =  'It is safe to uncheck the "backup tables"';
1697                 return FALSE;
1698              }
1699  
1700              // Return error if Backup was not successful.
1701              if (!$this->BackupTables($data, $filtered_tables))
1702              {
1703                 return FALSE;
1704              }
1705           }
1706        }
1707        return TRUE;
1708     }
1709  
1710     /**
1711     * Function to populate the database with the sql constructs which is in an sql file
1712     * @param array $data The actual database configuration values
1713     * @return boolean
1714     */
1715     function PopulateDb($data)
1716     {
1717        // Get the sql file name and set the path
1718        list($file) = array_values($this->mDatabaseSetup[$_POST['db_setup_options']]);
1719  
1720        $sql_file    = APPLICATION_PATH . "$file." . $this->mSupportedDatabases[$_POST['db_type']][2];
1721  
1722        // Check if the install/upgrade file exists
1723        if (file_exists($sql_file) && is_file($sql_file))
1724        {
1725           // Extract the variables to local namespace
1726           extract($data);
1727  
1728           // Get the current magic quotes runtime settings
1729           $mqr = @get_magic_quotes_runtime();
1730  
1731           // Disable magic quotes runtime. Some bytes in binary files may be interpreted as
1732           // \ (backslash), " (double quotes), ' (simple quote) or any "special" character
1733           // that has a meaning for string processing.
1734           @set_magic_quotes_runtime(0);
1735           $query = fread(fopen($sql_file, "r"), filesize($sql_file));
1736  
1737           // Re-set the magic quotes runtime settings
1738           @set_magic_quotes_runtime($mqr);
1739  
1740           // Get the sql queries
1741           $sql_blocks  = $this->SplitSql($query, $db_type);
1742  
1743           $sql_count = count($sql_blocks);
1744           for ($i=0; $i < $sql_count; $i++)
1745           {
1746              $sql_blocks[$i] = trim($sql_blocks[$i]);
1747              if(!empty($sql_blocks[$i]) && $sql_blocks[$i] != "#")
1748              {
1749                 $sql_blocks[$i] = str_replace($this->mUnixName . "_", $db_prefix, $sql_blocks[$i]);
1750  
1751                 $this->mDbConnection->Execute($sql_blocks[$i]);
1752                 if (($error_no = $this->mDbConnection->MetaError()))
1753                 {
1754                    switch ($error_no)
1755                    {
1756                       case '-5':
1757                       // If there are tables with the same name
1758                       $_SESSION['page_message'][] = 'Table ' .$this->mDbConnection->MetaErrorMsg($this->mDbConnection->MetaError());
1759                       $_SESSION['page_message'][] = 'There probably are tables in the database which have the same prefix you provided.';
1760                       $_SESSION['page_message'][] = 'It is advised to change the prefix provided or you can drop the existing tables if you don\'t need them. Make a backup if you are not certain.';
1761                       return FALSE;
1762                       break;
1763  
1764                       case '-1':
1765                       // We are using the unknown error code(-1) because ADOdb library may not have the error defined.
1766                       $_SESSION['page_message'][] = $this->mDbConnection->ErrorMsg();
1767                       return FALSE;
1768                       break;
1769  
1770                       default:
1771                       $_SESSION['page_message'][] = $this->mDbConnection->ErrorMsg() . ': ' . $this->mDbConnection->ErrorNo();
1772                       $_SESSION['page_message'][] = 'Unknown error, please notify Developer quoting the error number';
1773                       return FALSE;
1774                       break;
1775                    }
1776                 }
1777              }
1778           }
1779           //$_SESSION['page_message'][] = 'Successfully populated database with structure and data.';
1780           return TRUE;
1781        }
1782        else
1783        {
1784           $_SESSION['page_message'][] = 'SQL file required for importing structure and data is missing.';
1785           return FALSE;
1786        }
1787     }
1788  
1789  
1790  
1791     /**
1792     * Function to return status of boolean results in html format
1793     * @param boolean $boolean The status of the result in True/False form
1794     * @param string $type The type of html format to return
1795     * @return string Depending on the type of format to return
1796     */
1797     function ReturnStatus($boolean, $type = 'yes')
1798     {
1799        // Do a switch on the type of status
1800        switch($type)
1801        {
1802        case 'yes':
1803           return ($boolean)
1804           ?  '<span class="green">Yes</span>'
1805           :  '<span class="red">No</span>';
1806           break;
1807  
1808        case 'available':
1809           return ($boolean)
1810           ?  '<span class="green">Available</span>'
1811           :  '<span class="red">Missing</span>';
1812           break;
1813  
1814        case 'writeable':
1815           return ($boolean)
1816           ?  '<span class="green">Writeable</span>'
1817           :  '<span class="red">Un-writeable</span>';
1818           break;
1819  
1820        case 'on':
1821           return ($boolean)
1822           ?  '<span class="green">ON</span>'
1823           :  '<span class="red">OFF</span>';
1824           break;
1825        case 'support':
1826           return ($boolean)
1827           ?  '<span class="green">Supported</span>'
1828           :  '<span class="red">X</span>';
1829           break;
1830        default:
1831           return ($boolean)
1832           ?  '<span class="green">True</span>'
1833           :  '<span class="red">False</span>';
1834           break;
1835        }
1836     }
1837  
1838     function SetUpgradeLogin($data, $cookiesalt)
1839     {
1840        // Extract the varibales to local namespace
1841        extract($data);
1842  
1843        // The user should be remembered on this machine
1844        $cookie_time = time() + (60 * 60 * 24 * 30); // Set cookies for 30 days
1845  
1846        // Get current user details. Assuming its always user_id 1
1847        $result        = $this->mDbConnection->Query("SELECT * FROM {$db_prefix}users WHERE user_id = ?", array(1));
1848        $user        = $this->mDbConnection->Execute($result);
1849  
1850        // Get current user details.  We need this to see if their account is enabled or disabled
1851        $result = $this->mDbConnection->Execute("SELECT * FROM {$db_prefix}users WHERE user_id = ?", array(1));
1852        $user    = $result->FetchRow();
1853  
1854        // Set a couple of cookies
1855        setcookie('flyspray_userid', $user['user_id'], $cookie_time, "/");
1856        setcookie('flyspray_passhash', crypt($user['user_pass'], $cookiesalt), $cookie_time, "/");
1857  
1858        // If the user had previously requested a password change, remove the magic url
1859        $remove_magic = $this->mDbConnection->Query("UPDATE {$db_prefix}users SET
1860                             magic_url = ''
1861                             WHERE user_id = ?",
1862                             array($user['user_id'])
1863                          );
1864  
1865        $_SESSION['SUCCESS'] = 'Login successful.';
1866     }
1867  
1868  
1869     /**
1870     * Function to split the SQL queries from a SQL file into individual queries
1871     * Thanks to Ben Balbo http://www.benbalbo.com for the code comments
1872     * @param string $sql The sql queries which was grabbed from a SQL file
1873     */
1874     function SplitSql($sql, $db_type)
1875     {
1876        // Trim the SQL
1877        $sql = trim($sql);
1878        switch (strtolower($db_type))
1879        {
1880            
1881            // Removes any lines that start with a # and --
1882            //$sql = ereg_replace("\n#[^\n]*\n", "\n", $sql); // Doesn't work as expected
1883          case 'mysql':
1884              $sql = ereg_replace("#[^\n]*\n", "\n", $sql);
1885          break;
1886          
1887          case 'postgres':
1888              $sql = ereg_replace("--[^\n]*\n", "\n", $sql);
1889          break;
1890        }
1891        // This array only ever has 2 items [0] is previous character seen - [1] is current character
1892        $buffer = array();
1893  
1894        // Array for returning the SQL arrays
1895        $sql_lists = array();
1896  
1897        // Flag for defining whether we're parsing the innards of a string (i.e. we passed a " or ' recently
1898        $in_string = FALSE;
1899  
1900        // Loop through each character in the sql string
1901        for($i = 0; $i < strlen($sql)-1; $i++)
1902        {
1903  
1904           // If the character is equal to a semi colon and the flag is false
1905           // this is tru if the current char is a semicolon and it's not the first char in the string (i.e. $in_string contains something)
1906           if($sql[$i] == ";" && !$in_string)
1907           {
1908              // Get the characters from the beginning of the sql string up until the semi-colon
1909              $sql_lists[] = substr($sql, 0, $i);
1910  
1911              // Re-set the sql string to start from the current character and the rest of the string
1912              $sql = substr($sql, $i + 1);
1913              // Re-set the counter
1914              $i = 0;
1915           }
1916  
1917           // If we're flagged as being in a string (between '' or "") and we've just found what looks like a string terminator
1918           // check to see if previous char was not a backslash, and if so, we're not in a string anymore.
1919           // In other words, if we recently found a " and we've just found another ", we can consider ourselves not
1920           // in the string anymore, unless the previous char was a backslash which would escape the " we just found.
1921           if($in_string && ($sql[$i] == $in_string) && $buffer[1] != "\\")
1922           {
1923              $in_string = false;
1924           }
1925           elseif(!$in_string && ($sql[$i] == '"' || $sql[$i] == "'") && (!isset($buffer[0]) || $buffer[0] != "\\"))
1926           // Catches the start of the string - if we've found a ' or " and the previous char
1927           // wasn't a \ and we're not in a string, then we are now!
1928           {
1929              $in_string = $sql[$i];
1930           }
1931  
1932           // Scroll buffer. [0] is now equal to [1] if it had a value. current char is now in [1]
1933           if(isset($buffer[1]))
1934           {
1935              $buffer[0] = $buffer[1];
1936           }
1937           $buffer[1] = $sql[$i];
1938        }
1939  
1940        if(!empty($sql))
1941        {
1942           $sql_lists[] = $sql;
1943        }
1944        return $sql_lists;
1945     }
1946  
1947     /**
1948        * To verify if a string was empty or not.
1949        *
1950        * Usually used to validate user input. If the user has inputted empty data
1951        * or just blank spaces, we need to trim of such empty data and see if
1952        * anything else is left after trimming. If there is data remaining, then
1953        * the return value will be greater than 0 else it will be 0 (zero) which
1954        * equates to a TRUE/FALSE scenario
1955        *
1956        * @param string $arg The data to be checked
1957        *
1958        * @return The result of the check.
1959        */
1960     function TrimArgs($arg)
1961     {
1962        return strlen(trim($arg));
1963     }
1964  
1965     /**
1966     * Function to un-compress file archives
1967     * @param $from_location Location where archive resides
1968     * @param $filename The name of the file to un-compress
1969     * @param $to_location The location where to un-compress the archive
1970     * @return boolean TRUE else error message
1971     */
1972     function UncompressFile($from_location, $filename, $to_location)
1973     {
1974        // Require the Pear Archive_Tar Class
1975        require_once (OBJECTS_PATH . "/archive_tar.php");
1976  
1977        // use tar file
1978        $tar = new Archive_Tar("$from_location/$filename");
1979  
1980        // Extract the archive and return result
1981        if ($tar->extract($to_location) || !$tar->_error_message)
1982        {
1983           return TRUE;
1984        }
1985        else
1986        {
1987           $_SESSION['page_message'][] = $tar->_error_message;
1988        return FALSE;
1989        }
1990     }
1991  
1992  
1993     function UpgradePointNineSeven($data)
1994     {
1995        // Extract the data to local namespace
1996        extract($data);
1997  
1998        // Get the preferences table name.
1999        $preferences_table    = ($db_prefix != '')
2000                       ? str_replace("{$this->mUnixName}_", $db_prefix, $this->mPreferencesTable)
2001                       : $this->mPreferencesTable;
2002  
2003        $attachments_table    = ($db_prefix != '')
2004                       ? str_replace("{$this->mUnixName}_", $db_prefix, $this->mAttachmentsTable)
2005                       : $this->mAttachmentsTable;
2006  
2007        $comments_table    = ($db_prefix != '')
2008                       ? str_replace("{$this->mUnixName}_", $db_prefix, $this->mCommentsTable)
2009                       : $this->mCommentsTable;
2010  
2011        // Query to check the current version of Flyspray
2012        $sql    = "SELECT pref_value FROM $preferences_table WHERE pref_name = 'fs_ver'";
2013  
2014        // Check what version we are dealing with.
2015        $result = $this->mDbConnection->Execute($sql);
2016        if ($result)
2017        {
2018           $row = $result->FetchRow();
2019           if ($row['pref_value'] == '0.9.7')
2020           {
2021              // Run the upgrade script.
2022              if (!$this->PopulateDb($data))
2023              {
2024                 return FALSE;
2025              }
2026              else
2027              {
2028                  // Fix the Attachments to be within the comments
2029                  // Get a list of the attachments
2030                  $sql    = "
2031                  SELECT 
2032                      *
2033                  FROM 
2034                      $attachments_table
2035                  WHERE
2036                      comment_id < '1'
2037                  AND 
2038                      date_added > '0'";
2039                  
2040                  $attachments = $this->mDbConnection->Execute($sql);
2041                  if ($attachments)
2042                    {
2043                      // Cycle through each attachment
2044                      while($row = $attachments->FetchRow())
2045                      {
2046                          // Create a comment
2047                          $sql    = "
2048                          INSERT INTO 
2049                              flyspray_comments
2050                              (task_id, date_added, user_id, comment_text)
2051                          VALUES 
2052                              ( ?, ?, ?, ? )";
2053                          $data    = array($row['task_id'], $row['date_added'], $row['added_by'], $row['file_desc']);
2054                          $this->mDbConnection->Execute($sql, $data);
2055                      
2056                          // Retrieve the comment ID
2057                          $comment_sql    = "
2058                          SELECT
2059                              *
2060                          FROM
2061                              $comments_table
2062                          WHERE 
2063                              comment_text = ?
2064                          ORDER BY 
2065                              comment_id DESC";
2066                          
2067                          $comment = $this->mDbConnection->FetchRow($this->mDbConnection->Execute($comment_sql, array($row['file_desc'])));
2068                      
2069                          // Update the attachment entry to point it to the comment ID
2070                          $update_attachments    = "
2071                          UPDATE
2072                              flyspray_attachments
2073                          SET
2074                              comment_id = ?
2075                          WHERE
2076                              attachment_id = ?";
2077                          
2078                          $this->mDbConnection->Execute($update_attachments, array($comment['comment_id'], $row['attachment_id']));
2079                      }
2080                  }
2081                  return TRUE;
2082              }
2083           }
2084           else
2085           {
2086              $_SESSION['page_message'][] = 'Upgrade not Successful!';
2087              $_SESSION['page_message'][] = "You are trying to upgrade from the wrong {$this->mProductName} version ({$row['pref_value']}).";
2088              $_SESSION['page_message'][] = "You need to be having a version 0.9.7 of {$this->mProductName} installed in order to proceed with the upgrade path you have choosen.";
2089              return FALSE;
2090           }
2091        }
2092        else
2093        {
2094           $_SESSION['page_message'][] = 'Upgrade not Successful!';
2095           $_SESSION['page_message'][] = "Have you picked the right Upgrade path? Is your current version of {$this->mProductName}: 0.9.7 ?";
2096           return FALSE;
2097        }
2098     }
2099  
2100  
2101     function VerifyVariableTypes($type, $value)
2102     {
2103        $message = '';
2104        switch($type)
2105        {
2106           case 'string':
2107              return (!is_string($value))
2108              ? FALSE
2109              : TRUE;
2110           break;
2111  
2112           case 'number':
2113              return (!strval(intval($value)))
2114              ? FALSE
2115              : TRUE;
2116           break;
2117  
2118           case 'email address':
2119              $email_pattern = '/^[^@\s<&>]+@([-a-z0-9]+\.)+[a-z]{2,}$/i';
2120  
2121              if (preg_match($email_pattern, $value))
2122              {
2123                 return TRUE;
2124              }
2125              return FALSE;
2126           break;
2127  
2128           case 'boolean':
2129              return ($value)
2130              ? TRUE
2131              : FALSE;
2132           break;
2133  
2134           case 'password':
2135              return (strlen($value) >= $this->mMinPasswordLength)
2136              ? TRUE
2137              : FALSE;
2138           break;
2139           
2140           case 'folder':
2141               return (file_exists($value) && is_dir($value))
2142              ? TRUE
2143              : FALSE;
2144           break;
2145  
2146           default:
2147           return TRUE;
2148           break;
2149        }
2150     }
2151  
2152     /**
2153     * Function to output the templates
2154     * @param array $templates The collection of templates with their associated variables
2155     *
2156     */
2157     function OutputPage($templates = array())
2158     {
2159        if (sizeof($templates) == 0)
2160        {
2161           trigger_error("Templates not configured properly", E_USER_NOTICE);
2162        }
2163  
2164        // Define a template array. This will be used to store the dynamically created objects
2165        $template = array();
2166  
2167        // Get the keyname of the last array. This always will be the final template which gets outputted
2168        end($templates);
2169        $last = key($templates);
2170  
2171        // Define a set of common variables which plugin to the structure template.
2172        $common_vars = array('product_name' => $this->mProductName);
2173  
2174        // Loop through the templates array to dynamically create objects and assign variables to them.
2175        foreach($templates as $name => $module)
2176        {
2177  
2178           // Create a new object for the template
2179           $template[$name] = & new Template($module['path']);
2180  
2181           // Check if any vars need to be defined for the template and set them.
2182           if (isset($templates[$name]['vars']))
2183           {
2184              $template[$name]->SetVars($module['vars']);
2185           }
2186  
2187           // Check if any blocks have been defined.
2188           if (isset($templates[$name]['block']))
2189           {
2190              // If, then loop through the blocks and associate the blocks to their sections
2191              foreach($templates[$name]['block'] as $section => $plugin)
2192              {
2193                 // Check if the template exists before fetching. Else trigger an error.
2194                 if (file_exists($templates[$plugin]['path'] . '/' . $templates[$plugin]['template']))
2195                 {
2196                    // Fetch the contents of the block and plug it into the appropriate section
2197                    $template[$name]->Set($section, $template[$plugin]->fetch($templates[$plugin]['template']));
2198                 }
2199                 else
2200                 {
2201                    trigger_error("Template misconfiguration: ({$templates[$plugin]['path']}{$templates[$plugin]['template']}) not found!", E_USER_NOTICE);
2202                 }
2203              }
2204           }
2205  
2206           // Check if there are any variables which need appending new values
2207           if (isset($templates[$name]['append']))
2208           {
2209              // If, loop through the array of append variables
2210              foreach($templates[$name]['append'] as $vars => $value)
2211              {
2212                 // Check if the appending variable has already been given a value
2213                 if (isset($template[$name]->vars[$vars]))
2214                 {
2215                    // Append the value to the variable $vars of the current template object
2216                    $template[$name]->Append($vars, $value);
2217                 }
2218              }
2219           }
2220  
2221           // If it has reached the last template block
2222           if($name == $last)
2223           {
2224              // This will and HAS to be the last template
2225              // Associate the common variables to the template
2226              $template[$name]->SetVars($common_vars);
2227  
2228              // Check if the template exists before fetching and echoing. Else trigger an error.
2229              if (file_exists($module['path'] . '/'. $module['template']))
2230              {
2231                 // Echo the final template and exit the script
2232                 echo $template[$name]->Fetch($module['template']);
2233                 exit;
2234              }
2235              else
2236              {
2237                 trigger_error("Template misconfiguration: ({$templates[$plugin]['path']}{$templates[$plugin]['template']}) not found!", E_USER_NOTICE);
2238              }
2239           }
2240        }
2241     }
2242  }
2243  
2244  
2245  $setup = new Setup;
2246  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]