<?php
/**
 * @package linea21.loader
 * @author Simon Georget <simon@linea21.com>
 * @version $id SVN
 * @access public
 * @license http://opensource.org/licenses/gpl-3.0.html
 */
ob_start();
@set_time_limit(0);
error_reporting(E_ALL);

// defines
define('SITE_LINEA_URL', 'http://www.linea21.com');
define('USER_AGENT', 'Linea21 - Loader/0.4 (https://www.linea21.com)');
define('REFERER', $_SERVER["HTTP_HOST"].' Linea21 - Loader/0.4');
define('ZIP_FILE', '_tmp.zip');
define('BASE_PATH', dirname(__FILE__).'/');
define('END_LINE', "<br />");
define('PERFORM_TEST', true);
// TARGET_URL is set later - do not uncomment the following line
// U_L is defined later

# localized input
$lang = array(
		'en' => array(
                'already_installed' => '<em class="b">Linea21 seems to be already installed.</em>',
				'pre-requisites' => 'pre-requisites',
                'connection_failed' => 'Unable to connect to <em>%s</em>.',
                'OK' => '<em class="g">OK</em>',
                'not_OK' => '<em class="b">not OK</em>',
                'php_version' => 'PHP version >= 7.3',
                'is_writable' => 'Folder is writable',
				'simplexml_ext' => 'SimpleXML extension',
				'gd_ext' => 'GD extension',
				'mysqli_ext' => 'MySQLi extension',
				'zip_ext' => 'ZIP extension',
                'curl_ext' => 'cURL extension',
				'check_not_ok' => 'Sorry, settings do not allow the Loader to run correctly.',
                'dl_latest' => 'Downloading latest stable version',
                'dl_from' => 'Downloading from',
                'curl_error_no' => 'cURL error number',
				'curl_error_msg' => 'cURL error message',
                'zip_extract' => 'Extracting <em>%s</em> to <em>%s</em>',
				'del_msg' => 'Deleting <em>%s</em>',
                'succeed' => '<em class="g">succeed</em>',
				'failed' => '<em class="b">failed</em>',
                'end_up' => ' <em class="b">The automatic installation ended up. Please, change current settings or download Linea21 manually.</em>',
                'delete_loader' => 'Do not forget to delete <em>loader.php</em> file.',
                'go_on' => 'Téléchargement terminé, poursuivre l\'installation !'
),
        'fr' => array(
                'already_installed' => '<em class="b">Linea21 semble déjà installé.</em>',
				'pre-requisites' => 'Pré-requis',
                'connection_failed' => 'Connexion à <em>%s</em> impossible.',
                'OK' => '<em class="g">OK</em>',
                'not_OK' => '<em class="b">non OK</em>',
                'php_version' => 'PHP version >= 7.3',
                'is_writable' => 'Permissions en écriture sur le dossier',
				'simplexml_ext' => 'extension SimpleXML',
				'gd_ext' => 'extension GD',
				'mysqli_ext' => 'extension MySQLi',
				'zip_ext' => 'extension ZIP',
                'curl_ext' => 'extension cURL',
				'check_not_ok' => 'Desolé, la configuration actuelle ne permet pas de lançer le Loader.',
                'dl_latest' => 'Téléchargement de la dernière version stable',
                'dl_from' => 'Téléchargement depuis',
                'curl_error_no' => 'erreur cURL numéro',
				'curl_error_msg' => 'message d\'erreur cURL',
                'zip_extract' => 'Extraction de <em>%s</em> vers <em>%s</em>',
				'del_msg' => 'Suppression de <em>%s</em>',
                'succeed' => '<em class="g">succès</em>',
				'failed' => '<em class="b">échec</em>',
                'end_up' => ' <em class="b">L\'installation automatique a été stoppée. Veuillez modifier vos paramètres ou installer Linea21 manuellement.</em>',
                'delete_loader' => 'N\'oubliez pas de supprimer le fichier <em>loader.php</em>.',
                'go_on' => 'Téléchargement terminé, poursuivre l\'installation !'
)
);

$language = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],0,2));
if(!in_array($language, array_keys($lang))) $language = 'en';
define('U_L', $language);
$check = true;

