Commit fb04860c authored by Thomas Citharel's avatar Thomas Citharel
Browse files

Merge branch 'fixes' into 'v1.1.x'

Release 1.1.18

See merge request framasoft/framadate/framadate!499
parents 2995851e 9322a41d
image: framasoft/framadate-ci
image: framasoft/framadate-ci:7.3-pdo_mysql
stages:
- test
- deploy
- beta
- funky
# Run php-cs-fixer and phpunit on all branches
test:
......@@ -12,6 +10,14 @@ test:
- composer install -o --no-interaction --no-progress --prefer-dist
- php vendor/bin/php-cs-fixer fix --verbose --dry-run
- vendor/bin/phpunit --bootstrap app/tests/bootstrap.php --debug app/tests
image: framasoft/framadate-ci:${PHP_VERSION}-pdo_mysql
parallel:
matrix:
- PHP_VERSION:
- "7.3"
- "7.4"
- "8.0"
- "8.1"
cache:
paths:
- vendor/
......@@ -54,54 +60,3 @@ pages:
- tags
except:
- (beta|alpha)
# Deploy on develop
beta:
stage: beta
script:
- git checkout develop
- composer install -o --no-interaction --no-progress --prefer-dist --no-dev
- composer dump-autoload --optimize --no-dev --classmap-authoritative
- if [ ! -z ${ZANATA_CONFIG_FRAMABOT+x} ]; then mkdir -p ${HOME}/.config; echo -e "${ZANATA_CONFIG_FRAMABOT}" > ${HOME}/.config/zanata.ini; fi
- if [ ! -z ${ZANATA_CONFIG_FRAMABOT+x} ]; then make pull-locales; fi
- mkdir .public
- cp -r * .public
- cp -r .git .public
- mv .public public
- mkdir "${HOME}/.ssh"
- chmod 700 "${HOME}/.ssh"
- if [ ! -z ${DEPLOYEMENT_KNOWN_HOSTS+x} ]; then echo -e "${DEPLOYEMENT_KNOWN_HOSTS}" > ${HOME}/.ssh/known_hosts; fi
- eval `ssh-agent -s`
- if [ ! -z ${BETA_KEY+x} ]; then ssh-add <(echo "${BETA_KEY}" | base64 --decode -i); fi
- if [ ! -z ${BETA_KEY+x} ]; then rsync -a --delete --exclude admin/.stdout.log --exclude admin/.htpasswd --exclude app/inc/config.php --exclude stats/ --exclude error/ public/ ${BETA_USER}@${DEPLOYEMENT_HOST}:../../web/; fi
only:
- develop
# Deploy on funky
funky:
stage: funky
script:
- git checkout funky
- composer install
- mkdir tpl_c
- mkdir .public
- cp -r * .public
- mv .public public
- mkdir "${HOME}/.ssh"
- chmod 700 "${HOME}/.ssh"
- if [ ! -z ${DEPLOYEMENT_KNOWN_HOSTS+x} ]; then echo -e "${DEPLOYEMENT_KNOWN_HOSTS}" > ${HOME}/.ssh/known_hosts; fi
- eval `ssh-agent -s`
- if [ ! -z ${DEPLOYEMENT_KEY+x} ]; then ssh-add <(echo "${DEPLOYEMENT_KEY}" | base64 --decode -i); fi
- if [ ! -z ${DEPLOYEMENT_KEY+x} ]; then rsync -a --delete --exclude admin/.stdout.log --exclude admin/.htpasswd --exclude app/inc/config.php --exclude stats/ --exclude error/ public/ ${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:../../web/; fi
only:
- funky
# Push new translations strings to https://trad.framasoft.org
trads:
stage: deploy
image: framasoft/push-trad:latest
script:
- if [ ! -z ${ZANATA_CONFIG_FRAMABOT+x} ]; then mkdir -p ${HOME}/.config; echo -e "${ZANATA_CONFIG_FRAMABOT}" > ${HOME}/.config/zanata.ini; fi
- if [ ! -z ${ZANATA_CONFIG_FRAMABOT+x} ]; then make push-locales; fi
only:
- develop
# Changelog de framadate
## 1.1.18
20-12-2021
### Changed
- Dependency updates
- Replace abandonned SimpleMDE with EasyMDE fork
### Fixed
- Enforce the instance expiration limits when editing the poll expiration date once created, from poll admin
- Fixed some HTML markup validity
### Translations
- Fixed a missing french language key
- Enable Catalan language
## 1.1.17
18-10-2021
### Added
- Allow to export to ICS the best choices
### Changed
- Allow configuring AuthType for MailService
### Security
- Fix an XSS possibility in the result graph
## 1.1.16
22-03-2021
### Changed
- **Framadate now requires the `mbstring` PHP extension.** Make sure it's installed and activated before updating.
### Fixed
- Handle poll creator names being too long properly
## 1.1.15
22-03-2021
### Security
- Fixed cross-site scripting (XSS) attacks in poll description markdown preview. All administrators are encouraged to upgrade, especially if you have sensitive services and data on the same domain name.
This was reported by @martgil
https://framagit.org/framasoft/framadate/framadate/-/issues/546
## 1.1.14
08-03-2021
### Fixed
- Avoid error with a name too long https://framagit.org/framasoft/framadate/framadate/-/issues/530
## 1.1.13
08-03-2021
### Fixed
- Fixed error when closing a poll https://framagit.org/framasoft/framadate/framadate/-/issues/532
## 1.1.12
18-12-2020
### Changed
* Framadate now requires PHP 7.3
## 1.1.11
18-12-2020
### Fixed
- Fixed translations keys missing into emails https://framagit.org/framasoft/framadate/framadate/-/issues/463
### Translations
- Added Catalan translation
## 1.1.10
### Fixed
* Remove .git folder inside releases.
* Create releases through CI
## 1.1.9
### Fixed
- Fixes session issue https://framagit.org/framasoft/framadate/framadate/issues/255
- Fixes bug when editing column https://framagit.org/framasoft/framadate/framadate/issues/379
- Fix mail subject escaping https://framagit.org/framasoft/framadate/framadate/issues/375
## 1.1.8
### Fixed
- Stop creating `tpl_c` directory in releases and add a `.gitkeep`
- Show database connection issue details on installation panel
- Set the proper file rights on release packages
- Added `session.cookie_httponly = 1` to local php.ini file
## 1.1.7
### Fixed
- Fix issue with maximum number of participants https://framagit.org/framasoft/framadate/issues/353 (thanks to @lohmeyer for reporting it)
## 1.1.6
### Fixed
- Bump dependencies, including PHPMailer to version 6.x
- Fix an small issue with Smarty template
## 1.1.5
### Fixed
- Restrict custom poll URLs against app urls (thanks @mosterdt)
- Add a parameter to disable build-in font-awesome (thanks @mm)
- Fix an XSS security issue with time slots (thanks https://bitsoffreedom.nl for responsibly disclosing it).
## 1.1.4
### Fixed
* Add Fork-awesome, remove dependency to Font-Awesome Bootstrap CDN, add an option to disable it (https://framagit.org/framasoft/framadate/merge_requests/300 - @tcit)
## 1.1.3
### Fixed
* Fixing issue when no choice is selected introducted in https://framagit.org/framasoft/framadate/merge_requests/284 (https://framagit.org/framasoft/framadate/merge_requests/298 - @mm)
## 1.1.2
### Fixed
- Use Parsedown's Safe Mode
## 1.1.1
### Bug fixes
- Send email with correct vote address (thanks to @lohmeyer for finding it)
## 1.1.0
### Warning
**Framadate now requires PHP 5.6** to be used (it should still work under 5.4 but will not be supported anymore).
### Features
- Markdown editor for descriptions ! (@Antonin)
- Adding a maximum participants number (@SuperNach0)
- Allow setting SMTP config (Simon LEBLANC)
- Allow admins to give the vote link back to the voters (@mm, @tcit)
- Sending voters emails to remind themselves their voting url now works (@mm)
### Enhancements
- UI improvements for responsive design (@marjolaine-v)
- Better coherence for visible results and passwords (@TDavid)
- Added an edit button on the right when too many options (@SuperNach0)
- Emails with international characters are now allowed (added an unit test) (@mm)
### Translations
**New strings are available, don't hesitate to head to <https://trad.framasoft.org/zanata/project/view/framadate> to translate them into your language !**
### Fixed
- Reschedule function (https://framagit.org/framasoft/framadate/issues/203) (@TDavid)
- lang attribute must be a valid IETF language tag (@Rudloff)
- Fix datepicker js locale file path
- Fix everyone can always vote #267
- Fix MySQL error with `NO_ZERO_DATE` #224
- SimpleMDE Markdown Editor has been updated the latest version to remove console.log calls
- Fix width of `if need be` vote option and missing parenthesis
- Remove autocomplete on date fields
- Various fixes for value max error handling
- New error strings for bad formatted inputs (admin name, wrong value max option)
- Email is now a email field (better for virtual keyboards) and is html required as well as title
- Advanced settings for poll are now opened if there's error within them
- css fixes for pictures inside columns, and little space between editor and description text area (@marjolaine-v)
- released zip files now have proper chmod rights (@tcit)
- Best choices now work properly when there's no votes (@mm)
- Don't allow an existing name when updating a vote (@mm)
- Keep vote selections when there's an error on the name (@mm)
- Add a message « Your poll has been created » at the end of the poll form process (@mm)
### Documentation
- Move everything to wiki, translate everything to English
### Technical
- Continuous Integration handles the release process
- Translations with Zanata : https://trad.framasoft.org/zanata/project/view/framadate (@luc)
- Style fixes with PHP-CS
- Libraries updated
- Improved a few docs
- Use own Framadate Docker Image for CI
- https://beta.framadate.org now gets the latest translations for each deployment (@luc)
- A CI job tells if translations strings are up-to-date (@luc)
## 1.0.3
- Corrections de wording (fr / en)
## Version 1.0 (Erik - Markus - Ecmu - Julien - Imre - Luc - Pierre - Antonin - Olivier)
- Amélioration : Conserver les votes en cours lors que l'utilisateur envoie un commentaire
- Amélioration : Les mails sont envoyés en multipart pour les lecteurs ne supportant pas HTML
......@@ -105,7 +307,7 @@
- Fix : Bug à la création d'un sondage sans Javascript ou sans Cookies
- Fix : Erreur d'url avec les noms de domaine contenant "admin"
- Fix : Mise à jour de la doc d'installation
## Version 0.8 (juillet 2014 Pascal Chevrel - Armony Altinier - JosephK)
- Améliorations sur l'accessibilité
- Améliorations sur l'ergonomie
......@@ -139,7 +341,7 @@
## Changelog des 22 et 23 juin (pyg@framasoft.net)
- très nombreuses modifications CSS
- ajout de buttons.css pour des boutons plus propres
- ajout de buttons.css pour des boutons plus propres
- ajout de print.css pour une impression sans la classe "corps"
- refonte de la page d'accueil
- ajout de la framanav
......@@ -205,7 +407,7 @@
- Traduction de STUdS en anglais, allemand et espagnol,
- Changement de la CSS avec ajout du logo de l'Université de Strasbourg,
- Possibilité d'ajouter un commentaire pour les sondés.
Changelog version 0.4 (janvier 2009) :
- Possibilité de faire un export PDF pour envoyer la lettre de convocation à la date de réunion,
- Possibilité de rajouter des colonnes dans la partie administration de sondage,
......@@ -216,7 +418,7 @@
- Mise en place d'un repository Subversion pour partager les nouvelles versions de STUdS,
- Amélioration de la CSS pour un meilleur affichage,
- Modification du code source pour le rendre portable vers une autre machine.
Changelog version 0.2 (novembre 2008) :
- Lors de la création d'un sondage DATE, classement des dates par ordre croissant,
- Lors de la création d'un sondage DATE, accepter les horaires au format "8h" ou "8H",
......
......@@ -40,7 +40,7 @@ $is_admin = false;
/*----------*/
$logService = new LogService();
$pollService = new PollService($connect, $logService);
$pollService = new PollService($logService);
$inputService = new InputService();
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
$notificationService = new NotificationService($mailService);
......@@ -63,7 +63,7 @@ if (!empty($_POST['poll_admin'])) {
if (!$poll) {
$message = new Message('error', __('Error', 'This poll doesn\'t exist !'));
} else if ($poll && !$securityService->canAccessPoll($poll) && !$is_admin) {
} else if (!$is_admin && !$securityService->canAccessPoll($poll)) {
$message = new Message('error', __('Password', 'Wrong password'));
} else {
$name = $inputService->filterName($_POST['name']);
......@@ -88,8 +88,10 @@ if (!$poll) {
$smarty->error_reporting = E_ALL & ~E_NOTICE;
$smarty->assign('comments', $comments);
$smarty->assign('poll_id', $poll_id);
$smarty->assign('admin_poll_id', $admin_poll_id);
$comments_html = $smarty->fetch('part/comments_list.tpl');
$response = ['result' => $result, 'message' => $message, 'comments' => $comments_html];
echo json_encode($response);
echo json_encode($response, JSON_THROW_ON_ERROR);
......@@ -29,7 +29,7 @@ include_once __DIR__ . '/../app/inc/init.php';
$logService = new LogService();
$sessionService = new SessionService();
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
$pollService = new PollService($connect, $logService);
$pollService = new PollService($logService);
$result = false;
$message = null;
......@@ -45,7 +45,7 @@ if (!empty($_POST['poll'])) {
$token = $sessionService->get("Common", SESSION_EDIT_LINK_TOKEN);
$token_form_value = empty($_POST['token']) ? null : $_POST['token'];
$editedVoteUniqueId = filter_input(INPUT_POST, 'editedVoteUniqueId', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
if (is_null($poll) || $config['use_smtp'] === false || is_null($token) || is_null($token_form_value)
if ($config['use_smtp'] === false || is_null($poll) || is_null($token) || is_null($token_form_value)
|| !$token->check($token_form_value) || is_null($editedVoteUniqueId)) {
$message = new Message('error', __('Error', 'Something is going wrong...'));
}
......@@ -91,4 +91,4 @@ $smarty->error_reporting = E_ALL & ~E_NOTICE;
$response = ['result' => $result, 'message' => $message];
echo json_encode($response);
echo json_encode($response, JSON_THROW_ON_ERROR);
......@@ -20,7 +20,7 @@
use Framadate\Message;
use Framadate\Utils;
define('ROOT_DIR', __DIR__ . '/../');
const ROOT_DIR = __DIR__ . '/../';
/**
* Checking for missing vendors.
......@@ -58,7 +58,7 @@ require_once ROOT_DIR . 'app/inc/i18n.php';
* @param Message $b
* @return int
*/
function compareCheckMessage(Message $a, Message $b)
function compareCheckMessage(Message $a, Message $b): int
{
$values = [
'danger' => 0,
......@@ -90,7 +90,7 @@ $conf_filename = $inc_directory . 'config.php';
if (version_compare(PHP_VERSION, PHP_NEEDED_VERSION) >= 0) {
$messages[] = new Message('info', __f('Check','PHP version %s is enough (needed at least PHP %s).', PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION, PHP_NEEDED_VERSION));
} else {
$messages[] = new Message('danger', __f('Check','Your PHP version (%s) is too old. This application needs at least PHP %s.', phpversion(), PHP_NEEDED_VERSION));
$messages[] = new Message('danger', __f('Check','Your PHP version (%s) is too old. This application needs at least PHP %s.', PHP_VERSION, PHP_NEEDED_VERSION));
}
// INTL extension
......@@ -120,7 +120,7 @@ if (!file_exists(ROOT_DIR . COMPILE_DIR)) {
if (file_exists($conf_filename)) {
$messages[] = new Message('info', __('Check','The config file exists.'));
} elseif (is_writable($inc_directory)) {
$messages[] = new Message('info', __('Check','The config file directory (%s) is writable.', $inc_directory));
$messages[] = new Message('info', __f('Check','The config file directory (%s) is writable.', $inc_directory));
} else {
$messages[] = new Message('danger', __f('Check','The config file directory (%s) is not writable and the config file (%s) does not exists.', $inc_directory, $conf_filename));
}
......@@ -187,7 +187,7 @@ usort($messages, 'compareCheckMessage');
<div class="input-group input-group-sm pull-right col-xs-12 col-sm-2">
<select name="lang" class="form-control" title="<?=__('Language selector', 'Select the language')?>" >
<?php foreach ($ALLOWED_LANGUAGES as $lang_key => $language) { ?>
<option lang="fr" <?php if (substr($lang_key, 0, 2)===$locale) { echo 'selected';} ?> value="<?=substr($lang_key, 0, 2)?>"><?=$language?></option>
<option lang="fr" <?php if (strpos($lang_key, $locale) === 0) { echo 'selected';} ?> value="<?=substr($lang_key, 0, 2)?>"><?=$language?></option>
<?php } ?>
</select>
<span class="input-group-btn">
......
......@@ -17,6 +17,7 @@
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
*/
use Framadate\FramaDB;
use Framadate\Migration\AddColumn_hidden_In_poll_For_0_9;
use Framadate\Migration\AddColumn_receiveNewComments_For_0_9;
use Framadate\Migration\AddColumn_uniqId_In_vote_For_0_9;
......@@ -57,7 +58,7 @@ $migrations = [
// ---------------------------------------
// Check if MIGRATION_TABLE already exists
/** @var \Framadate\FramaDB $connect */
/** @var FramaDB $connect */
$tables = $connect->allTables();
$pdo = $connect->getPDO();
$prefixedMigrationTable = Utils::table(MIGRATION_TABLE);
......
......@@ -50,7 +50,7 @@ $poll_to_delete = null;
/*----------*/
$logService = new LogService();
$pollService = new PollService($connect, $logService);
$pollService = new PollService($logService);
$adminPollService = new AdminPollService($connect, $pollService, $logService);
$superAdminService = new SuperAdminService();
$securityService = new SecurityService();
......
......@@ -34,14 +34,14 @@ $message = null;
/*----------*/
$logService = new LogService();
$purgeService = new PurgeService($connect, $logService);
$purgeService = new PurgeService($logService);
$securityService = new SecurityService();
$inputService = new InputService();
/* POST */
/*-----*/
$action = $inputService->filterName(isset($_POST['action']) ? $_POST['action'] : null);
$action = $inputService->filterName($_POST['action'] ?? null);
/* PAGE */
/* ---- */
......@@ -57,4 +57,4 @@ $smarty->assign('crsf', $securityService->getToken('admin'));
$smarty->assign('title', __('Admin', 'Purge'));
$smarty->display('admin/purge.tpl');
\ No newline at end of file
$smarty->display('admin/purge.tpl');
......@@ -47,7 +47,7 @@ $editingVoteId = 0;
/*----------*/
$logService = new LogService();
$pollService = new PollService($connect, $logService);
$pollService = new PollService($logService);
$adminPollService = new AdminPollService($connect, $pollService, $logService);
$inputService = new InputService();
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
......@@ -137,9 +137,10 @@ if (isset($_POST['update_poll_info'])) {
break;
}
} elseif ($field === 'expiration_date') {
$expiration_date = $inputService->validateDate($_POST['expiration_date'], $pollService->minExpiryDate(), $pollService->maxExpiryDate());
if ($expiration_date) {
$poll->end_date = $expiration_date->getTimestamp();
$givenExpirationDate = $inputService->parseDate($_POST['expiration_date']);
$expiration_date = $inputService->validateDate($givenExpirationDate, $pollService->minExpiryDate(), $pollService->maxExpiryDate());
if ($poll->end_date !== $expiration_date->format('Y-m-d H:i:s')) {
$poll->end_date = $expiration_date->format('Y-m-d H:i:s');
$updated = true;
}
} elseif ($field === 'name') {
......@@ -151,26 +152,26 @@ if (isset($_POST['update_poll_info'])) {
$updated = true;
}
} elseif ($field === 'hidden') {
$hidden = isset($_POST['hidden']) ? $inputService->filterBoolean($_POST['hidden']) : false;
$hidden = isset($_POST['hidden']) && $inputService->filterBoolean($_POST['hidden']);
if ($hidden !== $poll->hidden) {
$poll->hidden = $hidden;
$poll->results_publicly_visible = false;
$updated = true;
}
} elseif ($field === 'removePassword') {
$removePassword = isset($_POST['removePassword']) ? $inputService->filterBoolean($_POST['removePassword']) : false;
$removePassword = isset($_POST['removePassword']) && $inputService->filterBoolean($_POST['removePassword']);
if ($removePassword) {
$poll->results_publicly_visible = false;
$poll->password_hash = null;
$updated = true;
}
} elseif ($field === 'password') {
$password = isset($_POST['password']) ? $_POST['password'] : null;
$password = $_POST['password'] ?? null;
/**
* Did the user choose results to be publicly visible ?
*/
$resultsPubliclyVisible = isset($_POST['resultsPubliclyVisible']) ? $inputService->filterBoolean($_POST['resultsPubliclyVisible']) : false;
$resultsPubliclyVisible = isset($_POST['resultsPubliclyVisible']) && $inputService->filterBoolean($_POST['resultsPubliclyVisible']);
/**
* If there's one, save the password
*/
......
......@@ -24,34 +24,34 @@ class Choice
* Name of the Choice
*/
private $name;
/**
* All availables slots for this Choice.
*/
private $slots;
public function __construct($name='')
{
$this->name = $name;
$this->slots = [];
}
public function addSlot($slot)
public function addSlot($slot): void
{
$this->slots[] = $slot;
}
public function getName()
public function getName(): string
{
return $this->name;
}
public function getSlots()
public function getSlots(): array
{
return $this->slots;
}
static function compare(Choice $a, Choice $b)
public static function compare(Choice $a, Choice $b): int
{
return strcmp($a->name, $b->name);
}
......
......@@ -23,14 +23,13 @@ namespace Framadate;
* Class Editable
*
* Is used to specify the poll's edition permissions.
* @TODO : wait to use the SplEnum
*
* @package Framadate
*/
class Editable { // extends SplEnum
const __default = self::EDITABLE_BY_ALL;
const NOT_EDITABLE = 0;
const EDITABLE_BY_ALL = 1;
const EDITABLE_BY_OWN = 2;
}
\ No newline at end of file
public const NOT_EDITABLE = 0;
public const EDITABLE_BY_ALL = 1;
public const EDITABLE_BY_OWN = 2;
}
......@@ -2,6 +2,4 @@
namespace Framadate\Exception;
class AlreadyExistsException extends \Exception {
function __construct() {
}
}
......@@ -2,6 +2,4 @@
namespace Framadate\Exception;
class ConcurrentEditionException extends \Exception {
function __construct() {
}
}
......@@ -7,6 +7,4 @@ namespace Framadate\Exception;
* Thrown when a poll has a maximum votes constraint for options, and a vote happened since the poll was rendered
*/
class ConcurrentVoteException extends \Exception {
function __construct() {
}
}
......@@ -2,6 +2,4 @@
namespace Framadate\Exception;
class MomentAlreadyExistsException extends \Exception {
function __construct() {
}
}
<?php
namespace Framadate\Exception;
/**
* Class PollNotFoundException
*
* Thrown when a poll isn't found in a critic