<?php
/**
 * @package linea21.externals
 * @subpackage Class Installer
 * @author Vadim V. Gabriel <vadimg88@gmail.com> - modified by Simon Georget <simon@linea21.com>
 * @link http://www.vadimg.co.il/
 * @version 1.0.0a
 * @license GNU Lesser General Public License
 */

/** Load the template class **/
require_once(INSTALLER_PATH . '/Installer_Template.php');


/**
 * Class installer
 *
 */
class Installer
{
  /**
   * Options property
   *
   * @var array
   */
  protected $_options = array();

  /**
   * View object
   *
   * @var object
   */
  protected $view;

  /**
   * Language array
   *
   * @var array
   */
  protected $lang = array();

  protected $default_lang = U_L;

  /**
   * Constructor
   *
   */
  public function __construct()
  {
    # Do we have a cookie
    if(isset($_COOKIE['lang']) && $_COOKIE['lang'] != '')
    {
      $this->default_lang = $_COOKIE['lang'];
    }

    # Change language
    if(isset($_POST['lang']) && $_POST['lang'] != '' && $this->default_lang != $_POST['lang'])
    {
      $path = INSTALLER_PATH . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'lang' . DIRECTORY_SEPARATOR . $_POST['lang'] . '.php';

      $path = '../languages/' .$_POST['lang']. '/installer.utf-8.php';

      if(file_exists($path))
      {
        $this->default_lang = $_POST['lang'];
        @setcookie('lang', $this->default_lang, time() + 60 * 60 * 24);
        $_POST['lang'] = 0;
        $this->nextStep('index');
      }
    }

    # Load the language file
    require_once( '../languages/' .$this->default_lang. '/installer.utf-8.php' );

    $this->lang = $lang;

    # Load the template class
    $this->view = new Installer_Template($this->lang);
    
    # Are config files writable?
    if(!is_writable('../install/') || !is_writable('../install/installer/data/')) {
    	$this->view->error($this->lang['L-13']);
    }
    # Are config files writable?
    if(!is_writable('../config/define_release.ini') || !is_writable('../config/define_db.ini') ) {
    	$this->view->error($this->lang['L-12']);
    }

    # Did we run it again?
    if(file_exists(INSTALLER_PATH . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'installer.lock'))
    {
      $this->view->error($this->lang['L-01']);
    }

    $allwed_steps = array('index' => 'indexAction', 'db' => 'dbAction', 'cfg' => 'configAction', 'database' => 'dbTables', 'config' => 'configWrite', 'finish' => 'finishInstaller');
    if(!in_array($_POST['step'], array_keys($allwed_steps)))
    {
      $this->nextStep('index');
    }

    # Display the right step
    $this->$allwed_steps[$_POST['step']]($_POST);
  }

  /**
   * Show welcome message
   *
   */
  public function indexAction()
  {
    $_SESSION = array(); // unset session

    $options = CultureSelectBox('lang', $this->default_lang);

    $this->view->vars = array('options' => $options);
    $this->view->render('index');
  }

  /**
   * Show database setup stuff
   *
   */
  public function dbAction()
  {
    $this->view->render('db');
  }

  public function configAction()
  {
    $root_path = str_replace('install', '', ROOT_PATH);
    $root_url =str_replace('install/install.php', '', BASE_URL);
    $this->view->vars = array('root_url' => $root_url, 'path' => $root_path);
    $this->view->render('config');
  }