// display localized message
function _t($var) {
  global $lang;

  return $lang[U_L][$var];
}

// buffer flush
function fl(){
  @ob_end_flush();
  @ob_flush();
  @flush();
  @ob_start();
}

// check if given extension is loaded
function check_ext($ext) {
  global $check;

  if (!extension_loaded($ext)) {
    $check = false;
    return _t('not_OK');
  } else {
    return _t('OK');
  }
}
// check PHP version
function check_php() {
	global $check;
	
  if (version_compare(PHP_VERSION, '7.3.0', '>=')) {
    return _t('OK'). ' ('.PHP_VERSION.')';
  } else {
	  $check = false;
    return _t('not_OK'). ' ('.PHP_VERSION.')';
  }
}

// check writable file/folder
function check_writable() {
  global $check;

  if (!is_writable(__DIR__)) {
    $check = false;
    return _t('not_OK');
  } else {
    return _t('OK');
  }
}

/**
 * This method unzips a directory within a zip-archive
 * @author Florian Wolf
 * @license LGPL v2 or later
 */
function extractZip( $zipFile = '', $dirFromZip = '' )
{
  define(DIRECTORY_SEPARATOR, '/');

  $zipDir = getcwd() . DIRECTORY_SEPARATOR;
  $zip = zip_open($zipDir.$zipFile);

  if ($zip)
  {
    while ($zip_entry = zip_read($zip))
    {
      //  $completePath = $zipDir . dirname(zip_entry_name($zip_entry));
      //  $completeName = $zipDir . zip_entry_name($zip_entry);
      $completePath = str_replace('linea21/', '', $zipDir . dirname(zip_entry_name($zip_entry)));
      $completeName = str_replace('linea21/', '', $zipDir . zip_entry_name($zip_entry));
       
      // Walk through path to create non existing directories
      // This won't apply to empty directories ! They are created further below
      if(!file_exists($completePath) && preg_match( '#^' . $dirFromZip .'.*#', dirname(zip_entry_name($zip_entry)) ) )
      {
        $tmp = '';
        foreach(explode('/',$completePath) AS $k)
        {
          $tmp .= $k.'/';
          if(!file_exists($tmp) )
          {
            @mkdir($tmp, 0777);
          }
        }
      }
       
      if (zip_entry_open($zip, $zip_entry, "r"))
      {
        if( preg_match( '#^' . $dirFromZip .'.*#', dirname(zip_entry_name($zip_entry)) ) )
        {
          if ($fd = @fopen($completeName, 'w+'))
          {
            fwrite($fd, zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)));
            fclose($fd);
          }
          else
          {
            // We think this was an empty directory - modified @simo
            if(!file_exists($completeName)) mkdir($completeName, 0777);
          }
          zip_entry_close($zip_entry);
        }
      }
    }
    zip_close($zip);
  }
  return true;
}
?>
<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Strict//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php echo U_L; ?>"
	lang="<?php echo U_L; ?>">
<head>
<title><?php echo USER_AGENT; ?></title>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
<style type='text/css'>
body {
	background-color: #242631;
	color: #bdbdbd;
	margin: 5% 20%;
	font-family: Verdana, Arial, Sans, sans-serif;
}

a {
	color: #B32CD9;
	text-decoration: none;
}

a:hover {
	color: #D073EA;
	text-decoration: underline;
}

em.g {
	color: #4d85bd;
	font-style: normal;
	font-weight:bold;
}

em.b {
	color: #c65252;
	font-style: normal;
	font-weight:bold;
}

h2 {
	color: #ddb664;
	margin-bottom: 0;
}

h1 {
	color: #737580;
	margin: 0;
	font-size: 130%;
}
</style>
</head>
<body>
<h1><?php echo USER_AGENT; ?></h1>
<?php
### Step 0
if(file_exists('./config/config.ini')) die(_t('already_installed'));


