diff --git a/admin/install.php b/admin/install.php
new file mode 100644
index 0000000000000000000000000000000000000000..9240f14783465115666ecaf1aaf50ee85a4d8ec5
--- /dev/null
+++ b/admin/install.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * This software is governed by the CeCILL-B license. If a copy of this license
+ * is not distributed with this file, you can obtain one at
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
+ *
+ * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
+ * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
+ *
+ * =============================
+ *
+ * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
+ * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
+ *
+ * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
+ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
+ */
+
+use Framadate\Services\InstallService;
+use Framadate\Utils;
+
+require_once '../app/inc/init.php';
+
+if (is_file(CONF_FILENAME)) {
+    header(('Location: ' . Utils::get_server_name()));
+    exit;
+}
+
+$error = null;
+$installService = new InstallService();
+
+if (!empty($_POST)) {
+    $installService->updateFields($_POST);
+    $result = $installService->install($smarty);
+
+    if ($result['status'] === 'OK') {
+        header(('Location: ' . Utils::get_server_name() . 'admin/migration.php'));
+        exit;
+    } else {
+        $error = __('Error', $result['code']);
+    }
+}
+
+$smarty->assign('error', $error);
+$smarty->assign('title', __('Admin', 'Installation'));
+$smarty->assign('fields', $installService->getFields());
+$smarty->display('admin/install.tpl');
\ No newline at end of file
diff --git a/app/classes/Framadate/Services/InstallService.php b/app/classes/Framadate/Services/InstallService.php
new file mode 100644
index 0000000000000000000000000000000000000000..0db9f1f8c8562e1c862048fc40fb9eac7027c65c
--- /dev/null
+++ b/app/classes/Framadate/Services/InstallService.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * This software is governed by the CeCILL-B license. If a copy of this license
+ * is not distributed with this file, you can obtain one at
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
+ *
+ * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
+ * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
+ *
+ * =============================
+ *
+ * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
+ * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
+ *
+ * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
+ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
+ */
+namespace Framadate\Services;
+use Framadate\Utils;
+use Smarty;
+
+/**
+ * This class helps to clean all inputs from the users or external services.
+ */
+class InstallService {
+
+    private $fields = array(
+        // General
+        'appName' => 'Framadate',
+        'appMail' => '',
+        'responseMail' => '',
+        'defaultLanguage' => 'fr',
+        'cleanUrl' => true,
+
+        // Database configuration
+        'dbConnectionString' => 'mysql:host=<HOST>;dbname=<SCHEMA>;port=3306',
+        'dbUser' => 'root',
+        'dbPassword' => '',
+        'dbPrefix' => 'fd_',
+        'migrationTable' => 'framadate_migration'
+    );
+
+    function __construct() {}
+
+    public function updateFields($data) {
+        foreach ($data as $field => $value) {
+            $this->fields[$field] = $value;
+        }
+    }
+
+    public function install(Smarty &$smarty) {
+        // Check values are present
+        if (empty($this->fields['appName']) || empty($this->fields['appMail']) || empty($this->fields['defaultLanguage']) || empty($this->fields['dbConnectionString']) || empty($this->fields['dbUser'])) {
+            return $this->error('MISSING_VALUES');
+        }
+
+        // Connect to database
+        $connect = $this->connectTo($this->fields['dbConnectionString'], $this->fields['dbUser'], $this->fields['dbPassword']);
+        if (!$connect) {
+            return $this->error('CANT_CONNECT_TO_DATABASE');
+        }
+
+        // Write configuration to conf.php file
+        $this->writeConfiguration($smarty);
+
+        return $this->ok();
+    }
+
+    function connectTo($connectionString, $user, $password) {
+        try {
+            $pdo = @new \PDO($connectionString, $user, $password);
+            $pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
+            $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+            return $pdo;
+        } catch(\Exception $e) {
+            return null;
+        }
+    }
+
+    function writeConfiguration(Smarty &$smarty) {
+        foreach($this->fields as $field=>$value) {
+            $smarty->assign($field, $value);
+        }
+
+        $content = $smarty->fetch('admin/config.tpl');
+
+        $this->writeToFile($content);
+    }
+
+    /**
+     * @param $content
+     */
+    function writeToFile($content) {
+        file_put_contents(CONF_FILENAME, $content);
+    }
+
+    /**
+     * @return array
+     */
+    function ok() {
+        return array(
+            'status' => 'OK',
+            'msg' => __f('Installation', 'Ended', Utils::get_server_name())
+        );
+    }
+
+    /**
+     * @param $msg
+     * @return array
+     */
+    function error($msg) {
+        return array(
+            'status' => 'ERROR',
+            'code' => $msg
+        );
+    }
+
+    public function getFields() {
+        return $this->fields;
+    }
+
+}
diff --git a/app/classes/Framadate/Utils.php b/app/classes/Framadate/Utils.php
index 5eec8b55093f04f8ca905bd8c5c966fd15f06c38..aca9b9baedabc2e7a668184c2bf41009edc1fa6e 100644
--- a/app/classes/Framadate/Utils.php
+++ b/app/classes/Framadate/Utils.php
@@ -75,7 +75,7 @@ class Utils {
         <script type="text/javascript" src="' . self::get_server_name() . 'js/bootstrap-datepicker.js"></script>
         <script type="text/javascript" src="' . self::get_server_name() . 'js/locales/bootstrap-datepicker.' . $locale . '.js"></script>
         <script type="text/javascript" src="' . self::get_server_name() . 'js/core.js"></script>';
-        if (file_exists($_SERVER['DOCUMENT_ROOT'] . "/nav/nav.js")) {
+        if (is_file($_SERVER['DOCUMENT_ROOT'] . "/nav/nav.js")) {
             echo '<script src="/nav/nav.js" id="nav_js" type="text/javascript" charset="utf-8"></script><!-- /Framanav -->';
         }
 
diff --git a/app/inc/XXconfig.php b/app/inc/XXconfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..6530d1364b3d3abd1b9accc4e946665dcc4a3d6b
--- /dev/null
+++ b/app/inc/XXconfig.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ * This software is governed by the CeCILL-B license. If a copy of this license
+ * is not distributed with this file, you can obtain one at
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
+ *
+ * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
+ * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
+ *
+ * =============================
+ *
+ * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
+ * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
+ *
+ * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
+ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
+ */
+
+// Fully qualified domain name of your webserver.
+// If this is unset or empty, the servername is determined automatically.
+// You *have to set this* if you are running Framedate behind a reverse proxy.
+// const APP_URL = '<www.mydomain.fr>';
+
+// Application name
+const NOMAPPLICATION = 'Développement OPZ';
+
+// Database administrator email
+const ADRESSEMAILADMIN = 'framadate-dev@olivierperez.fr';
+
+// Email for automatic responses (you should set it to "no-reply")
+const ADRESSEMAILREPONSEAUTO = 'no-reply@olivierperez.fr';
+
+// Database user
+const DB_USER= 'dev_framadate';
+
+// Database password
+const DB_PASSWORD = 'dev_framadate';
+
+// Database server name, leave empty to use a socket
+const DB_CONNECTION_STRING = 'mysql:host=localhost;dbname=framadate_dev;port=3306';
+
+// Name of the table that store migration script already executed
+const MIGRATION_TABLE = 'framadate_migration';
+
+// Table name prefix
+const TABLENAME_PREFIX = 'fd_';
+
+// Default Language using POSIX variant of BC P47 standard (choose in $ALLOWED_LANGUAGES)
+const DEFAULT_LANGUAGE = 'fr';
+
+// List of supported languages, fake constant as arrays can be used as constants only in PHP >=5.6
+$ALLOWED_LANGUAGES = [
+    'fr' => 'Français',
+    'en' => 'English',
+    'es' => 'Español',
+    'de' => 'Deutsch',
+    'it' => 'Italiano',
+];
+
+// Nom et emplacement du fichier image contenant le titre
+const IMAGE_TITRE = 'images/logo-framadate.png';
+
+// Clean URLs, boolean
+const URL_PROPRE = false;
+
+// Use REMOTE_USER data provided by web server
+const USE_REMOTE_USER =  true;
+
+// Path to the log file
+const LOG_FILE = 'admin/stdout.log';
+
+// Days (after expiration date) before purge a poll
+const PURGE_DELAY = 60;
+
+// Config
+$config = [
+    /* general config */
+    'use_smtp' => false,                     // use email for polls creation/modification/responses notification
+    /* home */
+    'show_what_is_that' => true,            // display "how to use" section
+    'show_the_software' => true,            // display technical information about the software
+    'show_cultivate_your_garden' => true,   // display "developpement and administration" information
+    /* create_classic_poll.php / create_date_poll.php */
+    'default_poll_duration' => 180,         // default values for the new poll duration (number of days).
+    /* create_classic_poll.php */
+    'user_can_add_img_or_link' => true,     // user can add link or URL when creating his poll.
+];
diff --git a/app/inc/config.template.php b/app/inc/config.template.php
index a29b57304cf5d6f6cdb1ddad9a2c34a8b0aa3ec6..9aad34e4bcce015035728a42cf554f0f5015f9f0 100644
--- a/app/inc/config.template.php
+++ b/app/inc/config.template.php
@@ -58,12 +58,6 @@ $ALLOWED_LANGUAGES = [
     'it' => 'Italiano',
 ];
 
-// Path to logo
-const LOGOBANDEAU = '<relative path to the logo file>';
-
-// Path to logo in PDF export
-const LOGOLETTRE = '<relative path to the logo file for pdf>';
-
 // Nom et emplacement du fichier image contenant le titre
 const IMAGE_TITRE = 'images/logo-framadate.png';
 
diff --git a/app/inc/init.php b/app/inc/init.php
index 63379ef6d02c0f715b561a6e0699baed5f67ffd8..8879bae747efb4e49ec09d9fc34ceb477ce3c5d6 100644
--- a/app/inc/init.php
+++ b/app/inc/init.php
@@ -32,15 +32,31 @@ if (ini_get('date.timezone') == '') {
 }
 
 define('ROOT_DIR', __DIR__ . '/../../');
+define('CONF_FILENAME', ROOT_DIR . '/app/inc/config.php');
 
-require_once __DIR__ . '/constants.php';
-require_once __DIR__ . '/config.php';
-require_once __DIR__ . '/i18n.php';
+if (is_file(CONF_FILENAME)) {
 
-// Smarty
-require_once __DIR__ . '/smarty.php';
+    require_once __DIR__ . '/constants.php';
+    @include_once __DIR__ . '/config.php';
+
+    // Connection to database
+    $connect = new FramaDB(DB_CONNECTION_STRING, DB_USER, DB_PASSWORD);
+    RepositoryFactory::init($connect);
+    $err = 0;
+} else {
+    define('NOMAPPLICATION', 'Framadate');
+    define('DEFAULT_LANGUAGE', 'fr');
+    define('IMAGE_TITRE', 'images/logo-framadate.png');
+    define('LOG_FILE', 'admin/stdout.log');
+    $ALLOWED_LANGUAGES = [
+        'fr' => 'Français',
+        'en' => 'English',
+        'es' => 'Español',
+        'de' => 'Deutsch',
+        'it' => 'Italiano',
+    ];
+}
 
-// Connection to database
-$connect = new FramaDB(DB_CONNECTION_STRING, DB_USER, DB_PASSWORD);
-RepositoryFactory::init($connect);
-$err = 0;
+require_once __DIR__ . '/i18n.php';
+// Smarty
+require_once __DIR__ . '/smarty.php';
\ No newline at end of file
diff --git a/app/inc/smarty.php b/app/inc/smarty.php
index 83dddedf9dff02250a492317db20887a54e9d333..26be0b30141eff986c43713a86cfaa032876e9b0 100644
--- a/app/inc/smarty.php
+++ b/app/inc/smarty.php
@@ -29,7 +29,7 @@ $smarty->assign('APPLICATION_NAME', NOMAPPLICATION);
 $smarty->assign('SERVER_URL', Utils::get_server_name());
 $smarty->assign('SCRIPT_NAME', $_SERVER['SCRIPT_NAME']);
 $smarty->assign('TITLE_IMAGE', IMAGE_TITRE);
-$smarty->assign('use_nav_js', file_exists($_SERVER['DOCUMENT_ROOT'] . '/nav/nav.js'));
+$smarty->assign('use_nav_js', is_file($_SERVER['DOCUMENT_ROOT'] . '/nav/nav.js'));
 $smarty->assign('locale', $locale);
 $smarty->assign('langs', $ALLOWED_LANGUAGES);
 $smarty->assign('date_format', $date_format);
diff --git a/buildlang.php b/buildlang.php
new file mode 100644
index 0000000000000000000000000000000000000000..9677f405d832727eee21053abc4e5a739f8661be
--- /dev/null
+++ b/buildlang.php
@@ -0,0 +1,46 @@
+<?php
+include_once __DIR__ . '/app/inc/init.php';
+?>
+<html>
+<head>
+    <meta charset="utf-8"/>
+</head>
+<body><pre><?php
+
+    $goodLang = $_GET['good'];
+    $otherLang = $_GET['other'];
+
+    $good = json_decode(file_get_contents(__DIR__ . '/locale/' . $goodLang . '.json'), true);
+    $other = json_decode(file_get_contents(__DIR__ . '/locale/' . $otherLang . '.json'), true);
+
+    foreach ($good as $sectionName => $section) {
+        foreach ($section as $key => $value) {
+            $good[$sectionName][$key] = getFromOther($other, $key, $value, $otherLang);
+        }
+    }
+
+    echo json_encode($good, JSON_PRETTY_PRINT | ~(JSON_ERROR_UTF8 | JSON_HEX_QUOT | JSON_HEX_APOS));
+
+    function getFromOther($other, $goodKey, $default, $otherLang) {
+        foreach ($other as $sectionName => $section) {
+            foreach ($section as $key => $value) {
+                if (
+                    strtolower($key) === strtolower($goodKey) ||
+                    strtolower(trim($key)) === strtolower($goodKey) ||
+                    strtolower(substr($key, 0, strlen($key) - 1)) === strtolower($goodKey) ||
+                    strtolower(trim(substr(trim($key), 0, strlen($key) - 1))) === strtolower($goodKey)
+                ) {
+                    return $value;
+                }
+            }
+        }
+
+        echo '[-]' . $goodKey . "\n";
+
+        return strtoupper($otherLang) . '_' . $default;
+    }
+
+    ?>
+</pre>
+</body>
+</html>
diff --git a/compare.php b/compare.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa780a4a772da52b1635d9822cdb2f2f9770c8b3
--- /dev/null
+++ b/compare.php
@@ -0,0 +1,69 @@
+<?php
+include_once __DIR__ . '/app/inc/init.php';
+?>
+<html>
+<head>
+    <meta charset="utf-8"/>
+</head>
+<body><pre><?php
+
+    $goodLang = $_GET['good'];
+    $testLang = $_GET['test'];
+
+    $good = json_decode(file_get_contents(__DIR__ . '/locale/' . $goodLang . '.json'), true);
+    $test = json_decode(file_get_contents(__DIR__ . '/locale/' . $testLang . '.json'), true);
+
+    $diffSection = false;
+
+    foreach ($good as $sectionName => $section) {
+        if (!isset($test[$sectionName])) {
+            echo '- section: ' . $sectionName . "\n";
+            $diffSection = true;
+        }
+    }
+    foreach ($test as $sectionName => $section) {
+        if (!isset($good[$sectionName])) {
+            echo '+ section: ' . $sectionName . "\n";
+            $diffSection = true;
+        }
+    }
+
+    if (!$diffSection and array_keys($good)!=array_keys($test)) {
+        var_dump(array_keys($good));
+        var_dump(array_keys($test));
+    } else {
+        echo 'All sections are in two langs.' . "\n";
+    }
+
+
+    $diff = array();
+
+    foreach ($good as $sectionName => $section) {
+        $diffSection = false;
+        foreach($section as $key=>$value) {
+            if (!isset($test[$sectionName][$key])) {
+                $diff[$sectionName]['-'][] = $key;
+                $diffSection = true;
+            }
+        }
+
+        if (!$diffSection and array_keys($good[$sectionName]) != array_keys($test[$sectionName])) {
+            $diff[$sectionName]['order_good'] = array_keys($good[$sectionName]);
+            $diff[$sectionName]['order_test'] = array_keys($test[$sectionName]);
+        }
+    }
+
+    foreach ($test as $sectionName => $section) {
+        foreach($section as $key=>$value) {
+            if (!isset($good[$sectionName][$key])) {
+                $diff[$sectionName]['+'][] = $key;
+            }
+        }
+    }
+    if (count($diff) > 0) {
+        var_dump($diff);
+    }
+    ?>
+</pre>
+</body>
+</html>
diff --git a/create_classic_poll.php b/create_classic_poll.php
index 0df4a69a82b3d4002225399cef2f2c957c62596e..87c5d249a36b9b904aa894c34133dd25c300e4c6 100644
--- a/create_classic_poll.php
+++ b/create_classic_poll.php
@@ -32,7 +32,7 @@ $pollService = new PollService($connect, $logService);
 $mailService = new MailService($config['use_smtp']);
 $purgeService = new PurgeService($connect, $logService);
 
-if (file_exists('bandeaux_local.php')) {
+if (is_file('bandeaux_local.php')) {
     include_once('bandeaux_local.php');
 } else {
     include_once('bandeaux.php');
diff --git a/index.php b/index.php
index 364c90c3ef2dfa5a65d3ecf523150f93112f897a..8ee6b6f9eb7d596c65a597183e49ab6d18ceba9d 100644
--- a/index.php
+++ b/index.php
@@ -18,9 +18,15 @@
  */
 
 use Framadate\Services\PollService;
+use Framadate\Utils;
 
 include_once __DIR__ . '/app/inc/init.php';
 
+if (!is_file(CONF_FILENAME)) {
+    header(('Location: ' . Utils::get_server_name() . 'admin/install.php'));
+    exit;
+}
+
 /* SERVICES */
 /* -------- */
 $logService = '\Framadate\Services\LogService';
diff --git a/install/InstallComposer.php b/install/InstallComposer.php
deleted file mode 100644
index a370f9580ab866322595aac5f78970a4fe5d30c4..0000000000000000000000000000000000000000
--- a/install/InstallComposer.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?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());
-        }
-    }
-
-}
diff --git a/install/InstallConfiguration.php b/install/InstallConfiguration.php
deleted file mode 100644
index 3595312e98e1c78d234833fc1c769f079b7a8dba..0000000000000000000000000000000000000000
--- a/install/InstallConfiguration.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?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;
-    }
-}
diff --git a/install/InstallSql.php b/install/InstallSql.php
deleted file mode 100644
index 749767b24b40841da6df73571ad8cf37356b10d8..0000000000000000000000000000000000000000
--- a/install/InstallSql.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?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);
-        }
-    }
-}
diff --git a/install/error.html b/install/error.html
deleted file mode 100644
index c6dc5ba17190d3a792eafe1e050a4641df1d8fd7..0000000000000000000000000000000000000000
--- a/install/error.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!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="Framadate" />
-                </h1>
-                <h2>Make your polls</h2>
-                <hr class="trait" role="presentation">
-            </header>
-            <main role="main">
-                <h3>Framadate 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>
diff --git a/install/install.css b/install/install.css
deleted file mode 100644
index 18f3dc539ee9ec75f531f15e039821948e604e6e..0000000000000000000000000000000000000000
--- a/install/install.css
+++ /dev/null
@@ -1,11 +0,0 @@
-header {
-    padding-bottom: 0;
-}
-
-main {
-    padding-top: 0;
-}
-
-fieldset {
-    margin: 1.5em 0;
-}
\ No newline at end of file
diff --git a/install/install.html b/install/install.html
deleted file mode 100644
index 1caa3af2c9c9e3764280be3595520e9d459f1a5f..0000000000000000000000000000000000000000
--- a/install/install.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!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="Framadate" />
-                </h1>
-                <h2>Make your polls</h2>
-                <hr class="trait" role="presentation">
-            </header>
-            <main role="main">
-                <h3>Framadate 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>
diff --git a/install/install.mysql.auto.sql b/install/install.mysql.auto.sql
deleted file mode 100644
index a42245e12f6a0a91f9733597c046827754409098..0000000000000000000000000000000000000000
--- a/install/install.mysql.auto.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-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');
diff --git a/install/install.mysql.sql b/install/install.mysql.sql
deleted file mode 100644
index aa0354cf984784bb559f1586a622202019f47781..0000000000000000000000000000000000000000
--- a/install/install.mysql.sql
+++ /dev/null
@@ -1,112 +0,0 @@
--- --------------------------------------------------------
-
---
--- Table structure `poll`
---
-
-CREATE TABLE IF NOT EXISTS `poll` (
-  `id`              CHAR(16)  NOT NULL,
-  `admin_id`        CHAR(24)  NOT NULL,
-  `title`           TEXT      NOT NULL,
-  `description`     TEXT,
-  `admin_name`      VARCHAR(64) DEFAULT NULL,
-  `admin_mail`      VARCHAR(128) DEFAULT NULL,
-  `creation_date`   TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
-  `end_date`        TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
-  `format`          VARCHAR(1) DEFAULT NULL,
-  `editable`        TINYINT(1) DEFAULT '0',
-  `receiveNewVotes` TINYINT(1) DEFAULT '0',
-  `active`          TINYINT(1) DEFAULT '1',
-  PRIMARY KEY (`id`)
-)
-  ENGINE = InnoDB
-  DEFAULT CHARSET = utf8;
-
--- --------------------------------------------------------
-
---
--- Table structure `slot`
---
-
-CREATE TABLE IF NOT EXISTS `slot` (
-  `id`      INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `poll_id` CHAR(16)         NOT NULL,
-  `title`   TEXT,
-  `moments` TEXT,
-  PRIMARY KEY (`id`),
-  KEY `poll_id` (`poll_id`)
-)
-  ENGINE = InnoDB
-  DEFAULT CHARSET = utf8;
-
--- --------------------------------------------------------
-
---
--- Table structure `comment`
---
-
-CREATE TABLE IF NOT EXISTS `comment` (
-  `id`      INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `poll_id` CHAR(16)         NOT NULL,
-  `name`    TEXT,
-  `comment` TEXT             NOT NULL,
-  PRIMARY KEY (`id`),
-  KEY `poll_id` (`poll_id`)
-)
-  ENGINE = InnoDB
-  DEFAULT CHARSET = utf8;
-
--- --------------------------------------------------------
-
---
--- Table structure `vote`
---
-
-CREATE TABLE IF NOT EXISTS `vote` (
-  `id`      INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
-  `poll_id` CHAR(16)         NOT NULL,
-  `name`    VARCHAR(64)      NOT NULL,
-  `choices` TEXT             NOT NULL,
-  PRIMARY KEY (`id`),
-  KEY `poll_id` (`poll_id`)
-)
-  ENGINE = InnoDB
-  DEFAULT CHARSET = utf8;
-
-
---
--- Data for Name: poll; Type: TABLE DATA;
---
-
-INSERT INTO `poll`
-(`id`, `description`, `admin_mail`, `admin_name`, `title`, `admin_id`, `end_date`, `format`)
-VALUES
-  ('aqg259dth55iuhwm', 'Repas de Noel du service', 'Stephanie@retaillard.com', 'Stephanie', 'Repas de Noel',
-   'aqg259dth55iuhwmy9d8jlwk', FROM_UNIXTIME('1627100361'), 'D');
-
---
--- Data for Name: slot; Type: TABLE DATA;
---
-
-INSERT INTO `slot` (`poll_id`, `title`, `moments`) VALUES
-  ('aqg259dth55iuhwm', '1225839600', '12h,19h'),
-  ('aqg259dth55iuhwm', '1226012400', '12h,19h'),
-  ('aqg259dth55iuhwm', '1226876400', '12h,19h'),
-  ('aqg259dth55iuhwm', '1227826800', '12h,19h');
-
---
--- Data for Name: vote; Type: TABLE DATA;
---
-
-INSERT INTO `vote` (`name`, `poll_id`, `choices`) VALUES
-  ('marcel', 'aqg259dth55iuhwm', '02202222'),
-  ('paul', 'aqg259dth55iuhwm', '20220202'),
-  ('sophie', 'aqg259dth55iuhwm', '22202200'),
-  ('barack', 'aqg259dth55iuhwm', '02200000'),
-  ('takashi', 'aqg259dth55iuhwm', '00002202'),
-  ('albert', 'aqg259dth55iuhwm', '20202200'),
-  ('alfred', 'aqg259dth55iuhwm', '02200200'),
-  ('marcs', 'aqg259dth55iuhwm', '02000020'),
-  ('laure', 'aqg259dth55iuhwm', '00220000'),
-  ('benda', 'aqg259dth55iuhwm', '22022022'),
-  ('albert', 'aqg259dth55iuhwm', '22222200');
diff --git a/install/install.php b/install/install.php
deleted file mode 100644
index 8cf9f3f9b13cdf0a390875d4cbe1549969d1bb20..0000000000000000000000000000000000000000
--- a/install/install.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?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';
diff --git a/locale/de.json b/locale/de.json
index f33b3aca3a55e59a04f8ba5c9673469c453ce569..a6d180d636c433f179bdbcfe79f9f7a7acdd8648 100644
--- a/locale/de.json
+++ b/locale/de.json
@@ -261,6 +261,7 @@
         "Migration": "Migration",
         "Purge": "Säuberung",
         "Logs": "Verlauf",
