PageRenderTime 128ms CodeModel.GetById 23ms app.highlight 82ms RepoModel.GetById 5ms app.codeStats 0ms

/application/controllers/InstallerController.php

https://bitbucket.org/sammousa/valuematchbv-ls2
PHP | 1213 lines | 926 code | 106 blank | 181 comment | 66 complexity | 010540839b80555a6a85ed62957af7db MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
   2/*
   3* LimeSurvey (tm)
   4* Copyright (C) 2011 The LimeSurvey Project Team / Carsten Schmitz
   5* All rights reserved.
   6* License: GNU/GPL License v2 or later, see LICENSE.php
   7* LimeSurvey is free software. This version may have been modified pursuant
   8* to the GNU General Public License, and as distributed it includes or
   9* is derivative of works licensed under the GNU General Public License or
  10* other free or open source software licenses.
  11* See COPYRIGHT.php for copyright notices and details.
  12*
  13* @author Shubham Sachdeva
  14*/
  15
  16/**
  17* Installer
  18*
  19* @todo Output code belongs into view
  20*
  21* @package LimeSurvey
  22* @author Shubham Sachdeva
  23* @copyright 2011
  24* @version $Id$
  25* @access public
  26*/
  27class InstallerController extends CController {
  28
  29    /**
  30    * @var CDbConnection
  31    */
  32    public $connection;
  33
  34    /**
  35    * clang
  36    */
  37    public $lang = null;
  38
  39    /**
  40    * Checks for action specific authorization and then executes an action
  41    *
  42    * @access public
  43    * @param string $action
  44    * @return bool
  45    */
  46    public function run($action = 'index')
  47    {
  48        self::_checkInstallation();
  49        self::_sessioncontrol();
  50
  51        switch ($action) {
  52
  53            case 'welcome':
  54                $this->stepWelcome();
  55                break;
  56
  57            case 'license':
  58                $this->stepLicense();
  59                break;
  60
  61            case 'viewlicense':
  62                $this->stepViewLicense();
  63                break;
  64
  65            case 'precheck':
  66                $this->stepPreInstallationCheck();
  67                break;
  68
  69            case 'database':
  70                $this->stepDatabaseConfiguration();
  71                break;
  72
  73            case 'createdb':
  74                $this->stepCreateDb();
  75                break;
  76
  77            case 'populatedb':
  78                $this->stepPopulateDb();
  79                break;
  80
  81            case 'optional':
  82                $this->stepOptionalConfiguration();
  83                break;
  84
  85            case 'index' :
  86            default :
  87                $this->redirect($this->createUrl('installer/welcome'));
  88                break;
  89
  90        }
  91    }
  92
  93    /**
  94    * Installer::_checkInstallation()
  95    *
  96    * Based on existance of 'sample_installer_file.txt' file, check if
  97    * installation should proceed further or not.
  98    * @return
  99    */
 100    function _checkInstallation()
 101    {
 102        if (file_exists(APPPATH . 'config/config.php') && empty($_POST['InstallerConfigForm']))
 103        {
 104            throw new CHttpException(500, 'Installation has been done already. Installer disabled.');
 105            exit();
 106        }
 107    }
 108
 109    /**
 110    * Load and set session vars
 111    *
 112    * @access protected
 113    * @return void
 114    */
 115    protected function _sessioncontrol()
 116    {
 117        if (empty(Yii::app()->session['installerLang']))
 118            Yii::app()->session['installerLang'] = 'en';
 119
 120        Yii::import('application.libraries.Limesurvey_lang');
 121        $this->lang = new Limesurvey_lang(Yii::app()->session['installerLang']);
 122        Yii::app()->setLang($this->lang);
 123    }
 124
 125    /**
 126    * welcome and language selection install step
 127    */
 128    private function stepWelcome()
 129    {
 130
 131        if (!empty($_POST['installerLang']))
 132        {
 133            Yii::app()->session['installerLang'] = $_POST['installerLang'];
 134            $this->redirect($this->createUrl('installer/license'));
 135        }
 136        $this->loadHelper('surveytranslator');
 137        Yii::app()->session->remove('configFileWritten');
 138
 139        $aData['clang'] = $clang = $this->lang;
 140        $aData['title'] = $clang->gT('Welcome');
 141        $aData['descp'] = $clang->gT('Welcome to the LimeSurvey installation wizard. This wizard will guide you through the installation, database setup and initial configuration of LimeSurvey.');
 142        $aData['classesForStep'] = array('on','off','off','off','off','off');
 143        $aData['progressValue'] = 0;
 144
 145        if (isset(Yii::app()->session['installerLang']))
 146        {
 147            $currentLanguage=Yii::app()->session['installerLang'];
 148        }
 149        else
 150            $currentLanguage='en';
 151
 152        foreach(getLanguageData(true, $currentLanguage) as $langkey => $languagekind)
 153        {
 154            $languages[htmlspecialchars($langkey)] = sprintf('%s - %s', $languagekind['nativedescription'], $languagekind['description']);
 155        }
 156        $aData['languages']=$languages;
 157        $this->render('/installer/welcome_view',$aData);
 158    }
 159
 160    /**
 161    * Display license
 162    */
 163    private function stepLicense()
 164    {
 165        $aData['clang'] = $clang = $this->lang;
 166        // $aData array contain all the information required by view.
 167        $aData['title'] = $clang->gT('License');
 168        $aData['descp'] = $clang->gT('GNU General Public License:');
 169        $aData['classesForStep'] = array('off','on','off','off','off','off');
 170        $aData['progressValue']=0;
 171
 172        if (strtolower($_SERVER['REQUEST_METHOD']) == 'post')
 173        {
 174            $this->redirect($this->createUrl('installer/precheck'));
 175        }
 176        Yii::app()->session['saveCheck'] = 'save';  // Checked in next step
 177
 178        $this->render('/installer/license_view',$aData);
 179    }
 180
 181    /**
 182    * display the license file as IIS for example
 183    * does not display it via the server.
 184    */
 185    public function stepViewLicense()
 186    {
 187        $filename = dirname(BASEPATH) . '/docs/license.txt';
 188        header('Content-Type: text/plain; charset=UTF-8');
 189        readfile($filename);
 190        exit;
 191    }
 192
 193    /**
 194    * check a few writing permissions and optional settings
 195    */
 196    private function stepPreInstallationCheck()
 197    {
 198        $aData['clang'] = $clang = $this->lang;
 199        $model = new InstallerConfigForm();
 200        //usual data required by view
 201        $aData['title'] = $clang->gT('Pre-installation check');
 202        $aData['descp'] = $clang->gT('Pre-installation check for LimeSurvey ').Yii::app()->getConfig('versionnumber');
 203        $aData['classesForStep'] = array('off','off','on','off','off','off');
 204        $aData['progressValue'] = 20;
 205        $aData['phpVersion'] = phpversion();
 206        // variable storing next button link.initially null
 207        $aData['next'] = '';
 208        $aData['dbtypes']=$model->supported_db_types;
 209
 210        $bProceed = $this->_check_requirements($aData);
 211        $aData['dbtypes']=$model->supported_db_types;
 212
 213        if(count($aData['dbtypes'])==0)
 214        {
 215            $bProceed=false;
 216        }
 217        // after all check, if flag value is true, show next button and sabe step2 status.
 218        if ($bProceed)
 219        {
 220            $aData['next'] = true;
 221            Yii::app()->session['step2'] = true;
 222        }
 223
 224        $this->render('/installer/precheck_view',$aData);
 225    }
 226
 227    /**
 228    * Configure database screen
 229    */
 230    private function stepDatabaseConfiguration()
 231    {
 232        $this->loadHelper('surveytranslator');
 233
 234        $aData['clang'] = $clang = $this->lang;
 235        // usual data required by view
 236        $aData['title'] = $clang->gT('Database configuration');
 237        $aData['descp'] = $clang->gT('Please enter the database settings you want to use for LimeSurvey:');
 238        $aData['classesForStep'] = array('off','off','off','on','off','off');
 239        $aData['progressValue'] = 40;
 240        $aData['model'] = $model = new InstallerConfigForm;
 241
 242        if(isset($_POST['InstallerConfigForm']))
 243        {
 244            $model->attributes = $_POST['InstallerConfigForm'];
 245
 246            //run validation, if it fails, load the view again else proceed to next step.
 247            if($model->validate()) {
 248                $sDatabaseType = $model->dbtype;
 249                $sDatabaseName = $model->dbname;
 250                $sDatabaseUser = $model->dbuser;
 251                $sDatabasePwd = $model->dbpwd;
 252                $sDatabasePrefix = $model->dbprefix;
 253                $sDatabaseLocation = $model->dblocation;
 254                $sDatabasePort = '';
 255                if (strpos($sDatabaseLocation, ':')!==false)
 256                {
 257                    list($sDatabaseLocation, $sDatabasePort) = explode(':', $sDatabaseLocation, 2);
 258                }
 259                else
 260                {
 261                    $sDatabasePort = self::_getDbPort($sDatabaseType, $sDatabasePort);
 262                }
 263
 264                $bDBExists = false;
 265                $bDBConnectionWorks = false;
 266                $aDbConfig = compact('sDatabaseType', 'sDatabaseName', 'sDatabaseUser', 'sDatabasePwd', 'sDatabasePrefix', 'sDatabaseLocation', 'sDatabasePort');
 267
 268                if (self::_dbConnect($aDbConfig, array())) {
 269                    $bDBExists = true;
 270                    $bDBConnectionWorks = true;
 271                } else {
 272                    $aDbConfig['sDatabaseName'] = '';
 273                    if (self::_dbConnect($aDbConfig, array())) {
 274                        $bDBConnectionWorks = true;
 275                    } else {
 276                        $model->addError('dblocation', $clang->gT('Connection with database failed. Please check database location, user name and password and try again.'));
 277                        $model->addError('dbpwd');
 278                        $model->addError('dbuser');
 279                    }
 280                }
 281
 282                //if connection with database fail
 283                if ($bDBConnectionWorks)
 284                {
 285                    //saving the form data
 286                    foreach(array('dbname', 'dbtype', 'dbpwd', 'dbuser', 'dbprefix') as $sStatusKey) {
 287                        Yii::app()->session[$sStatusKey] = $model->$sStatusKey;
 288                    }
 289                    Yii::app()->session['dbport'] = $sDatabasePort;
 290                    Yii::app()->session['dblocation'] = $sDatabaseLocation;
 291
 292                    //check if table exists or not
 293                    $sTestTablename = 'surveys';
 294                    $bTablesDoNotExist = false;
 295
 296                    // Check if the surveys table exists or not
 297                    if ($bDBExists == true) {
 298                        try {
 299                            $this->connection->createCommand()->select()->from('{{surveys}}')->queryAll();
 300                        } catch(Exception $e) {
 301                            $bTablesDoNotExist = true;
 302                        }
 303                    }
 304
 305                    $dbexistsbutempty = ($bDBExists && $bTablesDoNotExist);
 306
 307                    //store them in session
 308                    Yii::app()->session['databaseexist'] = $bDBExists;
 309                    Yii::app()->session['tablesexist'] = !$bTablesDoNotExist;
 310
 311                    // If database is up to date, redirect to administration screen.
 312                    if ($bDBExists && !$bTablesDoNotExist)
 313                    {
 314                        Yii::app()->session['optconfig_message'] = sprintf('<b>%s</b>', $clang->gT('The database you specified is up to date.'));
 315                        Yii::app()->session['step3'] = true;
 316
 317                        //wrte config file! as we no longer redirect to optional view
 318                        $this->_writeConfigFile();
 319
 320                        //$this->redirect($this->createUrl("installer/loadOptView"));
 321                        header("refresh:5;url=".$this->createUrl("/admin"));
 322                        echo sprintf( $clang->gT('The database you specified is up to date. You\'ll be redirected in 5 seconds. If not, click <a href="%s">here</a>.', 'unescaped'), $this->createUrl("/admin"));
 323                        exit();
 324                    }
 325
 326                    if (in_array($model->dbtype, array('mysql', 'mysqli'))) {
 327                        //for development - use mysql in the strictest mode  //Checked)
 328                        if (Yii::app()->getConfig('debug')>1) {
 329                            $this->connection->createCommand("SET SESSION SQL_MODE='STRICT_ALL_TABLES,ANSI'")->execute();
 330                        }
 331                        $versioninfo = $this->connection->getServerVersion();
 332                        if (version_compare($versioninfo,'4.1','<'))
 333                        {
 334                            die("<br />Error: You need at least MySQL version 4.1 to run LimeSurvey. Your version:".$versioninfo);
 335                        }
 336                        @$this->connection->createCommand("SET CHARACTER SET 'utf8'")->execute();  //Checked
 337                        @$this->connection->createCommand("SET NAMES 'utf8'")->execute();  //Checked
 338                    }
 339
 340                    // Setting dateformat for mssql driver. It seems if you don't do that the in- and output format could be different
 341                    if (in_array($model->dbtype, array('mssql', 'sqlsrv'))) {
 342                        @$this->connection->createCommand('SET DATEFORMAT ymd;')->execute();     //Checked
 343                        @$this->connection->createCommand('SET QUOTED_IDENTIFIER ON;')->execute();     //Checked
 344                    }
 345
 346                    //$aData array won't work here. changing the name
 347                    $values['title'] = $clang->gT('Database settings');
 348                    $values['descp'] = $clang->gT('Database settings');
 349                    $values['classesForStep'] = array('off','off','off','off','on','off');
 350                    $values['progressValue'] = 60;
 351
 352                    //it store text content
 353                    $values['adminoutputText'] = '';
 354                    //it store the form code to be displayed
 355                    $values['adminoutputForm'] = '';
 356
 357                    //if DB exist, check if its empty or up to date. if not, tell user LS can create it.
 358                    if (!$bDBExists)
 359                    {
 360                        Yii::app()->session['databaseDontExist'] = true;
 361
 362                        $values['adminoutputText'].= "\t<tr bgcolor='#efefef'><td align='center'>\n"
 363                        ."<strong>".$clang->gT("Database doesn't exist!")."</strong><br /><br />\n"
 364                        .$clang->gT("The database you specified does not exist:")."<br /><br />\n<strong>".$model->dbname."</strong><br /><br />\n"
 365                        .$clang->gT("LimeSurvey can attempt to create this database for you.")."<br /><br />\n";
 366
 367                        $values['adminoutputForm'] =  CHtml::form(array('installer/createdb'), 'post').
 368                        "<input type='submit' value='"
 369                        .$clang->gT("Create database")."' class='ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only' /></form>";
 370                    }
 371                    elseif ($dbexistsbutempty) //&& !(returnGlobal('createdbstep2')==$clang->gT("Populate database")))
 372                    {
 373                        Yii::app()->session['populatedatabase'] = true;
 374
 375                        //$this->connection->database = $model->dbname;
 376                        //						//$this->connection->createCommand("USE DATABASE `".$model->dbname."`")->execute();
 377                        $values['adminoutputText'].= sprintf($clang->gT('A database named "%s" already exists.'),$model->dbname)."<br /><br />\n"
 378                        .$clang->gT("Do you want to populate that database now by creating the necessary tables?")."<br /><br />";
 379
 380                        $values['adminoutputForm'] =  CHtml::form(array('installer/populatedb'), 'post')
 381                        ."<input class='ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only' type='submit' name='createdbstep2' value='".$clang->gT("Populate database")."' />"
 382                        ."</form>";
 383                    }
 384                    elseif (!$dbexistsbutempty)
 385                    {
 386                        //DB EXISTS, CHECK FOR APPROPRIATE UPGRADES
 387                        //$this->connection->database = $model->dbname;
 388                        //$this->connection->createCommand("USE DATABASE `$databasename`")->execute();
 389                        /* @todo Implement Upgrade */
 390                        //$output=CheckForDBUpgrades();
 391                        if ($output== '') {$values['adminoutput'].='<br />'.$clang->gT('LimeSurvey database is up to date. No action needed');}
 392                        else {$values['adminoutput'].=$output;}
 393                        $values['adminoutput'].= "<br />" . sprintf($clang->gT('Please <a href="%s">log in</a>.', 'unescaped'), $this->createUrl("/admin"));
 394                    }
 395                    $values['clang'] = $clang;
 396                    $this->render('/installer/dbsettings_view', $values);
 397                } else {
 398                    $this->render('/installer/dbconfig_view', $aData);
 399                }
 400            } else {
 401                $this->render('/installer/dbconfig_view', $aData);
 402            }
 403        } else {
 404            $this->render('/installer/dbconfig_view', $aData);
 405        }
 406    }
 407
 408    /**
 409    * Installer::stepCreateDb()
 410    * Create database.
 411    * @return
 412    */
 413    function stepCreateDb()
 414    {
 415        // check status. to be called only when database don't exist else rdirect to proper link.
 416        if(!Yii::app()->session['databaseDontExist']) {
 417            $this->redirect($this->createUrl('installer/welcome'));
 418        }
 419
 420        $aData['clang'] = $clang = $this->lang;
 421        $aData['model'] = $model = new InstallerConfigForm;
 422        $aData['title'] = $clang->gT("Database configuration");
 423        $aData['descp'] = $clang->gT("Please enter the database settings you want to use for LimeSurvey:");
 424        $aData['classesForStep'] = array('off','off','off','on','off','off');
 425        $aData['progressValue'] = 40;
 426
 427        $aDbConfig = self::_getDatabaseConfig();
 428        extract($aDbConfig);
 429        // unset database name for connection, since we want to create it and it doesn't already exists
 430        $aDbConfig['sDatabaseName'] = '';
 431        self::_dbConnect($aDbConfig, $aData);
 432
 433        $aData['adminoutputForm'] = '';
 434        // Yii doesn't have a method to create a database
 435        $createDb = true; // We are thinking positive
 436        switch ($sDatabaseType)
 437        {
 438            case 'mysqli':
 439            case 'mysql':
 440            try
 441            {
 442                $this->connection->createCommand("CREATE DATABASE `$sDatabaseName` DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci")->execute();
 443            }
 444            catch(Exception $e)
 445            {
 446                $createDb=false;
 447            }
 448            break;
 449            case 'mssql':
 450            case 'odbc':
 451            try
 452            {
 453                $this->connection->createCommand("CREATE DATABASE [$sDatabaseName];")->execute();
 454            }
 455            catch(Exception $e)
 456            {
 457                $createDb=false;
 458            }
 459            break;
 460            case 'postgres':
 461            try
 462            {
 463                $this->connection->createCommand("CREATE DATABASE \"$sDatabaseName\" ENCODING 'UTF8'")->execute();
 464            }
 465            catch (Exception $e)
 466            {
 467                $createdb = false;
 468            }
 469            break;
 470            default:
 471            try
 472            {
 473                $this->connection->createCommand("CREATE DATABASE $sDatabaseName")->execute();
 474            }
 475            catch(Exception $e)
 476            {
 477                $createDb=false;
 478            }
 479            break;
 480        }
 481
 482        //$this->load->dbforge();
 483        if ($createDb) //Database has been successfully created
 484        {
 485            $sDsn = self::_getDsn($sDatabaseType, $sDatabaseLocation, $sDatabasePort, $sDatabaseName, $sDatabaseUser, $sDatabasePwd);
 486            $this->connection = new CDbConnection($sDsn, $sDatabaseUser, $sDatabasePwd);
 487
 488            Yii::app()->session['populatedatabase'] = true;
 489            Yii::app()->session['databaseexist'] = true;
 490            unset(Yii::app()->session['databaseDontExist']);
 491
 492            $aData['adminoutputText'] = "<tr bgcolor='#efefef'><td colspan='2' align='center'> <br />"
 493            ."<strong><font class='successtitle'>\n"
 494            .$clang->gT("Database has been created.")."</font></strong><br /><br />\n"
 495            .$clang->gT("Please continue with populating the database.")."<br /><br />\n";
 496            $aData['adminoutputForm'] =  CHtml::form(array('installer/populatedb'), 'post')
 497            ."<input class='ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only' type='submit' name='createdbstep2' value='".$clang->gT("Populate database")."' /></form>";
 498        }
 499        else
 500        {
 501            $model->addError('dblocation', $clang->gT('Try again! Connection with database failed.'));
 502            $this->render('/installer/dbconfig_view',$aData);
 503        }
 504
 505        $aData['title'] = $clang->gT("Database settings");
 506        $aData['descp'] = $clang->gT("Database settings");
 507        $aData['classesForStep'] = array('off','off','off','off','on','off');
 508        $aData['progressValue'] = 60;
 509        $this->render('/installer/dbsettings_view',$aData);
 510    }
 511
 512    /**
 513    * Installer::stepPopulateDb()
 514    * Function to populate the database.
 515    * @return
 516    */
 517    function stepPopulateDb()
 518    {
 519        if (!Yii::app()->session['populatedatabase'])
 520        {
 521            $this->redirect($this->createUrl('installer/welcome'));
 522        }
 523
 524        $aData['clang'] = $clang = $this->lang;
 525        $aData['model'] = $model = new InstallerConfigForm;
 526        $aData['title'] = $clang->gT("Database configuration");
 527        $aData['descp'] = $clang->gT("Please enter the database settings you want to use for LimeSurvey:");
 528        $aData['classesForStep'] = array('off','off','off','on','off','off');
 529        $aData['progressValue'] = 40;
 530
 531        $aDbConfig = self::_getDatabaseConfig();
 532        extract($aDbConfig);
 533        self::_dbConnect($aDbConfig, $aData);
 534
 535        /* @todo Use Yii as it supports various db types and would better handle this process */
 536
 537        switch ($sDatabaseType)
 538        {
 539            case 'mysqli':
 540            case 'mysql':
 541                $sql_file = 'mysql';
 542                break;
 543            case 'sqlsrv':
 544            case 'mssql':
 545                $sql_file = 'mssql';
 546                break;
 547            case 'pgsql':
 548                $sql_file = 'pgsql';
 549                break;
 550            default:
 551                throw new Exception(sprintf('Unkown database type "%s".', $sDatabaseType));
 552        }
 553
 554        //checking DB Connection
 555        $aErrors = self::_setup_tables(dirname(APPPATH).'/installer/sql/create-'.$sql_file.'.sql');
 556        if ($aErrors === false)
 557        {
 558            $model->addError('dblocation', $clang->gT('Try again! Connection with database failed. Reason: ').implode(', ', $aErrors));
 559            $this->render('/installer/dbconfig_view', $aData);
 560        }
 561        elseif (count($aErrors)==0)
 562        {
 563            //$data1['adminoutput'] = '';
 564            //$data1['adminoutput'] .= sprintf("Database `%s` has been successfully populated.",$dbname)."</font></strong></font><br /><br />\n";
 565            //$data1['adminoutput'] .= "<input type='submit' value='Main Admin Screen' onclick=''>";
 566            $confirmation = sprintf($clang->gT("Database %s has been successfully populated."), sprintf('<b>%s</b>', Yii::app()->session['dbname']));
 567        }
 568        else
 569        {
 570            $confirmation = $clang->gT('Database was populated but there were errors:').'<p><ul>';
 571            foreach ($aErrors as $sError)
 572            {
 573                $confirmation.='<li>'.htmlspecialchars($sError).'</li>';
 574            }
 575            $confirmation.='</ul>';
 576        }
 577
 578        Yii::app()->session['tablesexist'] = true;
 579        Yii::app()->session['step3'] = true;
 580        Yii::app()->session['optconfig_message'] = $confirmation;
 581        unset(Yii::app()->session['populatedatabase']);
 582
 583        $this->redirect($this->createUrl('installer/optional'));
 584    }
 585
 586    /**
 587    * Optional settings screen
 588    */
 589    private function stepOptionalConfiguration()
 590    {
 591        $aData['clang'] = $clang = $this->lang;
 592        $aData['confirmation'] = Yii::app()->session['optconfig_message'];
 593        $aData['title'] = $clang->gT("Optional settings");
 594        $aData['descp'] = $clang->gT("Optional settings to give you a head start");
 595        $aData['classesForStep'] = array('off','off','off','off','off','on');
 596        $aData['progressValue'] = 80;
 597
 598        $this->loadHelper('surveytranslator');
 599        $aData['model'] = $model = new InstallerConfigForm('optional');
 600
 601        if(isset($_POST['InstallerConfigForm']))
 602        {
 603            $model->attributes = $_POST['InstallerConfigForm'];
 604
 605            //run validation, if it fails, load the view again else proceed to next step.
 606            if($model->validate()) {
 607                $adminLoginPwd = $model->adminLoginPwd;
 608                $confirmPwd = $model->confirmPwd;
 609                $defaultuser = $model->adminLoginName;
 610                $defaultpass = $model->adminLoginPwd;
 611                $siteadminname = $model->adminName;
 612                $siteadminbounce = $siteadminemail = $model->adminEmail;
 613                $sitename = $model->siteName;
 614                $defaultlang = $model->surveylang;
 615
 616                $aData['title'] = $clang->gT("Database configuration");
 617                $aData['descp'] = $clang->gT("Please enter the database settings you want to use for LimeSurvey:");
 618                $aData['classesForStep'] = array('off','off','off','on','off','off');
 619                $aData['progressValue'] = 40;
 620
 621                //config file is written, and we've a db in place
 622                $this->connection = Yii::app()->db;
 623
 624                //checking DB Connection
 625                if ($this->connection->getActive() == true) {
 626                    $password_hash=hash('sha256', $defaultpass);
 627                    try {
 628                        $this->connection->createCommand()->insert('{{users}}', array('users_name' => $defaultuser, 'password' => $password_hash, 'full_name' => $siteadminname, 'parent_id' => 0, 'lang' => $defaultlang, 'email' => $siteadminemail, 'create_survey' => 1, 'create_user' => 1, 'participant_panel' => 1, 'delete_user' => 1, 'superadmin' => 1, 'configurator' => 1, 'manage_template' => 1, 'manage_label' => 1));
 629                        $this->connection->createCommand()->insert("{{settings_global}}", array('stg_name' => 'SessionName', 'stg_value' => self::_getRandomString()));
 630
 631                        foreach(array('sitename', 'siteadminname', 'siteadminemail', 'siteadminbounce', 'defaultlang') as $insert) {
 632                            $this->connection->createCommand()->insert("{{settings_global}}", array('stg_name' => $insert, 'stg_value' => $$insert));
 633                        }
 634                        // only continue if we're error free otherwise setup is broken.
 635                    } catch (Exception $e) {
 636                        throw new Exception(sprintf('Could not add optional settings: %s.', $e));
 637                    }
 638
 639                    Yii::app()->session['deletedirectories'] = true;
 640
 641                    $aData['title'] = $clang->gT("Success!");
 642                    $aData['descp'] = $clang->gT("LimeSurvey has been installed successfully.");
 643                    $aData['classesForStep'] = array('off','off','off','off','off','off');
 644                    $aData['progressValue'] = 100;
 645                    $aData['user'] = $defaultuser;
 646                    $aData['pwd'] = $defaultpass;
 647
 648                    $this->render('/installer/success_view', $aData);
 649                    exit();
 650                }
 651            } else {
 652                // if passwords don't match, redirect to proper link.
 653                Yii::app()->session['optconfig_message'] = sprintf('<b>%s</b>', $clang->gT("Passwords don't match."));
 654                $this->redirect($this->createUrl('installer/optional'));
 655            }
 656        } elseif(empty(Yii::app()->session['configFileWritten'])) {
 657            $this->_writeConfigFile();
 658        }
 659
 660        $this->render('/installer/optconfig_view', $aData);
 661    }
 662
 663    /**
 664    * Loads a helper
 665    *
 666    * @access public
 667    * @param string $helper
 668    * @return void
 669    */
 670    public function loadHelper($helper)
 671    {
 672        Yii::import('application.helpers.' . $helper . '_helper', true);
 673    }
 674
 675    /**
 676    * Loads a library
 677    *
 678    * @access public
 679    * @param string $helper
 680    * @return void
 681    */
 682    public function loadLibrary($library)
 683    {
 684        Yii::import('application.libraries.'.$library, true);
 685    }
 686
 687    /**
 688    * check requirements
 689    *
 690    * @param array $data return theme variables
 691    * @return bool requirements met
 692    */
 693    private function _check_requirements(&$data)
 694    {
 695        // proceed variable check if all requirements are true. If any of them is false, proceed is set false.
 696        $bProceed = true; //lets be optimistic!
 697
 698        /**
 699        * check image HTML template
 700        *
 701        * @param bool $result
 702        */
 703        function check_HTML_image($result)
 704        {
 705            $label = array('wrong', 'right');
 706            return sprintf('<img src="%s/installer/images/tick-%s.png" alt="Found" />', Yii::app()->baseUrl, $label[$result]);
 707        }
 708
 709
 710        function is_writable_recursive($dir)
 711        {
 712            $folder = opendir($dir);
 713            while($file = readdir( $folder ))
 714                if($file != '.' && $file != '..' &&
 715                ( !is_writable(  $dir."/".$file  ) ||
 716                (  is_dir(   $dir."/".$file   ) && !is_writable_recursive(   $dir."/".$file   )  ) ))
 717                {
 718                    closedir($folder);
 719                    return false;
 720                }
 721                closedir($folder);
 722            return true;
 723        }
 724
 725        /**
 726        * check for a specific PHPFunction, return HTML image
 727        *
 728        * @param string $function
 729        * @param string $image return
 730        * @return bool result
 731        */
 732        function check_PHPFunction($function, &$image)
 733        {
 734            $result = function_exists($function);
 735            $image = check_HTML_image($result);
 736            return $result;
 737        }
 738
 739        /**
 740        * check if file or directory exists and is writeable, returns via parameters by reference
 741        *
 742        * @param string $path file or directory to check
 743        * @param int $type 0:undefined (invalid), 1:file, 2:directory
 744        * @param string $data to manipulate
 745        * @param string $base key for data manipulation
 746        * @param string $keyError key for error data
 747        * @return bool result of check (that it is writeable which implies existance)
 748        */
 749        function check_PathWriteable($path, $type, &$data, $base, $keyError, $bRecursive=false)
 750        {
 751            $result = false;
 752            $data[$base.'Present'] = 'Not Found';
 753            $data[$base.'Writable'] = '';
 754            switch($type) {
 755                case 1:
 756                    $exists = is_file($path);
 757                    break;
 758                case 2:
 759                    $exists = is_dir($path);
 760                    break;
 761                default:
 762                    throw new Exception('Invalid type given.');
 763            }
 764            if ($exists)
 765            {
 766                $data[$base.'Present'] = 'Found';
 767                if ((!$bRecursive && is_writable($path)) || ($bRecursive && is_writable_recursive($path)))
 768                {
 769                    $data[$base.'Writable'] = 'Writable';
 770                    $result = true;
 771                }
 772                else
 773                {
 774                    $data[$base.'Writable'] = 'Unwritable';
 775                }
 776            }
 777            $result || $data[$keyError] = true;
 778
 779            return $result;
 780        }
 781
 782        /**
 783        * check if file exists and is writeable, returns via parameters by reference
 784        *
 785        * @param string $file to check
 786        * @param string $data to manipulate
 787        * @param string $base key for data manipulation
 788        * @param string $keyError key for error data
 789        * @return bool result of check (that it is writeable which implies existance)
 790        */
 791        function check_FileWriteable($file, &$data, $base, $keyError)
 792        {
 793            return check_PathWriteable($file, 1, $data, $base, $keyError);
 794        }
 795
 796        /**
 797        * check if directory exists and is writeable, returns via parameters by reference
 798        *
 799        * @param string $directory to check
 800        * @param string $data to manipulate
 801        * @param string $base key for data manipulation
 802        * @param string $keyError key for error data
 803        * @return bool result of check (that it is writeable which implies existance)
 804        */
 805        function check_DirectoryWriteable($directory, &$data, $base, $keyError, $bRecursive=false)
 806        {
 807            return check_PathWriteable($directory, 2, $data, $base, $keyError, $bRecursive);
 808        }
 809
 810        //  version check
 811        if (version_compare(PHP_VERSION, '5.1.6', '<'))
 812            $bProceed = !$data['verror'] = true;
 813
 814        // mbstring library check
 815        if (!check_PHPFunction('mb_convert_encoding', $data['mbstringPresent']))
 816            $bProceed = false;
 817
 818        // JSON library check
 819        if (!check_PHPFunction('json_encode', $data['bJSONPresent']))
 820            $bProceed = false;
 821            
 822        // ** file and directory permissions checking **
 823
 824        // config directory
 825        if (!check_DirectoryWriteable(Yii::app()->getConfig('rootdir').'/application/config', $data, 'config', 'derror') )
 826            $bProceed = false;
 827
 828        // templates directory check
 829        if (!check_DirectoryWriteable(Yii::app()->getConfig('tempdir').'/', $data, 'tmpdir', 'tperror',true) )
 830            $bProceed = false;
 831
 832        //upload directory check
 833        if (!check_DirectoryWriteable(Yii::app()->getConfig('uploaddir').'/', $data, 'uploaddir', 'uerror',true) )
 834            $bProceed = false;
 835        
 836        // Session writable check
 837        $session = Yii::app()->session; /* @var $session CHttpSession */
 838        $sessionWritable = ($session->get('saveCheck', null)==='save');
 839        $data['sessionWritable'] = $sessionWritable;
 840        $data['sessionWritableImg'] = check_HTML_image($sessionWritable);
 841        if (!$sessionWritable){  
 842            // For recheck, try to set the value again
 843            $session['saveCheck'] = 'save';
 844            $bProceed = false;
 845        }
 846
 847        // ** optional settings check **
 848
 849        // gd library check
 850        if (function_exists('gd_info')) {
 851            $data['gdPresent'] = check_HTML_image(array_key_exists('FreeType Support', gd_info()));
 852        } else {
 853            $data['gdPresent'] = check_HTML_image(false);
 854        }
 855        // ldap library check
 856        check_PHPFunction('ldap_connect', $data['ldapPresent']);
 857
 858        // php zip library check
 859        check_PHPFunction('zip_open', $data['zipPresent']);
 860
 861        // zlib php library check
 862        check_PHPFunction('zlib_get_coding_type', $data['zlibPresent']);
 863        
 864        // imap php library check
 865        check_PHPFunction('imap_open', $data['bIMAPPresent']);
 866
 867        return $bProceed;
 868    }
 869
 870    /**
 871    * Installer::_setup_tables()
 872    * Function that actually modify the database. Read $sqlfile and execute it.
 873    * @param string $sqlfile
 874    * @return  Empty string if everything was okay - otherwise the error messages
 875    */
 876    function _setup_tables($sFileName, $aDbConfig = array(), $sDatabasePrefix = '')
 877    {
 878        extract(empty($aDbConfig) ? self::_getDatabaseConfig() : $aDbConfig);
 879        switch ($sDatabaseType) {
 880            case 'mysql':
 881            case 'mysqli':
 882                $this->connection->createCommand("ALTER DATABASE ". $this->connection->quoteTableName($sDatabaseName) ." DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;")->execute();
 883                break;
 884            case 'pgsql':
 885                if (version_compare($this->connection->getServerVersion(),'9','>=')) {
 886                    $this->connection->createCommand("ALTER DATABASE ". $this->connection->quoteTableName($sDatabaseName) ." SET bytea_output='escape';")->execute();
 887                }
 888                break;
 889        }
 890
 891        return $this->_executeSQLFile($sFileName, $sDatabasePrefix);
 892    }
 893
 894    /**
 895    * Executes an SQL file
 896    *
 897    * @param string $sFileName
 898    * @param string $sDatabasePrefix
 899    */
 900    function _executeSQLFile($sFileName, $sDatabasePrefix)
 901    {
 902        $aMessages = array();
 903        $sCommand = '';
 904
 905        if (!is_readable($sFileName)) {
 906            return false;
 907        } else {
 908            $aLines = file($sFileName);
 909        }
 910        foreach ($aLines as $sLine) {
 911            $sLine = rtrim($sLine);
 912            $iLineLength = strlen($sLine);
 913
 914            if ($iLineLength && $sLine[0] != '#' && substr($sLine,0,2) != '--') {
 915                if (substr($sLine, $iLineLength-1, 1) == ';') {
 916                    $line = substr($sLine, 0, $iLineLength-1);
 917                    $sCommand .= $sLine;
 918                    $sCommand = str_replace('prefix_', $sDatabasePrefix, $sCommand); // Table prefixes
 919
 920                    try {
 921                        $this->connection->createCommand($sCommand)->execute();
 922                    } catch(Exception $e) {
 923                        $aMessages[] = "Executing: ".$sCommand." failed! Reason: ".$e;
 924                    }
 925
 926                    $sCommand = '';
 927                } else {
 928                    $sCommand .= $sLine;
 929                }
 930            }
 931        }
 932        return $aMessages;
 933    }
 934
 935    /**
 936    * Function to write given database settings in APPPATH.'config/config.php'
 937    */
 938    function _writeConfigFile()
 939    {
 940        $aData['clang'] = $clang = $this->lang;
 941        //write config.php if database exists and has been populated.
 942        if (Yii::app()->session['databaseexist'] && Yii::app()->session['tablesexist'])
 943        {
 944
 945            extract(self::_getDatabaseConfig());
 946            $sDsn = self::_getDsn($sDatabaseType, $sDatabaseLocation, $sDatabasePort, $sDatabaseName, $sDatabaseUser, $sDatabasePwd);
 947
 948            // mod_rewrite existence check
 949            // Section commented out until a better method of knowing whether the mod_rewrite actually
 950            // works is found. In the meantime, it is better to set $showScriptName to 'true' so it
 951            // works on all installations, and allow users to change it manually later.
 952            //if ((function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) || strtolower(getenv('HTTP_MOD_REWRITE')) == 'on')
 953            //{
 954            //    $showScriptName = 'false';
 955            //}
 956            //else
 957            //{
 958            $showScriptName = 'true';
 959            //}
 960            if (stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false)
 961            {
 962                $sURLFormat='path';
 963            }
 964            else
 965            {
 966                $sURLFormat='get'; // Fall back to get if an Apache server cannot be determined reliably
 967            }
 968            
 969            $dbdata = "<?php if (!defined('BASEPATH')) exit('No direct script access allowed');" . "\n"
 970            ."/*"."\n"
 971            ."| -------------------------------------------------------------------"."\n"
 972            ."| DATABASE CONNECTIVITY SETTINGS"."\n"
 973            ."| -------------------------------------------------------------------"."\n"
 974            ."| This file will contain the settings needed to access your database."."\n"
 975            ."|"."\n"
 976            ."| For complete instructions please consult the 'Database Connection'" ."\n"
 977            ."| page of the User Guide."."\n"
 978            ."|"."\n"
 979            ."| -------------------------------------------------------------------"."\n"
 980            ."| EXPLANATION OF VARIABLES"."\n"
 981            ."| -------------------------------------------------------------------"."\n"
 982            ."|"                                                                    ."\n"
 983            ."|	'connectionString' Hostname, database, port and database type for " ."\n"
 984            ."|	 the connection. Driver example: mysql. Currently supported:"       ."\n"
 985            ."|				 mysql, pgsql, mssql, sqlite, oci"                      ."\n"
 986            ."|	'username' The username used to connect to the database"            ."\n"
 987            ."|	'password' The password used to connect to the database"            ."\n"
 988            ."|	'tablePrefix' You can add an optional prefix, which will be added"  ."\n"
 989            ."|				 to the table name when using the Active Record class"  ."\n"
 990            ."|"                                                                    ."\n"
 991            ."*/"                                                                   ."\n"
 992            . "return array("                             . "\n"
 993            ."\t"     . "'basePath' => dirname(dirname(__FILE__))," . "\n"
 994            ."\t"     . "'runtimePath' => dirname(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'tmp'.DIRECTORY_SEPARATOR.'runtime'," . "\n"
 995            ."\t"     . "'name' => 'LimeSurvey',"                   . "\n"
 996            ."\t"     . "'defaultController' => 'survey',"          . "\n"
 997            ."\t"     . ""                                          . "\n"
 998
 999            ."\t"     . "'import' => array("                        . "\n"
1000            ."\t\t"   . "'application.core.*',"                     . "\n"
1001            ."\t\t"   . "'application.models.*',"                   . "\n"
1002            ."\t\t"   . "'application.controllers.*',"              . "\n"
1003            ."\t\t"   . "'application.modules.*',"                  . "\n"
1004            ."\t"     . "),"                                        . "\n"
1005            ."\t"     . ""                                          . "\n"
1006
1007            ."\t"     . "'components' => array("                    . "\n"
1008            ."\t\t"   . "'db' => array("                            . "\n"
1009            ."\t\t\t" . "'connectionString' => '$sDsn',"            . "\n";
1010            if ($sDatabaseType!='sqlsrv')
1011            {
1012                $dbdata .="\t\t\t" . "'emulatePrepare' => true,"    . "\n";
1013
1014            }
1015            $dbdata .="\t\t\t" . "'username' => '$sDatabaseUser',"  . "\n"
1016            ."\t\t\t" . "'password' => '$sDatabasePwd',"            . "\n"
1017            ."\t\t\t" . "'charset' => 'utf8',"                      . "\n"
1018            ."\t\t\t" . "'tablePrefix' => '$sDatabasePrefix',"      . "\n";
1019
1020            if (in_array($sDatabaseType, array('mssql', 'sqlsrv'))) {
1021                $dbdata .="\t\t\t" ."'initSQLs'=>array('SET DATEFORMAT ymd;','SET QUOTED_IDENTIFIER ON;'),"    . "\n";
1022            }
1023
1024            $dbdata .="\t\t" . "),"                                          . "\n"
1025            ."\t\t"   . ""                                          . "\n"
1026
1027            ."\t\t"   . "// Uncomment the following line if you need table-based sessions". "\n"
1028            ."\t\t"   . "// 'session' => array ("                      . "\n"
1029            ."\t\t\t" . "// 'class' => 'system.web.CDbHttpSession',"   . "\n"
1030            ."\t\t\t" . "// 'connectionID' => 'db',"                   . "\n"
1031            ."\t\t\t" . "// 'sessionTableName' => '{{sessions}}',"     . "\n"
1032            ."\t\t"   . "// ),"                                        . "\n"
1033            ."\t\t"   . ""                                          . "\n"
1034
1035            /** @todo Uncomment after implementing the error controller */
1036            /*
1037            ."\t\t"   . "'errorHandler' => array("                  . "\n"
1038            ."\t\t\t" . "'errorAction' => 'error',"                 . "\n"
1039            ."\t\t"   . "),"                                        . "\n"
1040            ."\t\t"   . ""                                          . "\n"
1041            */
1042
1043            ."\t\t"   . "'urlManager' => array("                    . "\n"
1044            ."\t\t\t" . "'urlFormat' => '{$sURLFormat}',"           . "\n"
1045            ."\t\t\t" . "'rules' => require('routes.php'),"         . "\n"
1046            ."\t\t\t" . "'showScriptName' => $showScriptName,"      . "\n"
1047            ."\t\t"   . "),"                                        . "\n"
1048            ."\t"     . ""                                          . "\n"
1049
1050            ."\t"     . "),"                                        . "\n"
1051            ."\t"     . "// Use the following config variable to set modified optional settings copied from config-defaults.php". "\n"
1052            ."\t"     . "'config'=>array("                          . "\n"
1053            ."\t"     . "// debug: Set this to 1 if you are looking for errors. If you still get no errors after enabling this". "\n"
1054            ."\t"     . "// then please check your error-logs - either in your hosting provider admin panel or in some /logs directory". "\n"
1055            ."\t"     . "// on your webspace.". "\n"
1056            ."\t"     . "// LimeSurvey developers: Set this to 2 to additionally display STRICT PHP error messages and get full access to standard templates". "\n"
1057            ."\t\t"   . "'debug'=>0,"                                . "\n"
1058            ."\t\t"   . "'debugsql'=>0 // Set this to 1 to enanble sql logging, only active when debug = 2" . "\n"
1059            ."\t"     . ")"                                         . "\n"
1060            . ");"                                        . "\n"
1061            . "/* End of file config.php */"              . "\n"
1062            . "/* Location: ./application/config/config.php */";
1063
1064            if (is_writable(APPPATH . 'config')) {
1065                file_put_contents(APPPATH . 'config/config.php', $dbdata);
1066                Yii::app()->session['configFileWritten'] = true;
1067                $oUrlManager = Yii::app()->getComponent('urlManager');
1068                /* @var $oUrlManager CUrlManager */
1069                $oUrlManager->setUrlFormat($sURLFormat);
1070            } else {
1071                header('refresh:5;url='.$this->createUrl("installer/welcome"));
1072                echo "<b>".$clang->gT("Configuration directory is not writable")."</b><br/>";
1073                printf($clang->gT('You will be redirected in about 5 secs. If not, click <a href="%s">here</a>.' ,'unescaped'), $this->createUrl('installer/welcome'));
1074                exit;
1075            }
1076        }
1077    }
1078
1079    /**
1080    * Create a random ASCII string 
1081    *
1082    * @return string
1083    */
1084    function _getRandomString()
1085    {
1086        $totalChar = 64; // number of chars in the sid
1087        $sResult='';
1088        for ($i=0;$i<$totalChar;$i++)
1089        {
1090           $sResult.=chr(rand(33,126));
1091        }
1092        return $sResult;
1093    }
1094
1095    /**
1096    * Get the dsn for the database connection
1097    *
1098    * @param string $sDatabaseType
1099    * @param string $sDatabasePort
1100    */
1101    function _getDsn($sDatabaseType, $sDatabaseLocation, $sDatabasePort, $sDatabaseName, $sDatabaseUser, $sDatabasePwd)
1102    {
1103        switch ($sDatabaseType) {
1104            case 'mysql':
1105            case 'mysqli':
1106                $dsn = "mysql:host={$sDatabaseLocation};port={$sDatabasePort};dbname={$sDatabaseName};";
1107                break;
1108            case 'pgsql':
1109                if (empty($sDatabasePwd))
1110                {
1111                    // If there's no password, we need to write password=""; instead of password=;,
1112                    // or PostgreSQL's libpq will consider the DSN string part after "password="
1113                    // (including the ";" and the potential dbname) as part of the password definition.
1114                    $sDatabasePwd = '""';
1115                }
1116                $dsn = "pgsql:host={$sDatabaseLocation};port={$sDatabasePort};user={$sDatabaseUser};password={$sDatabasePwd};";
1117                if ($sDatabaseName!='')
1118                {
1119                    $dsn.="dbname={$sDatabaseName};";
1120                }
1121                break;
1122
1123            case 'mssql' :
1124            case 'sqlsrv':
1125                if ($sDatabasePort!=''){$sDatabaseLocation=$sDatabaseLocation.','.$sDatabasePort;}
1126                $dsn = $sDatabaseType.":Server={$sDatabaseLocation};Database={$sDatabaseName}";
1127                break;
1128            default:
1129                throw new Exception(sprintf('Unknown database type "%s".', $sDatabaseType));
1130        }
1131
1132        return $dsn;
1133    }
1134
1135    /**
1136    * Get the default port if database port is not set
1137    *
1138    * @param string $sDatabaseType
1139    * @param string $sDatabasePort
1140    * @return string
1141    */
1142    function _getDbPort($sDatabaseType, $sDatabasePort = '')
1143    {
1144        if (is_numeric($sDatabasePort))
1145            return $sDatabasePort;
1146
1147        switch ($sDatabaseType) {
1148            case 'mysql':
1149            case 'mysqli':
1150                $sDatabasePort = '3306';
1151                break;
1152            case 'pgsql':
1153                $sDatabasePort = '5432';
1154                break;
1155            case 'mssql' :
1156            case 'sqlsrv':
1157            default:
1158                $sDatabasePort = '';
1159        }
1160
1161        return $sDatabasePort;
1162    }
1163
1164    /**
1165    * Gets the database configuration from the session
1166    *
1167    * @return array Database Config
1168    */
1169    function _getDatabaseConfig()
1170    {
1171        $sDatabaseType = Yii::app()->session['dbtype'];
1172        $sDatabasePort = Yii::app()->session['dbport'];
1173        $sDatabaseName = Yii::app()->session['dbname'];
1174        $sDatabaseUser = Yii::app()->session['dbuser'];
1175        $sDatabasePwd = Yii::app()->session['dbpwd'];
1176        $sDatabasePrefix = Yii::app()->session['dbprefix'];
1177        $sDatabaseLocation = Yii::app()->session['dblocation'];
1178
1179        return compact('sDatabaseLocation', 'sDatabaseName', 'sDatabasePort', 'sDatabasePrefix', 'sDatabasePwd', 'sDatabaseType', 'sDatabaseUser');
1180    }
1181
1182    /**
1183    * Connect to the database
1184    *
1185    * Throw an error if there's an error
1186    */
1187    function _dbConnect($aDbConfig = array(), $aData = array())
1188    {
1189        extract(empty($aDbConfig) ? self::_getDatabaseConfig() : $aDbConfig);
1190        $sDsn = self::_getDsn($sDatabaseType, $sDatabaseLocation, $sDatabasePort, $sDatabaseName, $sDatabaseUser, $sDatabasePwd);
1191        $sDatabaseName = empty($sDatabaseName) ? '' : $sDatabaseName;
1192        $sDatabasePort = empty($sDatabasePort) ? '' : $sDatabasePort;
1193
1194        try {
1195 

Large files files are truncated, but you can click here to view the full file