### Step 1
?>
<?php if(PERFORM_TEST == true) { ?>
<h2><?php echo _t('pre-requisites'); ?></h2>

<?php
echo _t('php_version'). ' : ' .check_php().END_LINE;
echo _t('mysqli_ext'). ' : ' . check_ext('mysqli').END_LINE;
echo _t('gd_ext'). ' : ' . check_ext('gd').END_LINE;
echo _t('simplexml_ext'). ' : ' . check_ext('simplexml').END_LINE;
echo _t('zip_ext'). ' : ' . check_ext('zip').END_LINE;
echo _t('curl_ext'). ' : ' . check_ext('curl').END_LINE;
echo _t('is_writable'). ' : ' . check_writable().END_LINE;

$check === false ? die (_t('check_not_ok'). _t('end_up')): '';
fl();
} // PERFORM_TEST end
?>

<?php
### Step 2
// Get the latest stable version link (zip format)
if(!@$xml=simplexml_load_file(SITE_LINEA_URL.'/linea_version.xml')){
  die( _t('connection_failed'). _t('end_up'));
} else   {
  if(! defined('TARGET_URL')) define('TARGET_URL', $xml->zipfile);
}
?>

<h2><?php echo _t('dl_latest'); ?></h2>
<?php
echo _t('dl_from'). ' <em>'. TARGET_URL.'</em>';
fl();
// cURL request
$fp = fopen(ZIP_FILE, "w");
$h = curl_init();
curl_setopt($h, CURLOPT_USERAGENT, USER_AGENT);
curl_setopt($h, CURLOPT_URL,TARGET_URL);
curl_setopt($h, CURLOPT_FAILONERROR, true);
curl_setopt($h, CURLOPT_HEADER,0);
curl_setopt($h, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($h, CURLOPT_AUTOREFERER, false);
curl_setopt($h, CURLOPT_REFERER, REFERER);
curl_setopt($h, CURLOPT_TIMEOUT, 1000);
curl_setopt($h, CURLOPT_FILE, $fp);

$curl_res = curl_exec($h);

if (!$curl_res) {
  echo ' : '.  _t('failed').END_LINE;
  echo '<p class="b">';
  echo  _t('curl_error_no'). ' : ' .curl_errno($h).END_LINE;
  echo  _t('curl_error_msg'). ' : ' . curl_error($h);
  echo '</p>';
  die(_t('end_up'));
} else {
  echo ' : '.  _t('succeed').END_LINE;
}
curl_close($h);
// because of PHP bug http://bugs.php.net/bug.php?id=48676
// close $fp twice!
@fclose($fp);
@fclose($fp);
fl();



### Step 3
### Extracting zip file and cleaning
echo '<em>'.ZIP_FILE . '</em> : chmod ';
echo @chmod(ZIP_FILE, 777) == true ? _t('succeed').END_LINE : _t('failed').END_LINE;

echo sprintf(_t('zip_extract'), ZIP_FILE, BASE_PATH). ' : ';
fl();

// Un zip the file
/**
 * This is only available from PHP 5.2
 * unzip file to ./linea21/
 * to make this work correctly files have to move to ./
$zip = new ZipArchive;
$res = $zip->open(ZIP_FILE);
if ($res === TRUE) {
    $zip->extractTo('./');
    $zip->close();
    echo _t('succeed').END_LINE;
} else {
	echo _t('failed'). '('. $res . ')'.END_LINE;
}
* */
if(extractZip(ZIP_FILE) === true) echo _t('succeed').END_LINE; else echo _t('failed').END_LINE;

fl();

// deleting old files and ZIP archive)
echo sprintf(_t('del_msg').' : ', BASE_PATH.'linea21');
if(@rmdir(BASE_PATH.'linea21')) echo _t('succeed').END_LINE; else echo _t('failed').END_LINE;
echo sprintf(_t('del_msg').' : ', ZIP_FILE);
if(@unlink(ZIP_FILE)) echo _t('succeed').END_LINE; else echo _t('failed').END_LINE;


### Step 4
### Follow up on DB Install and set-up
?>
<p>&gt;&gt; <a href="./install/install.php"><?php echo _t('go_on'); ?></a></p>
<p class="info"><?php echo _t('delete_loader'); ?></p>
</body>
</html>
<?php ob_end_flush(); ?>