Merge branch 'feature/install_page' into release/0.9

This commit is contained in:
Olivier PEREZ 2015-09-07 16:59:03 +02:00
commit 72b43c2bf9
29 changed files with 643 additions and 490 deletions

48
admin/install.php Normal file
View File

@ -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');

View File

@ -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;
}
}

View File

@ -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 -->';
}

88
app/inc/XXconfig.php Normal file
View File

@ -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.
];

View File

@ -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';

View File

@ -32,15 +32,31 @@ if (ini_get('date.timezone') == '') {
}
define('ROOT_DIR', __DIR__ . '/../../');
define('CONF_FILENAME', ROOT_DIR . '/app/inc/config.php');
if (is_file(CONF_FILENAME)) {
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',
];
}
require_once __DIR__ . '/constants.php';
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/i18n.php';
// Smarty
require_once __DIR__ . '/smarty.php';
// Connection to database
$connect = new FramaDB(DB_CONNECTION_STRING, DB_USER, DB_PASSWORD);
RepositoryFactory::init($connect);
$err = 0;
require_once __DIR__ . '/smarty.php';

View File

@ -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);

46
buildlang.php Normal file
View File

@ -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>

69
compare.php Normal file
View File

@ -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>

View File

@ -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');

View File

@ -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';

View File

@ -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());
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}
}

View File

@ -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>

View File

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

View File

@ -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>

View File

@ -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');

View File

@ -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');

View File

@ -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';

View File

@ -261,6 +261,7 @@
"Migration": "Migration",
"Purge": "Säuberung",
"Logs": "Verlauf",
"Installation": "Installation",
"Poll ID": "Umfrage-ID",
"Format": "Format",
"Title": "Titel",

View File

@ -259,6 +259,7 @@
"Migration": "Migration",
"Purge": "Purge",
"Logs": "Logs",
"Installation": "Installation",
"Poll ID": "Poll ID",
"Format": "Format",
"Title": "Title",

View File

@ -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",

View File

@ -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"
}
}

View File

@ -261,6 +261,7 @@
"Migration": "IT_Migration",
"Purge": "IT_Purge",
"Logs": "Log",
"Installation": "Installazione",
"Poll ID": "ID sondaggio",
"Format": "Formato",
"Title": "Titolo",

15
po2json.php Normal file
View File

@ -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>

89
tpl/admin/config.tpl Normal file
View File

@ -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.
];

102
tpl/admin/install.tpl Normal file
View File

@ -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}

View File

@ -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>