  /**
   * Handle DB table quries
   *
   * @param array $options
   */
  public function dbTables(array $options)
  {
    # Make sure we have an array of options
    if(!is_array($options))
    {
      $this->view->error($this->lang['L-02']);
    }
    # Make sure we have everything we need!
    $required_db_options = array('dbtype', 'dbname', 'dbuser', 'dbpass', 'dbhost');
    foreach ($required_db_options as $required_db_option)
    {
      // set in session
      if(isset($_SESSION[$required_db_option])) unset ($_SESSION[$required_db_option]);
      $_SESSION[$required_db_option] = $options[$required_db_option];

      if(!isset($options[$required_db_option]))
      {
        $this->view->error($this->lang['L-03']);
      }
    }

    # Pass in to the options property
    $this->_options = $options;

    if($this->_options['dbtype']=='mysql') {
      # First test the connection
      $link = mysql_connect($this->_options['dbhost'], $this->_options['dbuser'], $this->_options['dbpass']);
      if(!$link)
      {
        $this->view->error($this->lang['L-04']);
      }

      # Select the DB
      $db_selected = mysql_select_db($this->_options['dbname'], $link);
      mysql_query("SET NAMES 'utf8'");
      if(!$db_selected && $this->_options['create_database']==0)
      {
        $this->view->error($this->lang['L-05']);
      }
      elseif (!$db_selected && $this->_options['create_database']==1)
      {
        # Create the DB
        $result = mysql_query("CREATE DATABASE {$this->_options['dbname']}", $link);
        if (!$result)
        {
          $this->view->error(sprintf($this->lang['L-06'], $this->_options['dbname'], htmlspecialchars(mysql_error())));
        } else {
          $db_selected = mysql_select_db($this->_options['dbname'], $link);
          mysql_query("SET NAMES 'utf8'");
        }
      }
    } elseif($this->_options['dbtype']=='pgsql') {
      $link= pg_connect('host=' .$this->_options['dbhost']. ' port=5432 dbname=' . $this->_options['dbname'] . ' user=' . $this->_options['dbuser']. ' password='  . $this->_options['dbpass']);
      if(!$link)
      {
        $this->view->error($this->lang['L-04']);
      }

    }

    # Load the database stuff
    require_once( '../languages/' .$this->default_lang. '/installer_input.utf-8.php' );
    $path = INSTALLER_PATH . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'database.php' ;
    if(!file_exists($path))
    {
      $this->view->error(sprintf($this->lang['L-07'], $path));
    }

    $SQL = array();
    require_once($path);

    $count = 0;
    $errors_count = 0;

    # Loop if we have any
    if(count($SQL))
    {
      # Start the count

      $errors = array();
      foreach ($SQL as $query)
      {
        if($this->_options['dbtype'] == 'mysql')  $result = mysql_query($query, $link);
        else $result = pg_query($link, $query);

        if (!$result)
        {
          if($this->_options['dbtype'] == 'mysql')  $errors[] = sprintf($this->lang['L-08'], htmlspecialchars(mysql_error()));
          else $errors[] = sprintf($this->lang['L-08'], htmlspecialchars(pg_last_error()));
          $errors_count++;
          continue;
        }

        # Increase it
        $count++;
      }
    }

    $error_string = '';

    # Did we had any errors?
    if(count($errors))
    {
      $error_string = "<br /><br />".sprintf($this->lang['I-14'], implode("<br /><br />", $errors));
    }

    # Redirect
    $this->view->vars = array('message' => sprintf($this->lang['L-09'], $count, $errors_count, $error_string), 'button' => $error_string ? $this->lang['I-16'] : $this->lang['I-03']);
    $this->view->render('dbdone');

  }

  /**
   * Display everything
   *
   */
  public function display()
  {
    $this->view->display();
  }

  /**
   * Write the configuration File
   *
   */
  public function configWrite()
  {
    include_once('../class/class.config_file.php');

    $config_file = new config_file;

    // update DB settings
    $ini_db=array();
    $ini_db['DB_NAME']=$_SESSION['dbname'];
    $ini_db['DB_USER']=$_SESSION['dbuser'];
    $ini_db['DB_PASS']=$_SESSION['dbpass'];
    $ini_db['DB_HOST']=$_SESSION['dbhost'];

    // update main ini file
    $ini_r=array();

    $ini_r['LANGUAGE']=$this->default_lang;
    if(substr($this->default_lang, 0, 2) == 'en') $ini_r['DATE_FORMAT']="yyyy-mm-dd";
    else $ini_r['DATE_FORMAT']="dd-mm-yyyy";
    $ini_r['SITE_NAME']=$_POST['SITE_NAME'];
    $ini_r['SITE_PATH']=$_POST['SITE_PATH'];
    $ini_r['SITE_ROOT_URL']=$_POST['SITE_ROOT_URL'];

    // mail settings
    $ini_r['SITE_MAIL']=$_POST['MAIL_FROM'];
    $ini_r['MAIL_FROM']=$_POST['MAIL_FROM'];
    $ini_r['MAIL_FROMNAME']=$_POST['MAIL_FROMNAME'];
    $ini_r['MAIL_REPLY']=$_POST['MAIL_FROM'];
    $ini_r['MAIL_REPLYNAME']=$_POST['MAIL_FROMNAME'];
    $ini_r['SQL']=$_SESSION['dbtype'];

    $config_file->setParams('define_release',$ini_r);
    $config_file->setParams('define_db',$ini_db);


    $config_file->writeDbParams();
    $config_file->writeReleaseParams();

    $this->finishInstaller();
  }

  /**
   * Finish the installer proccess
   *
   */
  public function finishInstaller()
  {
    # Lock the installer
    $path = INSTALLER_PATH . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . 'installer.lock';
    file_put_contents($path, "installer lock file");
    $_SESSION = array();
    $this->view->render('finish');
  }

  /**
   * Redirect to the next step
   *
   * @param string $step
   */
  public function nextStep($step)
  {
    $url = BASE_URL . '?step='.$step;
    if(!headers_sent())
    {
      header('Location: '. $url);
      exit;
    }

    print "<html><body><meta http-equiv='refresh' content='1;url={$url}'></body></html>";
    exit;
  }

  /**
   * Redirect screen with a message
   *
   * @param string $message
   */
  public function redirectScreen($message, $step)
  {
    $this->view->redirect($message, $step);
  }


  /**
   * Destructor
   *
   */
  public function __destruct()
  {


    @mysql_close();
    @pg_close();
    # Clear
    unset($this);
  }

}