+        "Installation": "Installation",
         "Poll ID": "Umfrage-ID",
         "Format": "Format",
         "Title": "Titel",
diff --git a/locale/en.json b/locale/en.json
index 8f0dbe7fa557ceeef41b2bb614703cf59b722852..2edcb2b51ef02d60d247c7690c6d4ab25d948cf4 100644
--- a/locale/en.json
+++ b/locale/en.json
@@ -259,6 +259,7 @@
     "Migration": "Migration",
     "Purge": "Purge",
     "Logs": "Logs",
+    "Installation": "Installation",
     "Poll ID": "Poll ID",
     "Format": "Format",
     "Title": "Title",
diff --git a/locale/es.json b/locale/es.json
index fbb6c6b86025bb946529eecead0f32d279f173de..763559024e5693968cd3b9694164e3f1cc5a5bc2 100644
--- a/locale/es.json
+++ b/locale/es.json
@@ -261,6 +261,7 @@
         "Migration": "ES_Migration",
         "Purge": "ES_Purge",
         "Logs": "Histórico",
+        "Installation": "Instalación",
         "Poll ID": "ES_ID sondage",
         "Format": "ES_Format",
         "Title": "ES_Titre",
diff --git a/locale/fr.json b/locale/fr.json
index 7e420b5fb914ebe1e0dd51f8a0af201a81a5e3fe..4c267f0ba303aeca566c9ab25ab2d1dfe8603364 100644
--- a/locale/fr.json
+++ b/locale/fr.json
@@ -36,7 +36,8 @@
     "Choice": "Choix",
     "Link": "Lien",
     "Search": "Chercher",
