Merge branch 'features/install' into 'master'

Page d'installation

Comme pas mal de monde a encore du mal avec composer, voici une page permettant de rendre simple l'installation.

Le script va :
* télécharger composer et l'utiliser directement en PHP (sans exec, en passant par les classes du PHAR)
* copier le fichier de config de template et remplacer les variables par les données indiquées par l'utilisateur
* insérer la base de données

Au passage, on passe plus sur du PDO au lieu des mysql_* afin d'éviter des erreurs de deprecated (mysql est toujours possible via le fichier d'installation)

See merge request !26
This commit is contained in:
JosephK 2014-12-03 11:30:59 +01:00
commit bbe89ad5c4
11 changed files with 366 additions and 8 deletions

View File

@ -20,11 +20,8 @@
// FRAMADATE version
const VERSION = 0.8;
// Server name
const STUDS_URL = '<www.mydomain.com>';
// Application name
const NOMAPPLICATION = "<Application name>";
const NOMAPPLICATION = '<Application name>';
// Database administrator email
const ADRESSEMAILADMIN = '<email address>';
@ -36,7 +33,7 @@ const ADRESSEMAILREPONSEAUTO = '<no-reply@mydomain.com>';
const BASE = '<database name>';
// Database user
const USERBASE = "<database user>";
const USERBASE = '<database user>';
// Database password
const USERPASSWD = '<database password>';

View File