-    "Creation date:": "Date de création :"
+    "Creation date:": "Date de création :",
+    "ASTERISK": "*"
   },
   "Date": {
     "dd/mm/yyyy": "jj/mm/aaaa",
@@ -261,6 +262,7 @@
     "Migration": "Migration",
     "Purge": "Purge",
     "Logs": "Historique",
+    "Installation": "Installation",
     "Poll ID": "ID sondage",
     "Format": "Format",
     "Title": "Titre",
@@ -309,6 +311,21 @@
     "Author's message": "Réservé à l'auteur",
     "For sending to the polled users": "Pour diffusion aux sondés"
   },
+  "Installation": {
+    "AppMail": "Adresse mail de l'application",
+    "AppName": "Nom de l'application",
+    "CleanUrl": "URL propres",
+    "Database": "Base de données",
+    "DbConnectionString": "Chaîne de connexion",
+    "DbPassword": "Mot de passe",
+    "DbPrefix": "Préfixe",
+    "DbUser": "Utilisateur",
+    "DefaultLanguage": "Langue par défaut",
+    "General": "Général",
+    "Install": "Installer",
+    "MigrationTable": "Table de migration",
+    "ResponseMail": "Mail de réponse"
+  },
   "Error": {
     "Error!": "Erreur !",
     "Enter a title": "Il faut saisir un titre !",
@@ -333,6 +350,8 @@
     "Adding vote failed": "Ajout d'un vote échoué",
     "Comment failed": "Commentaire échoué",
     "You can't create a poll with hidden results with the following edition option:": "Vous ne pouvez pas créer de sondage avec résulats cachés avec les options d'éditions suivantes : ",
-    "Failed to delete column": "Échec de la suppression de colonne"
+    "Failed to delete column": "Échec de la suppression de colonne",
+    "MISSING_VALUES": "Il manque des valeurs",
+    "CANT_CONNECT_TO_DATABASE": "Impossible de se connecter à la base de données"
   }
 }