@ -23,9 +23,16 @@ if (ini_get('date.timezone') == '') {
// Autoloading of dependencies with Composer
require_once __DIR__ . '/../../vendor/autoload.php';
include_once __DIR__ . '/constants.php';
include_once __DIR__ . '/i18n.php';
require_once __DIR__ . '/constants.php';
require_once __DIR__ . '/i18n.php';
$connect = NewADOConnection(BASE_TYPE);
$connect->Connect(SERVEURBASE, USERBASE, USERPASSWD, BASE);
if ('pdo' === BASE_TYPE) {
$database_host = 'mysql:host='.SERVEURBASE;
} else {
$database_host = SERVEURBASE;
}
$connect->Connect($database_host, USERBASE, USERPASSWD, BASE);
$err = 0;

View File

@ -0,0 +1,90 @@
<?php
class InstallComposer
{
/**
* @var string
*/
private $composer;
/**
* @return bool
*/
public function check()
{
return file_exists(dirname(__DIR__).'/vendor/autoload.php');
}
public function install()
{
require_once 'phar://'.$this->getComposer().'/src/bootstrap.php';
$this->initEnv();
$application = new \Composer\Console\Application();
$application->setAutoExit(false);
$input = new \Symfony\Component\Console\Input\ArrayInput(array(
'command' => 'install',
'-d' => __DIR__.'/..',
'-vvv',
'--optimize-autoloader',
));
$output = new \Symfony\Component\Console\Output\NullOutput();
$application->run($input, $output);
}
/**
* @return string
*/
private function getComposer()
{
if (null === $this->composer) {
$this->initComposer();
}
return $this->composer;
}
private function initComposer()
{
// Composer exist ?
$locations = array(
__DIR__.'/../composer.phar',
'/usr/bin/composer.phar',
'/usr/local/bin/composer.phar',
);
$this->composer = null;
foreach ($locations as $location) {
if (file_exists($location) === true) {
$this->composer = $location;
break;
}
}
// If composer not found, download it !
if (null === $this->composer) {
if (!file_put_contents(
__DIR__.'/../composer.phar',
file_get_contents('https://getcomposer.org/composer.phar')
)
) {
throw new \Exception('Impossible to download composer');
}
$this->composer = __DIR__.'/../composer.phar';
}
}
private function initEnv()
{
$composer_home = getenv('COMPOSER_HOME');
$personal_home = getenv('HOME');
if (empty($composer_home) === true && empty($personal_home) === true) {
putenv('COMPOSER_HOME='.sys_get_temp_dir());
}
}
}

View File

@ -0,0 +1,73 @@
<?php
class InstallConfiguration
{
/**
* @var array
*/
private $datas;
/**
* @var array
*/
private $checks = array(
'title' => 'Application name',
'email' => 'email address',
'no-reply-email' => 'no-reply@mydomain.com',
'db-name' => 'database name',
'db-user' => 'database user',
'db-pass' => 'database password',
'db-host' => 'database server',
'db-type' => 'database type',
);
/**
* @param array $datas
*/
public function __construct(array $datas)
{
$this->datas = $datas;
}
/**
* @return bool
*/
public function checkValues()
{
foreach (array_keys($this->checks) as $key) {
if (isset($this->datas[$key]) === false) {
return false;
}
}
return true;
}
public function copy($template, $destination)
{
$configuration = file_get_contents($template);
if (false === $configuration) {
throw new \Exception('Impossible to read template configuration');
}
$configuration = $this->convertConfigurationFile($configuration);
if (file_put_contents($destination, $configuration) === false) {
throw new \Exception('Impossible to save configuration');
}
}
private function convertConfigurationFile($content)
{
foreach ($this->checks as $replace => $search) {
$content = str_replace(
'\'<'.$search.'>\'',
var_export($this->datas[$replace], true),
$content
);
}
return $content;
}
}

24
install/InstallSql.php Normal file
View File

@ -0,0 +1,24 @@
<?php
class InstallSql
{
public function inject()
{
require_once __DIR__.'/../app/inc/init.php';
if ($connect->ErrorMsg() !== '') {
throw new \Exception('Bad database configuration : '.$connect->ErrorMsg());
}
$sqls = explode("\n", file_get_contents(__DIR__.'/install.mysql.auto.sql'));
foreach ($sqls as $sql) {
$sql = trim($sql);
if (empty($sql) === true) {
continue;
}
$query = $connect->Prepare($sql);
$cleaning = $connect->Execute($query);
}
}
}

33
install/error.html Normal file
View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>OpenSondage Installation</title>
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/style.css">
<link rel="stylesheet" href="../css/frama.css">
<link rel="stylesheet" href="install.css">
</head>
<body>
<div class="container ombre">
<header role="banner">
<h1>
<img src="../images/logo-framadate.png" width="360" height="50" alt="OpenSondage" />
</h1>
<h2>Make your polls</h2>
<hr class="trait" role="presentation">
</header>
<main role="main">
<h3>OpenSondage Installation</h3>
<div class="alert alert-danger" role="alert">
<?php echo htmlspecialchars($e->getMessage(), ENT_COMPAT | ENT_HTML401, 'UTF-8') ?>
</div>
<div class="alert alert-info" role="alert">
<pre>
<?php echo htmlspecialchars($e->getTraceAsString(), ENT_COMPAT | ENT_HTML401, 'UTF-8') ?>
</pre>
</div>
</main>
</div>
</body>
</html>

11
install/install.css Normal file
View File

@ -0,0 +1,11 @@
header {
padding-bottom: 0;
}
main {
padding-top: 0;
}
fieldset {
margin: 1.5em 0;
}

72
install/install.html Normal file
View File

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>OpenSondage Installation</title>
<link rel="stylesheet" href="../css/bootstrap.min.css">
<link rel="stylesheet" href="../css/style.css">
<link rel="stylesheet" href="../css/frama.css">
<link rel="stylesheet" href="install.css">
</head>
<body>
<div class="container ombre">
<header role="banner">
<h1>
<img src="../images/logo-framadate.png" width="360" height="50" alt="OpenSondage" />
</h1>
<h2>Make your polls</h2>
<hr class="trait" role="presentation">
</header>
<main role="main">
<h3>OpenSondage Installation</h3>
<form action="" method="post" role="form">
<fieldset>
<legend>General</legend>
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" name="title" placeholder="Application name" required>
</div>
<div class="form-group">
<label for="email">Administrator email</label>
<input type="email" class="form-control" id="email" name="email" placeholder="Email of the administrator" required>
</div>
<div class="form-group">
<label for="no-reply-email">No-reply email</label>
<input type="email" class="form-control" id="no-reply-email" name="no-reply-email" placeholder="Email for automatic responses" required>
</div>
</fieldset>
<fieldset>
<legend>Database</legend>
<div class="form-group">
<label for="db-type">Type</label>
<select name="db-type" id="db-type" required>
<option value="pdo">PDO - MySQL (recommanded)</option>
<option value="mysql">MySQL</option>
</select>
</div>
<div class="form-group">
<label for="db-host">Host</label>
<input type="text" class="form-control" id="db-host" name="db-host" value="localhost" required>
</div>
<div class="form-group">
<label for="db-name">Database name</label>
<input type="text" class="form-control" id="db-name" name="db-name" value="opensondage" required>
</div>
<div class="form-group">
<label for="db-user">Username</label>
<input type="text" class="form-control" id="db-user" name="db-user" value="root" required>
</div>
<div class="form-group">
<label for="db-pass">Password</label>
<input type="password" class="form-control" id="db-pass" name="db-pass" value="">
</div>
</fieldset>
<input type="submit" class="btn btn-success" name="install" value="Install">
</form>
</main>
</div>
</body>
</html>

View File

@ -0,0 +1,8 @@
CREATE TABLE IF NOT EXISTS `comments` (`id_comment` int(11) unsigned NOT NULL AUTO_INCREMENT, `id_sondage` char(16) NOT NULL, `comment` text NOT NULL, `usercomment` text, PRIMARY KEY (`id_comment`), KEY `id_sondage` (`id_sondage`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `sondage` (`id_sondage` char(16) NOT NULL, `commentaires` text, `mail_admin` varchar(128) DEFAULT NULL, `nom_admin` varchar(64) DEFAULT NULL, `titre` text, `id_sondage_admin` char(24) DEFAULT NULL, `date_creation` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `date_fin` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `format` varchar(2) DEFAULT NULL, `mailsonde` tinyint(1) DEFAULT '0', `statut` int(11) NOT NULL DEFAULT '1' COMMENT '1 = actif ; 0 = inactif ; ', UNIQUE KEY `id_sondage` (`id_sondage`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `sujet_studs` (`id_sondage` char(16) NOT NULL, `sujet` text, KEY `id_sondage` (`id_sondage`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `user_studs` (`id_users` int(11) unsigned NOT NULL AUTO_INCREMENT, `nom` varchar(64) NOT NULL, `id_sondage` char(16) NOT NULL, `reponses` text NOT NULL, PRIMARY KEY (`id_users`), KEY `id_sondage` (`id_sondage`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ;
INSERT INTO `sondage` (`id_sondage`, `commentaires`, `mail_admin`, `nom_admin`, `titre`, `id_sondage_admin`, `date_fin`, `format`) VALUES ('aqg259dth55iuhwm','Repas de Noel du service','Stephanie@retaillard.com','Stephanie', 'Repas de Noel','aqg259dth55iuhwmy9d8jlwk', FROM_UNIXTIME('1627100361'),'D+');
INSERT INTO `sujet_studs` (`id_sondage`, `sujet`) VALUES ('aqg259dth55iuhwm','1225839600@12h,1225839600@19h,1226012400@12h,1226012400@19h,1226876400@12h,1226876400@19h,1227049200@12h,1227049200@19h,1227826800@12h,1227826800@19h');
INSERT INTO `user_studs` (`nom`, `id_sondage`, `reponses`, `id_users`) VALUES ('marcel','aqg259dth55iuhwm','0110111101','933'), ('paul','aqg259dth55iuhwm','1011010111','935'), ('sophie','aqg259dth55iuhwm','1110110000','945'), ('barack','aqg259dth55iuhwm','0110000','948'), ('takashi','aqg259dth55iuhwm','0000110100','951'), ('albert','aqg259dth55iuhwm','1010110','975'), ('alfred','aqg259dth55iuhwm','0110010','1135'), ('marcs','aqg259dth55iuhwm','0100001010','1143'), ('laure','aqg259dth55iuhwm','0011000','1347'), ('benda','aqg259dth55iuhwm','1101101100','1667'), ('Albert','aqg259dth55iuhwm','1111110011','1668');

43
install/install.php Normal file
View File

@ -0,0 +1,43 @@
<?php
require_once __DIR__.'/InstallComposer.php';
require_once __DIR__.'/InstallConfiguration.php';
require_once __DIR__.'/InstallSql.php';
$configuration_file = __DIR__.'/../app/inc/constants.php';
if (file_exists($configuration_file) === true) {
header('Location: ../index.php');
exit;
}
if (isset($_POST['install']) === true) {
try {
// Composer installation
$composer = new InstallComposer();
if ($composer->check() === false) {
ini_set('max_execution_time', 0);
$composer->install();
}
// Save configuration
$configuration = new InstallConfiguration($_POST);
if ($configuration->checkValues() === false) {
throw new \Exception('Bad value for configuration');
}
$configuration->copy($configuration_file.'.template', $configuration_file);
// Inject database
$sql = new InstallSql();
$sql->inject();
header('Location: ../index.php');
die();
} catch (Exception $e) {
require_once __DIR__.'/error.html';
die();
}
}
require_once __DIR__.'/install.html';