diff --git a/locale/it.json b/locale/it.json
index 977f254ae14dd5e5dcdf232cad2bda9a6e39551d..904efa694f76a265baf1f4416a671c38168313ff 100644
--- a/locale/it.json
+++ b/locale/it.json
@@ -261,6 +261,7 @@
     "Migration": "IT_Migration",
     "Purge": "IT_Purge",
     "Logs": "Log",
+    "Installation": "Installazione",
     "Poll ID": "ID sondaggio",
     "Format": "Formato",
     "Title": "Titolo",
diff --git a/po2json.php b/po2json.php
new file mode 100644
index 0000000000000000000000000000000000000000..07b77b78622ce32f9300c937ce87c14e574d76b6
--- /dev/null
+++ b/po2json.php
@@ -0,0 +1,15 @@
+<?php
+include_once __DIR__ . '/app/inc/init.php';
+?>
+<html>
+<head>
+    <meta charset="utf-8"/>
+</head>
+<body><pre><?php
+$lang = 'fr_FR';
+$po = file_get_contents(__DIR__ . '/locale/' . $lang . '/LC_MESSAGES/Studs.po');
+$converter = new \o80\convert\Po2JsonConverter();
+$json = $converter->convert($po);
+print_r($json);
+?></pre></body>
+</html>
diff --git a/tpl/admin/config.tpl b/tpl/admin/config.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..3254e91968421c01c9b93a6878498c3b25e4ef6b
--- /dev/null
+++ b/tpl/admin/config.tpl
@@ -0,0 +1,89 @@
+<?php
+/**
+ * This software is governed by the CeCILL-B license. If a copy of this license
+ * is not distributed with this file, you can obtain one at
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt
+ *
+ * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ
+ * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft)
+ *
+ * =============================
+ *
+ * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
+ * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur
+ * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt
+ *
+ * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
+ * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
+ */
+
+// Fully qualified domain name of your webserver.
+// If this is unset or empty, the servername is determined automatically.
+// You *have to set this* if you are running Framedate behind a reverse proxy.
+// const APP_URL = '<www.mydomain.fr>';
+
+// Application name
+const NOMAPPLICATION = '{$appName}';
+
+// Database administrator email
+const ADRESSEMAILADMIN = '{$appMail}';
+
+// Email for automatic responses (you should set it to "no-reply")
+const ADRESSEMAILREPONSEAUTO = '{$responseMail}';
+
+// Database server name, leave empty to use a socket
+const DB_CONNECTION_STRING = '{$dbConnectionString}';
+
+// Database user
+const DB_USER= '{$dbUser}';
+
+// Database password
+const DB_PASSWORD = '{$dbPassword}';
+
+// Table name prefix
+const TABLENAME_PREFIX = '{$dbPrefix}';
+
+// Name of the table that store migration script already executed
+const MIGRATION_TABLE = '{$migrationTable}';
+
+// Default Language
+const DEFAULT_LANGUAGE = '{$defaultLanguage}';
+
+// List of supported languages, fake constant as arrays can be used as constants only in PHP >=5.6
+$ALLOWED_LANGUAGES = [
+    'fr' => 'Français',
+    'en' => 'English',
+    'es' => 'Español',
+    'de' => 'Deutsch',
+    'it' => 'Italiano',
+];
+
+// Nom et emplacement du fichier image contenant le titre
+const IMAGE_TITRE = 'images/logo-framadate.png';
+
+// Clean URLs, boolean
+const URL_PROPRE = {if in_array($cleanUrl, array('1', 'on', 'true'))}true{else}false{/if};
+
+// Use REMOTE_USER data provided by web server
+const USE_REMOTE_USER =  true;
+
+// Path to the log file
+const LOG_FILE = 'admin/stdout.log';
+
+// Days (after expiration date) before purge a poll
+const PURGE_DELAY = 60;
+
+// Config
+$config = [
+    /* general config */
+    'use_smtp' => true,                     // use email for polls creation/modification/responses notification
+    /* home */
+    'show_what_is_that' => true,            // display "how to use" section
+    'show_the_software' => true,            // display technical information about the software
+    'show_cultivate_your_garden' => true,   // display "developpement and administration" information
+    /* create_classic_poll.php / create_date_poll.php */
+    'default_poll_duration' => 180,         // default values for the new poll duration (number of days).
+    /* create_classic_poll.php */
+    'user_can_add_img_or_link' => true,     // user can add link or URL when creating his poll.
+];
+
diff --git a/tpl/admin/install.tpl b/tpl/admin/install.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..38f613cc5bcaaffcbc3db3cd95c8b32960e4a5b1
--- /dev/null
+++ b/tpl/admin/install.tpl
@@ -0,0 +1,102 @@
+{extends 'admin/admin_page.tpl'}
+
+{block 'main'}
+<div class="row">
+    <div class="col-md-12">
+        <form action="" method="POST">
+
+            {if $error}
+                <div id="result" class="alert alert-danger">{$error}</div>
+            {/if}
+
+            <fieldset>
+                <legend>{__('Installation', 'General')}</legend>
+                <div class="form-group">
+                    <div class="form-group">
+                        <div class="input-group">
+                            <label for="appName" class="input-group-addon">{__('Generic', 'ASTERISK')} {__('Installation', 'AppName')}</label>
+                            <input type="text" class="form-control" id="appName" name="appName" value="{$fields['appName']}" autofocus required>
+                        </div>
+                    </div>
+
+                    <div class="form-group">
+                        <div class="input-group">
+                            <label for="appMail" class="input-group-addon">{__('Generic', 'ASTERISK')} {__('Installation', 'AppMail')}</label>
+                            <input type="email" class="form-control" id="appMail" name="appMail" value="{$fields['appMail']}" required>
+                        </div>
+                    </div>
+
+                    <div class="form-group">
+                        <div class="input-group">
+                            <label for="responseMail" class="input-group-addon">{__('Installation', 'ResponseMail')}</label>
+                            <input type="email" class="form-control" id="responseMail" name="responseMail" value="{$fields['responseMail']}">
+                        </div>
+                    </div>
+
+                    <div class="form-group">
+                        <div class="input-group">
+                            <label for="defaultLanguage" class="input-group-addon">{__('Generic', 'ASTERISK')} {__('Installation', 'DefaultLanguage')}</label>
+                            <select type="email" class="form-control" id="defaultLanguage" name="defaultLanguage" required>
+                                {foreach $langs as $lang=>$label}
+                                    <option value="{$lang}" {if $lang==$fields['defaultLanguage']}selected{/if}>{$label}</option>
+                                {/foreach}
+                            </select>
+                        </div>
+                    </div>
+
+                    <div class="input-group">
+                        <label for="cleanUrl" class="input-group-addon">{__('Installation', 'CleanUrl')}</label>
+
+                        <div class="form-control">
+                            <input type="checkbox" id="cleanUrl" name="cleanUrl" {($fields['cleanUrl']) ? 'checked' : ''}>
+                        </div>
+                    </div>
+                </div>
+            </fieldset>
+
+            <fieldset>
+                <legend>{__('Installation', 'Database')}</legend>
+                <div class="form-group">
+                    <div class="input-group">
+                        <label for="dbConnectionString" class="input-group-addon">{__('Generic', 'ASTERISK')} {__('Installation', 'DbConnectionString')}</label>
+                        <input type="text" class="form-control" id="dbConnectionString" name="dbConnectionString" value="{$fields['dbConnectionString']}" required>
+                    </div>
+                </div>
+
+                <div class="form-group">
+                    <div class="input-group">
+                        <label for="dbUser" class="input-group-addon">{__('Generic', 'ASTERISK')} {__('Installation', 'DbUser')}</label>
+                        <input type="text" class="form-control" id="dbUser" name="dbUser" value="{$fields['dbUser']}" required>
+                    </div>
+                </div>
+
+                <div class="form-group">
+                    <div class="input-group">
+                        <label for="dbPassword" class="input-group-addon">{__('Installation', 'DbPassword')}</label>
+                        <input type="password" class="form-control" id="dbPassword" name="dbPassword" value="{$fields['dbPassword']}">
+                    </div>
+                </div>
+
+                <div class="form-group">
+                    <div class="input-group">
+                        <label for="dbPrefix" class="input-group-addon">{__('Installation', 'DbPrefix')}</label>
+                        <input type="text" class="form-control" id="dbPrefix" name="dbPrefix" value="{$fields['dbPrefix']}">
+                    </div>
+                </div>
+
+                <div class="form-group">
+                    <div class="input-group">
+                        <label for="migrationTable" class="input-group-addon">{__('Generic', 'ASTERISK')} {__('Installation', 'MigrationTable')}</label>
+                        <input type="text" class="form-control" id="migrationTable" name="migrationTable" value="{$fields['migrationTable']}" required>
+                    </div>
+                </div>
+            </fieldset>
+
+            <div class="text-center form-group">
+                <button type="submit" class="btn btn-primary">{__('Installation', 'Install')}</button>
+            </div>
+
+        </form>
+    </div>
+</div>
+{/block}
diff --git a/tpl/create_poll.tpl b/tpl/create_poll.tpl
index c064dbf72353264cf590ee8a85e6881335dba21f..a298396d8a1fca243e1b6a19631bc7384c4fb3c0 100644
--- a/tpl/create_poll.tpl
+++ b/tpl/create_poll.tpl
@@ -96,10 +96,6 @@
                 <div class="form-group">
                     <div class="col-sm-offset-4 col-sm-8">
                         <div class="radio">
-                            <label>
-                                <input type="radio" name="editable" {if empty($poll_editable) or $poll_editable==constant("Framadate\Editable::NOT_EDITABLE")}checked{/if} value="{constant("Framadate\Editable::NOT_EDITABLE")}">
-                                {__('Step 1', 'Votes cannot be modified.')}
-                            </label>
                             <label>
                                 <input type="radio" name="editable" id="editableByAll" {if $poll_editable==constant("Framadate\Editable::EDITABLE_BY_ALL")}checked{/if} value="{constant("Framadate\Editable::EDITABLE_BY_ALL")}">
                                 {__('Step 1', 'All voters can modify any vote')}
@@ -108,6 +104,10 @@
                                 <input type="radio" name="editable" {if $poll_editable==constant("Framadate\Editable::EDITABLE_BY_OWN")}checked{/if} value="{constant("Framadate\Editable::EDITABLE_BY_OWN")}">
                                 {__('Step 1', 'Voters can modify their vote themselves')}
                             </label>
+                            <label>
+                                <input type="radio" name="editable" {if empty($poll_editable) or $poll_editable==constant("Framadate\Editable::NOT_EDITABLE")}checked{/if} value="{constant("Framadate\Editable::NOT_EDITABLE")}">
+                                {__('Step 1', 'Votes cannot be modified.')}
+                            </label>
                         </div>
                     </div>
                 </div>