Compare commits
231 Commits
chapril-1.
...
v1.2.0-alp
Author | SHA1 | Date |
---|---|---|
Thomas Citharel | 86324bd1f4 | |
Thomas Citharel | 082644a021 | |
Thomas Citharel | 82012628d1 | |
Thomas Citharel | 485fb03405 | |
Thomas Citharel | 6395a3db0b | |
Thomas Citharel | 2da258509c | |
Thomas Citharel | b93733ab8e | |
Thomas Citharel | 1d0b565594 | |
Thomas Citharel | 9f2cf79171 | |
Thomas Citharel | be80321545 | |
Thomas Citharel | 532118ef06 | |
Liquidsoul | aa61f40d51 | |
Liquidsoul | 1a66bd8bbe | |
Liquidsoul | f641a35f8b | |
Liquidsoul | 8f23917639 | |
Thomas Citharel | cd55e9a40a | |
Thomas Citharel | bc964e87a7 | |
Paul B | c93741f475 | |
Liquidsoul | cefcb834d7 | |
Thomas Citharel | 9aaf5b3bbd | |
Thomas Citharel | 13d1103698 | |
Thomas Citharel | cb6c0baa26 | |
Nicolas Bouilleaud | b6723120ab | |
Paul B | 9dd1a6ecf9 | |
Paul B | dd55b7444c | |
Paul B | f0b38fdb42 | |
Paul B | 5d74a5600d | |
Liquidsoul | 95e7977c1b | |
Nicolas Bouilleaud | bc78721381 | |
Nicolas Bouilleaud | 955faa108c | |
Nicolas Bouilleaud | 94739ba971 | |
Nicolas Bouilleaud | 20240fee15 | |
Nicolas Bouilleaud | 780392bb37 | |
Nicolas Bouilleaud | aca1b57dfc | |
Nicolas Bouilleaud | 0353e6f0d7 | |
Nicolas Bouilleaud | 98c43f4685 | |
Nicolas Bouilleaud | e7947354ac | |
Nicolas Bouilleaud | 1f05d88c42 | |
Nicolas Bouilleaud | 31f0a26baa | |
Nicolas Bouilleaud | ecac9ccc94 | |
Nicolas Bouilleaud | 3a6317c25a | |
Thomas Citharel | 705abe6cd6 | |
PaulR | c26fef6b39 | |
Thomas Citharel | d87ca39693 | |
Thomas Citharel | 2c056068de | |
Thomas Citharel | 36bff4d5cc | |
Thomas Citharel | b63e90e53f | |
Liquidsoul | e03ad97382 | |
Pierre de La Morinerie | fe5d28e394 | |
Pierre de La Morinerie | 78714069f0 | |
Thomas Citharel | c9382973ca | |
Thomas Citharel | a0d29ea0d5 | |
Thomas Citharel | 4bd8e248e0 | |
Pierre de La Morinerie | ee4053c524 | |
Thomas Citharel | 93d9f44bb1 | |
Liquidsoul | c72dfa17b8 | |
Liquidsoul | 26d3552276 | |
Liquidsoul | fb05b82e66 | |
Liquidsoul | 8dcea674e8 | |
Liquidsoul | ad8f8ab22c | |
Liquidsoul | 29e599983e | |
Thomas Citharel | 4f7e858ed3 | |
Thomas Citharel | 3cebdfa1ea | |
Thomas Citharel | 89d94fb16b | |
m | f2b57fec9b | |
Thomas Citharel | d50305afb3 | |
Thomas Citharel | 1062f72d56 | |
Nicolas Bouilleaud | 61c449205c | |
Pierre de La Morinerie | 20c324a018 | |
Pierre de La Morinerie | d110ee558f | |
Thomas Citharel | 723cf83484 | |
Thomas Citharel | b73ce470b8 | |
Thomas Citharel | fd2d00b2f6 | |
Thomas Citharel | ec939a8a30 | |
Thomas Citharel | 0fb673457b | |
Clermonté | 2e87e1f761 | |
Clermonté | 38552da738 | |
Paul B | 6d9130ef84 | |
Marc Karassev | 3ec6435323 | |
Thomas Citharel | 4b8de04f60 | |
Thomas Citharel | 5fb1887497 | |
Marc Karassev | b58e61c575 | |
Antonin | d819327c61 | |
Thomas Citharel | 324ac9dfcb | |
Thomas Citharel | 409c5e3d2b | |
Paul B | 64f086c04f | |
Liquidsoul | 46e0edc3dd | |
Thomas Citharel | 80336b431e | |
Thomas Citharel | bd6f2ab1d2 | |
Thomas Citharel | 6a4b2a44a1 | |
Liquidsoul | 7703360d44 | |
Liquidsoul | 5268a5bd7a | |
Mindiell | 2624f2da10 | |
Thomas Citharel | 0493a05526 | |
Thomas Citharel | 69d00042e6 | |
Cyril Roelandt | f626d29843 | |
Paul B | a51ee59d1c | |
Nicolas Bouilleaud | 7b0e42bec4 | |
Paul B | ed223f2176 | |
Nicolas Bouilleaud | 6b91a226ba | |
Thomas Citharel | b272a5a7a1 | |
Paul B | e8620026cf | |
Thomas Citharel | 5f7388cddb | |
Paul B | dc164c4d79 | |
Thomas Citharel | e13f66eb4d | |
Nicolas Bouilleaud | 3071455882 | |
Thomas Citharel | a29c25883a | |
Thomas Citharel | 6090568446 | |
Florent Grouin | e78ad00d28 | |
JosephK | c3e29e7e82 | |
Thomas Citharel | c4551c2e71 | |
Tai Kedzierski | 179b048f59 | |
Maik Hummel | b549beabde | |
Thomas Citharel | cbf6fbffc7 | |
Thierry Munoz | 4e1a0e944a | |
Thomas Citharel | 47261c5677 | |
Tai Kedzierski | 537037154e | |
Thierry Munoz | 49c1ec8de7 | |
Tai Kedzierski | 4242fe2914 | |
Thomas Citharel | 76db7de73c | |
Delattre Yoann | b5effb8eaa | |
Yoann | 28a82388cf | |
Thomas Citharel | 49bd7c9169 | |
Thomas Citharel | f313699149 | |
Thomas Citharel | d29b703e0e | |
Marc Karassev | 14b00691c7 | |
Thomas Citharel | 7baf995f91 | |
Thomas Citharel | d0207ebb5b | |
Luc Didry | ff88628acf | |
Thomas Citharel | 3402571e85 | |
Luc Didry | ed95625cbe | |
Luc Didry | 6b3c5f0610 | |
Thomas Citharel | 5e43c1974d | |
Luc Didry | f691694ff1 | |
Thomas Citharel | 19bec88184 | |
Thomas Citharel | 8f115461e1 | |
Thomas Citharel | d8123634fa | |
Thomas Citharel | 8dcfb0d494 | |
Thomas Citharel | e7d5b1762e | |
Thomas Citharel | f861b77326 | |
Thomas Citharel | c4b562d016 | |
Thomas Citharel | a5373818fb | |
Thomas Citharel | f1678c1744 | |
Thomas Citharel | 3438635cda | |
Thomas Citharel | f8f4cc6076 | |
Thomas Citharel | 4b8fe75f95 | |
Thomas Citharel | 149b64e3b0 | |
Thomas Citharel | ce11049630 | |
Thomas Citharel | f656c790d0 | |
Thomas Citharel | 14053d20c9 | |
Thomas Citharel | 92f699337f | |
Thomas Citharel | af760cf273 | |
Thomas Citharel | f4c901d6cd | |
Thomas Citharel | b04f95f0e1 | |
Thomas Citharel | bd748e5da7 | |
Thomas Citharel | e793a77b2a | |
Thomas Citharel | e078e2d22b | |
Thomas Citharel | 52bc066b05 | |
Thomas Citharel | 4b394e9546 | |
Thomas Citharel | d6c2f01457 | |
Thomas Citharel | 7305c0f89c | |
Thomas Citharel | 2cd54d9c4d | |
Thomas Citharel | 964952433c | |
Thomas Citharel | 4c0c2a16f9 | |
Meteor-Furet | e6716bc745 | |
Meteor-Furet | b5ce4baf60 | |
Meteor-Furet | feb0c1e6ce | |
Thomas Citharel | bcd5acdea5 | |
Thomas Citharel | 2e3fe1dcd3 | |
chrosey | ad450e2798 | |
chrosey | 141e9105be | |
chrosey | fad662e09a | |
Thomas Citharel | 586e59e23f | |
Thomas Citharel | d5f0f5a289 | |
Thomas Citharel | 442fd174e9 | |
Thomas Citharel | 081a32b1bb | |
Thomas De Backer | 5951519ad8 | |
PICHOU Kyâne | a64e182076 | |
Thomas Citharel | 823c41d2e4 | |
Thomas Citharel | f28198e497 | |
Thomas Citharel | fe93733872 | |
Thomas Citharel | 5631167ca7 | |
Thomas Citharel | 87a61ebea3 | |
Thomas Citharel | b008bfea9b | |
Thomas Citharel | 3ba045791f | |
Thomas Citharel | 7f41eb831c | |
Thomas Citharel | 006a191544 | |
Quentin Dupont | 235002cd24 | |
Thomas Citharel | c4e9cb59d3 | |
m | 8e8ffedc4a | |
Thomas Citharel | 2b351bc3d1 | |
Thomas Citharel | 17c264721e | |
m | e379b58d58 | |
m | b2a550d09b | |
Thomas Citharel | 0409256588 | |
Thomas Citharel | abec2cb6a3 | |
Thomas Citharel | b24cc43c85 | |
Thomas Citharel | 4c4fb1557f | |
m | 0841675577 | |
Thomas Citharel | aa690bb6d8 | |
Thomas Citharel | 06c3a8a078 | |
m | 41578b19c8 | |
m | 81092482af | |
Thomas Citharel | 290ec002d5 | |
m | 3330d28f29 | |
m | fb7c5e2f12 | |
m | cc0f572335 | |
m | 0b598b8e80 | |
Thomas Citharel | 2627dc2ae6 | |
Thomas Citharel | 1a3081b58d | |
Thomas Citharel | 685d8b5e3d | |
Thomas Citharel | 7a12d98943 | |
Thomas Citharel | c1ea6ae2a8 | |
JMarlow | 68d5b64180 | |
Thomas Citharel | 6dd8fb1723 | |
Luc Didry | b89622695e | |
Luc Didry | 7d9f5becec | |
m | 5b2a40ac58 | |
m | 0f4587adf8 | |
Thomas Citharel | 3878c3ce7c | |
Thomas Citharel | a004576592 | |
m | 081fdae5f5 | |
Thomas Citharel | 8528a7fe65 | |
Thomas Citharel | c723c81697 | |
m | afd83efd79 | |
m | 00b871df5c | |
m | 3b54590bde | |
m | 6455f4be87 | |
Thomas Citharel | 83ba53dffa | |
framartin | 94f7288446 | |
m | f9c3cde701 |
|
@ -25,3 +25,4 @@ Thumbs.db
|
|||
.project
|
||||
.idea/
|
||||
*.iml
|
||||
test_database.sqlite
|
||||
|
|
108
.gitlab-ci.yml
108
.gitlab-ci.yml
|
@ -1,34 +1,91 @@
|
|||
image: framasoft/framadate-ci
|
||||
variables:
|
||||
TESTING_IMAGE: framasoft/framadate-ci:php-7.2
|
||||
|
||||
image: ${TESTING_IMAGE}
|
||||
|
||||
cache:
|
||||
key: "${TESTING_IMAGE}:${CI_PROJECT_ID}"
|
||||
paths:
|
||||
- vendor/
|
||||
|
||||
before_script:
|
||||
- composer install -o --no-interaction --no-progress --prefer-dist
|
||||
|
||||
stages:
|
||||
- test
|
||||
- deploy
|
||||
- beta
|
||||
- funky
|
||||
|
||||
# Run php-cs-fixer and phpunit on all branches
|
||||
# Run phpunit on all branches
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- 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
|
||||
cache:
|
||||
paths:
|
||||
- vendor/
|
||||
|
||||
check-trad:
|
||||
# Run php-cs-fixer on all branches
|
||||
lint:
|
||||
stage: test
|
||||
allow_failure: true
|
||||
script:
|
||||
- if [ -z ${ZANATA_CONFIG_FRAMABOT+x} ]; then echo "*** Unable to check if translations need to be pulled, exiting ***"; exit 1; fi
|
||||
- export ORIG=$(git diff-files --shortstat)
|
||||
- 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
|
||||
- git status > /dev/null 2>&1
|
||||
- export CHANGES=$(git diff-files --shortstat)
|
||||
- if [[ $CHANGES != $ORIG ]]; then echo "*** There is changes in locales ***"; echo "*** You need to do `make pull-locales` in your repo ***"; exit 1; fi
|
||||
only:
|
||||
- develop
|
||||
- php vendor/bin/php-cs-fixer fix --verbose --dry-run --diff
|
||||
|
||||
# Run doctrine migrations with MySQL
|
||||
.db:migration:mysql:
|
||||
stage: test
|
||||
variables:
|
||||
APP_ENV: "test"
|
||||
MYSQL_DATABASE: "fd_test"
|
||||
MYSQL_ROOT_PASSWORD: "coucou"
|
||||
FRAMADATE_DB_DRIVER: 'pdo_mysql'
|
||||
FRAMADATE_DB_HOST: "mysql"
|
||||
FRAMADATE_DB_NAME: "${MYSQL_DATABASE}"
|
||||
FRAMADATE_DB_USER: "root"
|
||||
FRAMADATE_DB_PASSWORD: "${MYSQL_ROOT_PASSWORD}"
|
||||
script:
|
||||
- docker-php-ext-install "${FRAMADATE_DB_DRIVER}"
|
||||
- bin/doctrine migrations:status -vvv
|
||||
- bin/doctrine migrations:migrate --no-interaction -vvv
|
||||
- bin/doctrine migrations:status -vvv
|
||||
|
||||
db:migration:mysql:5.6:
|
||||
extends: .db:migration:mysql
|
||||
services:
|
||||
- 'mysql:5.6'
|
||||
|
||||
db:migration:mysql:5.7:
|
||||
extends: .db:migration:mysql
|
||||
services:
|
||||
- 'mysql:5.7'
|
||||
|
||||
db:migration:mysql:8:
|
||||
extends: .db:migration:mysql
|
||||
services:
|
||||
- name: 'mysql:8'
|
||||
command: ['--default-authentication-plugin=mysql_native_password']
|
||||
|
||||
# Run doctrine migrations with PostgreSQL
|
||||
.db:migration:postgresql:
|
||||
stage: test
|
||||
variables:
|
||||
APP_ENV: "test"
|
||||
POSTGRES_DB: "fd_test"
|
||||
POSTGRES_USER: "marmotte"
|
||||
POSTGRES_PASSWORD: "sleeping"
|
||||
FRAMADATE_DB_DRIVER: 'pdo_pgsql'
|
||||
FRAMADATE_DB_HOST: "postgres"
|
||||
FRAMADATE_DB_NAME: "${POSTGRES_DB}"
|
||||
FRAMADATE_DB_USER: "${POSTGRES_USER}"
|
||||
FRAMADATE_DB_PASSWORD: "${POSTGRES_PASSWORD}"
|
||||
script:
|
||||
- docker-php-ext-install "${FRAMADATE_DB_DRIVER}"
|
||||
- bin/doctrine migrations:status -vvv
|
||||
- bin/doctrine migrations:migrate --no-interaction -vvv
|
||||
- bin/doctrine migrations:status -vvv
|
||||
|
||||
db:migration:postgresql:9.6:
|
||||
extends: .db:migration:postgresql
|
||||
services:
|
||||
- 'postgres:9.6'
|
||||
|
||||
# Create artifacts on master
|
||||
pages:
|
||||
|
@ -42,6 +99,7 @@ pages:
|
|||
- mv `ls -A | grep -v framadate` ./framadate
|
||||
- find framadate/ -type d -exec chmod 750 {} \;
|
||||
- find framadate/ -type f -exec chmod 640 {} \;
|
||||
- rm -rf framadate/.git
|
||||
- zip -r latest.zip framadate
|
||||
- mkdir .public
|
||||
- cp latest.zip .public
|
||||
|
@ -58,11 +116,8 @@ pages:
|
|||
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
|
||||
|
@ -80,7 +135,6 @@ beta:
|
|||
funky:
|
||||
stage: funky
|
||||
script:
|
||||
- git checkout funky
|
||||
- composer install
|
||||
- mkdir tpl_c
|
||||
- mkdir .public
|
||||
|
@ -94,13 +148,3 @@ funky:
|
|||
- 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
|
||||
|
|
3
.php_cs
3
.php_cs
|
@ -38,7 +38,8 @@ return PhpCsFixer\Config::create()
|
|||
->exclude([
|
||||
'vendor',
|
||||
'var',
|
||||
'web'
|
||||
'web',
|
||||
'tpl_c',
|
||||
])
|
||||
->in(__DIR__)
|
||||
)
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/bash
|
||||
po2json -i po/en.po -t locale/en.json --progress none -o po/default.json
|
||||
|
||||
for i in po/*.po
|
||||
do
|
||||
j=$(echo $i | cut -d '.' -f 1 | cut -d '/' -f 2)
|
||||
po2json -i $i -t locale/en.json --progress none | ./.renest_json.pl > po/$j.json
|
||||
mv po/$j.json locale/
|
||||
done
|
|
@ -1,40 +0,0 @@
|
|||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use JSON;
|
||||
|
||||
my $json = JSON->new->utf8->space_before(0)->space_after(1)->indent(4)->canonical(1);
|
||||
|
||||
my $en_file = 'po/default.json';
|
||||
my $en;
|
||||
{
|
||||
open my $fh, '<', $en_file or die;
|
||||
local $/ = undef;
|
||||
$en = <$fh>;
|
||||
close $fh;
|
||||
}
|
||||
|
||||
$en = $json->decode($en);
|
||||
|
||||
my $new_json = {};
|
||||
my $old_json = '';
|
||||
|
||||
while (defined(my $line = <STDIN>)) {
|
||||
$old_json .= $line;
|
||||
}
|
||||
|
||||
$old_json = $json->decode($old_json);
|
||||
for my $key (keys %{$old_json}) {
|
||||
my $index = index($key, '.');
|
||||
my $real_key = substr($key, 0, $index++);
|
||||
my $trad_key = substr($key, $index);
|
||||
|
||||
if ($old_json->{$key}) {
|
||||
$new_json->{$real_key}->{$trad_key} = $old_json->{$key};
|
||||
} else {
|
||||
$new_json->{$real_key}->{$trad_key} = $en->{$key};
|
||||
}
|
||||
}
|
||||
|
||||
print $json->encode($new_json);
|
|
@ -1,3 +1,7 @@
|
|||
This changelog file is **deprecated**. For an up-to-date changelog, please check [the tags](https://framagit.org/framasoft/framadate/tags).
|
||||
|
||||
---------------------
|
||||
|
||||
# Changelog de framadate
|
||||
|
||||
## Version 1.0 (Erik - Markus - Ecmu - Julien - Imre - Luc - Pierre - Antonin - Olivier)
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# Contributing
|
||||
|
||||
Please report issues on <https://framagit.org/framasoft/framadate/issues>
|
||||
|
||||
If you made a change and want it to be available in official repository, merge requests are welcome!
|
||||
|
||||
Read the [guidelines](https://framagit.org/framasoft/framadate/wikis/coding) to submit your changes.
|
|
@ -1 +1 @@
|
|||
# [Now available here](https://framagit.org/framasoft/framadate/wikis/home)
|
||||
# [Now available here](https://framagit.org/framasoft/framadate/framadate/wikis/home)
|
12
Makefile
12
Makefile
|
@ -1,12 +1,8 @@
|
|||
locales:
|
||||
json2po -P -i locale/en.json -t locale/en.json -o po/framadate.pot
|
||||
|
||||
push-locales: locales
|
||||
zanata-cli -q -B push
|
||||
push-locales:
|
||||
zanata-cli -q -B push --errors --project-version `git branch | grep \* | cut -d ' ' -f2-`
|
||||
|
||||
pull-locales:
|
||||
zanata-cli -q -B pull --min-doc-percent 50
|
||||
./.po2json.sh
|
||||
zanata-cli -q -B pull --min-doc-percent 50 --project-version `git branch | grep \* | cut -d ' ' -f2-`
|
||||
|
||||
stats-locales:
|
||||
zanata-cli -q stats
|
||||
zanata-cli -q stats --project-version `git branch | grep \* | cut -d ' ' -f2-`
|
||||
|
|
10
README.md
10
README.md
|
@ -7,23 +7,23 @@
|
|||
---
|
||||
# Installation
|
||||
|
||||
Follow the instructions on our Wiki : <https://framagit.org/framasoft/framadate/wikis/home>
|
||||
Follow the instructions on our Wiki : <https://framagit.org/framasoft/framadate/framadate/wikis/home>
|
||||
|
||||
# Contribute
|
||||
|
||||
## Code
|
||||
Follow the instructions on <https://framagit.org/framasoft/framadate/wikis/coding>
|
||||
Follow the instructions on <https://framagit.org/framasoft/framadate/framadate/wikis/coding>
|
||||
|
||||
# Traductions
|
||||
|
||||
Follow the instructions on <https://framagit.org/framasoft/framadate/wikis/translating>
|
||||
Follow the instructions on <https://framagit.org/framasoft/framadate/framadate/wikis/translating>
|
||||
|
||||
# Used libraries
|
||||
|
||||
* PHP [PHP 5.6](http://php.net)
|
||||
* Templating [Smarty](http://www.smarty.net/),
|
||||
* I18N [o80-i18n](https://github.com/olivierperez/o80-i18n)
|
||||
* Database: PostgreSQL ou [MySQL 5.5](https://dev.mysql.com/downloads/mysql/5.5.html)
|
||||
* i18n [Symfony/Translation](https://github.com/symfony/Translation)
|
||||
* Database: PostgreSQL 9.6 or [MySQL 5.6+](https://dev.mysql.com/downloads/mysql/5.6.html)/[MariaDB 10.1+](https://www.debian.org/releases/stable/mips/release-notes/ch-whats-new.en.html#mariadb-replaces-mysql)
|
||||
|
||||
---
|
||||
|
||||
|
|
|
@ -17,12 +17,7 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
use Framadate\Message;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SecurityService;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
|
@ -39,12 +34,10 @@ $is_admin = false;
|
|||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
|
||||
$notificationService = new NotificationService($mailService);
|
||||
$securityService = new SecurityService();
|
||||
$inputService = Services::input();
|
||||
$notificationService = Services::notification();
|
||||
$pollService = Services::poll();
|
||||
$securityService = Services::security();
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
@ -62,7 +55,7 @@ if (!empty($_POST['poll_admin'])) {
|
|||
}
|
||||
|
||||
if (!$poll) {
|
||||
$message = new Message('error', __('Error', 'This poll doesn\'t exist !'));
|
||||
$message = new Message('error', __('Error', "This poll doesn't exist!"));
|
||||
} else if ($poll && !$securityService->canAccessPoll($poll) && !$is_admin) {
|
||||
$message = new Message('error', __('Password', 'Wrong password'));
|
||||
} else {
|
||||
|
@ -77,7 +70,7 @@ if (!$poll) {
|
|||
// Add comment
|
||||
$result = $pollService->addComment($poll_id, $name, $comment);
|
||||
if ($result) {
|
||||
$message = new Message('success', __('Comments', 'Comment added'));
|
||||
$message = new Message('success', __('Comments', 'Comment saved'));
|
||||
$notificationService->sendUpdateNotification($poll, NotificationService::ADD_COMMENT, $name);
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Comment failed'));
|
||||
|
|
|
@ -18,18 +18,14 @@
|
|||
*/
|
||||
|
||||
use Framadate\Message;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SessionService;
|
||||
use Framadate\Utils;
|
||||
|
||||
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);
|
||||
$mailService = Services::mail();
|
||||
$notificationService = Services::notification();
|
||||
$pollService = Services::poll();
|
||||
$sessionService = Services::session();
|
||||
|
||||
$result = false;
|
||||
$message = null;
|
||||
|
@ -47,7 +43,7 @@ $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)
|
||||
|| !$token->check($token_form_value) || is_null($editedVoteUniqueId)) {
|
||||
$message = new Message('error', __('Error', 'Something is going wrong...'));
|
||||
$message = new Message('error', __('Error', 'Something has gone wrong...'));
|
||||
}
|
||||
|
||||
if (is_null($message)) {
|
||||
|
@ -70,16 +66,7 @@ if (is_null($message)) {
|
|||
}
|
||||
|
||||
if (is_null($message)) {
|
||||
$url = Utils::getUrlSondage($poll_id, false, $editedVoteUniqueId);
|
||||
|
||||
$smarty->assign('poll', $poll);
|
||||
$smarty->assign('poll_id', $poll_id);
|
||||
$smarty->assign('editedVoteUniqueId', $editedVoteUniqueId);
|
||||
$body = $smarty->fetch('mail/remember_edit_link.tpl');
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '][' . __('EditLink', 'REMINDER') . '] ' . __f('EditLink', 'Edit link for poll "%s"', $poll->title);
|
||||
|
||||
$mailService->send($email, $subject, $body);
|
||||
$notificationService->sendEditedVoteNotification($email, $poll, $poll_id, $editedVoteUniqueId);
|
||||
$sessionService->remove("Common", SESSION_EDIT_LINK_TOKEN);
|
||||
$sessionService->set("Common", SESSION_EDIT_LINK_TIME, time());
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ define('ROOT_DIR', __DIR__ . '/../');
|
|||
/**
|
||||
* Checking for missing vendors.
|
||||
*/
|
||||
if (!file_exists(ROOT_DIR . 'vendor/autoload.php') || !file_exists(ROOT_DIR . 'vendor/o80/i18n/src/shortcuts.php')) {
|
||||
if (!file_exists(ROOT_DIR . 'vendor/autoload.php')) {
|
||||
die ("ERROR: You should use <code>composer install</code> to fetch dependant libraries.");
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,6 @@ if (!file_exists(ROOT_DIR . 'vendor/autoload.php') || !file_exists(ROOT_DIR . 'v
|
|||
* Stripped ini sequence
|
||||
*/
|
||||
require_once ROOT_DIR . 'vendor/autoload.php';
|
||||
require_once ROOT_DIR . 'vendor/o80/i18n/src/shortcuts.php';
|
||||
require_once ROOT_DIR . 'app/inc/constants.php';
|
||||
if (session_id() === '') {
|
||||
session_start();
|
||||
|
@ -112,7 +111,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));
|
||||
}
|
||||
|
@ -177,14 +176,14 @@ usort($messages, 'compareCheckMessage');
|
|||
<div class="row">
|
||||
<form method="get" action="" class="hidden-print">
|
||||
<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')?>" >
|
||||
<select name="lang" class="form-control" title="<?=__('Language selector', 'Select 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>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-default btn-sm" title="<?=__('Language selector', 'Select the language')?>">OK</button>
|
||||
</span>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-default btn-sm" title="<?=__('Language selector', 'Select language')?>">OK</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<?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/OpenSondage: 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)
|
||||
*/
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
Services::purge()->cleanDemoPoll();
|
|
@ -28,6 +28,7 @@ if (is_file(CONF_FILENAME)) {
|
|||
}
|
||||
|
||||
$error = null;
|
||||
$result['details'] = null;
|
||||
$installService = new InstallService();
|
||||
|
||||
if (!empty($_POST)) {
|
||||
|
|
|
@ -17,112 +17,64 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
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;
|
||||
use Framadate\Migration\AddColumn_ValueMax_In_poll_For_1_1;
|
||||
use Framadate\Migration\AddColumns_password_hash_And_results_publicly_visible_In_poll_For_0_9;
|
||||
use Framadate\Migration\Alter_Comment_table_adding_date;
|
||||
use Framadate\Migration\Alter_Comment_table_for_name_length;
|
||||
use Framadate\Migration\Fix_MySQL_No_Zero_Date;
|
||||
use Framadate\Migration\From_0_0_to_0_8_Migration;
|
||||
use Framadate\Migration\From_0_8_to_0_9_Migration;
|
||||
use Framadate\Migration\Generate_uniqId_for_old_votes;
|
||||
use Framadate\Migration\Increase_pollId_size;
|
||||
use Framadate\Migration\Migration;
|
||||
use Framadate\Migration\RPadVotes_from_0_8;
|
||||
use Doctrine\DBAL\Migrations\Configuration\Configuration;
|
||||
use Doctrine\DBAL\Migrations\Migration;
|
||||
use Doctrine\DBAL\Migrations\OutputWriter;
|
||||
use Doctrine\DBAL\Migrations\Tools\Console\Helper\MigrationStatusInfosHelper;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
require_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
set_time_limit(300);
|
||||
class MigrationLogger {
|
||||
private $log;
|
||||
|
||||
// List a Migration sub classes to execute
|
||||
$migrations = [
|
||||
new From_0_0_to_0_8_Migration(),
|
||||
new From_0_8_to_0_9_Migration(),
|
||||
new AddColumn_receiveNewComments_For_0_9(),
|
||||
new AddColumn_uniqId_In_vote_For_0_9(),
|
||||
new AddColumn_hidden_In_poll_For_0_9(),
|
||||
new AddColumn_ValueMax_In_poll_For_1_1(),
|
||||
new Generate_uniqId_for_old_votes(),
|
||||
new RPadVotes_from_0_8(),
|
||||
new Alter_Comment_table_for_name_length(),
|
||||
new Alter_Comment_table_adding_date(),
|
||||
new AddColumns_password_hash_And_results_publicly_visible_In_poll_For_0_9(),
|
||||
new Increase_pollId_size(),
|
||||
new AddColumn_ValueMax_In_poll_For_1_1(),
|
||||
new Fix_MySQL_No_Zero_Date(),
|
||||
];
|
||||
// ---------------------------------------
|
||||
|
||||
// Check if MIGRATION_TABLE already exists
|
||||
/** @var \Framadate\FramaDB $connect */
|
||||
$tables = $connect->allTables();
|
||||
$pdo = $connect->getPDO();
|
||||
$prefixedMigrationTable = Utils::table(MIGRATION_TABLE);
|
||||
|
||||
if (!in_array($prefixedMigrationTable, $tables, true)) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . $prefixedMigrationTable . '` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` TEXT NOT NULL,
|
||||
`execute_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
ENGINE = MyISAM
|
||||
DEFAULT CHARSET = utf8;');
|
||||
}
|
||||
|
||||
$selectStmt = $pdo->prepare('SELECT id FROM `' . $prefixedMigrationTable . '` WHERE name=?');
|
||||
$insertStmt = $pdo->prepare('INSERT INTO `' . $prefixedMigrationTable . '` (name) VALUES (?)');
|
||||
$countSucceeded = 0;
|
||||
$countFailed = 0;
|
||||
$countSkipped = 0;
|
||||
|
||||
// Loop on every Migration sub classes
|
||||
$success = [];
|
||||
$fail = [];
|
||||
foreach ($migrations as $migration) {
|
||||
$className = get_class($migration);
|
||||
|
||||
// Check if $className is a Migration sub class
|
||||
if (!$migration instanceof Migration) {
|
||||
$smarty->assign('error', 'The class ' . $className . ' is not a sub class of Framadate\\Migration\\Migration.');
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
public function __construct()
|
||||
{
|
||||
$this->log = '';
|
||||
}
|
||||
|
||||
// Check if the Migration is already executed
|
||||
$selectStmt->execute([$className]);
|
||||
$executed = $selectStmt->rowCount();
|
||||
$selectStmt->closeCursor();
|
||||
public function addLine($message)
|
||||
{
|
||||
$this->log .= $message . "\n";
|
||||
}
|
||||
|
||||
if (!$executed && $migration->preCondition($pdo)) {
|
||||
$migration->execute($pdo);
|
||||
if ($insertStmt->execute([$className])) {
|
||||
$countSucceeded++;
|
||||
$success[] = $migration->description();
|
||||
} else {
|
||||
$countFailed++;
|
||||
$fail[] = $migration->description();
|
||||
}
|
||||
} else {
|
||||
$countSkipped++;
|
||||
public function getLog()
|
||||
{
|
||||
return $this->log;
|
||||
}
|
||||
}
|
||||
|
||||
$countTotal = $countSucceeded + $countFailed + $countSkipped;
|
||||
$executing = false;
|
||||
$migration = null;
|
||||
$output = '';
|
||||
|
||||
$smarty->assign('success', $success);
|
||||
$smarty->assign('fail', $fail);
|
||||
if (isset($_POST['execute'])) {
|
||||
$executing = true;
|
||||
}
|
||||
|
||||
$smarty->assign('countSucceeded', $countSucceeded);
|
||||
$smarty->assign('countFailed', $countFailed);
|
||||
$smarty->assign('countSkipped', $countSkipped);
|
||||
$smarty->assign('countTotal', $countTotal);
|
||||
$smarty->assign('time', $total_time = round((microtime(true)-$_SERVER['REQUEST_TIME_FLOAT']), 4));
|
||||
$migrationsDirectory = __DIR__ . '/../app/classes/Framadate/Migrations';
|
||||
$log = new MigrationLogger();
|
||||
|
||||
$configuration = new Configuration($connect, new OutputWriter(function ($message) use ($log) {
|
||||
$log->addLine($message);
|
||||
}));
|
||||
$configuration->setMigrationsTableName(Utils::table(MIGRATION_TABLE) . '_new');
|
||||
$configuration->setMigrationsDirectory($migrationsDirectory);
|
||||
$configuration->setMigrationsNamespace('DoctrineMigrations');
|
||||
$configuration->registerMigrationsFromDirectory($migrationsDirectory);
|
||||
|
||||
if ($executing) {
|
||||
$migration = new Migration($configuration);
|
||||
$migration->migrate();
|
||||
$output = trim(strip_tags($log->getLog()));
|
||||
}
|
||||
$infos = (new MigrationStatusInfosHelper($configuration))->getMigrationsInfos();
|
||||
|
||||
$smarty->assign('countTotal', $infos['Available Migrations']);
|
||||
$smarty->assign('countExecuted', $infos['Executed Migrations']);
|
||||
$smarty->assign('countWaiting', $infos['New Migrations']);
|
||||
$smarty->assign('executing', $executing);
|
||||
$smarty->assign('title', __('Admin', 'Migration'));
|
||||
|
||||
$smarty->assign('output', $output);
|
||||
$smarty->assign('time', round((microtime(true)-$_SERVER['REQUEST_TIME_FLOAT']), 4));
|
||||
$smarty->display('admin/migration.tpl');
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Services\AdminPollService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Services\SuperAdminService;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
|
@ -49,11 +45,10 @@ $poll_to_delete = null;
|
|||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||
$adminPollService = Services::adminPoll();
|
||||
$pollService = Services::poll();
|
||||
$securityService = Services::security();
|
||||
$superAdminService = new SuperAdminService();
|
||||
$securityService = new SecurityService();
|
||||
|
||||
/* GET */
|
||||
/*-----*/
|
||||
|
|
|
@ -17,11 +17,6 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Services\SecurityService;
|
||||
|
||||
include_once __DIR__ . '/../app/inc/init.php';
|
||||
include_once __DIR__ . '/../bandeaux.php';
|
||||
|
||||
|
@ -33,10 +28,9 @@ $message = null;
|
|||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$purgeService = new PurgeService($connect, $logService);
|
||||
$securityService = new SecurityService();
|
||||
$inputService = new InputService();
|
||||
$inputService = Services::input();
|
||||
$purgeService = Services::purge();
|
||||
$securityService = Services::security();
|
||||
|
||||
/* POST */
|
||||
/*-----*/
|
||||
|
@ -57,4 +51,4 @@ $smarty->assign('crsf', $securityService->getToken('admin'));
|
|||
|
||||
$smarty->assign('title', __('Admin', 'Purge'));
|
||||
|
||||
$smarty->display('admin/purge.tpl');
|
||||
$smarty->display('admin/purge.tpl');
|
||||
|
|
|
@ -16,20 +16,17 @@
|
|||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Framadate\Editable;
|
||||
use Framadate\Exception\AlreadyExistsException;
|
||||
use Framadate\Exception\ConcurrentEditionException;
|
||||
use Framadate\Exception\ConcurrentVoteException;
|
||||
use Framadate\Exception\MomentAlreadyExistsException;
|
||||
use Framadate\Exception\SlotAlreadyExistsException;
|
||||
use Framadate\Message;
|
||||
use Framadate\Security\PasswordHasher;
|
||||
use Framadate\Services\AdminPollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SessionService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
@ -46,13 +43,11 @@ $editingVoteId = 0;
|
|||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$adminPollService = new AdminPollService($connect, $pollService, $logService);
|
||||
$inputService = new InputService();
|
||||
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
|
||||
$notificationService = new NotificationService($mailService);
|
||||
$sessionService = new SessionService();
|
||||
$adminPollService = Services::adminPoll();
|
||||
$inputService = Services::input();
|
||||
$notificationService = Services::notification();
|
||||
$pollService = Services::poll();
|
||||
$sessionService = Services::session();
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
@ -67,7 +62,7 @@ if (!empty($_GET['poll'])) {
|
|||
if ($poll) {
|
||||
$poll_id = $poll->id;
|
||||
} else {
|
||||
$smarty->assign('error', __('Error', 'This poll doesn\'t exist !'));
|
||||
$smarty->assign('error', __('Error', "This poll doesn't exist!"));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
@ -80,8 +75,8 @@ $messagePollCreated = $sessionService->get("Framadate", "messagePollCreated", FA
|
|||
|
||||
if ($messagePollCreated) {
|
||||
$sessionService->remove("Framadate", "messagePollCreated");
|
||||
|
||||
$message = new Message('success', __('adminstuds', 'The poll is created.'));
|
||||
|
||||
$message = new Message('success', __('adminstuds', 'The poll was created.'));
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
|
@ -219,12 +214,17 @@ $selectedNewVotes = [];
|
|||
|
||||
if (!empty($_POST['save'])) { // Save edition of an old vote
|
||||
$name = $inputService->filterName($_POST['name']);
|
||||
if(empty($_POST['mail']) || $inputService->filterMail($_POST['mail'])===false) {
|
||||
$mail = null;
|
||||
} else {
|
||||
$mail = $inputService->filterMail($_POST['mail']);
|
||||
}
|
||||
$editedVote = filter_input(INPUT_POST, 'save', FILTER_VALIDATE_INT);
|
||||
$choices = $inputService->filterArray($_POST['choices'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => CHOICE_REGEX]]);
|
||||
$slots_hash = $inputService->filterMD5($_POST['control']);
|
||||
|
||||
if (empty($editedVote)) {
|
||||
$message = new Message('danger', __('Error', 'Something is going wrong...'));
|
||||
$message = new Message('danger', __('Error', 'Something has gone wrong...'));
|
||||
}
|
||||
if (count($choices) !== count($_POST['choices'])) {
|
||||
$message = new Message('danger', __('Error', 'There is a problem with your choices'));
|
||||
|
@ -233,14 +233,14 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
|||
if ($message === null) {
|
||||
// Update vote
|
||||
try {
|
||||
$result = $pollService->updateVote($poll_id, $editedVote, $name, $choices, $slots_hash);
|
||||
$result = $pollService->updateVote($poll_id, $editedVote, $name, $choices, $slots_hash, $mail);
|
||||
if ($result) {
|
||||
$message = new Message('success', __('adminstuds', 'Vote updated'));
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Update vote failed'));
|
||||
}
|
||||
} catch (AlreadyExistsException $aee) {
|
||||
$message = new Message('danger', __('Error', 'The name you\'ve chosen already exist in this poll!'));
|
||||
$message = new Message('danger', __('Error', "The name you've chosen already exists in this poll!"));
|
||||
} catch (ConcurrentEditionException $cee) {
|
||||
$message = new Message('danger', __('Error', 'Poll has been updated before you vote'));
|
||||
} catch (ConcurrentVoteException $cve) {
|
||||
|
@ -249,6 +249,11 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
|||
}
|
||||
} elseif (isset($_POST['save'])) { // Add a new vote
|
||||
$name = $inputService->filterName($_POST['name']);
|
||||
if(empty($_POST['mail']) || $inputService->filterMail($_POST['mail'])===false) {
|
||||
$mail = null;
|
||||
} else {
|
||||
$mail = $inputService->filterMail($_POST['mail']);
|
||||
}
|
||||
$choices = $inputService->filterArray($_POST['choices'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => CHOICE_REGEX]]);
|
||||
$slots_hash = $inputService->filterMD5($_POST['control']);
|
||||
|
||||
|
@ -262,7 +267,7 @@ if (!empty($_POST['save'])) { // Save edition of an old vote
|
|||
if ($message === null) {
|
||||
// Add vote
|
||||
try {
|
||||
$result = $pollService->addVote($poll_id, $name, $choices, $slots_hash);
|
||||
$result = $pollService->addVote($poll_id, $name, $choices, $slots_hash, $mail);
|
||||
if ($result) {
|
||||
$message = new Message('success', __('adminstuds', 'Vote added'));
|
||||
} else {
|
||||
|
@ -392,12 +397,43 @@ if (isset($_GET['delete_column'])) {
|
|||
}
|
||||
|
||||
if ($result) {
|
||||
$message = new Message('success', __('adminstuds', 'Column removed'));
|
||||
$message = new Message('success', __('adminstuds', 'Column deleted'));
|
||||
} else {
|
||||
$message = new Message('danger', __('Error', 'Failed to delete column'));
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// Collect the mails of a column
|
||||
// -------------------------------
|
||||
|
||||
if (isset($_GET['collect_mail'])) {
|
||||
$column_str = strval(filter_input(INPUT_GET, 'collect_mail', FILTER_DEFAULT));
|
||||
$column_str = strval(Utils::base64url_decode($column_str));
|
||||
$column = intval($column_str);
|
||||
$votes = $pollService->splitVotes($pollService->allVotesByPollId($poll_id));
|
||||
$mails_yes = $mails_ifneedbe = $mails_no = [];
|
||||
foreach ($votes as $vote) {
|
||||
if (intval($vote->choices[$column]) === 2 && $vote->mail !== NULL) {
|
||||
$mails_yes[] = $vote->mail;
|
||||
} elseif (intval($vote->choices[$column]) === 1 && $vote->mail !== NULL) {
|
||||
$mails_ifneedbe[] = $vote->mail;
|
||||
} elseif($vote->mail !== NULL) {
|
||||
$mails_no[] = $vote->mail;
|
||||
}
|
||||
}
|
||||
|
||||
$smarty->assign('poll_id', $poll_id);
|
||||
$smarty->assign('admin_poll_id', $admin_poll_id);
|
||||
$smarty->assign('admin', true);
|
||||
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title . ' - ' . __('adminstuds', 'Collect the emails of the polled users for the choice'));
|
||||
$smarty->assign('mails_yes', $mails_yes);
|
||||
$smarty->assign('mails_ifneedbe', $mails_ifneedbe);
|
||||
$smarty->assign('mails_no', $mails_no);
|
||||
$smarty->display('display_mails.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
// -------------------------------
|
||||
// Add a slot
|
||||
// -------------------------------
|
||||
|
@ -424,18 +460,22 @@ if (isset($_POST['confirm_add_column'])) {
|
|||
exit_displaying_add_column(new Message('danger', __('Error', "Can't create an empty column.")));
|
||||
}
|
||||
if ($poll->format === 'D') {
|
||||
$date = DateTime::createFromFormat(__('Date', 'datetime_parseformat'), $_POST['newdate'])->setTime(0, 0, 0);
|
||||
$date = $inputService->filterDate($_POST['newdate']);
|
||||
$time = $date->getTimestamp();
|
||||
$newmoment = str_replace(',', '-', strip_tags($_POST['newmoment']));
|
||||
$newmoment = strip_tags($_POST['newmoment']);
|
||||
$adminPollService->addDateSlot($poll_id, $time, $newmoment);
|
||||
} else {
|
||||
$newslot = str_replace(',', '-', strip_tags($_POST['choice']));
|
||||
$newslot = strip_tags($_POST['choice']);
|
||||
$adminPollService->addClassicSlot($poll_id, $newslot);
|
||||
}
|
||||
|
||||
$message = new Message('success', __('adminstuds', 'Choice added'));
|
||||
} catch (SlotAlreadyExistsException $e) {
|
||||
exit_displaying_add_column(new Message('danger', __f('Error', 'The column %s already exists', $e->getSlot())));
|
||||
} catch (MomentAlreadyExistsException $e) {
|
||||
exit_displaying_add_column(new Message('danger', __('Error', 'The column already exists')));
|
||||
exit_displaying_add_column(new Message('danger', __f('Error', 'The column %s already exists with %s', $e->getSlot(), $e->getMoment())));
|
||||
} catch (DBALException $e) {
|
||||
exit_displaying_add_column(new Message('danger', __('Error', 'Error while adding a column')));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -443,14 +483,16 @@ if (isset($_POST['confirm_add_column'])) {
|
|||
$slots = $pollService->allSlotsByPoll($poll);
|
||||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
$comments = $pollService->allCommentsByPollId($poll_id);
|
||||
$deletion_date = clone $poll->end_date;
|
||||
$deletion_date->add(new DateInterval('P' . PURGE_DELAY . 'D'));
|
||||
|
||||
// Assign data to template
|
||||
$smarty->assign('poll_id', $poll_id);
|
||||
$smarty->assign('admin_poll_id', $admin_poll_id);
|
||||
$smarty->assign('poll', $poll);
|
||||
$smarty->assign('title', __('Generic', 'Poll') . ' - ' . $poll->title);
|
||||
$smarty->assign('expired', strtotime($poll->end_date) < time());
|
||||
$smarty->assign('deletion_date', strtotime($poll->end_date) + PURGE_DELAY * 86400);
|
||||
$smarty->assign('expired', $poll->end_date < new DateTime());
|
||||
$smarty->assign('deletion_date', $deletion_date);
|
||||
$smarty->assign('slots', $poll->format === 'D' ? $pollService->splitSlots($slots) : $slots);
|
||||
$smarty->assign('slots_hash', $pollService->hashSlots($slots));
|
||||
$smarty->assign('votes', $pollService->splitVotes($votes));
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
<?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/OpenSondage: 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;
|
||||
|
||||
use Doctrine\DBAL\Migrations\AbstractMigration as DoctrineAbstractMigration;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
|
||||
abstract class AbstractMigration extends DoctrineAbstractMigration
|
||||
{
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @param $class
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @return bool
|
||||
*/
|
||||
public function legacyCheck(Schema $schema, $class)
|
||||
{
|
||||
/**
|
||||
* If there's no legacy table, we can go on
|
||||
*/
|
||||
if (!$schema->hasTable(Utils::table(MIGRATION_TABLE))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$migration_table = $schema->getTable(Utils::table(MIGRATION_TABLE));
|
||||
/**
|
||||
* We check the migration table
|
||||
*/
|
||||
if ($migration_table->hasColumn('name')) {
|
||||
/** @var $stmt \Doctrine\DBAL\Driver\Statement */
|
||||
$stmt = $this->connection->prepare('SELECT * FROM ' . Utils::table(MIGRATION_TABLE) . ' WHERE name = ?');
|
||||
$stmt->execute([$class]);
|
||||
return $stmt->rowCount() > 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -24,34 +24,34 @@ class Choice
|
|||
* Name of the Choice
|
||||
*/
|
||||
private $name;
|
||||
|
||||
|
||||
/**
|
||||
* All availables slots for this Choice.
|
||||
* All available slots for this Choice.
|
||||
*/
|
||||
private $slots;
|
||||
|
||||
public function __construct($name='')
|
||||
|
||||
public function __construct($name = '')
|
||||
{
|
||||
$this->name = $name;
|
||||
$this->slots = [];
|
||||
}
|
||||
|
||||
|
||||
public function addSlot($slot)
|
||||
{
|
||||
$this->slots[] = $slot;
|
||||
}
|
||||
|
||||
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
|
||||
public function getSlots()
|
||||
{
|
||||
return $this->slots;
|
||||
}
|
||||
|
||||
static function compare(Choice $a, Choice $b)
|
||||
|
||||
public static function compare(Choice $a, Choice $b)
|
||||
{
|
||||
return strcmp($a->name, $b->name);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
<?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/OpenSondage: 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;
|
||||
|
||||
/**
|
||||
* Class CollectMail
|
||||
*
|
||||
* Is used to specify the poll's edition permissions.
|
||||
* @TODO : wait to use the SplEnum
|
||||
*
|
||||
* @package Framadate
|
||||
*/
|
||||
class CollectMail { // extends SplEnum
|
||||
const NO_COLLECT = 0;
|
||||
const COLLECT = 1;
|
||||
const COLLECT_REQUIRED = 2;
|
||||
const COLLECT_REQUIRED_VERIFIED = 3;
|
||||
}
|
|
@ -1,7 +1,20 @@
|
|||
<?php
|
||||
namespace Framadate\Exception;
|
||||
|
||||
class MomentAlreadyExistsException extends \Exception {
|
||||
function __construct() {
|
||||
class MomentAlreadyExistsException extends SlotAlreadyExistsException {
|
||||
public $moment;
|
||||
|
||||
public function __construct($slot, $moment, $message = '')
|
||||
{
|
||||
parent::__construct($slot, $message);
|
||||
$this->moment = $moment;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getMoment()
|
||||
{
|
||||
return $this->moment;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
namespace Framadate\Exception;
|
||||
|
||||
class SlotAlreadyExistsException extends \Exception {
|
||||
public $slot;
|
||||
|
||||
public function __construct($slot, $message = '')
|
||||
{
|
||||
parent::__construct($message);
|
||||
$this->slot = $slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getSlot()
|
||||
{
|
||||
return $this->slot;
|
||||
}
|
||||
}
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
namespace Framadate;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class Form
|
||||
{
|
||||
public $title;
|
||||
|
@ -26,9 +28,20 @@ class Form
|
|||
public $admin_name;
|
||||
public $admin_mail;
|
||||
public $format;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
*/
|
||||
public $end_date;
|
||||
|
||||
/**
|
||||
* @var DateTime
|
||||
*/
|
||||
public $creation_date;
|
||||
|
||||
public $choix_sondage;
|
||||
public $ValueMax;
|
||||
public $errors = [];
|
||||
|
||||
/**
|
||||
* Tells if users can modify their choices.
|
||||
|
@ -82,13 +95,21 @@ class Form
|
|||
*/
|
||||
public $results_publicly_visible;
|
||||
|
||||
/**
|
||||
* Tells if voters email addresses are collected or not.
|
||||
* @var \Framadate\CollectMail
|
||||
*/
|
||||
public $collect_users_mail;
|
||||
|
||||
/**
|
||||
* List of available choices
|
||||
*/
|
||||
private $choices;
|
||||
|
||||
public function __construct(){
|
||||
public function __construct()
|
||||
{
|
||||
$this->editable = Editable::EDITABLE_BY_ALL;
|
||||
$this->collect_users_mail = CollectMail::NO_COLLECT;
|
||||
$this->clearChoices();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?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/OpenSondage: 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;
|
||||
|
||||
use PDO;
|
||||
|
||||
class FramaDB {
|
||||
/**
|
||||
* PDO Object, connection to database.
|
||||
*/
|
||||
private $pdo = null;
|
||||
|
||||
function __construct($connection_string, $user, $password) {
|
||||
$this->pdo = new \PDO($connection_string, $user, $password);
|
||||
$this->pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
|
||||
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \PDO Connection to database
|
||||
*/
|
||||
function getPDO() {
|
||||
return $this->pdo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all tables in database.
|
||||
*
|
||||
* @return array The array of table names
|
||||
*/
|
||||
function allTables() {
|
||||
$result = $this->pdo->query('SHOW TABLES');
|
||||
$schemas = $result->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
return $schemas;
|
||||
}
|
||||
|
||||
function prepare($sql) {
|
||||
return $this->pdo->prepare($sql);
|
||||
}
|
||||
|
||||
function beginTransaction() {
|
||||
$this->pdo->beginTransaction();
|
||||
}
|
||||
|
||||
function commit() {
|
||||
$this->pdo->commit();
|
||||
}
|
||||
|
||||
function rollback() {
|
||||
$this->pdo->rollback();
|
||||
}
|
||||
|
||||
function errorCode() {
|
||||
return $this->pdo->errorCode();
|
||||
}
|
||||
|
||||
function errorInfo() {
|
||||
return $this->pdo->errorInfo();
|
||||
}
|
||||
|
||||
function query($sql) {
|
||||
return $this->pdo->query($sql);
|
||||
}
|
||||
|
||||
public function lastInsertId() {
|
||||
return $this->pdo->lastInsertId();
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field hidden on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumn_hidden_In_poll_For_0_9 implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Add column "hidden" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterPollTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('poll') . '`
|
||||
ADD `hidden` TINYINT( 1 ) NOT NULL DEFAULT "0"');
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field receiveNewComments on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumn_receiveNewComments_For_0_9 implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Add column "receiveNewComments" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterPollTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('poll') . '`
|
||||
ADD `receiveNewComments` TINYINT(1) DEFAULT \'0\'
|
||||
AFTER `receiveNewVotes`');
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field uniqId on the vote table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumn_uniqId_In_vote_For_0_9 implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Add column "uniqId" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterPollTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('vote') . '`
|
||||
ADD `uniqId` CHAR(16) NOT NULL
|
||||
AFTER `id`,
|
||||
ADD INDEX (`uniqId`) ;');
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the fields password_hash and results_publicly_visible on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumns_password_hash_And_results_publicly_visible_In_poll_For_0_9 implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Add columns "password_hash" and "results_publicly_visible" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterPollTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('poll') . '`
|
||||
ADD `password_hash` VARCHAR(255) NULL DEFAULT NULL ,
|
||||
ADD `results_publicly_visible` TINYINT(1) NULL DEFAULT NULL');
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration sets Poll.end_date to NULL by default
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.1
|
||||
*/
|
||||
class Fix_MySQL_No_Zero_Date implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Sets Poll end_date to NULL by default (work around MySQL NO_ZERO_DATE)';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->prepare("SELECT Column_Default from Information_Schema.Columns where Table_Name = ? AND Column_Name = ?;");
|
||||
$stmt->bindValue(1, Utils::table('poll'));
|
||||
$stmt->bindValue(2, 'end_date');
|
||||
$stmt->execute();
|
||||
$default = $stmt->fetch(\PDO::FETCH_COLUMN);
|
||||
|
||||
$driver_name = $pdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
return $default !== null && $driver_name === 'mysql';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool|void if the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$pdo->exec('ALTER TABLE ' . Utils::table('poll') . ' MODIFY end_date TIMESTAMP NULL DEFAULT NULL;');
|
||||
}
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* Class From_0_0_to_0_8_Migration
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.8
|
||||
*/
|
||||
class From_0_0_to_0_8_Migration implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'First installation of the Framadate application (v0.8)';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES like \'' . TABLENAME_PREFIX . '%\''); //issue187 : pouvoir installer framadate dans une base contenant d'autres tables.
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if there is no tables but the MIGRATION_TABLE one
|
||||
$diff = array_diff($tables, [Utils::table(MIGRATION_TABLE)]);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
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 NULL DEFAULT NULL,
|
||||
`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;');
|
||||
|
||||
$pdo->exec('
|
||||
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;');
|
||||
|
||||
$pdo->exec('
|
||||
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 ;');
|
||||
|
||||
$pdo->exec('
|
||||
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 ;');
|
||||
}
|
||||
}
|
|
@ -1,292 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This class executes the aciton in database to migrate data from version 0.8 to 0.9.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class From_0_8_to_0_9_Migration implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'From 0.8 to 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.8 are presents
|
||||
$diff = array_diff(['sondage', 'sujet_studs', 'comments', 'user_studs'], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->createPollTable($pdo);
|
||||
$this->createCommentTable($pdo);
|
||||
$this->createSlotTable($pdo);
|
||||
$this->createVoteTable($pdo);
|
||||
|
||||
$pdo->beginTransaction();
|
||||
$this->migrateFromSondageToPoll($pdo);
|
||||
$this->migrateFromCommentsToComment($pdo);
|
||||
$this->migrateFromSujetStudsToSlot($pdo);
|
||||
$this->migrateFromUserStudsToVote($pdo);
|
||||
$pdo->commit();
|
||||
|
||||
$this->dropOldTables($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function createPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('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 NULL DEFAULT NULL,
|
||||
`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');
|
||||
}
|
||||
|
||||
private function migrateFromSondageToPoll(\PDO $pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT
|
||||
`id_sondage`,
|
||||
`id_sondage_admin`,
|
||||
`titre`,
|
||||
`commentaires`,
|
||||
`nom_admin`,
|
||||
`mail_admin`,
|
||||
`date_creation`,
|
||||
`date_fin`,
|
||||
SUBSTR(`format`, 1, 1) AS `format`,
|
||||
CASE SUBSTR(`format`, 2, 1)
|
||||
WHEN \'+\' THEN 1
|
||||
ELSE 0 END AS `editable`,
|
||||
`mailsonde`,
|
||||
CASE SUBSTR(`format`, 2, 1)
|
||||
WHEN \'-\' THEN 0
|
||||
ELSE 1 END AS `active`
|
||||
FROM sondage');
|
||||
|
||||
$insert = $pdo->prepare('
|
||||
INSERT INTO `' . Utils::table('poll') . '`
|
||||
(`id`, `admin_id`, `title`, `description`, `admin_name`, `admin_mail`, `creation_date`, `end_date`, `format`, `editable`, `receiveNewVotes`, `active`)
|
||||
VALUE (?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$row->id_sondage_admin,
|
||||
$this->unescape($row->titre),
|
||||
$this->unescape($row->commentaires),
|
||||
$this->unescape($row->nom_admin),
|
||||
$this->unescape($row->mail_admin),
|
||||
$row->date_creation,
|
||||
$row->date_fin,
|
||||
$row->format,
|
||||
$row->editable,
|
||||
$row->mailsonde,
|
||||
$row->active
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createSlotTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('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');
|
||||
}
|
||||
|
||||
private function migrateFromSujetStudsToSlot(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SELECT * FROM sujet_studs');
|
||||
$sujets = $stmt->fetchAll();
|
||||
$slots = [];
|
||||
|
||||
foreach ($sujets as $sujet) {
|
||||
$newSlots = $this->transformSujetToSlot($sujet);
|
||||
foreach ($newSlots as $newSlot) {
|
||||
$slots[] = $newSlot;
|
||||
}
|
||||
}
|
||||
|
||||
$prepared = $pdo->prepare('INSERT INTO ' . Utils::table('slot') . ' (`poll_id`, `title`, `moments`) VALUE (?,?,?)');
|
||||
foreach ($slots as $slot) {
|
||||
$prepared->execute([
|
||||
$slot->poll_id,
|
||||
$this->unescape($slot->title),
|
||||
!empty($slot->moments) ? $this->unescape($slot->moments) : null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createCommentTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('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');
|
||||
}
|
||||
|
||||
private function migrateFromCommentsToComment(\PDO $pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT
|
||||
`id_sondage`,
|
||||
`usercomment`,
|
||||
`comment`
|
||||
FROM `comments`');
|
||||
|
||||
$insert = $pdo->prepare('
|
||||
INSERT INTO `' . Utils::table('comment') . '` (`poll_id`, `name`, `comment`)
|
||||
VALUE (?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$this->unescape($row->usercomment),
|
||||
$this->unescape($row->comment)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function createVoteTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
CREATE TABLE IF NOT EXISTS `' . Utils::table('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');
|
||||
}
|
||||
|
||||
private function migrateFromUserStudsToVote(\PDO $pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT
|
||||
`id_sondage`,
|
||||
`nom`,
|
||||
REPLACE(REPLACE(REPLACE(`reponses`, 1, \'X\'), 2, 1), \'X\', 2) reponses
|
||||
FROM `user_studs`');
|
||||
|
||||
$insert = $pdo->prepare('
|
||||
INSERT INTO `' . Utils::table('vote') . '` (`poll_id`, `name`, `choices`)
|
||||
VALUE (?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$this->unescape($row->nom),
|
||||
$row->reponses
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function transformSujetToSlot($sujet) {
|
||||
$slots = [];
|
||||
$ex = explode(',', $sujet->sujet);
|
||||
$isDatePoll = strpos($sujet->sujet, '@');
|
||||
$lastSlot = null;
|
||||
|
||||
foreach ($ex as $atomicSlot) {
|
||||
if ($isDatePoll === false) { // Classic poll
|
||||
$slot = new \stdClass();
|
||||
$slot->poll_id = $sujet->id_sondage;
|
||||
$slot->title = $atomicSlot;
|
||||
$slots[] = $slot;
|
||||
} else { // Date poll
|
||||
$values = explode('@', $atomicSlot);
|
||||
if ($lastSlot === null || $lastSlot->title !== $values[0]) {
|
||||
$lastSlot = new \stdClass();
|
||||
$lastSlot->poll_id = $sujet->id_sondage;
|
||||
$lastSlot->title = $values[0];
|
||||
$lastSlot->moments = count($values) === 2 ? $values[1] : '-';
|
||||
$slots[] = $lastSlot;
|
||||
} else {
|
||||
$lastSlot->moments .= ',' . (count($values) === 2 ? $values[1] : '-');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $slots;
|
||||
}
|
||||
|
||||
private function dropOldTables(\PDO $pdo) {
|
||||
$pdo->exec('DROP TABLE `comments`');
|
||||
$pdo->exec('DROP TABLE `sujet_studs`');
|
||||
$pdo->exec('DROP TABLE `user_studs`');
|
||||
$pdo->exec('DROP TABLE `sondage`');
|
||||
}
|
||||
|
||||
private function unescape($value) {
|
||||
return stripslashes(html_entity_decode($value, ENT_QUOTES));
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Security\Token;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration generate uniqId for all legacy votes.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Generate_uniqId_for_old_votes implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
function description() {
|
||||
return 'Generate "uniqId" in "vote" table for all legacy votes';
|
||||
}
|
||||
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$pdo->beginTransaction();
|
||||
$this->generateUniqIdsForEmptyOnes($pdo);
|
||||
$pdo->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function generateUniqIdsForEmptyOnes($pdo) {
|
||||
$select = $pdo->query('
|
||||
SELECT `id`
|
||||
FROM `' . Utils::table('vote') . '`
|
||||
WHERE `uniqid` = \'\'');
|
||||
|
||||
$update = $pdo->prepare('
|
||||
UPDATE `' . Utils::table('vote') . '`
|
||||
SET `uniqid` = :uniqid
|
||||
WHERE `id` = :id');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$token = Token::getToken(16);
|
||||
$update->execute([
|
||||
'uniqid' => $token,
|
||||
'id' => $row->id
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
namespace Framadate\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
class Increase_pollId_size implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Increase the size of id column in poll table';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the Migration should be executed
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the execution succeeded
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterCommentTable($pdo);
|
||||
$this->alterPollTable($pdo);
|
||||
$this->alterSlotTable($pdo);
|
||||
$this->alterVoteTable($pdo);
|
||||
}
|
||||
|
||||
private function alterCommentTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('comment') . '`
|
||||
CHANGE `poll_id` `poll_id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('poll') . '`
|
||||
CHANGE `id` `id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
|
||||
}
|
||||
|
||||
private function alterSlotTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('slot') . '`
|
||||
CHANGE `poll_id` `poll_id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
|
||||
}
|
||||
|
||||
private function alterVoteTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('vote') . '`
|
||||
CHANGE `poll_id` `poll_id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
<?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/OpenSondage: 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\Migration;
|
||||
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration RPad votes from version 0.8.
|
||||
* Because some votes does not have enough values for their poll.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class RPadVotes_from_0_8 implements Migration {
|
||||
function description() {
|
||||
return 'RPad votes from version 0.8.';
|
||||
}
|
||||
|
||||
function preCondition(\PDO $pdo) {
|
||||
$stmt = $pdo->query('SHOW TABLES');
|
||||
$tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
|
||||
|
||||
// Check if tables of v0.9 are presents
|
||||
$diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
|
||||
return count($diff) === 0;
|
||||
}
|
||||
|
||||
function execute(\PDO $pdo) {
|
||||
$pdo->beginTransaction();
|
||||
$this->rpadVotes($pdo);
|
||||
$pdo->commit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function rpadVotes($pdo) {
|
||||
$pdo->exec('UPDATE ' . Utils::table('vote') . ' fv
|
||||
INNER JOIN (
|
||||
SELECT v.id, RPAD(v.choices, inn.slots_count, \'0\') new_choices
|
||||
FROM ' . Utils::table('vote') . ' v
|
||||
INNER JOIN
|
||||
(SELECT s.poll_id, SUM(IFNULL(LENGTH(s.moments) - LENGTH(REPLACE(s.moments, \',\', \'\')) + 1, 1)) slots_count
|
||||
FROM ' . Utils::table('slot') . ' s
|
||||
GROUP BY s.poll_id
|
||||
ORDER BY s.poll_id) inn ON inn.poll_id = v.poll_id
|
||||
WHERE LENGTH(v.choices) != inn.slots_count
|
||||
) computed ON fv.id = computed.id
|
||||
SET fv.choices = computed.new_choices');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
|
||||
/**
|
||||
* Class From_0_0_to_0_8_Migration
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.8
|
||||
*/
|
||||
class Version20150101000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'First installation of the Framadate application (v0.8)';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @return void true is the execution succeeded
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema,'Framadate\Migration\From_0_0_to_0_8_Migration'), 'Migration has been executed in an earlier database migration system');
|
||||
$sondage = $schema->createTable('sondage');
|
||||
$sondage->addColumn('id_sondage', 'string');
|
||||
$sondage->addColumn('commentaires', 'text');
|
||||
$sondage->addColumn('mail_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('nom_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('titre', 'text');
|
||||
$sondage->addColumn('id_sondage_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('date_creation', 'datetime', ['default' => (new \DateTime())->format('Y-m-d H:i:s')]);
|
||||
$sondage->addColumn('date_fin', 'datetime', ['notnull' => false]);
|
||||
$sondage->addColumn('format', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('mailsonde', 'boolean', ['default' => false]);
|
||||
$sondage->addColumn('statut', 'integer', ['default' => '1']);
|
||||
$sondage->addUniqueIndex(['id_sondage'], 'sondage_index_id_sondage');
|
||||
|
||||
$sujetStuds = $schema->createTable('sujet_studs');
|
||||
$sujetStuds->addColumn('id_sondage', 'string');
|
||||
$sujetStuds->addColumn('sujet', 'text');
|
||||
$sujetStuds->addIndex(['id_sondage'], 'sujet_studs_index_id_sondage');
|
||||
|
||||
$comments = $schema->createTable('comments');
|
||||
$schema->createSequence('comments_seq');
|
||||
$comments->addColumn('id_comment', 'integer', ['autoincrement' => true]);
|
||||
$comments->addColumn('id_sondage', 'string');
|
||||
$comments->addColumn('comment', 'text');
|
||||
$comments->addColumn('usercomment', 'text', ['notnull' => false]);
|
||||
$comments->addUniqueIndex(['id_comment'], 'comments_index_id_comment');
|
||||
$comments->addIndex(['id_sondage'], 'comments_index_id_sondage');
|
||||
|
||||
$userStuds = $schema->createTable('user_studs');
|
||||
$schema->createSequence('user_studs_seq');
|
||||
$userStuds->addColumn('id_users', 'integer', ['autoincrement' => true]);
|
||||
$userStuds->addColumn('nom', 'string');
|
||||
$userStuds->addColumn('id_sondage', 'string');
|
||||
$userStuds->addColumn('reponses', 'text');
|
||||
$userStuds->addUniqueIndex(['id_users'], 'user_studs_index_id_users');
|
||||
$userStuds->addIndex(['id_sondage'], 'user_studs_index_id_sondage');
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$this->addSql('DROP TABLE sondage');
|
||||
$this->addSql('DROP TABLE sujet_studs');
|
||||
$this->addSql('DROP TABLE comments');
|
||||
$this->addSql('DROP TABLE user_studs');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This class executes the aciton in database to migrate data from version 0.8 to 0.9.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150102000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'From 0.8 to 0.9 first part';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema,'Framadate\Migration\From_0_8_to_0_9_Migration'), 'Migration has been executed in an earlier database migration system');
|
||||
foreach (['sondage', 'sujet_studs', 'comments', 'user_studs'] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
|
||||
$this->createPollTable($schema);
|
||||
$this->createCommentTable($schema);
|
||||
$this->createSlotTable($schema);
|
||||
$this->createVoteTable($schema);
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$sondage = $schema->createTable('sondage');
|
||||
$sondage->addColumn('id_sondage', 'string');
|
||||
$sondage->addColumn('commentaires', 'text');
|
||||
$sondage->addColumn('mail_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('nom_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('titre', 'text');
|
||||
$sondage->addColumn('id_sondage_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('date_creation', 'datetime', ['default' => (new \DateTime())->format('Y-m-d H:i:s')]);
|
||||
$sondage->addColumn('date_fin', 'datetime', ['notnull' => false]);
|
||||
$sondage->addColumn('format', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('mailsonde', 'boolean', ['default' => false]);
|
||||
$sondage->addColumn('statut', 'integer', ['default' => '1']);
|
||||
$sondage->addUniqueIndex(['id_sondage'], 'sondage_index_id_sondage');
|
||||
|
||||
$sujetStuds = $schema->createTable('sujet_studs');
|
||||
$sujetStuds->addColumn('id_sondage', 'string');
|
||||
$sujetStuds->addColumn('sujet', 'text');
|
||||
$sujetStuds->addIndex(['id_sondage'], 'sujet_studs_index_id_sondage');
|
||||
|
||||
$comments = $schema->createTable('comments');
|
||||
$schema->createSequence('comments_seq');
|
||||
$comments->addColumn('id_comment', 'integer', ['autoincrement' => true]);
|
||||
$comments->addColumn('id_sondage', 'string');
|
||||
$comments->addColumn('comment', 'text');
|
||||
$comments->addColumn('usercomment', 'text', ['notnull' => false]);
|
||||
$comments->addUniqueIndex(['id_comment'], 'comments_index_id_comment');
|
||||
$comments->addIndex(['id_sondage'], 'comments_index_id_sondage');
|
||||
|
||||
$userStuds = $schema->createTable('user_studs');
|
||||
$schema->createSequence('user_studs_seq');
|
||||
$userStuds->addColumn('id_users', 'integer', ['autoincrement' => true]);
|
||||
$userStuds->addColumn('nom', 'string');
|
||||
$userStuds->addColumn('id_sondage', 'string');
|
||||
$userStuds->addColumn('reponses', 'text');
|
||||
$userStuds->addUniqueIndex(['id_users'], 'user_studs_index_id_users');
|
||||
$userStuds->addIndex(['id_sondage'], 'user_studs_index_id_sondage');
|
||||
|
||||
$schema->dropTable(Utils::table('poll'));
|
||||
$schema->dropTable(Utils::table('comment'));
|
||||
$schema->dropTable(Utils::table('vote'));
|
||||
$schema->dropTable(Utils::table('slot'));
|
||||
}
|
||||
|
||||
private function createPollTable(Schema $schema)
|
||||
{
|
||||
$poll = $schema->createTable(Utils::table('poll'));
|
||||
$poll->addColumn('id', 'string');
|
||||
$poll->addColumn('admin_id', 'string');
|
||||
$poll->addColumn('title', 'text');
|
||||
$poll->addColumn('description', 'text', ['notnull' => false]);
|
||||
$poll->addColumn('admin_name', 'string');
|
||||
$poll->addColumn('admin_mail', 'string', ['notnull' => false]);
|
||||
$poll->addColumn('creation_date', 'datetime', ['default' => (new \DateTime())->format('Y-m-d H:i:s')]);
|
||||
$poll->addColumn('end_date', 'datetime', ['notnull' => false]);
|
||||
$poll->addColumn('format', 'string', ['default' => null, 'notnull' => false]);
|
||||
$poll->addColumn('editable', 'integer', ['default' => 0]);
|
||||
$poll->addColumn('receiveNewVotes', 'boolean', ['default' => false]);
|
||||
$poll->addColumn('active', 'boolean', ['default' => true]);
|
||||
$poll->addUniqueIndex(['id'], 'poll_index_id');
|
||||
}
|
||||
|
||||
private function createSlotTable(Schema $schema)
|
||||
{
|
||||
$slot = $schema->createTable(Utils::table('slot'));
|
||||
$schema->createSequence('slot_seq');
|
||||
$slot->addColumn('id', 'integer', ['autoincrement' => true]);
|
||||
$slot->addColumn('poll_id', 'string');
|
||||
$slot->addColumn('title', 'text');
|
||||
$slot->addColumn('moments', 'text', ['notnull' => false]);
|
||||
$slot->addUniqueIndex(['id'], 'slot_index_id');
|
||||
$slot->addIndex(['poll_id'], 'slot_index_poll_id');
|
||||
}
|
||||
|
||||
private function createCommentTable(Schema $schema)
|
||||
{
|
||||
$comment = $schema->createTable(Utils::table('comment'));
|
||||
$schema->createSequence('comment_seq');
|
||||
$comment->addColumn('id', 'integer', ['autoincrement' => true]);
|
||||
$comment->addColumn('poll_id', 'string');
|
||||
$comment->addColumn('name', 'text', ['notnull' => false]);
|
||||
$comment->addColumn('comment', 'text');
|
||||
$comment->addUniqueIndex(['id'], 'comment_index_id');
|
||||
$comment->addIndex(['poll_id'], 'comment_index_poll_id');
|
||||
}
|
||||
|
||||
private function createVoteTable(Schema $schema)
|
||||
{
|
||||
$vote = $schema->createTable(Utils::table('vote'));
|
||||
$schema->createSequence('vote_seq');
|
||||
$vote->addColumn('id', 'integer', ['autoincrement' => true]);
|
||||
$vote->addColumn('poll_id', 'string');
|
||||
$vote->addColumn('name', 'string');
|
||||
$vote->addColumn('choices', 'string');
|
||||
$vote->addUniqueIndex(['id'], 'vote_index_id');
|
||||
$vote->addIndex(['poll_id'], 'vote_index_poll_id');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This class executes the aciton in database to migrate data from version 0.8 to 0.9.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150102100000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'From 0.8 to 0.9 second part';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema,'Framadate\Migration\From_0_8_to_0_9_Migration'), 'Migration has been executed in an earlier database migration system');
|
||||
foreach ([Utils::table('poll'), Utils::table('comment'), Utils::table('slot'), Utils::table('vote')] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
|
||||
$this->migrateFromSondageToPoll();
|
||||
$this->migrateFromCommentsToComment();
|
||||
$this->migrateFromSujetStudsToSlot();
|
||||
//$this->migrateFromUserStudsToVote();
|
||||
|
||||
$this->dropOldTables($schema);
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$sondage = $schema->createTable('sondage');
|
||||
$sondage->addColumn('id_sondage', 'string');
|
||||
$sondage->addColumn('commentaires', 'text');
|
||||
$sondage->addColumn('mail_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('nom_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('titre', 'text');
|
||||
$sondage->addColumn('id_sondage_admin', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('date_creation', 'datetime', ['default' => (new \DateTime())->format('Y-m-d H:i:s')]);
|
||||
$sondage->addColumn('date_fin', 'datetime', ['notnull' => false]);
|
||||
$sondage->addColumn('format', 'string', ['notnull' => false]);
|
||||
$sondage->addColumn('mailsonde', 'boolean', ['default' => false]);
|
||||
$sondage->addColumn('statut', 'integer', ['default' => '1']);
|
||||
$sondage->addUniqueIndex(['id_sondage'], 'sondage_index_id_sondage');
|
||||
|
||||
$sujetStuds = $schema->createTable('sujet_studs');
|
||||
$sujetStuds->addColumn('id_sondage', 'string');
|
||||
$sujetStuds->addColumn('sujet', 'text');
|
||||
$sujetStuds->addIndex(['id_sondage'], 'sujet_studs_index_id_sondage');
|
||||
|
||||
$comments = $schema->createTable('comments');
|
||||
$schema->createSequence('comments_seq');
|
||||
$comments->addColumn('id_comment', 'integer', ['autoincrement' => true]);
|
||||
$comments->addColumn('id_sondage', 'string');
|
||||
$comments->addColumn('comment', 'text');
|
||||
$comments->addColumn('usercomment', 'text', ['notnull' => false]);
|
||||
$comments->addUniqueIndex(['id_comment'], 'comments_index_id_comment');
|
||||
$comments->addIndex(['id_sondage'], 'comments_index_id_sondage');
|
||||
|
||||
$userStuds = $schema->createTable('user_studs');
|
||||
$schema->createSequence('user_studs_seq');
|
||||
$userStuds->addColumn('id_users', 'integer', ['autoincrement' => true]);
|
||||
$userStuds->addColumn('nom', 'string');
|
||||
$userStuds->addColumn('id_sondage', 'string');
|
||||
$userStuds->addColumn('reponses', 'text');
|
||||
$userStuds->addUniqueIndex(['id_users'], 'user_studs_index_id_users');
|
||||
$userStuds->addIndex(['id_sondage'], 'user_studs_index_id_sondage');
|
||||
|
||||
$schema->dropTable(Utils::table('poll'));
|
||||
$schema->dropTable(Utils::table('comment'));
|
||||
$schema->dropTable(Utils::table('vote'));
|
||||
$schema->dropTable(Utils::table('slot'));
|
||||
}
|
||||
|
||||
private function migrateFromSondageToPoll()
|
||||
{
|
||||
$select = $this->connection->query('
|
||||
SELECT
|
||||
id_sondage,
|
||||
id_sondage_admin,
|
||||
titre,
|
||||
commentaires,
|
||||
nom_admin,
|
||||
mail_admin,
|
||||
date_creation,
|
||||
date_fin,
|
||||
SUBSTR(format, 1, 1) AS format,
|
||||
CASE SUBSTR(format, 2, 1)
|
||||
WHEN \'+\' THEN 1
|
||||
ELSE 0 END AS editable,
|
||||
mailsonde,
|
||||
CASE SUBSTR(format, 2, 1)
|
||||
WHEN \'-\' THEN 0
|
||||
ELSE 1 END AS active
|
||||
FROM sondage');
|
||||
|
||||
$insert = $this->connection->prepare('
|
||||
INSERT INTO ' . Utils::table('poll') . '
|
||||
(id, admin_id, title, description, admin_name, admin_mail, creation_date, end_date, format, editable, receiveNewVotes, active)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$row->id_sondage_admin,
|
||||
$this->unescape($row->titre),
|
||||
$this->unescape($row->commentaires),
|
||||
$this->unescape($row->nom_admin),
|
||||
$this->unescape($row->mail_admin),
|
||||
$row->date_creation,
|
||||
$row->date_fin,
|
||||
$row->format,
|
||||
$row->editable,
|
||||
$row->mailsonde,
|
||||
$row->active
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function migrateFromSujetStudsToSlot()
|
||||
{
|
||||
$stmt = $this->connection->query('SELECT * FROM sujet_studs');
|
||||
$sujets = $stmt->fetchAll();
|
||||
$slots = [];
|
||||
|
||||
foreach ($sujets as $sujet) {
|
||||
$newSlots = $this->transformSujetToSlot($sujet);
|
||||
foreach ($newSlots as $newSlot) {
|
||||
$slots[] = $newSlot;
|
||||
}
|
||||
}
|
||||
|
||||
$prepared = $this->connection->prepare('INSERT INTO ' . Utils::table('slot') . ' (poll_id, title, moments) VALUES (?,?,?)');
|
||||
foreach ($slots as $slot) {
|
||||
$prepared->execute([
|
||||
$slot->poll_id,
|
||||
$this->unescape($slot->title),
|
||||
!empty($slot->moments) ? $this->unescape($slot->moments) : null
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function migrateFromCommentsToComment()
|
||||
{
|
||||
$select = $this->connection->query('
|
||||
SELECT
|
||||
id_sondage,
|
||||
usercomment,
|
||||
comment
|
||||
FROM comments');
|
||||
|
||||
$insert = $this->connection->prepare('
|
||||
INSERT INTO ' . Utils::table('comment') . ' (poll_id, name, comment)
|
||||
VALUES (?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$this->unescape($row->usercomment),
|
||||
$this->unescape($row->comment)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function migrateFromUserStudsToVote()
|
||||
{
|
||||
$select = $this->connection->query('
|
||||
SELECT
|
||||
id_sondage,
|
||||
nom,
|
||||
REPLACE(REPLACE(REPLACE(reponses, 1, \'X\'), 2, 1), \'X\', 2) reponses
|
||||
FROM user_studs');
|
||||
|
||||
$insert = $this->connection->prepare('
|
||||
INSERT INTO ' . Utils::table('vote') . ' (poll_id, name, choices)
|
||||
VALUES (?,?,?)');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$insert->execute([
|
||||
$row->id_sondage,
|
||||
$this->unescape($row->nom),
|
||||
$row->reponses
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function transformSujetToSlot($sujet)
|
||||
{
|
||||
$slots = [];
|
||||
$ex = explode(',', $sujet->sujet);
|
||||
$isDatePoll = strpos($sujet->sujet, '@');
|
||||
$lastSlot = null;
|
||||
|
||||
foreach ($ex as $atomicSlot) {
|
||||
if ($isDatePoll === false) { // Classic poll
|
||||
$slot = new \stdClass();
|
||||
$slot->poll_id = $sujet->id_sondage;
|
||||
$slot->title = $atomicSlot;
|
||||
$slots[] = $slot;
|
||||
} else { // Date poll
|
||||
$values = explode('@', $atomicSlot);
|
||||
if ($lastSlot === null || $lastSlot->title !== $values[0]) {
|
||||
$lastSlot = new \stdClass();
|
||||
$lastSlot->poll_id = $sujet->id_sondage;
|
||||
$lastSlot->title = $values[0];
|
||||
$lastSlot->moments = count($values) === 2 ? $values[1] : '-';
|
||||
$slots[] = $lastSlot;
|
||||
} else {
|
||||
$lastSlot->moments .= ',' . (count($values) === 2 ? $values[1] : '-');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $slots;
|
||||
}
|
||||
|
||||
private function dropOldTables(Schema $schema)
|
||||
{
|
||||
$schema->dropTable('comments');
|
||||
$schema->dropTable('sujet_studs');
|
||||
$schema->dropTable('user_studs');
|
||||
$schema->dropTable('sondage');
|
||||
}
|
||||
|
||||
private function unescape($value)
|
||||
{
|
||||
return stripslashes(html_entity_decode($value, ENT_QUOTES));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field receiveNewComments on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150117000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Add column "receiveNewComments" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema,'Framadate\Migration\AddColumn_receiveNewComments_For_0_9'), 'Migration has been executed in an earlier database migration system');
|
||||
foreach ([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
$this->skipIf($pollTable->hasColumn('receiveNewComments'), 'Column receiveNewComments already exists');
|
||||
|
||||
$pollTable->addColumn('receiveNewComments', 'boolean', ['default' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
$pollTable->dropColumn('receiveNewComments');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field uniqId on the vote table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150402000000 extends AbstractMigration
|
||||
{
|
||||
private $indexUniqIdName = 'IDX_vote_uniqId';
|
||||
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Add column "uniqId" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\AddColumn_uniqId_In_vote_For_0_9'), 'Migration has been executed in an earlier database migration system');
|
||||
foreach ([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
$voteTable = $schema->getTable(Utils::table('vote'));
|
||||
|
||||
$this->skipIf($voteTable->hasColumn('uniqId'), 'Column uniqId already existing');
|
||||
|
||||
$voteTable->addColumn('uniqId', 'string', ['length' => 16]);
|
||||
$voteTable->addIndex(['uniqId'], $this->indexUniqIdName);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$voteTable = $schema->getTable(Utils::table('vote'));
|
||||
|
||||
$voteTable->dropIndex($this->indexUniqIdName);
|
||||
$voteTable->dropColumn('uniqId');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the field hidden on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150405000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Add column "hidden" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\AddColumn_hidden_In_poll_For_0_9'), 'Migration has been executed in an earlier database migration system');
|
||||
foreach ([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
|
||||
$this->skipIf($pollTable->hasColumn('hidden'), 'Column hidden already existing in table poll');
|
||||
|
||||
$pollTable->addColumn('hidden', 'boolean', ['default' => false, 'notnull' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
|
||||
$pollTable->dropColumn('hidden');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Security\Token;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration generate uniqId for all legacy votes.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150624000000 extends AbstractMigration
|
||||
{
|
||||
public function description()
|
||||
{
|
||||
return 'Generate "uniqId" in "vote" table for all legacy votes';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\Generate_uniqId_for_old_votes'), 'Migration has been executed in an earlier database migration system');
|
||||
foreach ([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
|
||||
$this->connection->beginTransaction();
|
||||
|
||||
$select = $this->connection->query('
|
||||
SELECT id
|
||||
FROM ' . Utils::table('vote') . '
|
||||
WHERE uniqid = \'\'');
|
||||
|
||||
$update = $this->connection->prepare('
|
||||
UPDATE ' . Utils::table('vote') . '
|
||||
SET uniqid = :uniqid
|
||||
WHERE id = :id');
|
||||
|
||||
while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
|
||||
$token = Token::getToken(16);
|
||||
$update->execute([
|
||||
'uniqid' => $token,
|
||||
'id' => $row->id
|
||||
]);
|
||||
}
|
||||
|
||||
$this->connection->commit();
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// TODO: Implement down() method.
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?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<EFBFBD>l DROZ
|
||||
* Authors of Framadate/OpenSondage: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est r<EFBFBD>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<EFBFBD>l DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration RPad votes from version 0.8.
|
||||
* Because some votes does not have enough values for their poll.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20150918000000 extends AbstractMigration
|
||||
{
|
||||
public function description()
|
||||
{
|
||||
return 'RPad votes from version 0.8.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf(
|
||||
$this->legacyCheck($schema, 'Framadate\Migration\RPadVotes_from_0_8'),
|
||||
'Migration has been executed in an earlier database migration system'
|
||||
);
|
||||
foreach ([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table(
|
||||
'comment'
|
||||
)] as $table) {
|
||||
$this->skipIf(!$schema->hasTable($table), 'Missing table ' . $table);
|
||||
}
|
||||
|
||||
$driver_name = $this->connection->getDatabasePlatform()->getName();
|
||||
switch ($driver_name) {
|
||||
case 'mysql':
|
||||
$this->addSql(
|
||||
'UPDATE ' . Utils::table('vote') . ' fv
|
||||
INNER JOIN (
|
||||
SELECT v.id, RPAD(v.choices, inn.slots_count, \'0\') new_choices
|
||||
FROM ' . Utils::table('vote') . ' v
|
||||
INNER JOIN
|
||||
(SELECT s.poll_id, SUM(IFNULL(LENGTH(s.moments) - LENGTH(REPLACE(s.moments, \',\', \'\')) + 1, 1)) slots_count
|
||||
FROM ' . Utils::table('slot') . ' s
|
||||
GROUP BY s.poll_id
|
||||
ORDER BY s.poll_id) inn ON inn.poll_id = v.poll_id
|
||||
WHERE LENGTH(v.choices) != inn.slots_count
|
||||
) computed ON fv.id = computed.id
|
||||
SET fv.choices = computed.new_choices'
|
||||
);
|
||||
break;
|
||||
case 'postgresql':
|
||||
$this->addSql(
|
||||
"UPDATE " . Utils::table('vote') . " fv
|
||||
SET choices = computed.new_choices
|
||||
FROM (
|
||||
SELECT v.id, RPAD(v.choices::text, inn.slots_count::int, '0') new_choices
|
||||
FROM " . Utils::table('vote') . " v
|
||||
INNER JOIN
|
||||
(SELECT s.poll_id, SUM(coalesce(LENGTH(s.moments) - LENGTH(REPLACE(s.moments, ',', '')) + 1, 1)) slots_count
|
||||
FROM " . Utils::table('slot') . " s
|
||||
GROUP BY s.poll_id
|
||||
ORDER BY s.poll_id) inn ON inn.poll_id = v.poll_id
|
||||
WHERE LENGTH(v.choices) != inn.slots_count
|
||||
) computed WHERE fv.id = computed.id"
|
||||
);
|
||||
break;
|
||||
default:
|
||||
$this->skipIf(true, "Not on MySQL or PostgreSQL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// TODO: Implement down() method.
|
||||
}
|
||||
}
|
|
@ -16,8 +16,11 @@
|
|||
* 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\Migration;
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
|
@ -26,45 +29,43 @@ use Framadate\Utils;
|
|||
* @package Framadate\Migration
|
||||
* @version 1.0
|
||||
*/
|
||||
class Alter_Comment_table_for_name_length implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
class Version20151012075900 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
public function description()
|
||||
{
|
||||
return 'Alter the comment table to set a length to the name column.';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
return true;
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\Alter_Comment_table_for_name_length'), 'Migration has been executed in an earlier database migration system');
|
||||
$commentTable = $schema->getTable(Utils::table('comment'));
|
||||
|
||||
$commentTable->changeColumn('name', ['default' => null, 'notnull' => false]);
|
||||
|
||||
$commentTable->changeColumn('name', ['type' => Type::getType('string'), 'length' => 64, 'notnull' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterCommentTable($pdo);
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$commentTable = $schema->getTable(Utils::table('comment'));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterCommentTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('comment') . '`
|
||||
CHANGE `name` `name` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ;');
|
||||
$commentTable->changeColumn('name', ['type' => Type::getType('string')]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration alter the comment table to add a date column.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.0
|
||||
*/
|
||||
class Version20151012082600 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Alter the comment table to add a date column.';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\Alter_Comment_table_adding_date'), 'Migration has been executed in an earlier database migration system');
|
||||
$commentTable = $schema->getTable(Utils::table('comment'));
|
||||
|
||||
$this->skipIf($commentTable->hasColumn('date'), 'Column date in comment table already exists');
|
||||
|
||||
// The default for datetime types is only available for MySQL 5.6
|
||||
// See the "Functionality Added or Changed" section,
|
||||
// "Important Change: In MySQL, the TIMESTAMP data type" element, on
|
||||
// https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-6.html
|
||||
$commentTable->addColumn('date', 'datetime', ['default' => 0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$commentTable = $schema->getTable(Utils::table('comment'));
|
||||
|
||||
$commentTable->dropColumn('comment');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the fields password_hash and results_publicly_visible on the poll table.
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class Version20151028000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Add columns "password_hash" and "results_publicly_visible" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\AddColumns_password_hash_And_results_publicly_visible_In_poll_For_0_9'), 'Migration has been executed in an earlier database migration system');
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
|
||||
$this->skipIf($pollTable->hasColumn('password_hash'), 'Column password_hash in table poll already exists');
|
||||
$this->skipIf($pollTable->hasColumn('results_publicly_visible'), 'Column results_publicly_visible in table poll already exists');
|
||||
|
||||
$pollTable->addColumn('password_hash', 'string', ['notnull' => false]);
|
||||
$pollTable->addColumn('results_publicly_visible', 'boolean', ['notnull' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
|
||||
$pollTable->dropColumn('password_hash');
|
||||
$pollTable->dropColumn('results_publicly_visible');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
class Version20151205000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Increase the size of id column in poll table';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\Increase_pollId_size'), 'Migration has been executed in an earlier database migration system');
|
||||
$commentTable = $schema->getTable(Utils::table('comment'));
|
||||
|
||||
$commentTable->changeColumn('poll_id', ['type' => Type::getType('string'), 'length' => 64, 'notnull' => true]);
|
||||
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
|
||||
$pollTable->changeColumn('id', ['type' => Type::getType('string'), 'length' => 64, 'notnull' => true]);
|
||||
|
||||
$slotTable = $schema->getTable(Utils::table('slot'));
|
||||
|
||||
$slotTable->changeColumn('poll_id', ['type' => Type::getType('string'), 'length' => 64, 'notnull' => true]);
|
||||
|
||||
$voteTable = $schema->getTable(Utils::table('vote'));
|
||||
|
||||
$voteTable->changeColumn('poll_id', ['type' => Type::getType('string'), 'length' => 64, 'notnull' => true]);
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// TODO: Implement down() method.
|
||||
}
|
||||
}
|
|
@ -16,8 +16,10 @@
|
|||
* 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\Migration;
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
|
@ -26,45 +28,38 @@ use Framadate\Utils;
|
|||
* @package Framadate\Migration
|
||||
* @version 0.9
|
||||
*/
|
||||
class AddColumn_ValueMax_In_poll_For_1_1 implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
class Version20180220000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
public function description()
|
||||
{
|
||||
return 'Add column "ValueMax" in table "vote" for version 0.9';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
return true;
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\AddColumn_ValueMax_In_poll_For_1_1'), 'Migration has been executed in an earlier database migration system');
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
$pollTable->addColumn('ValueMax', 'smallint', ['default' => null, 'notnull' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterPollTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterPollTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('poll') . '`
|
||||
ADD `ValueMax` TINYINT NULL;');
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$pollTable = $schema->getTable(Utils::table('poll'));
|
||||
$pollTable->dropColumn('ValueMax');
|
||||
}
|
||||
}
|
|
@ -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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration sets Poll.end_date to NULL by default
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.1
|
||||
*/
|
||||
class Version20180411000000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Sets Poll end_date to NULL by default (work around MySQL NO_ZERO_DATE)';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param Connection|\PDO $connection The connection to database
|
||||
* @return bool true if the Migration should be executed.
|
||||
*/
|
||||
public function preCondition(Connection $connection)
|
||||
{
|
||||
$driver_name = $connection->getWrappedConnection()->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
|
||||
if ($driver_name === 'mysql') {
|
||||
$stmt = $connection->prepare(
|
||||
"SELECT Column_Default from Information_Schema.Columns where Table_Name = ? AND Column_Name = ?;"
|
||||
);
|
||||
$stmt->bindValue(1, Utils::table('poll'));
|
||||
$stmt->bindValue(2, 'end_date');
|
||||
$stmt->execute();
|
||||
$default = $stmt->fetch(\PDO::FETCH_COLUMN);
|
||||
|
||||
return $default === null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
// We don't disable this migration even if legacy because it wasn't working correctly before
|
||||
// $this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\Fix_MySQL_No_Zero_Date'), 'Migration has been executed in an earlier database migration system');
|
||||
$this->skipIf($this->preCondition($this->connection), "Database server isn't MySQL or poll end_date default value was already NULL");
|
||||
$poll = $schema->getTable(Utils::table('poll'));
|
||||
$poll->changeColumn('end_date', ['default' => null, 'notnull' => false]);
|
||||
}
|
||||
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the column collect_users_mail in the poll table
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.2
|
||||
*/
|
||||
class Version20180419170000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Add column collect_users_mail in table poll';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\AddColumn_collect_mail_In_poll'), 'Migration has been executed in an earlier database migration system');
|
||||
$poll = $schema->getTable(Utils::table('poll'));
|
||||
$poll->addColumn('collect_users_mail', 'boolean', ['default' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$poll = $schema->getTable(Utils::table('poll'));
|
||||
$poll->dropColumn('collect_users_mail');
|
||||
}
|
||||
}
|
|
@ -16,55 +16,50 @@
|
|||
* 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\Migration;
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration alter the comment table to add a date column.
|
||||
* This migration adds the column mail in the vote table
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.0
|
||||
* @version 1.2
|
||||
*/
|
||||
class Alter_Comment_table_adding_date implements Migration {
|
||||
function __construct() {
|
||||
}
|
||||
|
||||
class Version20180419180000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description() {
|
||||
return 'Alter the comment table to add a date column.';
|
||||
public function description()
|
||||
{
|
||||
return 'Add column mail in table vote';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the Migration should be executed.
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
function preCondition(\PDO $pdo) {
|
||||
return true;
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf($this->legacyCheck($schema, 'Framadate\Migration\AddColumn_collect_mail_In_poll'), 'Migration has been executed in an earlier database migration system');
|
||||
$vote = $schema->getTable(Utils::table('vote'));
|
||||
$vote->addColumn('mail', 'string', ['default' => null, 'notnull' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true is the execution succeeded
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
function execute(\PDO $pdo) {
|
||||
$this->alterCommentTable($pdo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function alterCommentTable(\PDO $pdo) {
|
||||
$pdo->exec('
|
||||
ALTER TABLE `' . Utils::table('comment') . '`
|
||||
ADD `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ;');
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$vote = $schema->getTable(Utils::table('vote'));
|
||||
$vote->dropColumn('mail');
|
||||
}
|
||||
}
|
|
@ -16,31 +16,45 @@
|
|||
* 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\Migration;
|
||||
namespace DoctrineMigrations;
|
||||
|
||||
interface Migration {
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the column mail in the vote table
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.2
|
||||
*/
|
||||
class Version20180419190000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
function description();
|
||||
public function description()
|
||||
{
|
||||
return 'Remove the old migration table';
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could check if the execute method should be called.
|
||||
* It is called before the execute method.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the Migration should be executed
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Migrations\SkipMigrationException
|
||||
*/
|
||||
function preCondition(\PDO $pdo);
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$this->skipIf(!$schema->hasTable(Utils::table(MIGRATION_TABLE)), "The old migration table wasn't created, no need to delete it.");
|
||||
$schema->dropTable(Utils::table(MIGRATION_TABLE));
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode is called only one time in the migration page.
|
||||
*
|
||||
* @param \PDO $pdo The connection to database
|
||||
* @return bool true if the execution succeeded
|
||||
* @param Schema $schema
|
||||
*/
|
||||
function execute(\PDO $pdo);
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
// No need to recreate legacy migration table
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
<?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/OpenSondage: 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 DoctrineMigrations;
|
||||
|
||||
use Doctrine\DBAL\Schema\Schema;
|
||||
use Framadate\AbstractMigration;
|
||||
use Framadate\Utils;
|
||||
|
||||
/**
|
||||
* This migration adds the column collect_users_mail in the poll table
|
||||
*
|
||||
* @package Framadate\Migration
|
||||
* @version 1.2
|
||||
*/
|
||||
class Version20180525110000 extends AbstractMigration
|
||||
{
|
||||
/**
|
||||
* This method should describe in english what is the purpose of the migration class.
|
||||
*
|
||||
* @return string The description of the migration class
|
||||
*/
|
||||
public function description()
|
||||
{
|
||||
return 'Change column collect_users_mail in table poll from boolean to smallint';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function up(Schema $schema)
|
||||
{
|
||||
$poll = $schema->getTable(Utils::table('poll'));
|
||||
$poll->addColumn('collect_users_mail_integer', 'smallint', ['default' => 0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function postUp(Schema $schema)
|
||||
{
|
||||
$this->addSql('UPDATE ' . Utils::table('poll') . ' SET collect_users_mail_integer = collect_users_mail');
|
||||
$this->addSql('ALTER TABLE ' . Utils::table('poll') . ' DROP COLUMN collect_users_mail');
|
||||
if ($this->connection->getDatabasePlatform()->getName() === 'mysql') {
|
||||
$this->addSql(
|
||||
'ALTER TABLE ' . Utils::table('poll') . ' CHANGE collect_users_mail_integer collect_users_mail SMALLINT'
|
||||
);
|
||||
} else {
|
||||
$this->addSql(
|
||||
'ALTER TABLE ' . Utils::table('poll') . ' RENAME COLUMN collect_users_mail_integer to collect_users_mail'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
* @throws \Doctrine\DBAL\Schema\SchemaException
|
||||
*/
|
||||
public function down(Schema $schema)
|
||||
{
|
||||
$poll = $schema->getTable(Utils::table('poll'));
|
||||
$poll->addColumn('collect_users_mail_boolean', 'boolean', ['default' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function postDown(Schema $schema)
|
||||
{
|
||||
$this->addSql('UPDATE ' . Utils::table('poll') . ' SET collect_users_mail_boolean = collect_users_mail > 0');
|
||||
$this->addSql('ALTER TABLE ' . Utils::table('poll') . ' DROP COLUMN collect_users_mail');
|
||||
|
||||
if ($this->connection->getDatabasePlatform()->getName() === 'mysql') {
|
||||
$this->addSql(
|
||||
'ALTER TABLE ' . Utils::table('poll') . ' CHANGE collect_users_mail_boolean collect_users_mail SMALLINT'
|
||||
);
|
||||
} else {
|
||||
$this->addSql(
|
||||
'ALTER TABLE ' . Utils::table('poll') . ' RENAME COLUMN collect_users_mail_boolean to collect_users_mail'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +1,82 @@
|
|||
<?php
|
||||
namespace Framadate\Repositories;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\ConnectionException;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use PDOStatement;
|
||||
|
||||
abstract class AbstractRepository {
|
||||
/**
|
||||
* @var FramaDB
|
||||
* @var Connection
|
||||
*/
|
||||
private $connect;
|
||||
protected $connect;
|
||||
|
||||
/**
|
||||
* PollRepository constructor.
|
||||
* @param FramaDB $connect
|
||||
* @param Connection $connect
|
||||
*/
|
||||
function __construct(FramaDB $connect) {
|
||||
public function __construct(Connection $connect) {
|
||||
$this->connect = $connect;
|
||||
$this->connect->setFetchMode(\PDO::FETCH_OBJ);
|
||||
}
|
||||
|
||||
public function beginTransaction() {
|
||||
public function beginTransaction()
|
||||
{
|
||||
$this->connect->beginTransaction();
|
||||
}
|
||||
|
||||
public function commit() {
|
||||
/**
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function commit()
|
||||
{
|
||||
$this->connect->commit();
|
||||
}
|
||||
|
||||
function rollback() {
|
||||
/**
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function rollback()
|
||||
{
|
||||
$this->connect->rollback();
|
||||
}
|
||||
|
||||
public function prepare($sql) {
|
||||
/**
|
||||
* @return QueryBuilder
|
||||
*/
|
||||
public function createQueryBuilder()
|
||||
{
|
||||
return $this->connect->createQueryBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sql
|
||||
*@throws DBALException
|
||||
* @return bool|Statement|PDOStatement
|
||||
*/
|
||||
public function prepare($sql)
|
||||
{
|
||||
return $this->connect->prepare($sql);
|
||||
}
|
||||
|
||||
function query($sql) {
|
||||
/**
|
||||
* @param string $sql
|
||||
*@throws DBALException
|
||||
* @return bool|Statement|PDOStatement
|
||||
*/
|
||||
public function query($sql)
|
||||
{
|
||||
return $this->connect->query($sql);
|
||||
}
|
||||
|
||||
function lastInsertId() {
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function lastInsertId()
|
||||
{
|
||||
return $this->connect->lastInsertId();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
<?php
|
||||
namespace Framadate\Repositories;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Exception\InvalidArgumentException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Framadate\Utils;
|
||||
|
||||
class CommentRepository extends AbstractRepository {
|
||||
function __construct(FramaDB $connect) {
|
||||
parent::__construct($connect);
|
||||
}
|
||||
|
||||
function findAllByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('comment') . '` WHERE poll_id = ? ORDER BY id');
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws DBALException
|
||||
* @return array
|
||||
*/
|
||||
public function findAllByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('comment') . ' WHERE poll_id = ? ORDER BY id');
|
||||
$prepared->execute([$poll_id]);
|
||||
|
||||
return $prepared->fetchAll();
|
||||
$comments = $prepared->fetchAll();
|
||||
|
||||
/**
|
||||
* Hack to make date a proper DateTime
|
||||
*/
|
||||
return array_map(function($comment) {
|
||||
$comment->date = Type::getType(Type::DATETIME)->convertToPhpValue($comment->date, $this->connect->getDatabasePlatform());
|
||||
return $comment;
|
||||
}, $comments);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,32 +35,44 @@ class CommentRepository extends AbstractRepository {
|
|||
* @param $comment
|
||||
* @return bool
|
||||
*/
|
||||
function insert($poll_id, $name, $comment) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('comment') . '` (poll_id, name, comment) VALUES (?,?,?)');
|
||||
|
||||
return $prepared->execute([$poll_id, $name, $comment]);
|
||||
public function insert($poll_id, $name, $comment)
|
||||
{
|
||||
return $this->connect->insert(Utils::table('comment'), ['poll_id' => $poll_id, 'name' => $name, 'comment' => $comment]) > 0;
|
||||
}
|
||||
|
||||
function deleteById($poll_id, $comment_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id, $comment_id]);
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @param $comment_id
|
||||
* @throws InvalidArgumentException
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteById($poll_id, $comment_id)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('comment'), ['poll_id' => $poll_id, 'id' => $comment_id]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all comments of a given poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the given poll.
|
||||
* @return bool|null true if action succeeded.
|
||||
* @throws InvalidArgumentException
|
||||
* @return bool true if action succeeded.
|
||||
*/
|
||||
function deleteByPollId($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
public function deleteByPollId($poll_id)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('comment'), ['poll_id' => $poll_id]) > 0;
|
||||
}
|
||||
|
||||
public function exists($poll_id, $name, $comment) {
|
||||
$prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND name = ? AND comment = ?');
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @param $name
|
||||
* @param $comment
|
||||
* @throws DBALException
|
||||
* @return bool
|
||||
*/
|
||||
public function exists($poll_id, $name, $comment)
|
||||
{
|
||||
$prepared = $this->prepare('SELECT 1 FROM ' . Utils::table('comment') . ' WHERE poll_id = ? AND name = ? AND comment = ?');
|
||||
$prepared->execute([$poll_id, $name, $comment]);
|
||||
|
||||
return $prepared->rowCount() > 0;
|
||||
|
|
|
@ -1,79 +1,148 @@
|
|||
<?php
|
||||
namespace Framadate\Repositories;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Exception\InvalidArgumentException;
|
||||
use Doctrine\DBAL\Types\Type;
|
||||
use Exception;
|
||||
use Framadate\Form;
|
||||
use Framadate\Utils;
|
||||
use PDO;
|
||||
|
||||
class PollRepository extends AbstractRepository {
|
||||
function __construct(FramaDB $connect) {
|
||||
parent::__construct($connect);
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @param $admin_poll_id
|
||||
* @param Form $form
|
||||
* @throws Exception
|
||||
*/
|
||||
public function insertPoll($poll_id, $admin_poll_id, Form $form)
|
||||
{
|
||||
$this->connect->insert(Utils::table('poll'), [
|
||||
'id' => $poll_id,
|
||||
'admin_id' => $admin_poll_id,
|
||||
'title' => $form->title,
|
||||
'description' => $form->description,
|
||||
'admin_name' => $form->admin_name,
|
||||
'admin_mail' => $form->admin_mail,
|
||||
'end_date' => $form->end_date->format('Y-m-d H:i:s'),
|
||||
'format' => $form->format,
|
||||
'editable' => ($form->editable>=0 && $form->editable<=2) ? $form->editable : 0,
|
||||
'receiveNewVotes' => $form->receiveNewVotes ? 1 : 0,
|
||||
'receiveNewComments' => $form->receiveNewComments ? 1 : 0,
|
||||
'hidden' => $form->hidden ? 1 : 0,
|
||||
'password_hash' => $form->password_hash,
|
||||
'results_publicly_visible' => $form->results_publicly_visible ? 1 : 0,
|
||||
'ValueMax' => $form->ValueMax,
|
||||
'collect_users_mail' => ($form->collect_users_mail >= 0 && $form->collect_users_mail <= 3) ? $form->collect_users_mail : 0,
|
||||
]);
|
||||
}
|
||||
|
||||
public function insertPoll($poll_id, $admin_poll_id, $form) {
|
||||
$sql = 'INSERT INTO `' . Utils::table('poll') . '`
|
||||
(id, admin_id, title, description, admin_name, admin_mail, end_date, format, editable, receiveNewVotes, receiveNewComments, hidden, password_hash, results_publicly_visible,ValueMax)
|
||||
VALUES (?,?,?,?,?,?,FROM_UNIXTIME(?),?,?,?,?,?,?,?,?)';
|
||||
$prepared = $this->prepare($sql);
|
||||
$prepared->execute([$poll_id, $admin_poll_id, $form->title, $form->description, $form->admin_name, $form->admin_mail, $form->end_date, $form->format, ($form->editable>=0 && $form->editable<=2) ? $form->editable : 0, $form->receiveNewVotes ? 1 : 0, $form->receiveNewComments ? 1 : 0, $form->hidden ? 1 : 0, $form->password_hash, $form->results_publicly_visible ? 1 : 0,$form->ValueMax]);
|
||||
}
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws DBALException
|
||||
* @return mixed
|
||||
*/
|
||||
public function findById($poll_id)
|
||||
{
|
||||
$prepared = $this->connect->executeQuery('SELECT * FROM ' . Utils::table('poll') . ' WHERE id = ?', [$poll_id]);
|
||||
|
||||
function findById($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE id = ?');
|
||||
|
||||
$prepared->execute([$poll_id]);
|
||||
$poll = $prepared->fetch();
|
||||
$prepared->closeCursor();
|
||||
|
||||
/**
|
||||
* Hack to make date a proper DateTime
|
||||
*/
|
||||
$poll->creation_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->creation_date, $this->connect->getDatabasePlatform());
|
||||
$poll->end_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->end_date, $this->connect->getDatabasePlatform());
|
||||
|
||||
return $poll;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $admin_poll_id
|
||||
* @throws DBALException
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByAdminId($admin_poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE admin_id = ?');
|
||||
$prepared = $this->connect->executeQuery('SELECT * FROM ' . Utils::table('poll') . ' WHERE admin_id = ?', [$admin_poll_id]);
|
||||
|
||||
$prepared->execute([$admin_poll_id]);
|
||||
$poll = $prepared->fetch();
|
||||
$prepared->closeCursor();
|
||||
|
||||
$poll->creation_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->creation_date, $this->connect->getDatabasePlatform());
|
||||
$poll->end_date = Type::getType(Type::DATETIME)->convertToPhpValue($poll->end_date, $this->connect->getDatabasePlatform());
|
||||
|
||||
return $poll;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws DBALException
|
||||
* @return bool
|
||||
*/
|
||||
public function existsById($poll_id) {
|
||||
$prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('poll') . '` WHERE id = ?');
|
||||
$prepared = $this->prepare('SELECT 1 FROM ' . Utils::table('poll') . ' WHERE id = ?');
|
||||
|
||||
$prepared->execute([$poll_id]);
|
||||
|
||||
return $prepared->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $admin_poll_id
|
||||
* @throws DBALException
|
||||
* @return bool
|
||||
*/
|
||||
public function existsByAdminId($admin_poll_id) {
|
||||
$prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('poll') . '` WHERE admin_id = ?');
|
||||
$prepared = $this->prepare('SELECT 1 FROM ' . Utils::table('poll') . ' WHERE admin_id = ?');
|
||||
|
||||
$prepared->execute([$admin_poll_id]);
|
||||
|
||||
return $prepared->rowCount() > 0;
|
||||
}
|
||||
|
||||
function update($poll) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('poll') . '` SET title=?, admin_name=?, admin_mail=?, description=?, end_date=?, active=?, editable=?, hidden=?, password_hash=?, results_publicly_visible=? WHERE id = ?');
|
||||
|
||||
return $prepared->execute([$poll->title, $poll->admin_name, $poll->admin_mail, $poll->description, $poll->end_date, $poll->active, ($poll->editable>=0 && $poll->editable<=2) ? $poll->editable : 0, $poll->hidden ? 1 : 0, $poll->password_hash, $poll->results_publicly_visible ? 1 : 0, $poll->id]);
|
||||
/**
|
||||
* @param $poll
|
||||
* @return bool
|
||||
*/
|
||||
public function update($poll)
|
||||
{
|
||||
return $this->connect->update(Utils::table('poll'), [
|
||||
'title' => $poll->title,
|
||||
'admin_name' => $poll->admin_name,
|
||||
'admin_mail' => $poll->admin_mail,
|
||||
'description' => $poll->description,
|
||||
'end_date' => $poll->end_date->format('Y-m-d H:i:s'), # TODO : Harmonize dates between here and insert
|
||||
'active' => $poll->active,
|
||||
'editable' => $poll->editable >= 0 && $poll->editable <= 2 ? $poll->editable : 0,
|
||||
'hidden' => $poll->hidden ? 1 : 0,
|
||||
'password_hash' => $poll->password_hash,
|
||||
'results_publicly_visible' => $poll->results_publicly_visible ? 1 : 0
|
||||
], [
|
||||
'id' => $poll->id
|
||||
]) > 0;
|
||||
}
|
||||
|
||||
function deleteById($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('poll') . '` WHERE id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws InvalidArgumentException
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteById($poll_id)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('poll'), ['id' => $poll_id]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find old polls. Limit: 20.
|
||||
*
|
||||
* @throws DBALException
|
||||
* @return array Array of old polls
|
||||
*/
|
||||
public function findOldPolls() {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE DATE_ADD(`end_date`, INTERVAL ' . PURGE_DELAY . ' DAY) < NOW() AND `end_date` != 0 LIMIT 20');
|
||||
$prepared->execute([]);
|
||||
public function findOldPolls()
|
||||
{
|
||||
$prepared = $this->connect->executeQuery('SELECT * FROM ' . Utils::table('poll') . ' WHERE DATE_ADD(end_date, INTERVAL ? DAY) < NOW() AND end_date != 0 LIMIT 20', [PURGE_DELAY]);
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
@ -84,52 +153,53 @@ class PollRepository extends AbstractRepository {
|
|||
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>..., 'mail'=>...]
|
||||
* @param int $start The number of first entry to select
|
||||
* @param int $limit The number of entries to find
|
||||
* @throws DBALException
|
||||
* @return array The found polls
|
||||
*/
|
||||
public function findAll($search, $start, $limit) {
|
||||
// Polls
|
||||
|
||||
|
||||
$request = "";
|
||||
$request .= "SELECT p.*,";
|
||||
$request .= " (SELECT count(1) FROM `" . Utils::table('vote') . "` v WHERE p.id=v.poll_id) votes";
|
||||
$request .= " FROM `" . Utils::table('poll') . "` p";
|
||||
$request .= " (SELECT count(1) FROM " . Utils::table('vote') . " v WHERE p.id=v.poll_id) votes";
|
||||
$request .= " FROM " . Utils::table('poll') . " p";
|
||||
$request .= " WHERE 1";
|
||||
|
||||
|
||||
$values = [];
|
||||
|
||||
|
||||
if (!empty($search["poll"])) {
|
||||
$request .= " AND p.id LIKE :poll";
|
||||
$values["poll"] = "{$search["poll"]}%";
|
||||
}
|
||||
|
||||
|
||||
$fields = [
|
||||
// key of $search => column name
|
||||
"title" => "title",
|
||||
"name" => "admin_name",
|
||||
"mail" => "admin_mail",
|
||||
];
|
||||
|
||||
|
||||
foreach ($fields as $searchKey => $columnName) {
|
||||
if (empty($search[$searchKey])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$request .= " AND p.$columnName LIKE :$searchKey";
|
||||
$values[$searchKey] = "%{$search[$searchKey]}%";
|
||||
}
|
||||
|
||||
|
||||
$request .= " ORDER BY p.title ASC";
|
||||
$request .= " LIMIT :start, :limit";
|
||||
|
||||
|
||||
$prepared = $this->prepare($request);
|
||||
|
||||
|
||||
foreach ($values as $searchKey => $value) {
|
||||
$prepared->bindParam(":$searchKey", $value, PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
|
||||
$prepared->bindParam(':start', $start, PDO::PARAM_INT);
|
||||
$prepared->bindParam(':limit', $limit, PDO::PARAM_INT);
|
||||
|
||||
|
||||
$prepared->execute();
|
||||
|
||||
return $prepared->fetchAll();
|
||||
|
@ -139,26 +209,28 @@ class PollRepository extends AbstractRepository {
|
|||
* Find all polls that are created with the given admin mail.
|
||||
*
|
||||
* @param string $mail Email address of the poll admin
|
||||
* @throws DBALException
|
||||
* @return array The list of matching polls
|
||||
*/
|
||||
public function findAllByAdminMail($mail) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('poll') . '` WHERE admin_mail = :admin_mail');
|
||||
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('poll') . ' WHERE admin_mail = :admin_mail');
|
||||
$prepared->execute(['admin_mail' => $mail]);
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the total number of polls in databse.
|
||||
* Get the total number of polls in database.
|
||||
*
|
||||
* @param array $search Array of search : ['id'=>..., 'title'=>..., 'name'=>...]
|
||||
* @throws DBALException
|
||||
* @return int The number of polls
|
||||
*/
|
||||
public function count($search = null) {
|
||||
// Total count
|
||||
$prepared = $this->prepare('
|
||||
SELECT count(1) nb
|
||||
FROM `' . Utils::table('poll') . '` p
|
||||
FROM ' . Utils::table('poll') . ' p
|
||||
WHERE (:id = "" OR p.id LIKE :id)
|
||||
AND (:title = "" OR p.title LIKE :title)
|
||||
AND (:name = "" OR p.admin_name LIKE :name)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
namespace Framadate\Repositories;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
class RepositoryFactory {
|
||||
private static $connect;
|
||||
|
@ -29,9 +29,9 @@ class RepositoryFactory {
|
|||
private static $commentRepository;
|
||||
|
||||
/**
|
||||
* @param FramaDB $connect
|
||||
* @param Connection $connect
|
||||
*/
|
||||
static function init(FramaDB $connect) {
|
||||
static function init(Connection $connect) {
|
||||
self::$connect = $connect;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,28 +4,24 @@
|
|||
* 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 STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Rapha<EFBFBD>l DROZ
|
||||
* Authors of Framadate/OpenSondage: Framasoft (https://github.com/framasoft)
|
||||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* Ce logiciel est r<EFBFBD>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 STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Rapha<EFBFBD>l DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate\Repositories;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Framadate\Choice;
|
||||
use Framadate\Utils;
|
||||
|
||||
class SlotRepository extends AbstractRepository {
|
||||
function __construct(FramaDB $connect) {
|
||||
parent::__construct($connect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert a bulk of slots.
|
||||
*
|
||||
|
@ -33,11 +29,10 @@ class SlotRepository extends AbstractRepository {
|
|||
* @param array $choices
|
||||
*/
|
||||
public function insertSlots($poll_id, $choices) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('slot') . '` (poll_id, title, moments) VALUES (?, ?, ?)');
|
||||
|
||||
foreach ($choices as $choice) {
|
||||
/** @var Choice $choice */
|
||||
// We prepared the slots (joined by comas)
|
||||
$joinedSlots = '';
|
||||
$joinedSlots = null;
|
||||
$first = true;
|
||||
foreach ($choice->getSlots() as $slot) {
|
||||
if ($first) {
|
||||
|
@ -49,16 +44,22 @@ class SlotRepository extends AbstractRepository {
|
|||
}
|
||||
|
||||
// We execute the insertion
|
||||
if (empty($joinedSlots)) {
|
||||
$prepared->execute([$poll_id, $choice->getName(), null]);
|
||||
} else {
|
||||
$prepared->execute([$poll_id, $choice->getName(), $joinedSlots]);
|
||||
}
|
||||
$this->connect->insert(Utils::table('slot'), [
|
||||
'poll_id' => $poll_id,
|
||||
'title' => $choice->getName(),
|
||||
'moments' => $joinedSlots
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function listByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? ORDER BY id');
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @return array
|
||||
*/
|
||||
public function listByPollId($poll_id)
|
||||
{
|
||||
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('slot') . ' WHERE poll_id = ? ORDER BY id');
|
||||
$prepared->execute([$poll_id]);
|
||||
|
||||
return $prepared->fetchAll();
|
||||
|
@ -69,10 +70,11 @@ class SlotRepository extends AbstractRepository {
|
|||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $datetime int The datetime of the slot
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @return mixed Object The slot found, or null
|
||||
*/
|
||||
function findByPollIdAndDatetime($poll_id, $datetime) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND SUBSTRING_INDEX(title, \'@\', 1) = ?');
|
||||
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('slot') . ' WHERE poll_id = ? AND SUBSTRING_INDEX(title, \'@\', 1) = ?');
|
||||
|
||||
$prepared->execute([$poll_id, $datetime]);
|
||||
$slot = $prepared->fetch();
|
||||
|
@ -89,10 +91,9 @@ class SlotRepository extends AbstractRepository {
|
|||
* @param $moments mixed|null The moments joined with ","
|
||||
* @return bool true if action succeeded
|
||||
*/
|
||||
function insert($poll_id, $title, $moments) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('slot') . '` (poll_id, title, moments) VALUES (?,?,?)');
|
||||
|
||||
return $prepared->execute([$poll_id, $title, $moments]);
|
||||
function insert($poll_id, $title, $moments)
|
||||
{
|
||||
return $this->connect->insert(Utils::table('slot'), ['poll_id' => $poll_id, 'title' => $title, 'moments' => $moments]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -103,10 +104,9 @@ class SlotRepository extends AbstractRepository {
|
|||
* @param $newMoments mixed The new moments
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function update($poll_id, $datetime, $newMoments) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('slot') . '` SET moments = ? WHERE poll_id = ? AND title = ?');
|
||||
|
||||
return $prepared->execute([$newMoments, $poll_id, $datetime]);
|
||||
function update($poll_id, $datetime, $newMoments)
|
||||
{
|
||||
return $this->connect->update(Utils::table('slot'), ['moments' => $newMoments], ['poll_id' => $poll_id, 'title' => $datetime]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,15 +114,21 @@ class SlotRepository extends AbstractRepository {
|
|||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @param $datetime mixed The datetime of the slot
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @return bool
|
||||
*/
|
||||
function deleteByDateTime($poll_id, $datetime) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ? AND title = ?');
|
||||
$prepared->execute([$poll_id, $datetime]);
|
||||
public function deleteByDateTime($poll_id, $datetime)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('slot'), ['poll_id' => $poll_id, 'title' => $datetime]) > 0;
|
||||
}
|
||||
|
||||
function deleteByPollId($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('slot') . '` WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteByPollId($poll_id)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('slot'), ['poll_id' => $poll_id]) > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,48 @@
|
|||
<?php
|
||||
namespace Framadate\Repositories;
|
||||
|
||||
use Framadate\FramaDB;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\Driver\Statement;
|
||||
use Doctrine\DBAL\Query\QueryBuilder;
|
||||
use Framadate\Utils;
|
||||
|
||||
class VoteRepository extends AbstractRepository {
|
||||
function __construct(FramaDB $connect) {
|
||||
parent::__construct($connect);
|
||||
}
|
||||
|
||||
function allUserVotesByPollId($poll_id) {
|
||||
$prepared = $this->prepare('SELECT * FROM `' . Utils::table('vote') . '` WHERE poll_id = ? ORDER BY id');
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @throws DBALException
|
||||
* @return array
|
||||
*/
|
||||
public function allUserVotesByPollId($poll_id)
|
||||
{
|
||||
$prepared = $this->prepare('SELECT * FROM ' . Utils::table('vote') . ' WHERE poll_id = ? ORDER BY id');
|
||||
$prepared->execute([$poll_id]);
|
||||
|
||||
return $prepared->fetchAll();
|
||||
}
|
||||
|
||||
function insertDefault($poll_id, $insert_position) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTRING(choices, 1, ?), " ", SUBSTRING(choices, ?)) WHERE poll_id = ?'); //#51 : default value for unselected vote
|
||||
|
||||
return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]);
|
||||
/**
|
||||
* Insert default values for slots
|
||||
*
|
||||
* @param string $poll_id
|
||||
* @param integer $insert_position
|
||||
* @return Statement|int
|
||||
*/
|
||||
public function insertDefault($poll_id, $insert_position)
|
||||
{
|
||||
$qb = $this->createQueryBuilder();
|
||||
$sql = $this->connect->getDatabasePlatform()->getName() === 'sqlite' ?
|
||||
$this->generateSQLForInsertDefaultSQLite($qb, $insert_position) :
|
||||
$this->generateSQLForInsertDefault($qb, $insert_position)
|
||||
;
|
||||
$query = $qb->update(Utils::table('vote'))
|
||||
->set('choices', $sql)
|
||||
->where($qb->expr()->eq('poll_id', $qb->createNamedParameter($poll_id)))
|
||||
;
|
||||
return $query->execute();
|
||||
}
|
||||
|
||||
function insert($poll_id, $name, $choices, $token) {
|
||||
$prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices, uniqId) VALUES (?,?,?,?)');
|
||||
$prepared->execute([$poll_id, $name, $choices, $token]);
|
||||
function insert($poll_id, $name, $choices, $token, $mail) {
|
||||
$this->connect->insert(Utils::table('vote'), ['poll_id' => $poll_id, 'name' => $name, 'choices' => $choices, 'uniqId' => $token, 'mail' => $mail]);
|
||||
|
||||
$newVote = new \stdClass();
|
||||
$newVote->poll_id = $poll_id;
|
||||
|
@ -32,26 +50,38 @@ class VoteRepository extends AbstractRepository {
|
|||
$newVote->name = $name;
|
||||
$newVote->choices = $choices;
|
||||
$newVote->uniqId = $token;
|
||||
$newVote->mail=$mail;
|
||||
|
||||
return $newVote;
|
||||
}
|
||||
|
||||
function deleteById($poll_id, $vote_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND id = ?');
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @param $vote_id
|
||||
* @throws DBALException
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteById($poll_id, $vote_id)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('vote'), ['poll_id' => $poll_id, 'id' => $vote_id]) > 0;
|
||||
}
|
||||
|
||||
return $prepared->execute([$poll_id, $vote_id]);
|
||||
public function deleteOldVotesByPollId($poll_id, $votesToDelete) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ? ORDER BY `poll_id` ASC LIMIT ' . $votesToDelete);
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all votes of a given poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the given poll.
|
||||
* @throws DBALException
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function deleteByPollId($poll_id) {
|
||||
$prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$poll_id]);
|
||||
public function deleteByPollId($poll_id)
|
||||
{
|
||||
return $this->connect->delete(Utils::table('vote'), ['poll_id' => $poll_id]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,16 +91,37 @@ class VoteRepository extends AbstractRepository {
|
|||
* @param $index int The index of the vote into the poll
|
||||
* @return bool|null true if action succeeded.
|
||||
*/
|
||||
function deleteByIndex($poll_id, $index) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTR(choices, 1, ?), SUBSTR(choices, ?)) WHERE poll_id = ?');
|
||||
|
||||
return $prepared->execute([$index, $index + 2, $poll_id]);
|
||||
public function deleteByIndex($poll_id, $index)
|
||||
{
|
||||
$qb = $this->createQueryBuilder();
|
||||
$sql = $this->connect->getDatabasePlatform()->getName() === 'sqlite' ?
|
||||
$this->generateSQLForInsertDefaultSQLite($qb, $index, true) :
|
||||
$this->generateSQLForInsertDefault($qb, $index, true)
|
||||
;
|
||||
$query = $qb->update(Utils::table('vote'))
|
||||
->set('choices', $sql)
|
||||
->where($qb->expr()->eq('poll_id', $qb->createNamedParameter($poll_id)))
|
||||
;
|
||||
return $query->execute();
|
||||
}
|
||||
|
||||
function update($poll_id, $vote_id, $name, $choices) {
|
||||
$prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = ?, name = ? WHERE poll_id = ? AND id = ?');
|
||||
|
||||
return $prepared->execute([$choices, $name, $poll_id, $vote_id]);
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @param $vote_id
|
||||
* @param $name
|
||||
* @param $choices
|
||||
* @return bool
|
||||
*/
|
||||
public function update($poll_id, $vote_id, $name, $choices, $mail)
|
||||
{
|
||||
return $this->connect->update(Utils::table('vote'), [
|
||||
'choices' => $choices,
|
||||
'name' => $name,
|
||||
'mail' => $mail,
|
||||
], [
|
||||
'poll_id' => $poll_id,
|
||||
'id' => $vote_id,
|
||||
]) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -78,26 +129,60 @@ class VoteRepository extends AbstractRepository {
|
|||
*
|
||||
* @param int $poll_id ID of the poll
|
||||
* @param string $name Name of the vote
|
||||
* @throws DBALException
|
||||
* @return bool true if vote already exists
|
||||
*/
|
||||
public function existsByPollIdAndName($poll_id, $name) {
|
||||
$prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND name = ?');
|
||||
$prepared = $this->prepare('SELECT 1 FROM ' . Utils::table('vote') . ' WHERE poll_id = ? AND name = ?');
|
||||
$prepared->execute([$poll_id, $name]);
|
||||
return $prepared->rowCount() > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if name is already used for the given poll and another vote.
|
||||
*
|
||||
* @param int $poll_id ID of the poll
|
||||
* @param string $name Name of the vote
|
||||
* @param int $vote_id ID of the current vote
|
||||
* @throws DBALException
|
||||
* @return bool true if vote already exists
|
||||
*/
|
||||
public function existsByPollIdAndNameAndVoteId($poll_id, $name, $vote_id) {
|
||||
$prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND name = ? AND id != ?');
|
||||
$prepared = $this->prepare('SELECT 1 FROM ' . Utils::table('vote') . ' WHERE poll_id = ? AND name = ? AND id != ?');
|
||||
$prepared->execute([$poll_id, $name, $vote_id]);
|
||||
return $prepared->rowCount() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryBuilder $qb
|
||||
* @param $insert_position
|
||||
* @param bool $delete
|
||||
* @return string
|
||||
*/
|
||||
private function generateSQLForInsertDefaultSQLite($qb, $insert_position, $delete = false)
|
||||
{
|
||||
$position = $insert_position + ($delete ? 2 : 1);
|
||||
return 'SUBSTR(choices, 1, '
|
||||
. $qb->createNamedParameter($insert_position)
|
||||
. ') || " " || SUBSTR(choices, '
|
||||
. $qb->createNamedParameter($position)
|
||||
. ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param QueryBuilder $qb
|
||||
* @param int $insert_position
|
||||
* @param bool $delete
|
||||
* @return string
|
||||
*/
|
||||
private function generateSQLForInsertDefault($qb, $insert_position, $delete = false)
|
||||
{
|
||||
$position = $insert_position + ($delete ? 2 : 1);
|
||||
return 'CONCAT(SUBSTR(choices, 1, '
|
||||
. $qb->createNamedParameter($insert_position)
|
||||
. '), " ", SUBSTR(choices, '
|
||||
. $qb->createNamedParameter($position)
|
||||
. '))';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Framadate\Security;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<?php
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\ConnectionException;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Framadate\Exception\MomentAlreadyExistsException;
|
||||
use Framadate\FramaDB;
|
||||
use Framadate\Form;
|
||||
use Framadate\Repositories\RepositoryFactory;
|
||||
use Framadate\Utils;
|
||||
use stdClass;
|
||||
|
||||
/**
|
||||
* Class AdminPollService
|
||||
|
@ -21,7 +24,7 @@ class AdminPollService {
|
|||
private $voteRepository;
|
||||
private $commentRepository;
|
||||
|
||||
function __construct(FramaDB $connect, PollService $pollService, LogService $logService) {
|
||||
function __construct(Connection $connect, PollService $pollService, LogService $logService) {
|
||||
$this->connect = $connect;
|
||||
$this->pollService = $pollService;
|
||||
$this->logService = $logService;
|
||||
|
@ -31,12 +34,18 @@ class AdminPollService {
|
|||
$this->commentRepository = RepositoryFactory::commentRepository();
|
||||
}
|
||||
|
||||
function updatePoll($poll) {
|
||||
global $config;
|
||||
if ($poll->end_date > $poll->creation_date) {
|
||||
return $this->pollRepository->update($poll);
|
||||
}
|
||||
return false;
|
||||
/**
|
||||
* @param Form $poll
|
||||
* @return bool
|
||||
*/
|
||||
public function updatePoll($poll) {
|
||||
if ($poll->end_date < $poll->creation_date) {
|
||||
$poll->end_date = $poll->creation_date;
|
||||
} elseif ($poll->end_date > $this->pollService->maxExpiryDate()) {
|
||||
$poll->end_date = $this->pollService->maxExpiryDate();
|
||||
}
|
||||
|
||||
return $this->pollRepository->update($poll);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,7 +100,15 @@ class AdminPollService {
|
|||
*/
|
||||
function deleteEntirePoll($poll_id) {
|
||||
$poll = $this->pollRepository->findById($poll_id);
|
||||
$this->logService->log('DELETE_POLL', "id:$poll->id, format:$poll->format, admin:$poll->admin_name, mail:$poll->admin_mail");
|
||||
$this->logService->logEntries(
|
||||
'DELETE_POLL',
|
||||
[
|
||||
"id:$poll->id",
|
||||
"format:$poll->format",
|
||||
"admin:$poll->admin_name",
|
||||
"mail:$poll->admin_mail"
|
||||
]
|
||||
);
|
||||
|
||||
// Delete the entire poll
|
||||
$this->voteRepository->deleteByPollId($poll_id);
|
||||
|
@ -110,7 +127,10 @@ class AdminPollService {
|
|||
* @return bool true if action succeeded
|
||||
*/
|
||||
public function deleteDateSlot($poll, $slot) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll->id . ', slot:' . json_encode($slot));
|
||||
$this->logService->logEntries(
|
||||
'DELETE_SLOT',
|
||||
["id:$poll->id", 'slot:' . json_encode($slot)]
|
||||
);
|
||||
|
||||
$datetime = $slot->title;
|
||||
$moment = $slot->moment;
|
||||
|
@ -158,7 +178,9 @@ class AdminPollService {
|
|||
}
|
||||
|
||||
public function deleteClassicSlot($poll, $slot_title) {
|
||||
$this->logService->log('DELETE_SLOT', 'id:' . $poll->id . ', slot:' . $slot_title);
|
||||
$this->logService->logEntries(
|
||||
['DELETE_SLOT', "id:$poll->id", "slot:$slot_title"]
|
||||
);
|
||||
|
||||
$slots = $this->pollService->allSlotsByPoll($poll);
|
||||
|
||||
|
@ -197,36 +219,50 @@ class AdminPollService {
|
|||
* @param $datetime int The datetime
|
||||
* @param $new_moment string The moment's name
|
||||
* @throws MomentAlreadyExistsException When the moment to add already exists in database
|
||||
* @throws ConnectionException
|
||||
*/
|
||||
public function addDateSlot($poll_id, $datetime, $new_moment) {
|
||||
$this->logService->log('ADD_COLUMN', 'id:' . $poll_id . ', datetime:' . $datetime . ', moment:' . $new_moment);
|
||||
$this->logService->logEntries(
|
||||
'ADD_COLUMN',
|
||||
["id:$poll_id", "datetime:$datetime", "moment:$new_moment"]
|
||||
);
|
||||
|
||||
$slots = $this->slotRepository->listByPollId($poll_id);
|
||||
$result = $this->findInsertPosition($slots, $datetime);
|
||||
|
||||
// Begin transaction
|
||||
$this->connect->beginTransaction();
|
||||
|
||||
if ($result->slot !== null) {
|
||||
$slot = $result->slot;
|
||||
$moments = explode(',', $slot->moments);
|
||||
|
||||
// Check if moment already exists (maybe not necessary)
|
||||
if (in_array($new_moment, $moments, true)) {
|
||||
throw new MomentAlreadyExistsException();
|
||||
}
|
||||
|
||||
// Update found slot
|
||||
$moments[] = $new_moment;
|
||||
$this->slotRepository->update($poll_id, $datetime, implode(',', $moments));
|
||||
} else {
|
||||
$this->slotRepository->insert($poll_id, $datetime, $new_moment);
|
||||
try {
|
||||
$slots = $this->slotRepository->listByPollId($poll_id);
|
||||
$result = $this->findInsertPosition($slots, $datetime);
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('ERROR', "Database error, couldn't find slot insert position" . $e->getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
$this->voteRepository->insertDefault($poll_id, $result->insert);
|
||||
try {
|
||||
// Begin transaction
|
||||
$this->connect->beginTransaction();
|
||||
|
||||
// Commit transaction
|
||||
$this->connect->commit();
|
||||
if ($result->slot !== null) {
|
||||
$slot = $result->slot;
|
||||
$moments = explode(',', $slot->moments);
|
||||
|
||||
// Check if moment already exists (maybe not necessary)
|
||||
if (in_array($new_moment, $moments, true)) {
|
||||
throw new MomentAlreadyExistsException($slot, $new_moment);
|
||||
}
|
||||
|
||||
// Update found slot
|
||||
$moments[] = $new_moment;
|
||||
$this->slotRepository->update($poll_id, $datetime, implode(',', $moments));
|
||||
} else {
|
||||
$this->slotRepository->insert($poll_id, $datetime, $new_moment);
|
||||
}
|
||||
|
||||
$this->voteRepository->insertDefault($poll_id, $result->insert);
|
||||
|
||||
// Commit transaction
|
||||
$this->connect->commit();
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('ERROR', "Database error, couldn't insert date slot" . $e->getMessage());
|
||||
$this->connect->rollBack();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -238,9 +274,14 @@ class AdminPollService {
|
|||
* @param $poll_id int The ID of the poll
|
||||
* @param $title int The title
|
||||
* @throws MomentAlreadyExistsException When the moment to add already exists in database
|
||||
* @throws ConnectionException
|
||||
* @throws \Doctrine\DBAL\DBALException
|
||||
*/
|
||||
public function addClassicSlot($poll_id, $title) {
|
||||
$this->logService->log('ADD_COLUMN', 'id:' . $poll_id . ', title:' . $title);
|
||||
$this->logService->logEntries(
|
||||
'ADD_COLUMN',
|
||||
["id:$poll_id", "title:$title"]
|
||||
);
|
||||
|
||||
$slots = $this->slotRepository->listByPollId($poll_id);
|
||||
|
||||
|
@ -272,10 +313,10 @@ class AdminPollService {
|
|||
*
|
||||
* @param $slots array All the slots of the poll
|
||||
* @param $datetime int The datetime of the new slot
|
||||
* @return \stdClass An object like this one: {insert:X, slot:Y} where Y can be null.
|
||||
* @return stdClass An object like this one: {insert:X, slot:Y} where Y can be null.
|
||||
*/
|
||||
private function findInsertPosition($slots, $datetime) {
|
||||
$result = new \stdClass();
|
||||
$result = new stdClass();
|
||||
$result->slot = null;
|
||||
$result->insert = 0;
|
||||
|
||||
|
@ -292,14 +333,15 @@ class AdminPollService {
|
|||
$result->insert += count($moments);
|
||||
$result->slot = $slot;
|
||||
break;
|
||||
} elseif ($datetime < $rowDatetime) {
|
||||
}
|
||||
|
||||
if ($datetime < $rowDatetime) {
|
||||
// We have to insert before this slot
|
||||
break;
|
||||
}
|
||||
$result->insert += count($moments);
|
||||
}
|
||||
$result->insert += count($moments);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ namespace Framadate\Services;
|
|||
use DateTime;
|
||||
use Egulias\EmailValidator\EmailValidator;
|
||||
use Egulias\EmailValidator\Validation\RFCValidation;
|
||||
use InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* This class helps to clean all inputs from the users or external services.
|
||||
|
@ -115,14 +116,25 @@ class InputService {
|
|||
return filter_var($editable, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => EDITABLE_CHOICE_REGEX]]);
|
||||
}
|
||||
|
||||
public function filterCollectMail($collectMail) {
|
||||
return filter_var($collectMail, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => COLLECT_MAIL_CHOICE_REGEX]]);
|
||||
}
|
||||
|
||||
public function filterComment($comment) {
|
||||
$comment = str_replace("\r\n", "\n", $comment);
|
||||
return $this->returnIfNotBlank($comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $date
|
||||
* @return DateTime
|
||||
*/
|
||||
public function filterDate($date) {
|
||||
$dDate = DateTime::createFromFormat(__('Date', 'datetime_parseformat'), $date)->setTime(0, 0, 0);
|
||||
return $dDate->format('Y-m-d H:i:s');
|
||||
$dDate = parse_translation_date($date);
|
||||
if ($dDate) {
|
||||
return $dDate;
|
||||
}
|
||||
throw new InvalidArgumentException('Invalid date');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*
|
||||
* =============================
|
||||
*
|
||||
* Ce logiciel est r<EFBFBD>gi par la licence CeCILL-B. Si une copie de cette licence
|
||||
* 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
|
||||
*
|
||||
|
@ -17,6 +17,9 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
namespace Framadate\Services;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Framadate\Utils;
|
||||
use Smarty;
|
||||
|
||||
|
@ -33,7 +36,9 @@ class InstallService {
|
|||
'cleanUrl' => true,
|
||||
|
||||
// Database configuration
|
||||
'dbConnectionString' => 'mysql:host=<HOST>;dbname=<SCHEMA>;port=3306',
|
||||
'dbName' => 'framadate',
|
||||
'dbPort' => 3306,
|
||||
'dbHost' => 'localhost',
|
||||
'dbUser' => 'root',
|
||||
'dbPassword' => '',
|
||||
'dbPrefix' => 'fd_',
|
||||
|
@ -50,15 +55,15 @@ class InstallService {
|
|||
|
||||
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');
|
||||
if (empty($this->fields['appName']) || empty($this->fields['appMail']) || empty($this->fields['defaultLanguage']) || empty($this->fields['dbName']) || empty($this->fields['dbHost']) || empty($this->fields['dbPort']) || empty($this->fields['dbUser'])) {
|
||||
return $this->error('Missing values');
|
||||
}
|
||||
|
||||
// Connect to database
|
||||
try {
|
||||
$connect = $this->connectTo($this->fields['dbConnectionString'], $this->fields['dbUser'], $this->fields['dbPassword']);
|
||||
} catch(\Exception $e) {
|
||||
return $this->error('CANT_CONNECT_TO_DATABASE', $e->getMessage());
|
||||
$connect = $this->connectTo($this->fields);
|
||||
} catch(\Doctrine\DBAL\DBALException $e) {
|
||||
return $this->error('Unable to connect to database', $e->getMessage());
|
||||
}
|
||||
|
||||
// Write configuration to conf.php file
|
||||
|
@ -70,18 +75,20 @@ class InstallService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Connect to PDO compatible source
|
||||
*
|
||||
* @param string $connectionString
|
||||
* @param string $user
|
||||
* @param string $password
|
||||
* @return \PDO
|
||||
* @param $fields
|
||||
* @return \Doctrine\DBAL\Connection|null
|
||||
*/
|
||||
function connectTo($connectionString, $user, $password) {
|
||||
$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;
|
||||
function connectTo($fields) {
|
||||
$doctrineConfig = new Configuration();
|
||||
$connectionParams = [
|
||||
'dbname' => $fields['dbName'],
|
||||
'user' => $fields['dbUser'],
|
||||
'password' => $fields['dbPassword'],
|
||||
'host' => $fields['dbHost'],
|
||||
'driver' => $fields['dbDriver'],
|
||||
'charset' => $fields['dbDriver'] === 'pdo_mysql' ? 'utf8mb4' : 'utf8',
|
||||
];
|
||||
return DriverManager::getConnection($connectionParams, $doctrineConfig);
|
||||
}
|
||||
|
||||
function writeConfiguration(Smarty &$smarty) {
|
||||
|
@ -96,6 +103,7 @@ class InstallService {
|
|||
|
||||
/**
|
||||
* @param $content
|
||||
* @return bool|int
|
||||
*/
|
||||
function writeToFile($content) {
|
||||
return @file_put_contents(CONF_FILENAME, $content);
|
||||
|
|
|
@ -19,5 +19,19 @@ class LogService {
|
|||
function log($tag, $message) {
|
||||
error_log(date('Ymd His') . ' [' . $tag . '] ' . $message . "\n", 3, ROOT_DIR . LOG_FILE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a list of entries as a single message to the log file.
|
||||
*
|
||||
* @param $tag string A tag is used to quickly found a message when reading log file
|
||||
* @param $entries array some entries to join with comma into a single message
|
||||
*/
|
||||
function logEntries($tag, $entries) {
|
||||
$escapeCommas = function($value) {
|
||||
return str_replace(',', '-', $value);
|
||||
};
|
||||
$message = join(', ', array_map($escapeCommas, $entries));
|
||||
|
||||
error_log(date('Ymd His') . ' [' . $tag . '] ' . $message . "\n", 3, ROOT_DIR . LOG_FILE);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,26 +8,51 @@ class MailService {
|
|||
|
||||
const MAILSERVICE_KEY = 'mailservice';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $smtp_allowed;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $smtp_options = [];
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $use_sendmail;
|
||||
|
||||
/**
|
||||
* @var LogService
|
||||
*/
|
||||
private $logService;
|
||||
|
||||
function __construct($smtp_allowed, $smtp_options = []) {
|
||||
/**
|
||||
* MailService constructor.
|
||||
* @param $smtp_allowed
|
||||
* @param array $smtp_options
|
||||
* @param bool $use_sendmail
|
||||
*/
|
||||
public function __construct($smtp_allowed, $smtp_options = [], $use_sendmail = false) {
|
||||
$this->logService = new LogService();
|
||||
$this->smtp_allowed = $smtp_allowed;
|
||||
if (true === is_array($smtp_options)) {
|
||||
$this->smtp_options = $smtp_options;
|
||||
}
|
||||
$this->use_sendmail = $use_sendmail;
|
||||
}
|
||||
|
||||
public function isValidEmail($email) {
|
||||
return filter_var($email, FILTER_VALIDATE_EMAIL);
|
||||
}
|
||||
|
||||
public function isEnabled() {
|
||||
return $this->smtp_allowed === true;
|
||||
}
|
||||
|
||||
public function send($to, $subject, $body, $msgKey = null) {
|
||||
if ($this->smtp_allowed === true && $this->canSendMsg($msgKey)) {
|
||||
if ($this->isEnabled() && $this->canSendMsg($msgKey)) {
|
||||
$mail = new PHPMailer(true);
|
||||
$this->configureMailer($mail);
|
||||
|
||||
|
@ -45,12 +70,14 @@ class MailService {
|
|||
$mail->Subject = $subject;
|
||||
|
||||
// Bodies
|
||||
$body = $body . ' <br/><br/>' . __('Mail', 'Thanks for your trust.') . ' <br/>' . NOMAPPLICATION . ' <hr/>' . __('Mail', 'FOOTER');
|
||||
$body = $body . ' <br/><br/>' . __('Mail', 'Thank you for your trust.') . ' <br/>' . NOMAPPLICATION . ' <hr/>' . __('Mail', "\"The road is long, but the way is clear…\"<br/>Framasoft lives only by your donations.<br/>Thank you in advance for your support https://soutenir.framasoft.org");
|
||||
$mail->isHTML(true);
|
||||
$mail->msgHTML($body, ROOT_DIR, true);
|
||||
$mail->CharSet = PHPMailer::CHARSET_UTF8;
|
||||
$mail->msgHTML($body, ROOT_DIR, function ($html) use ($mail) {
|
||||
return $this->html2text($mail, $html);
|
||||
});
|
||||
|
||||
// Build headers
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->addCustomHeader('Auto-Submitted', 'auto-generated');
|
||||
$mail->addCustomHeader('Return-Path', '<>');
|
||||
|
||||
|
@ -82,7 +109,11 @@ class MailService {
|
|||
* @param PHPMailer $mailer
|
||||
*/
|
||||
private function configureMailer(PHPMailer $mailer) {
|
||||
$mailer->isSMTP();
|
||||
if ($this->use_sendmail) {
|
||||
$mailer->isSendmail();
|
||||
} else {
|
||||
$mailer->isSMTP();
|
||||
}
|
||||
|
||||
$available_options = [
|
||||
'host' => 'Host',
|
||||
|
@ -99,4 +130,18 @@ class MailService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom "advanced" callback to pass to msgHTML function
|
||||
*
|
||||
* @param PHPMailer $mailer a PHPMailer instance
|
||||
* @param string $html the HTML body of an email
|
||||
*/
|
||||
private function html2text(PHPMailer $mailer, $html) {
|
||||
$html = preg_replace('/<a[^>]*href="([^"]+)"[^>]*>(.*?)<\/a>/si', '${2}: ${1}', $html);
|
||||
|
||||
$html = preg_replace('/<br\/>/', "\n", $html);
|
||||
|
||||
return $mailer->html2text($html);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Framadate\Services;
|
||||
|
||||
use \stdClass;
|
||||
|
@ -14,10 +13,20 @@ class NotificationService {
|
|||
const UPDATE_POLL = 10;
|
||||
const DELETED_POLL = 11;
|
||||
|
||||
private $mailService;
|
||||
const TEMPLATES_MAPPING = [
|
||||
self::UPDATE_VOTE => 'mail/updated_vote.html.tpl',
|
||||
self::ADD_VOTE => 'mail/added_vote.html.tpl',
|
||||
self::ADD_COMMENT => 'mail/added_comment.html.tpl',
|
||||
self::UPDATE_POLL => 'mail/updated_poll.html.tpl',
|
||||
self::DELETED_POLL => 'mail/deleted_poll.html.tpl'
|
||||
];
|
||||
|
||||
function __construct(MailService $mailService) {
|
||||
private $mailService;
|
||||
private $smarty;
|
||||
|
||||
function __construct(MailService $mailService, \Smarty $smarty) {
|
||||
$this->mailService = $mailService;
|
||||
$this->smarty = $smarty;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,42 +47,24 @@ class NotificationService {
|
|||
|
||||
if ($isVoteAndCanSendIt || $isCommentAndCanSendIt || $isOtherType) {
|
||||
if (self::isParticipation($type)) {
|
||||
$translationString = 'Poll\'s participation: %s';
|
||||
$translationString = 'Poll participation: %s';
|
||||
} else {
|
||||
$translationString = 'Notification of poll: %s';
|
||||
}
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '] ' . __f('Mail', $translationString, $poll->title);
|
||||
|
||||
$message = '';
|
||||
$this->smarty->assign('username', $name);
|
||||
$this->smarty->assign('poll_title', $poll->title);
|
||||
$this->smarty->assign('poll_url', Utils::getUrlSondage($poll->admin_id, true));
|
||||
|
||||
$urlSondage = Utils::getUrlSondage($poll->admin_id, true);
|
||||
$link = '<a href="' . $urlSondage . '">' . $urlSondage . '</a>' . "\n\n";
|
||||
$template_name = self::TEMPLATES_MAPPING[$type];
|
||||
|
||||
switch ($type) {
|
||||
case self::UPDATE_VOTE:
|
||||
$message .= $name . ' ';
|
||||
$message .= __('Mail', "updated a vote.\nYou can find your poll at the link") . " :\n\n";
|
||||
$message .= $link;
|
||||
break;
|
||||
case self::ADD_VOTE:
|
||||
$message .= $name . ' ';
|
||||
$message .= __('Mail', "filled a vote.\nYou can find your poll at the link") . " :\n\n";
|
||||
$message .= $link;
|
||||
break;
|
||||
case self::ADD_COMMENT:
|
||||
$message .= $name . ' ';
|
||||
$message .= __('Mail', "wrote a comment.\nYou can find your poll at the link") . " :\n\n";
|
||||
$message .= $link;
|
||||
break;
|
||||
case self::UPDATE_POLL:
|
||||
$message = __f('Mail', 'Someone just change your poll available at the following link %s.', Utils::getUrlSondage($poll->admin_id, true)) . "\n\n";
|
||||
break;
|
||||
case self::DELETED_POLL:
|
||||
$message = __f('Mail', 'Someone just delete your poll %s.', Utils::htmlEscape($poll->title)) . "\n\n";
|
||||
break;
|
||||
if (!is_null($template_name)) {
|
||||
$message = $this->smarty->fetch($template_name);
|
||||
} else {
|
||||
$message = '';
|
||||
}
|
||||
|
||||
$messageTypeKey = $type . '-' . $poll->id;
|
||||
$this->mailService->send($poll->admin_mail, $subject, $message, $messageTypeKey);
|
||||
}
|
||||
|
@ -83,4 +74,40 @@ class NotificationService {
|
|||
{
|
||||
return $type >= self::UPDATE_POLL;
|
||||
}
|
||||
|
||||
function sendPollCreationMails($creator_mail, $creator_name, $poll_name, $poll_id, $admin_poll_id) {
|
||||
if (!$this->mailService->isEnabled() || !$this->mailService->isValidEmail($creator_mail)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->smarty->assign('poll_creator_name', Utils::htmlMailEscape($creator_name));
|
||||
$this->smarty->assign('poll_name', Utils::htmlMailEscape($poll_name));
|
||||
$this->smarty->assign('poll_url', Utils::getUrlSondage($poll_id));
|
||||
$message_participants = $this->smarty->fetch('mail/participants_forward_email.html.tpl');
|
||||
$this->mailService->send($creator_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Participant link') . '] ' . __('Generic', 'Poll') . ': ' . $poll_name, $message_participants);
|
||||
|
||||
$this->smarty->assign('poll_admin_url', Utils::getUrlSondage($admin_poll_id, true));
|
||||
$message_admin = $this->smarty->fetch('mail/creation_notification_email.html.tpl');
|
||||
$this->mailService->send($creator_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Message for the author') . '] ' . __('Generic', 'Poll') . ': ' . $poll_name, $message_admin);
|
||||
}
|
||||
|
||||
function sendEditedVoteNotification($email, &$poll, $poll_id, $edited_vote_id) {
|
||||
$url = Utils::getUrlSondage($poll_id, false, $edited_vote_id);
|
||||
|
||||
$this->smarty->assign('poll', $poll);
|
||||
$this->smarty->assign('poll_id', $poll_id);
|
||||
$this->smarty->assign('editedVoteUniqueId', $edited_vote_id);
|
||||
$body = $this->smarty->fetch('mail/remember_edit_link.tpl');
|
||||
|
||||
$subject = '[' . NOMAPPLICATION . '][' . __('EditLink', 'REMINDER') . '] ' . __f('EditLink', 'Edit link for poll "%s"', $poll->title);
|
||||
|
||||
$this->mailService->send($email, $subject, $body);
|
||||
}
|
||||
|
||||
function sendFindPollsByMailNotification($mail, &$polls) {
|
||||
$this->smarty->assign('polls', $polls);
|
||||
$body = $this->smarty->fetch('mail/find_polls.tpl');
|
||||
|
||||
$this->mailService->send($mail, __('FindPolls', 'List of your polls') . ' - ' . NOMAPPLICATION, $body, 'SEND_POLLS');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,26 +18,49 @@
|
|||
*/
|
||||
namespace Framadate\Services;
|
||||
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\ConnectionException;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Exception;
|
||||
use Framadate\Exception\AlreadyExistsException;
|
||||
use Framadate\Exception\ConcurrentEditionException;
|
||||
use Framadate\Exception\ConcurrentVoteException;
|
||||
use Framadate\Form;
|
||||
use Framadate\FramaDB;
|
||||
use Framadate\Repositories\RepositoryFactory;
|
||||
use Framadate\Security\Token;
|
||||
use RuntimeException;
|
||||
use stdClass;
|
||||
|
||||
class PollService {
|
||||
private $connect;
|
||||
private $logService;
|
||||
|
||||
private $pollRepository;
|
||||
private $slotRepository;
|
||||
private $voteRepository;
|
||||
private $commentRepository;
|
||||
/**
|
||||
* @var NotificationService
|
||||
*/
|
||||
private $notificationService;
|
||||
/**
|
||||
* @var SessionService
|
||||
*/
|
||||
private $sessionService;
|
||||
/**
|
||||
* @var PurgeService
|
||||
*/
|
||||
private $purgeService;
|
||||
|
||||
function __construct(FramaDB $connect, LogService $logService) {
|
||||
$this->connect = $connect;
|
||||
/**
|
||||
* @var LogService
|
||||
*/
|
||||
private $logService;
|
||||
|
||||
public function __construct(LogService $logService, NotificationService $notificationService, SessionService $sessionService, PurgeService $purgeService) {
|
||||
$this->logService = $logService;
|
||||
$this->notificationService = $notificationService;
|
||||
$this->sessionService = $sessionService;
|
||||
$this->purgeService = $purgeService;
|
||||
$this->pollRepository = RepositoryFactory::pollRepository();
|
||||
$this->slotRepository = RepositoryFactory::slotRepository();
|
||||
$this->voteRepository = RepositoryFactory::voteRepository();
|
||||
|
@ -48,26 +71,48 @@ class PollService {
|
|||
* Find a poll from its ID.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @return \stdClass|null The found poll, or null
|
||||
* @return stdClass|null The found poll, or null
|
||||
*/
|
||||
function findById($poll_id) {
|
||||
if (preg_match(POLL_REGEX, $poll_id)) {
|
||||
return $this->pollRepository->findById($poll_id);
|
||||
try {
|
||||
if (preg_match(POLL_REGEX, $poll_id)) {
|
||||
return $this->pollRepository->findById($poll_id);
|
||||
}
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('ERROR', 'Database error : ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $admin_poll_id
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function findByAdminId($admin_poll_id) {
|
||||
if (preg_match(ADMIN_POLL_REGEX, $admin_poll_id)) {
|
||||
return $this->pollRepository->findByAdminId($admin_poll_id);
|
||||
try {
|
||||
if (preg_match(ADMIN_POLL_REGEX, $admin_poll_id)) {
|
||||
return $this->pollRepository->findByAdminId($admin_poll_id);
|
||||
}
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('ERROR', 'Database error : ' . $e->getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function allCommentsByPollId($poll_id) {
|
||||
return $this->commentRepository->findAllByPollId($poll_id);
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @return array
|
||||
*/
|
||||
public function allCommentsByPollId($poll_id)
|
||||
{
|
||||
try {
|
||||
return $this->commentRepository->findAllByPollId($poll_id);
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('error', $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function allVotesByPollId($poll_id) {
|
||||
|
@ -88,74 +133,149 @@ class PollService {
|
|||
* @param $name
|
||||
* @param $choices
|
||||
* @param $slots_hash
|
||||
* @param string $mail
|
||||
* @throws AlreadyExistsException
|
||||
* @throws ConcurrentEditionException
|
||||
* @throws ConcurrentVoteException
|
||||
* @return bool
|
||||
*/
|
||||
public function updateVote($poll_id, $vote_id, $name, $choices, $slots_hash) {
|
||||
public function updateVote($poll_id, $vote_id, $name, $choices, $slots_hash, $mail) {
|
||||
$this->checkVoteConstraints($choices, $poll_id, $slots_hash, $name, $vote_id);
|
||||
|
||||
|
||||
// Update vote
|
||||
$choices = implode($choices);
|
||||
return $this->voteRepository->update($poll_id, $vote_id, $name, $choices);
|
||||
return $this->voteRepository->update($poll_id, $vote_id, $name, $choices, $mail);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $poll_id
|
||||
* @param $name
|
||||
* @param $choices
|
||||
* @param $slots_hash
|
||||
* @param string $mail
|
||||
* @throws AlreadyExistsException
|
||||
* @throws ConcurrentEditionException
|
||||
* @throws ConcurrentVoteException
|
||||
* @return \stdClass
|
||||
* @return stdClass
|
||||
*/
|
||||
function addVote($poll_id, $name, $choices, $slots_hash) {
|
||||
function addVote($poll_id, $name, $choices, $slots_hash, $mail) {
|
||||
$this->checkVoteConstraints($choices, $poll_id, $slots_hash, $name);
|
||||
|
||||
|
||||
// Insert new vote
|
||||
$choices = implode($choices);
|
||||
$token = $this->random(16);
|
||||
return $this->voteRepository->insert($poll_id, $name, $choices, $token);
|
||||
return $this->voteRepository->insert($poll_id, $name, $choices, $token, $mail);
|
||||
}
|
||||
|
||||
function addComment($poll_id, $name, $comment) {
|
||||
if ($this->commentRepository->exists($poll_id, $name, $comment)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return $this->commentRepository->insert($poll_id, $name, $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main entry point for poll creation. This action does all the following:
|
||||
* - Validate input data
|
||||
* - Create the poll in database
|
||||
* - Send emails
|
||||
* - Cleanups post creation (session and purges)
|
||||
*
|
||||
* @param Form $form
|
||||
* @return array
|
||||
* @param string $end_date
|
||||
* @return string|null returns the admin_id if the poll was created
|
||||
*/
|
||||
function createPoll(Form $form) {
|
||||
// Generate poll IDs, loop while poll ID already exists
|
||||
function doPollCreation(Form $form, $end_date) {
|
||||
// Min/Max archive date
|
||||
$min_expiry_time = $this->minExpiryDate();
|
||||
$max_expiry_time = $this->maxExpiryDate();
|
||||
|
||||
if (empty($form->id)) { // User want us to generate an id for him
|
||||
do {
|
||||
$poll_id = $this->random(16);
|
||||
} while ($this->pollRepository->existsById($poll_id));
|
||||
$admin_poll_id = $poll_id . $this->random(8);
|
||||
} else { // User have choosen the poll id
|
||||
$poll_id = $form->id;
|
||||
do {
|
||||
$admin_poll_id = $this->random(24);
|
||||
} while ($this->pollRepository->existsByAdminId($admin_poll_id));
|
||||
if (!empty($end_date)) {
|
||||
$registredate = explode('/', $end_date);
|
||||
|
||||
if (is_array($registredate) && count($registredate) === 3) {
|
||||
$time = mktime(0, 0, 0, $registredate[1], $registredate[0], $registredate[2]);
|
||||
|
||||
if ($time < $min_expiry_time) {
|
||||
$form->end_date = $min_expiry_time;
|
||||
} elseif ($max_expiry_time < $time) {
|
||||
$form->end_date = $max_expiry_time;
|
||||
} else {
|
||||
$form->end_date = $time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert poll + slots
|
||||
if (empty($form->end_date)) {
|
||||
// By default, expiration date is 6 months after last day
|
||||
$form->end_date = $max_expiry_time;
|
||||
}
|
||||
|
||||
// Insert poll in database
|
||||
list($poll_id, $admin_poll_id) = $this->createPoll($form);
|
||||
|
||||
// Send confirmation by mail if enabled
|
||||
if (!is_null($ids)) {
|
||||
// Everything went well
|
||||
$this->notificationService->sendPollCreationMails($form->admin_mail, $form->admin_name, $form->title, $poll_id, $admin_poll_id);
|
||||
|
||||
// Clean Form data in session
|
||||
$this->sessionService->removeAll('form');
|
||||
// Creation message
|
||||
$this->sessionService->set("Framadate", "messagePollCreated", TRUE);
|
||||
// Delete old polls
|
||||
$this->purgeService->repeatedCleanings();
|
||||
} else {
|
||||
// Add an error in the form
|
||||
$form->errors = [
|
||||
__('Error', 'GenericErrorPollCreation')
|
||||
];
|
||||
// TODO: change this to use sessionService function
|
||||
$_SESSION['form'] = serialize($form);
|
||||
}
|
||||
|
||||
return $admin_poll_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Form $form
|
||||
* @throws ConnectionException
|
||||
* @return array
|
||||
*/
|
||||
public function createPoll(Form $form) {
|
||||
// Generate poll IDs, loop while poll ID already exists
|
||||
|
||||
$this->pollRepository->beginTransaction();
|
||||
$this->pollRepository->insertPoll($poll_id, $admin_poll_id, $form);
|
||||
$this->slotRepository->insertSlots($poll_id, $form->getChoices());
|
||||
$this->pollRepository->commit();
|
||||
try {
|
||||
if (empty($form->id)) { // User want us to generate an id for him
|
||||
do {
|
||||
$poll_id = $this->random(16);
|
||||
} while ($this->pollRepository->existsById($poll_id));
|
||||
$admin_poll_id = $poll_id . $this->random(8);
|
||||
} else { // User have chosen the poll id
|
||||
$poll_id = $form->id;
|
||||
do {
|
||||
$admin_poll_id = $this->random(24);
|
||||
} while ($this->pollRepository->existsByAdminId($admin_poll_id));
|
||||
}
|
||||
|
||||
$this->logService->log('CREATE_POLL', 'id:' . $poll_id . ', title: ' . $form->title . ', format:' . $form->format . ', admin:' . $form->admin_name . ', mail:' . $form->admin_mail);
|
||||
// Insert poll + slots
|
||||
$this->pollRepository->insertPoll($poll_id, $admin_poll_id, $form);
|
||||
$this->slotRepository->insertSlots($poll_id, $form->getChoices());
|
||||
$this->pollRepository->commit();
|
||||
|
||||
return [$poll_id, $admin_poll_id];
|
||||
$this->logService->log(
|
||||
'CREATE_POLL',
|
||||
'id:' . $poll_id . ', title: ' . $form->title . ', format:' . $form->format . ', admin:' . $form->admin_name . ', mail:' . $form->admin_mail
|
||||
);
|
||||
|
||||
return [$poll_id, $admin_poll_id];
|
||||
} catch (DBALException $e) {
|
||||
$this->pollRepository->rollback();
|
||||
$this->logService->log('ERROR', "Poll couldn't be saved : " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function findAllByAdminMail($mail) {
|
||||
|
@ -164,7 +284,7 @@ class PollService {
|
|||
|
||||
/**
|
||||
* @param array $votes
|
||||
* @param \stdClass $poll
|
||||
* @param stdClass $poll
|
||||
* @return array
|
||||
*/
|
||||
public function computeBestChoices($votes, $poll) {
|
||||
|
@ -196,8 +316,8 @@ class PollService {
|
|||
function splitSlots($slots) {
|
||||
$splitted = [];
|
||||
foreach ($slots as $slot) {
|
||||
$obj = new \stdClass();
|
||||
$obj->day = $slot->title;
|
||||
$obj = new stdClass();
|
||||
$obj->day = (new DateTime())->setTimestamp((int) $slot->title);
|
||||
$obj->moments = explode(',', $slot->moments);
|
||||
|
||||
$splitted[] = $obj;
|
||||
|
@ -219,11 +339,12 @@ class PollService {
|
|||
function splitVotes($votes) {
|
||||
$splitted = [];
|
||||
foreach ($votes as $vote) {
|
||||
$obj = new \stdClass();
|
||||
$obj = new stdClass();
|
||||
$obj->id = $vote->id;
|
||||
$obj->name = $vote->name;
|
||||
$obj->uniqId = $vote->uniqId;
|
||||
$obj->choices = str_split($vote->choices);
|
||||
$obj->mail = $vote->mail;
|
||||
|
||||
$splitted[] = $obj;
|
||||
}
|
||||
|
@ -232,18 +353,25 @@ class PollService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @return int The max timestamp allowed for expiry date
|
||||
* @throws Exception
|
||||
* @return DateTime The max timestamp allowed for expiry date
|
||||
*/
|
||||
public function maxExpiryDate() {
|
||||
global $config;
|
||||
return time() + (86400 * $config['default_poll_duration']);
|
||||
try {
|
||||
global $config;
|
||||
$default_poll_duration = isset($config['default_poll_duration']) ? $config['default_poll_duration'] : 60;
|
||||
return (new DateTime())->add(new DateInterval('P' . $default_poll_duration . 'D'));
|
||||
} catch (Exception $e) {
|
||||
throw new RuntimeException('Configuration Exception');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int The min timestamp allowed for expiry date
|
||||
* @throws Exception
|
||||
* @return DateTime The min timestamp allowed for expiry date
|
||||
*/
|
||||
public function minExpiryDate() {
|
||||
return time() + 86400;
|
||||
return (new DateTime())->add(new DateInterval('P1D'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -257,7 +385,7 @@ class PollService {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param \stdClass $poll
|
||||
* @param stdClass $poll
|
||||
* @return array
|
||||
*/
|
||||
private function computeEmptyBestChoices($poll)
|
||||
|
@ -292,7 +420,7 @@ class PollService {
|
|||
private function random($length) {
|
||||
return Token::getToken($length);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param $choices
|
||||
* @param $poll_id
|
||||
|
@ -310,20 +438,20 @@ class PollService {
|
|||
} else {
|
||||
$exists = $this->voteRepository->existsByPollIdAndNameAndVoteId($poll_id, $name, $vote_id);
|
||||
}
|
||||
|
||||
|
||||
if ($exists) {
|
||||
throw new AlreadyExistsException();
|
||||
}
|
||||
|
||||
|
||||
$poll = $this->findById($poll_id);
|
||||
|
||||
|
||||
// Check that no-one voted in the meantime and it conflicts the maximum votes constraint
|
||||
$this->checkMaxVotes($choices, $poll, $poll_id);
|
||||
|
||||
|
||||
// Check if slots are still the same
|
||||
$this->checkThatSlotsDidntChanged($poll, $slots_hash);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method checks if the hash send by the user is the same as the computed hash.
|
||||
*
|
||||
|
@ -342,7 +470,7 @@ class PollService {
|
|||
* This method checks if the votes doesn't conflicts the maximum votes constraint
|
||||
*
|
||||
* @param $user_choice
|
||||
* @param \stdClass $poll
|
||||
* @param stdClass $poll
|
||||
* @param string $poll_id
|
||||
* @throws ConcurrentVoteException
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?php
|
||||
namespace Framadate\Services;
|
||||
use Framadate\FramaDB;
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Framadate\Repositories\RepositoryFactory;
|
||||
|
||||
/**
|
||||
|
@ -15,7 +16,7 @@ class PurgeService {
|
|||
private $voteRepository;
|
||||
private $commentRepository;
|
||||
|
||||
function __construct(FramaDB $connect, LogService $logService) {
|
||||
function __construct(Connection $connect, LogService $logService) {
|
||||
$this->logService = $logService;
|
||||
$this->pollRepository = RepositoryFactory::pollRepository();
|
||||
$this->slotRepository = RepositoryFactory::slotRepository();
|
||||
|
@ -23,52 +24,91 @@ class PurgeService {
|
|||
$this->commentRepository = RepositoryFactory::commentRepository();
|
||||
}
|
||||
|
||||
public function repeatedCleanings() {
|
||||
$this->purgeOldPolls();
|
||||
|
||||
if (0 === time() % 10) {
|
||||
$this->cleanDemoPoll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode purges all old polls (the ones with end_date in past).
|
||||
*
|
||||
* @return bool true is action succeeded
|
||||
*/
|
||||
function purgeOldPolls() {
|
||||
$oldPolls = $this->pollRepository->findOldPolls();
|
||||
$count = count($oldPolls);
|
||||
public function purgeOldPolls() {
|
||||
try {
|
||||
$oldPolls = $this->pollRepository->findOldPolls();
|
||||
$count = count($oldPolls);
|
||||
|
||||
if ($count > 0) {
|
||||
$this->logService->log('EXPIRATION', 'Going to purge ' . $count . ' poll(s)...');
|
||||
if ($count > 0) {
|
||||
$this->logService->log('EXPIRATION', 'Going to purge ' . $count . ' poll(s)...');
|
||||
|
||||
foreach ($oldPolls as $poll) {
|
||||
if ($this->purgePollById($poll->id)) {
|
||||
$this->logService->log('EXPIRATION_SUCCESS', 'id: ' . $poll->id . ', title:' . $poll->title . ', format: ' . $poll->format . ', admin: ' . $poll->admin_name);
|
||||
} else {
|
||||
$this->logService->log('EXPIRATION_FAILED', 'id: ' . $poll->id . ', title:' . $poll->title . ', format: ' . $poll->format . ', admin: ' . $poll->admin_name);
|
||||
foreach ($oldPolls as $poll) {
|
||||
if ($this->purgePollById($poll->id)) {
|
||||
$this->logService->log(
|
||||
'EXPIRATION_SUCCESS',
|
||||
'id: ' . $poll->id . ', title:' . $poll->title . ', format: ' . $poll->format . ', admin: ' . $poll->admin_name
|
||||
);
|
||||
} else {
|
||||
$this->logService->log(
|
||||
'EXPIRATION_FAILED',
|
||||
'id: ' . $poll->id . ', title:' . $poll->title . ', format: ' . $poll->format . ', admin: ' . $poll->admin_name
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $count;
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('ERROR', $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
|
||||
return $count;
|
||||
}
|
||||
|
||||
|
||||
public function cleanDemoPoll() {
|
||||
if (!defined("DEMO_POLL_ID") || !defined("DEMO_POLL_NUMBER_VOTES")) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->voteRepository->beginTransaction();
|
||||
|
||||
$demoVotes = $this->voteRepository->allUserVotesByPollId(DEMO_POLL_ID);
|
||||
$votesToDelete = count($demoVotes) - DEMO_POLL_NUMBER_VOTES;
|
||||
|
||||
if ($votesToDelete > 0) {
|
||||
$this->voteRepository->deleteOldVotesByPollId(DEMO_POLL_ID, $votesToDelete);
|
||||
}
|
||||
|
||||
$this->voteRepository->commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* This methode delete all data about a poll.
|
||||
*
|
||||
* @param $poll_id int The ID of the poll
|
||||
* @return bool true is action succeeded
|
||||
*/
|
||||
function purgePollById($poll_id) {
|
||||
private function purgePollById($poll_id) {
|
||||
$done = true;
|
||||
|
||||
$this->pollRepository->beginTransaction();
|
||||
$done &= $this->commentRepository->deleteByPollId($poll_id);
|
||||
$done &= $this->voteRepository->deleteByPollId($poll_id);
|
||||
$done &= $this->slotRepository->deleteByPollId($poll_id);
|
||||
$done &= $this->pollRepository->deleteById($poll_id);
|
||||
try {
|
||||
$this->pollRepository->beginTransaction();
|
||||
$done &= $this->commentRepository->deleteByPollId($poll_id);
|
||||
$done &= $this->voteRepository->deleteByPollId($poll_id);
|
||||
$done &= $this->slotRepository->deleteByPollId($poll_id);
|
||||
$done &= $this->pollRepository->deleteById($poll_id);
|
||||
|
||||
if ($done) {
|
||||
$this->pollRepository->commit();
|
||||
} else {
|
||||
$this->pollRepository->rollback();
|
||||
if ($done) {
|
||||
$this->pollRepository->commit();
|
||||
} else {
|
||||
$this->pollRepository->rollback();
|
||||
}
|
||||
} catch (DBALException $e) {
|
||||
$this->logService->log('ERROR', $e->getMessage());
|
||||
}
|
||||
|
||||
return $done;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Framadate\Services;
|
||||
|
||||
class SessionService {
|
||||
|
@ -55,9 +54,20 @@ class SessionService {
|
|||
unset($_SESSION[$section][$key]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a session section
|
||||
*
|
||||
* @param $section
|
||||
*/
|
||||
public function removeAll($section) {
|
||||
assert(!empty($section));
|
||||
|
||||
unset($_SESSION[$section]);
|
||||
}
|
||||
|
||||
private function initSectionIfNeeded($section) {
|
||||
if (!isset($_SESSION[$section])) {
|
||||
$_SESSION[$section] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,15 +25,23 @@ class Utils {
|
|||
* @return string Server name
|
||||
*/
|
||||
public static function get_server_name() {
|
||||
$scheme = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')) ? 'https' : 'http';
|
||||
$port = in_array($_SERVER['SERVER_PORT'], ['80', '443'], true) ? '' : ':' . $_SERVER['SERVER_PORT'];
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
|
||||
$serverPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : '';
|
||||
|
||||
$scheme = (
|
||||
(defined('FORCE_HTTPS') && FORCE_HTTPS ) ||
|
||||
(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ||
|
||||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
|
||||
) ? 'https' : 'http';
|
||||
|
||||
$domain = defined('APP_URL') ? APP_URL : $serverName;
|
||||
$port = in_array($serverPort, ['80', '443'], true) ? '' : ':' . $serverPort;
|
||||
$dirname = dirname($_SERVER['SCRIPT_NAME']);
|
||||
$dirname = $dirname === '\\' ? '/' : $dirname . '/';
|
||||
$dirname = str_replace('/admin', '', $dirname);
|
||||
$dirname = str_replace('/action', '', $dirname);
|
||||
$server_name = (defined('APP_URL') ? APP_URL : $_SERVER['SERVER_NAME']) . $port . $dirname;
|
||||
|
||||
return $scheme . '://' . preg_replace('#//+#', '/', $server_name);
|
||||
return $scheme . '://' . preg_replace('#//+#', '/', $domain . $port . $dirname);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<?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/OpenSondage: 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 Framadate behind a reverse proxy.
|
||||
// const APP_URL = '<www.mydomain.fr>';
|
||||
|
||||
// Application name
|
||||
const NOMAPPLICATION = 'Framadate';
|
||||
|
||||
// Database administrator email
|
||||
const ADRESSEMAILADMIN = 'admin@app.tld';
|
||||
|
||||
// Email for automatic responses (you should set it to "no-reply")
|
||||
const ADRESSEMAILREPONSEAUTO = 'no@reply';
|
||||
|
||||
// Database driver
|
||||
const DB_DRIVER = FRAMADATE_DB_DRIVER;
|
||||
|
||||
// Database name
|
||||
const DB_NAME = FRAMADATE_DB_NAME;
|
||||
|
||||
// Database host
|
||||
const DB_HOST = FRAMADATE_DB_HOST;
|
||||
|
||||
// Database port
|
||||
const DB_PORT = FRAMADATE_DB_PORT;
|
||||
|
||||
// Database user
|
||||
const DB_USER = FRAMADATE_DB_USER;
|
||||
|
||||
// Database password
|
||||
const DB_PASSWORD = FRAMADATE_DB_PASSWORD;
|
||||
|
||||
// Table name prefix
|
||||
const TABLENAME_PREFIX = 'fd_';
|
||||
|
||||
// Name of the table that stores migration script already executed
|
||||
const MIGRATION_TABLE = 'framadate_migration';
|
||||
|
||||
// Default Language
|
||||
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',
|
||||
'oc' => 'Occitan',
|
||||
'es' => 'Español',
|
||||
'de' => 'Deutsch',
|
||||
'nl' => 'Dutch',
|
||||
'it' => 'Italiano',
|
||||
'br' => 'Brezhoneg',
|
||||
'hu' => 'Magyar',
|
||||
];
|
||||
|
||||
// Path to image file with the title
|
||||
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 purging a poll
|
||||
const PURGE_DELAY = 60;
|
||||
|
||||
// Max slots per poll
|
||||
const MAX_SLOTS_PER_POLL = 366;
|
||||
|
||||
// Number of seconds before we allow to resend an "Remember Edit Link" email.
|
||||
const TIME_EDIT_LINK_EMAIL = 60;
|
||||
|
||||
// Config
|
||||
$config = [
|
||||
/* general config */
|
||||
'use_smtp' => false, // use email for polls creation/modification/responses notification
|
||||
'smtp_options' => [
|
||||
'host' => 'localhost', // SMTP server (you could add many servers (main and backup for example) : use ";" like separator
|
||||
'auth' => false, // Enable SMTP authentication
|
||||
'username' => '', // SMTP username
|
||||
'password' => '', // SMTP password
|
||||
'secure' => '', // Enable encryption (false, tls or ssl)
|
||||
'port' => 25, // TCP port to connect to
|
||||
],
|
||||
/* 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 "development 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.
|
||||
'markdown_editor_by_default' => true, // The markdown editor for the description is enabled by default
|
||||
'provide_fork_awesome' => true, // Whether the build-in fork-awesome should be provided
|
||||
];
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
// FRAMADATE version
|
||||
const VERSION = '1.1.8';
|
||||
const VERSION = '1.2.0-alpha.1';
|
||||
|
||||
// PHP Needed version
|
||||
const PHP_NEEDED_VERSION = '5.6';
|
||||
|
@ -33,6 +33,7 @@ const CHOICE_REGEX = '/^[ 012]$/';
|
|||
const BOOLEAN_REGEX = '/^(on|off|true|false|1|0)$/i';
|
||||
const BOOLEAN_TRUE_REGEX = '/^(on|true|1)$/i';
|
||||
const EDITABLE_CHOICE_REGEX = '/^[0-2]$/';
|
||||
const COLLECT_MAIL_CHOICE_REGEX = '/^[0-3]$/';
|
||||
const BASE64_REGEX = '/^[A-Za-z0-9]+$/';
|
||||
const MD5_REGEX = '/^[A-Fa-f0-9]{32}$/';
|
||||
|
||||
|
|
145
app/inc/i18n.php
145
app/inc/i18n.php
|
@ -17,29 +17,134 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
// Prepare I18N instance
|
||||
$i18n = \o80\i18n\I18N::instance();
|
||||
$i18n->setDefaultLang(DEFAULT_LANGUAGE);
|
||||
$i18n->setPath(__DIR__ . '/../../locale');
|
||||
const DATE_FORMAT_FULL = 'EEEE d MMMM y';
|
||||
const DATE_FORMAT_SHORT = 'EEEE d MMMM y';
|
||||
const DATE_FORMAT_DAY = 'E d';
|
||||
const DATE_FORMAT_DATE = 'dd-MM-y';
|
||||
const DATE_FORMAT_MONTH_YEAR = 'MMMM y';
|
||||
const DATE_FORMAT_DATETIME_SHORT = 'EEEE d';
|
||||
|
||||
// Change langauge when user asked for it
|
||||
if (isset($_POST['lang']) && is_string($_POST['lang']) && in_array($_POST['lang'], array_keys($ALLOWED_LANGUAGES), true)) {
|
||||
$_SESSION['lang'] = $_POST['lang'];
|
||||
// Change session language when requested
|
||||
if (isset($_REQUEST['lang'])
|
||||
&& array_key_exists($_REQUEST['lang'], $ALLOWED_LANGUAGES)) {
|
||||
$_SESSION['lang'] = $_REQUEST['lang'];
|
||||
}
|
||||
|
||||
/* <html lang="$locale"> */
|
||||
$i18n->get('', 'Something, just to load the dictionary');
|
||||
$locale = str_replace('_', '-', $i18n->getLoadedLang());
|
||||
// Try the user-specified locale, or the browser-specified locale.
|
||||
if (isset($_SESSION['lang'])) {
|
||||
$wanted_locale = $_SESSION['lang'];
|
||||
} else {
|
||||
$wanted_locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
|
||||
}
|
||||
// Use the best available locale.
|
||||
$locale = locale_lookup(array_keys($ALLOWED_LANGUAGES), $wanted_locale, false, DEFAULT_LANGUAGE);
|
||||
|
||||
/* Date Format */
|
||||
$date_format['txt_full'] = __('Date', 'FULL'); //summary in create_date_poll.php and removal date in choix_(date|autre).php
|
||||
$date_format['txt_short'] = __('Date', 'SHORT'); // radio title
|
||||
$date_format['txt_day'] = __('Date', 'DAY');
|
||||
$date_format['txt_date'] = __('Date', 'DATE');
|
||||
$date_format['txt_month_year'] = __('Date', 'MONTH_YEAR');
|
||||
$date_format['txt_datetime_short'] = __('Date', 'DATETIME');
|
||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { //%e can't be used on Windows platform, use %#d instead
|
||||
foreach ($date_format as $k => $v) {
|
||||
$date_format[$k] = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $v); //replace %e by %#d for windows
|
||||
/**
|
||||
* Formats a DateTime according to the IntlDateFormatter
|
||||
*
|
||||
* @param DateTime $date
|
||||
* @param string $pattern
|
||||
* @param $forceLocale
|
||||
* @return string
|
||||
*/
|
||||
function date_format_intl(DateTime $date, $pattern = DATE_FORMAT_FULL, $forceLocale = null) {
|
||||
global $locale;
|
||||
$local_locale = $forceLocale || $locale;
|
||||
|
||||
$dateFormatter = IntlDateFormatter::create(
|
||||
$local_locale,
|
||||
IntlDateFormatter::FULL,
|
||||
IntlDateFormatter::FULL,
|
||||
date_default_timezone_get(),
|
||||
IntlDateFormatter::GREGORIAN,
|
||||
$pattern
|
||||
);
|
||||
return $dateFormatter->format($date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a DateTime according to a translated format
|
||||
*
|
||||
* @param DateTime $date
|
||||
* @param string $pattern
|
||||
* @return string
|
||||
*/
|
||||
function date_format_translation(DateTime $date, $pattern = 'Y-m-d') {
|
||||
return $date->format(__('Date', $pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into a DateTime according to the IntlDateFormatter
|
||||
*
|
||||
* @param $dateString
|
||||
* @param string $pattern
|
||||
* @param string|null $forceLocale
|
||||
* @return DateTime|null
|
||||
*/
|
||||
function parse_intl_date($dateString, $pattern = DATE_FORMAT_DATE, $forceLocale = null) {
|
||||
global $locale;
|
||||
$local_locale = $forceLocale || $locale;
|
||||
|
||||
$dateFormatter = IntlDateFormatter::create(
|
||||
$local_locale,
|
||||
IntlDateFormatter::FULL,
|
||||
IntlDateFormatter::FULL,
|
||||
date_default_timezone_get(),
|
||||
IntlDateFormatter::GREGORIAN,
|
||||
$pattern
|
||||
);
|
||||
$timestamp = $dateFormatter->parse($dateString);
|
||||
try {
|
||||
return (new DateTime())->setTimestamp($timestamp);
|
||||
} catch (Exception $e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string into a DateTime according to a translated format
|
||||
*
|
||||
* @param string $dateString
|
||||
* @param string $pattern
|
||||
* @return DateTime
|
||||
*/
|
||||
function parse_translation_date($dateString, $pattern = 'Y-m-d') {
|
||||
return DateTime::createFromFormat(__('Date', $pattern), $dateString);
|
||||
}
|
||||
|
||||
/* i18n helper functions */
|
||||
use Symfony\Component\Translation\Loader\PoFileLoader;
|
||||
use Symfony\Component\Translation\Translator;
|
||||
|
||||
class __i18n {
|
||||
private static $translator;
|
||||
private static $fallbacktranslator;
|
||||
|
||||
public static function init($locale) {
|
||||
self::$translator = new Translator($locale);
|
||||
self::$translator->addLoader('pofile', new PoFileLoader());
|
||||
self::$translator->addResource('pofile', ROOT_DIR . "po/{$locale}.po", $locale);
|
||||
# Fallback:
|
||||
# For Symfony/Translation, empty strings are valid, but in po files, untranslated strings are "".
|
||||
# This means we cannot use the standard $translator->setFallbackLocales() mechanism :(
|
||||
self::$fallbacktranslator = new Translator(DEFAULT_LANGUAGE);
|
||||
self::$fallbacktranslator->addLoader('pofile', new PoFileLoader());
|
||||
self::$fallbacktranslator->addResource('pofile', ROOT_DIR . "po/" . DEFAULT_LANGUAGE . ".po", DEFAULT_LANGUAGE);
|
||||
}
|
||||
|
||||
public static function translate($key) {
|
||||
return self::$translator->trans($key)
|
||||
?: self::$fallbacktranslator->trans($key);
|
||||
}
|
||||
}
|
||||
__i18n::init($locale);
|
||||
|
||||
function __($section, $key) {
|
||||
return __i18n::translate($key);
|
||||
}
|
||||
|
||||
function __f($section, $key, $args) {
|
||||
$msg = __i18n::translate($key);
|
||||
$args = array_slice(func_get_args(), 2);
|
||||
return vsprintf($msg, $args);
|
||||
}
|
||||
|
|
|
@ -16,12 +16,15 @@
|
|||
* 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\FramaDB;
|
||||
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use Doctrine\DBAL\DBALException;
|
||||
use Doctrine\DBAL\DriverManager;
|
||||
use Framadate\Repositories\RepositoryFactory;
|
||||
use Framadate\Services\LogService;
|
||||
|
||||
// Autoloading of dependencies with Composer
|
||||
require_once __DIR__ . '/../../vendor/autoload.php';
|
||||
require_once __DIR__ . '/../../vendor/o80/i18n/src/shortcuts.php';
|
||||
|
||||
if (session_id() === '') {
|
||||
session_start();
|
||||
|
@ -32,17 +35,48 @@ if (ini_get('date.timezone') === '') {
|
|||
}
|
||||
|
||||
define('ROOT_DIR', __DIR__ . '/../../');
|
||||
define('CONF_FILENAME', ROOT_DIR . '/app/inc/config.php');
|
||||
|
||||
$path = '/app/inc/config.php';
|
||||
if (getenv('APP_ENV') === 'test') {
|
||||
$path = '/app/inc/config.test.php';
|
||||
// Read DB connection params from Environment Variables if possible
|
||||
define('FRAMADATE_DB_DRIVER', getenv('FRAMADATE_DB_DRIVER') ? getenv('FRAMADATE_DB_DRIVER') : 'pdo_sqlite');
|
||||
define('FRAMADATE_DB_NAME', getenv('FRAMADATE_DB_NAME') ? getenv('FRAMADATE_DB_NAME') : 'framadate');
|
||||
define('FRAMADATE_DB_HOST', getenv('FRAMADATE_DB_HOST') ? getenv('FRAMADATE_DB_HOST') : '');
|
||||
define('FRAMADATE_DB_PORT', getenv('FRAMADATE_DB_PORT') ? getenv('FRAMADATE_DB_PORT') : '');
|
||||
define('FRAMADATE_DB_USER', getenv('FRAMADATE_DB_USER') ? getenv('FRAMADATE_DB_USER') : '');
|
||||
define('FRAMADATE_DB_PASSWORD', getenv('FRAMADATE_DB_PASSWORD') ? getenv('FRAMADATE_DB_PASSWORD') : '');
|
||||
}
|
||||
define('CONF_FILENAME', ROOT_DIR . $path);
|
||||
|
||||
require_once __DIR__ . '/constants.php';
|
||||
|
||||
if (is_file(CONF_FILENAME)) {
|
||||
@include_once __DIR__ . '/config.php';
|
||||
@include_once CONF_FILENAME;
|
||||
|
||||
// Connection to database
|
||||
$connect = new FramaDB(DB_CONNECTION_STRING, DB_USER, DB_PASSWORD);
|
||||
RepositoryFactory::init($connect);
|
||||
$err = 0;
|
||||
$doctrineConfig = new Configuration();
|
||||
$connectionParams = [
|
||||
'dbname' => DB_NAME,
|
||||
'user' => DB_USER,
|
||||
'password' => DB_PASSWORD,
|
||||
'host' => DB_HOST,
|
||||
'driver' => DB_DRIVER,
|
||||
'charset' => DB_DRIVER === 'pdo_mysql' ? 'utf8mb4' : 'utf8',
|
||||
];
|
||||
|
||||
if (DB_DRIVER === 'pdo_sqlite') {
|
||||
$connectionParams['path'] = ROOT_DIR . '/test_database.sqlite';
|
||||
}
|
||||
|
||||
try {
|
||||
$connect = DriverManager::getConnection($connectionParams, $doctrineConfig);
|
||||
RepositoryFactory::init($connect);
|
||||
$err = 0;
|
||||
} catch (DBALException $e) {
|
||||
$logger = new LogService();
|
||||
$logger->log('ERROR', $e->getMessage());
|
||||
}
|
||||
} else {
|
||||
define('NOMAPPLICATION', 'Framadate');
|
||||
define('DEFAULT_LANGUAGE', 'fr');
|
||||
|
@ -61,3 +95,6 @@ if (is_file(CONF_FILENAME)) {
|
|||
require_once __DIR__ . '/i18n.php';
|
||||
// Smarty
|
||||
require_once __DIR__ . '/smarty.php';
|
||||
|
||||
require_once __DIR__ . '/services.php';
|
||||
Services::init($connect, $smarty);
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Framadate\Services\AdminPollService;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\NotificationService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Services\SessionService;
|
||||
|
||||
class Services {
|
||||
private static $connect;
|
||||
private static $smarty;
|
||||
|
||||
private static $adminPollService;
|
||||
private static $inputService;
|
||||
private static $logService;
|
||||
private static $mailService;
|
||||
private static $notificationService;
|
||||
private static $pollService;
|
||||
private static $purgeService;
|
||||
private static $securityService;
|
||||
private static $sessionService;
|
||||
|
||||
public static function init(Connection $connect, \Smarty $smarty) {
|
||||
self::$connect = $connect;
|
||||
self::$smarty = $smarty;
|
||||
}
|
||||
|
||||
public static function adminPoll() {
|
||||
if (self::$adminPollService === null) {
|
||||
self::$adminPollService = new AdminPollService(self::$connect, self::poll(), self::log());
|
||||
}
|
||||
return self::$adminPollService;
|
||||
}
|
||||
|
||||
public static function input() {
|
||||
if (self::$inputService === null) {
|
||||
self::$inputService = new InputService();
|
||||
}
|
||||
return self::$inputService;
|
||||
}
|
||||
|
||||
public static function log() {
|
||||
if (self::$logService === null) {
|
||||
self::$logService = new LogService();
|
||||
}
|
||||
return self::$logService;
|
||||
}
|
||||
|
||||
public static function mail() {
|
||||
if (self::$mailService === null) {
|
||||
self::$mailService = new MailService($config['use_smtp'], $config['smtp_options'], $config['use_sendmail']);
|
||||
}
|
||||
return self::$mailService;
|
||||
}
|
||||
|
||||
public static function notification() {
|
||||
if (self::$notificationService === null) {
|
||||
self::$notificationService = new NotificationService(self::mail(), self::$smarty);
|
||||
}
|
||||
return self::$notificationService;
|
||||
}
|
||||
|
||||
public static function poll() {
|
||||
if (self::$pollService === null) {
|
||||
self::$pollService = new PollService(self::log(), self::notification(), self::session(), self::purge());
|
||||
}
|
||||
return self::$pollService;
|
||||
}
|
||||
|
||||
public static function purge() {
|
||||
if (self::$purgeService === null) {
|
||||
self::$purgeService = new PurgeService(self::$connect, self::log());
|
||||
}
|
||||
return self::$purgeService;
|
||||
}
|
||||
|
||||
public static function session() {
|
||||
if (self::$sessionService === null) {
|
||||
self::$sessionService = new SessionService();
|
||||
}
|
||||
return self::$sessionService;
|
||||
}
|
||||
|
||||
public static function security() {
|
||||
if (self::$securityService === null) {
|
||||
self::$securityService = new SecurityService();
|
||||
}
|
||||
return self::$securityService;
|
||||
}
|
||||
}
|
|
@ -25,15 +25,18 @@ $smarty->setCompileDir(ROOT_DIR . COMPILE_DIR);
|
|||
$smarty->setCacheDir(ROOT_DIR . '/cache/');
|
||||
$smarty->caching = false;
|
||||
|
||||
$serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
|
||||
|
||||
$smarty->assign('APPLICATION_NAME', NOMAPPLICATION);
|
||||
$smarty->assign('APPLICATION_VERSION', VERSION);
|
||||
$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', strstr($_SERVER['SERVER_NAME'], 'framadate.org'));
|
||||
|
||||
$smarty->assign('use_nav_js', strstr($serverName, 'framadate.org'));
|
||||
$smarty->assign('provide_fork_awesome', !isset($config['provide_fork_awesome']) || $config['provide_fork_awesome']);
|
||||
$smarty->assign('locale', $locale);
|
||||
$smarty->assign('langs', $ALLOWED_LANGUAGES);
|
||||
$smarty->assign('date_format', $date_format);
|
||||
if (isset($config['tracking_code'])) {
|
||||
$smarty->assign('tracking_code', $config['tracking_code']);
|
||||
}
|
||||
|
@ -42,7 +45,8 @@ if (defined('FAVICON')) {
|
|||
}
|
||||
|
||||
// Dev Mode
|
||||
if (isset($_SERVER['FRAMADATE_DEVMODE']) && $_SERVER['FRAMADATE_DEVMODE']) {
|
||||
if (php_sapi_name() === 'cli-server') {
|
||||
$smarty->caching = 0;
|
||||
$smarty->force_compile = true;
|
||||
$smarty->compile_check = true;
|
||||
} else {
|
||||
|
@ -77,6 +81,21 @@ function smarty_modifier_html($html) {
|
|||
return Utils::htmlEscape($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* markdown_to_text
|
||||
* Retrieves a markdown string and tries to make a plain text value
|
||||
*
|
||||
* @param array $options
|
||||
* @return string
|
||||
*/
|
||||
function smarty_function_markdown_to_text($options, Smarty_Internal_Template $template)
|
||||
{
|
||||
global $locale;
|
||||
$text = strip_tags(Parsedown::instance()->text($options['markdown']));
|
||||
$number_letters = (new NumberFormatter($locale, NumberFormatter::ORDINAL))->format($options['id'] + 1);
|
||||
return $text !== '' ? $text : __f('Poll results', '%s option', $number_letters);
|
||||
}
|
||||
|
||||
function smarty_modifier_html_special_chars($html) {
|
||||
return Utils::htmlMailEscape($html);
|
||||
}
|
||||
|
@ -106,3 +125,38 @@ function smarty_modifier_locale_2_lang($locale) {
|
|||
function path_for_datepicker_locale($lang) {
|
||||
return __DIR__ . '/../../js/locales/bootstrap-datepicker.' . $lang . '.js';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $date
|
||||
* @param string $pattern
|
||||
* @return string
|
||||
*/
|
||||
function smarty_modifier_date_format_intl(DateTime $date, $pattern) {
|
||||
return date_format_intl($date, $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $date
|
||||
* @return int
|
||||
*/
|
||||
function smarty_modifier_date_to_timestamp(DateTime $date) {
|
||||
return $date->getTimestamp();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $timestamp
|
||||
* @throws Exception
|
||||
* @return DateTime
|
||||
*/
|
||||
function smarty_modifier_timestamp_to_date($timestamp) {
|
||||
return (new DateTime())->setTimestamp((int) $timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DateTime $date
|
||||
* @param string $pattern
|
||||
* @return bool|DateTime
|
||||
*/
|
||||
function smarty_modifier_date_format_translation(DateTime $date, $pattern = 'Y-m-d') {
|
||||
return date_format_translation($date, $pattern);
|
||||
}
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Framadate\Services;
|
||||
|
||||
use Framadate\FramaTestCase;
|
||||
|
||||
class InputServiceUnitTest extends FramaTestCase
|
||||
{
|
||||
public function liste_emails() {
|
||||
public function liste_emails()
|
||||
{
|
||||
return [
|
||||
// valids addresses
|
||||
"valid address" => ["example@example.com", "example@example.com"],
|
||||
"local address" => ["test@localhost", "test@localhost"],
|
||||
"IP address" => ["ip.email@127.0.0.1", "ip.email@127.0.0.1"],
|
||||
"with spaces arround" => [" with@spaces ", "with@spaces"],
|
||||
"unicode caracters" => ["unicode.éà@idn-œ.com", "unicode.éà@idn-œ.com"],
|
||||
"valid address" => ["example@example.com", "example@example.com"],
|
||||
"local address" => ["test@localhost", "test@localhost"],
|
||||
"IP address" => ["ip.email@127.0.0.1", "ip.email@127.0.0.1"],
|
||||
"with spaces arround" => [" with@spaces ", "with@spaces"],
|
||||
"unicode caracters" => ["unicode.éà@idn-œ.com", "unicode.éà@idn-œ.com"],
|
||||
// invalids addresses
|
||||
"without domain" => ["without-domain", FALSE],
|
||||
"space inside" => ["example example@example.com", FALSE],
|
||||
"forbidden chars" => ["special_chars.@example.com", FALSE],
|
||||
"without domain" => ["without-domain", FALSE],
|
||||
"space inside" => ["example example@example.com", FALSE],
|
||||
"forbidden chars" => ["special_chars.@example.com", FALSE],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider liste_emails
|
||||
*/
|
||||
public function test_filterMail($email, $expected) {
|
||||
$inputService = new InputService();
|
||||
$filtered = $inputService->filterMail($email);
|
||||
/**
|
||||
* @dataProvider liste_emails
|
||||
*/
|
||||
public function test_filterMail($email, $expected)
|
||||
{
|
||||
$inputService = new InputService();
|
||||
$filtered = $inputService->filterMail($email);
|
||||
|
||||
$this->assertSame($expected, $filtered);
|
||||
}
|
||||
$this->assertSame($expected, $filtered);
|
||||
}
|
||||
}
|
||||
|
|
13
bandeaux.php
13
bandeaux.php
|
@ -30,9 +30,9 @@ function bandeau_titre($titre)
|
|||
if(count($ALLOWED_LANGUAGES) > 1){
|
||||
echo '<form method="post" action="" class="hidden-print">
|
||||
<div class="input-group input-group-sm pull-right col-md-2 col-xs-4">
|
||||
<select name="lang" class="form-control" title="' . __('Language selector', 'Select the language') . '" >' . liste_lang() . '</select>
|
||||
<select name="lang" class="form-control" title="' . __('Language selector', 'Select language') . '" >' . liste_lang() . '</select>
|
||||
<span class="input-group-btn">
|
||||
<button type="submit" class="btn btn-default btn-sm" title="' . __('Language selector', 'Change the language') . '">OK</button>
|
||||
<button type="submit" class="btn btn-default btn-sm" title="' . __('Language selector', 'Change language') . '">OK</button>
|
||||
</span>
|
||||
</div>
|
||||
</form>';
|
||||
|
@ -43,15 +43,6 @@ function bandeau_titre($titre)
|
|||
<hr class="trait" role="presentation" />
|
||||
</header>
|
||||
<main role="main">';
|
||||
|
||||
global $connect;
|
||||
$tables = $connect->allTables();
|
||||
$diff = array_diff([Utils::table('comment'), Utils::table('poll'), Utils::table('slot'), Utils::table('vote')], $tables);
|
||||
if (0 !== count($diff)) {
|
||||
echo '<div class="alert alert-danger">' . __('Error', 'Framadate is not properly installed, please check the "INSTALL" to setup the database before continuing.') . '</div>';
|
||||
bandeau_pied();
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
function liste_lang()
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
use Doctrine\DBAL\Migrations\Configuration\Configuration;
|
||||
use Doctrine\DBAL\Tools\Console\Helper\ConnectionHelper;
|
||||
use Framadate\Utils;
|
||||
use Symfony\Component\Console\Application;
|
||||
use Symfony\Component\Console\Helper\HelperSet;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Output\ConsoleOutput;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
|
||||
try {
|
||||
require_once __DIR__ . '/../app/inc/init.php';
|
||||
|
||||
$input = new ArgvInput();
|
||||
$output = new ConsoleOutput();
|
||||
$style = new SymfonyStyle($input, $output);
|
||||
|
||||
if ($connect === null) {
|
||||
throw new \Exception("Undefined database connection\n");
|
||||
}
|
||||
|
||||
// replace the ConsoleRunner::run() statement with:
|
||||
$cli = new Application('Doctrine Command Line Interface', VERSION);
|
||||
$cli->setCatchExceptions(true);
|
||||
|
||||
$helperSet = new HelperSet(
|
||||
[
|
||||
'db' => new ConnectionHelper($connect),
|
||||
'question' => new QuestionHelper(),
|
||||
]
|
||||
);
|
||||
|
||||
$cli->setHelperSet($helperSet);
|
||||
|
||||
$migrateCommand = new \Doctrine\DBAL\Migrations\Tools\Console\Command\MigrateCommand();
|
||||
$statusCommand = new \Doctrine\DBAL\Migrations\Tools\Console\Command\StatusCommand();
|
||||
|
||||
$migrationsDirectory = __DIR__ . '/../app/classes/Framadate/Migrations';
|
||||
|
||||
$configuration = new Configuration($connect);
|
||||
$configuration->setMigrationsTableName(Utils::table(MIGRATION_TABLE) . '_new');
|
||||
$configuration->setMigrationsDirectory($migrationsDirectory);
|
||||
$configuration->setMigrationsNamespace('DoctrineMigrations');
|
||||
$configuration->registerMigrationsFromDirectory($migrationsDirectory);
|
||||
$migrateCommand->setMigrationConfiguration($configuration);
|
||||
$statusCommand->setMigrationConfiguration($configuration);
|
||||
|
||||
// Register All Doctrine Commands
|
||||
$cli->addCommands([$migrateCommand, $statusCommand]);
|
||||
|
||||
// Runs console application
|
||||
$cli->run($input, $output);
|
||||
} catch (\Exception $e) {
|
||||
$style->error($e->getMessage());
|
||||
exit(1);
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?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>
|
68
compare.php
68
compare.php
|
@ -1,68 +0,0 @@
|
|||
<?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 = [];
|
||||
|
||||
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>
|
|
@ -3,7 +3,7 @@
|
|||
"description": "Application to facilitate the schedule of events or classic polls",
|
||||
"homepage": "https://framadate.org/",
|
||||
"keywords": ["poll", "framadate"],
|
||||
"version": "0.9.0",
|
||||
"version": "1.2.0-alpha.1",
|
||||
"license": "CECILL-B",
|
||||
|
||||
"type": "project",
|
||||
|
@ -56,18 +56,22 @@
|
|||
"require": {
|
||||
"php": ">=5.6.0",
|
||||
"ext-pdo": "*",
|
||||
"ext-intl": "*",
|
||||
"smarty/smarty": "^3.1",
|
||||
"o80/i18n": "dev-develop",
|
||||
"phpmailer/phpmailer": "~6.0",
|
||||
"ircmaxell/password-compat": "dev-master",
|
||||
"roave/security-advisories": "dev-master",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"egulias/email-validator": "~2.1"
|
||||
"egulias/email-validator": "~2.1",
|
||||
"doctrine/dbal": "^2.5",
|
||||
"doctrine/migrations": "^1.5",
|
||||
"sensiolabs/ansi-to-html": "^1.1",
|
||||
"symfony/translation": "^3.4"
|
||||
},
|
||||
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^5.7",
|
||||
"friendsofphp/php-cs-fixer": "~2.0"
|
||||
"friendsofphp/php-cs-fixer": "~2.0",
|
||||
"roave/security-advisories": "dev-master"
|
||||
},
|
||||
|
||||
"autoload": {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -17,125 +17,96 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
use Framadate\Choice;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Services\SessionService;
|
||||
use Framadate\Form;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* Service */
|
||||
/*---------*/
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
|
||||
$purgeService = new PurgeService($connect, $logService);
|
||||
$sessionService = new SessionService();
|
||||
$pollService = Services::poll();
|
||||
|
||||
if (is_file('bandeaux_local.php')) {
|
||||
include_once('bandeaux_local.php');
|
||||
} else {
|
||||
include_once('bandeaux.php');
|
||||
include_once 'bandeaux.php';
|
||||
}
|
||||
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (($config['use_smtp']) ? empty($_SESSION['form']->admin_mail) : false)) {
|
||||
$max_expiry_time = $pollService->maxExpiryDate();
|
||||
|
||||
$form = isset($_SESSION['form']) ? unserialize($_SESSION['form']) : null;
|
||||
|
||||
if ($form === null || !($form instanceof Form)) {
|
||||
$smarty->assign('title', __('Error', 'Error!'));
|
||||
$smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation.'));
|
||||
$smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation, or your session has expired.'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
// Min/Max archive date
|
||||
$min_expiry_time = $pollService->minExpiryDate();
|
||||
$max_expiry_time = $pollService->maxExpiryDate();
|
||||
|
||||
// The poll format is AUTRE (other)
|
||||
if ($_SESSION['form']->format !== 'A') {
|
||||
$_SESSION['form']->format = 'A';
|
||||
$_SESSION['form']->clearChoices();
|
||||
}
|
||||
// The poll format is AUTRE (other) if we are in this file
|
||||
if (!isset($form->format)) {
|
||||
$form->format = 'A';
|
||||
}
|
||||
|
||||
// Step 4 : Data prepare before insert in DB
|
||||
if (isset($_POST['confirmation'])) {
|
||||
// Define expiration date
|
||||
$enddate = filter_input(INPUT_POST, 'enddate', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]{2}/[0-9]{2}/[0-9]{4}$#']]);
|
||||
// The poll format is AUTRE (other)
|
||||
if ($form->format !== 'A') {
|
||||
$form->format = 'A';
|
||||
$form->clearChoices();
|
||||
}
|
||||
|
||||
if (!empty($enddate)) {
|
||||
$registredate = explode('/', $enddate);
|
||||
if (!isset($form->title) || !isset($form->admin_name) || ($config['use_smtp'] && !isset($form->admin_mail))) {
|
||||
$step = 1;
|
||||
} elseif (isset($_POST['confirmation'])) {
|
||||
$step = 4;
|
||||
} elseif (empty($form->errors) && empty($_POST['fin_sondage_autre']) ) {
|
||||
$step = 2;
|
||||
} else {
|
||||
$step = 3;
|
||||
}
|
||||
|
||||
if (is_array($registredate) && count($registredate) === 3) {
|
||||
$time = mktime(0, 0, 0, $registredate[1], $registredate[0], $registredate[2]);
|
||||
|
||||
if ($time < $min_expiry_time) {
|
||||
$_SESSION['form']->end_date = $min_expiry_time;
|
||||
} elseif ($max_expiry_time < $time) {
|
||||
$_SESSION['form']->end_date = $max_expiry_time;
|
||||
} else {
|
||||
$_SESSION['form']->end_date = $time;
|
||||
}
|
||||
}
|
||||
switch ($step) {
|
||||
case 2: // Step 2/4 : Select choices of the poll
|
||||
$choices = $form->getChoices();
|
||||
$nb_choices = max( 5- count($choices), 0);
|
||||
while ($nb_choices-- > 0) {
|
||||
$c = new Choice('');
|
||||
$form->addChoice($c);
|
||||
}
|
||||
|
||||
if (empty($_SESSION['form']->end_date)) {
|
||||
// By default, expiration date is 6 months after last day
|
||||
$_SESSION['form']->end_date = $max_expiry_time;
|
||||
}
|
||||
$_SESSION['form'] = serialize($form);
|
||||
|
||||
// Insert poll in database
|
||||
$ids = $pollService->createPoll($_SESSION['form']);
|
||||
$poll_id = $ids[0];
|
||||
$admin_poll_id = $ids[1];
|
||||
// Display step 2
|
||||
$smarty->assign('title', __('Step 2 classic', 'Poll options (2 of 3)'));
|
||||
$smarty->assign('choices', $form->getChoices());
|
||||
$smarty->assign('allowMarkdown', $config['user_can_add_img_or_link']);
|
||||
$smarty->assign('error', null);
|
||||
|
||||
// Send confirmation by mail if enabled
|
||||
if ($config['use_smtp'] === true) {
|
||||
$message = __('Mail', "This is the message you have to send to the people you want to poll. \nNow, you have to send this message to everyone you want to poll.");
|
||||
$message .= '<br/><br/>';
|
||||
$message .= Utils::htmlMailEscape($_SESSION['form']->admin_name) . ' ' . __('Mail', 'hast just created a poll called') . ' : "' . Utils::htmlMailEscape($_SESSION['form']->title) . '".<br/>';
|
||||
$message .= sprintf(__('Mail', 'Thanks for filling the poll at the link above') . ' :<br/><br/><a href="%1$s">%1$s</a>', Utils::getUrlSondage($poll_id));
|
||||
|
||||
$message_admin = __('Mail', "This message should NOT be sent to the polled people. It is private for the poll's creator.\n\nYou can now modify it at the link above");
|
||||
$message_admin .= sprintf(' :<br/><br/><a href="%1$s">%1$s</a>', Utils::getUrlSondage($admin_poll_id, true));
|
||||
|
||||
if ($mailService->isValidEmail($_SESSION['form']->admin_mail)) {
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Author\'s message') . '] ' . __('Generic', 'Poll') . ': ' . $_SESSION['form']->title, $message_admin);
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'For sending to the polled users') . '] ' . __('Generic', 'Poll') . ': ' . $_SESSION['form']->title, $message);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean Form data in $_SESSION
|
||||
unset($_SESSION['form']);
|
||||
|
||||
// Delete old polls
|
||||
$purgeService->purgeOldPolls();
|
||||
|
||||
// creation message
|
||||
$sessionService->set("Framadate", "messagePollCreated", TRUE);
|
||||
|
||||
// Redirect to poll administration
|
||||
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
|
||||
$smarty->display('create_classic_poll_step_2.tpl');
|
||||
exit;
|
||||
} // Step 3/4 : Confirm poll creation and choose a removal date
|
||||
else if (isset($_POST['fin_sondage_autre'])) {
|
||||
// Store choices in $_SESSION
|
||||
if (isset($_POST['choices'])) {
|
||||
$_SESSION['form']->clearChoices();
|
||||
|
||||
case 3: // Step 3/4 : Confirm poll creation and choose a removal date
|
||||
// Handle Step2 submission
|
||||
if (!empty($_POST['choices'])) {
|
||||
// remove empty choices
|
||||
$_POST['choices'] = array_filter($_POST['choices'], function ($c) {
|
||||
return !empty($c);
|
||||
});
|
||||
|
||||
$form->clearChoices();
|
||||
|
||||
// store choices in $_SESSION
|
||||
foreach ($_POST['choices'] as $c) {
|
||||
if (!empty($c)) {
|
||||
$c = strip_tags($c);
|
||||
$choice = new Choice($c);
|
||||
$_SESSION['form']->addChoice($choice);
|
||||
}
|
||||
$c = strip_tags($c);
|
||||
$choice = new Choice($c);
|
||||
$form->addChoice($choice);
|
||||
}
|
||||
}
|
||||
|
||||
// Expiration date is initialised with config parameter. Value will be modified in step 4 if user has defined an other date
|
||||
$_SESSION['form']->end_date = $max_expiry_time;
|
||||
// Expiry date is initialised with config parameter. Value will be modified in step 4 if user has defined an other date
|
||||
$form->end_date = $max_expiry_time;
|
||||
|
||||
// Summary
|
||||
$summary = '<ol>';
|
||||
foreach ($_SESSION['form']->getChoices() as $i=>$choice) {
|
||||
foreach ($form->getChoices() as $i => $choice) {
|
||||
/** @var Choice $choice */
|
||||
preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/', $choice->getName(), $md_a_img); // Markdown [![alt](src)](href)
|
||||
preg_match_all('/!\[(.*?)\]\((.*?)\)/', $choice->getName(), $md_img); // Markdown ![alt](src)
|
||||
preg_match_all('/\[(.*?)\]\((.*?)\)/', $choice->getName(), $md_a); // Markdown [text](href)
|
||||
|
@ -157,100 +128,43 @@ if (empty($_SESSION['form']->title) || empty($_SESSION['form']->admin_name) || (
|
|||
}
|
||||
$summary .= '</ol>';
|
||||
|
||||
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); //textual date
|
||||
$end_date_str = date_format_intl($max_expiry_time); //textual date
|
||||
|
||||
$smarty->assign('title', __('Step 3', 'Removal date and confirmation (3 on 3)'));
|
||||
$_SESSION['form'] = serialize($form);
|
||||
|
||||
$smarty->assign('title', __('Step 3', 'Removal date and confirmation (3 of 3)'));
|
||||
$smarty->assign('summary', $summary);
|
||||
$smarty->assign('end_date_str', $end_date_str);
|
||||
$smarty->assign('default_poll_duration', $config['default_poll_duration']);
|
||||
$smarty->assign('use_smtp', $config['use_smtp']);
|
||||
$smarty->assign('errors', $form->errors);
|
||||
|
||||
$smarty->display('create_classic_poll_step3.tpl');
|
||||
$smarty->display('create_poll_step_3.tpl');
|
||||
exit;
|
||||
|
||||
// Step 2/4 : Select choices of the poll
|
||||
} else {
|
||||
Utils::print_header(__('Step 2 classic', 'Poll subjects (2 on 3)'));
|
||||
bandeau_titre(__('Step 2 classic', 'Poll subjects (2 on 3)'));
|
||||
case 4:
|
||||
// Step 4 : Do the poll creation
|
||||
|
||||
echo '
|
||||
<form name="formulaire" action="' . Utils::get_server_name() . 'create_classic_poll.php" method="POST" class="form-horizontal" role="form">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2">';
|
||||
echo '
|
||||
<div class="alert alert-info">
|
||||
<p>' . __('Step 2 classic', 'To make a generic poll you need to propose at least two choices between differents subjects.') . '</p>
|
||||
<p>' . __('Step 2 classic', 'You can add or remove additional choices with the buttons') . ' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">' . __('Generic', 'Remove') . '</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">' . __('Generic', 'Add') . '</span></p>';
|
||||
if ($config['user_can_add_img_or_link']) {
|
||||
echo ' <p>' . __('Step 2 classic', 'It\'s possible to propose links or images by using') . ' <a href="http://' . $locale . '.wikipedia.org/wiki/Markdown">' . __('Step 2 classic', 'the Markdown syntax') . '</a>.</p>';
|
||||
// Read expiration date passed in POST parameters
|
||||
$end_date = filter_input(INPUT_POST, 'enddate', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]{2}/[0-9]{2}/[0-9]{4}$#']]);
|
||||
|
||||
$admin_poll_id = $pollService->doPollCreation($form, $end_date);
|
||||
|
||||
if (!is_null($admin_poll_id)) {
|
||||
// Redirect to poll administration
|
||||
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
|
||||
} else {
|
||||
// Redirect to current page
|
||||
$referer = $_SERVER['HTTP_REFERER'];
|
||||
header("Location: $referer");
|
||||
}
|
||||
echo ' </div>' . "\n";
|
||||
|
||||
// Fields choices : 5 by default
|
||||
$choices = $_SESSION['form']->getChoices();
|
||||
$nb_choices = max(count($choices), 5);
|
||||
for ($i = 0; $i < $nb_choices; $i++) {
|
||||
$choice = isset($choices[$i]) ? $choices[$i] : new Choice();
|
||||
echo '
|
||||
<div class="form-group choice-field">
|
||||
<label for="choice' . $i . '" class="col-sm-2 control-label">' . __('Generic', 'Choice') . ' ' . ($i + 1) . '</label>
|
||||
<div class="col-sm-10 input-group">
|
||||
<input type="text" class="form-control" name="choices[]" size="40" value="' . $choice->getName() . '" id="choice' . $i . '" />';
|
||||
if ($config['user_can_add_img_or_link']) {
|
||||
echo '<span class="input-group-addon btn-link md-a-img" title="' . __('Step 2 classic', 'Add a link or an image') . ' - ' . __('Generic', 'Choice') . ' ' . ($i + 1) . '" ><span class="glyphicon glyphicon-picture"></span> <span class="glyphicon glyphicon-link"></span></span>';
|
||||
}
|
||||
echo '
|
||||
</div>
|
||||
</div>' . "\n";
|
||||
}
|
||||
|
||||
echo '
|
||||
<div class="col-md-4">
|
||||
<div class="btn-group btn-group">
|
||||
<button type="button" id="remove-a-choice" class="btn btn-default" title="' . __('Step 2 classic', 'Remove a choice') . '"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">' . __('Generic', 'Remove') . '</span></button>
|
||||
<button type="button" id="add-a-choice" class="btn btn-default" title="' . __('Step 2 classic', 'Add a choice') . '"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">' . __('Generic', 'Add') . '</span></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8 text-right">
|
||||
<a class="btn btn-default" href="' . Utils::get_server_name() . 'create_poll.php?type=classic" title="' . __('Step 2', 'Back to step 1') . '">' . __('Generic', 'Back') . '</a>
|
||||
<button name="fin_sondage_autre" value="' . __('Generic', 'Next') . '" type="submit" class="btn btn-success disabled" title="' . __('Step 2', 'Go to step 3') . '">' . __('Generic', 'Next') . '</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="md-a-imgModal" tabindex="-1" role="dialog" aria-labelledby="md-a-imgModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">' . __('Generic', 'Close') . '</span></button>
|
||||
<p class="modal-title" id="md-a-imgModalLabel">' . __('Step 2 classic', 'Add a link or an image') . '</p>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="alert alert-info">' . __('Step 2 classic', 'These fields are optional. You can add a link, an image or both.') . '</p>
|
||||
<div class="form-group">
|
||||
<label for="md-img"><span class="glyphicon glyphicon-picture"></span> ' . __('Step 2 classic', 'URL of the image') . '</label>
|
||||
<input id="md-img" type="text" placeholder="http://…" class="form-control" size="40" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="md-a"><span class="glyphicon glyphicon-link"></span> ' . __('Generic', 'Link') . '</label>
|
||||
<input id="md-a" type="text" placeholder="http://…" class="form-control" size="40" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="md-text">' . __('Step 2 classic', 'Alternative text') . '</label>
|
||||
<input id="md-text" type="text" class="form-control" size="40" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-default" data-dismiss="modal">' . __('Generic', 'Cancel') . '</button>
|
||||
<button type="button" class="btn btn-primary">' . __('Generic', 'Add') . '</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script type="text/javascript" src="js/app/framadatepicker.js"></script>
|
||||
<script type="text/javascript" src="js/app/classic_poll.js"></script>
|
||||
' . "\n";
|
||||
|
||||
bandeau_pied();
|
||||
}
|
||||
exit;
|
||||
|
||||
case 1:
|
||||
default:
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
$smarty->assign('title', __('Error', 'Error!'));
|
||||
$smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation, or your session has expired.'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
|
|
@ -17,80 +17,76 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft https://framagit.org/framasoft/framadate/)
|
||||
*/
|
||||
use Framadate\Choice;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\PurgeService;
|
||||
use Framadate\Services\SessionService;
|
||||
use Framadate\Form;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* Service */
|
||||
/*---------*/
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
|
||||
$purgeService = new PurgeService($connect, $logService);
|
||||
$inputService = new InputService();
|
||||
$sessionService = new SessionService();
|
||||
$inputService = Services::input();
|
||||
$pollService = Services::poll();
|
||||
|
||||
if (is_readable('bandeaux_local.php')) {
|
||||
include_once('bandeaux_local.php');
|
||||
}
|
||||
|
||||
// Min/Max archive date
|
||||
$min_expiry_time = $pollService->minExpiryDate();
|
||||
$max_expiry_time = $pollService->maxExpiryDate();
|
||||
|
||||
// The poll format is DATE
|
||||
if ($_SESSION['form']->format !== 'D') {
|
||||
$_SESSION['form']->format = 'D';
|
||||
$_SESSION['form']->clearChoices();
|
||||
$form = isset($_SESSION['form']) ? unserialize($_SESSION['form']) : null;
|
||||
|
||||
if ($form === null || !($form instanceof Form)) {
|
||||
$smarty->assign('title', __('Error', 'Error!'));
|
||||
$smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation, or your session has expired.'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['form']->title) || !isset($_SESSION['form']->admin_name) || ($config['use_smtp'] && !isset($_SESSION['form']->admin_mail))) {
|
||||
// The poll format is DATE if we are in this file
|
||||
if (!isset($form->format)) {
|
||||
$form->format = 'D';
|
||||
}
|
||||
// If we come from another format, we need to clear choices
|
||||
if ($form->format !== 'D') {
|
||||
$form->format = 'D';
|
||||
$form->clearChoices();
|
||||
}
|
||||
|
||||
if (!isset($form->title) || !isset($form->admin_name) || ($config['use_smtp'] && !isset($form->admin_mail))) {
|
||||
$step = 1;
|
||||
} else if (!empty($_POST['confirmation'])) {
|
||||
$step = 4;
|
||||
} else if (empty($_POST['choixheures']) || isset($_SESSION['form']->totalchoixjour)) {
|
||||
} else if (empty($form->errors) && (empty($_POST['choixheures']) || isset($form->totalchoixjour))) {
|
||||
$step = 2;
|
||||
} else {
|
||||
$step = 3;
|
||||
}
|
||||
|
||||
switch ($step) {
|
||||
case 1:
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
$smarty->assign('title', __('Error', 'Error!'));
|
||||
$smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation.'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
|
||||
case 2:
|
||||
// Step 2/4 : Select dates of the poll
|
||||
|
||||
// Prefill form->choices
|
||||
foreach ($_SESSION['form']->getChoices() as $c) {
|
||||
foreach ($form->getChoices() as $c) {
|
||||
/** @var Choice $c */
|
||||
$count = 3 - count($c->getSlots());
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$c->addSlot('');
|
||||
}
|
||||
}
|
||||
|
||||
$count = 3 - count($_SESSION['form']->getChoices());
|
||||
$count = 3 - count($form->getChoices());
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$c = new Choice('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
$c->addSlot('');
|
||||
$_SESSION['form']->addChoice($c);
|
||||
$form->addChoice($c);
|
||||
}
|
||||
|
||||
$_SESSION['form'] = serialize($form);
|
||||
|
||||
// Display step 2
|
||||
$smarty->assign('title', __('Step 2 date', 'Poll dates (2 on 3)'));
|
||||
$smarty->assign('choices', $_SESSION['form']->getChoices());
|
||||
$smarty->assign('title', __('Step 2 date', 'Poll dates (2 of 3)'));
|
||||
$smarty->assign('choices', $form->getChoices());
|
||||
$smarty->assign('error', null);
|
||||
|
||||
$smarty->display('create_date_poll_step_2.tpl');
|
||||
|
@ -109,8 +105,8 @@ switch ($step) {
|
|||
// Check if there are at most MAX_SLOTS_PER_POLL slots
|
||||
if (count($_POST['days']) > MAX_SLOTS_PER_POLL) {
|
||||
// Display step 2
|
||||
$smarty->assign('title', __('Step 2 date', 'Poll dates (2 on 3)'));
|
||||
$smarty->assign('choices', $_SESSION['form']->getChoices());
|
||||
$smarty->assign('title', __('Step 2 date', 'Poll dates (2 of 3)'));
|
||||
$smarty->assign('choices', $form->getChoices());
|
||||
$smarty->assign('error', __f('Error', 'You can\'t select more than %d dates', MAX_SLOTS_PER_POLL));
|
||||
|
||||
$smarty->display('create_date_poll_step_2.tpl');
|
||||
|
@ -118,7 +114,7 @@ switch ($step) {
|
|||
}
|
||||
|
||||
// Clear previous choices
|
||||
$_SESSION['form']->clearChoices();
|
||||
$form->clearChoices();
|
||||
|
||||
// Reorder moments to deal with suppressed dates
|
||||
$moments = [];
|
||||
|
@ -135,10 +131,10 @@ switch ($step) {
|
|||
|
||||
if (!empty($day)) {
|
||||
// Add choice to Form data
|
||||
$date = DateTime::createFromFormat(__('Date', 'datetime_parseformat'), $_POST['days'][$i])->setTime(0, 0, 0);
|
||||
$time = $date->getTimestamp();
|
||||
$date = DateTime::createFromFormat(__('Date', 'Y-m-d'), $_POST['days'][$i])->setTime(0, 0, 0);
|
||||
$time = (string) $date->getTimestamp();
|
||||
$choice = new Choice($time);
|
||||
$_SESSION['form']->addChoice($choice);
|
||||
$form->addChoice($choice);
|
||||
|
||||
$schedules = $inputService->filterArray($moments[$i], FILTER_DEFAULT);
|
||||
for ($j = 0; $j < count($schedules); $j++) {
|
||||
|
@ -148,14 +144,16 @@ switch ($step) {
|
|||
}
|
||||
}
|
||||
}
|
||||
$_SESSION['form']->sortChoices();
|
||||
$form->sortChoices();
|
||||
}
|
||||
|
||||
// Display step 3
|
||||
$summary = '<ul>';
|
||||
$choices = $_SESSION['form']->getChoices();
|
||||
$choices = $form->getChoices();
|
||||
foreach ($choices as $choice) {
|
||||
$summary .= '<li>' . strftime($date_format['txt_full'], $choice->getName());
|
||||
/** @var Choice $choice */
|
||||
$date = (new DateTime())->setTimestamp((int) $choice->getName());
|
||||
$summary .= '<li>' . $end_date_str = date_format_intl($date); //textual date
|
||||
$first = true;
|
||||
foreach ($choice->getSlots() as $slots) {
|
||||
$summary .= $first ? ': ' : ', ';
|
||||
|
@ -166,78 +164,43 @@ switch ($step) {
|
|||
}
|
||||
$summary .= '</ul>';
|
||||
|
||||
$end_date_str = utf8_encode(strftime($date_format['txt_date'], $max_expiry_time)); // textual date
|
||||
$end_date_str = date_format_intl($max_expiry_time); //textual date
|
||||
|
||||
$smarty->assign('title', __('Step 3', 'Removal date and confirmation (3 on 3)'));
|
||||
$_SESSION['form'] = serialize($form);
|
||||
|
||||
$smarty->assign('title', __('Step 3', 'Removal date and confirmation (3 of 3)'));
|
||||
$smarty->assign('summary', $summary);
|
||||
$smarty->assign('end_date_str', $end_date_str);
|
||||
$smarty->assign('default_poll_duration', $config['default_poll_duration']);
|
||||
$smarty->assign('use_smtp', $config['use_smtp']);
|
||||
$smarty->assign('errors', $form->errors);
|
||||
|
||||
$smarty->display('create_classic_poll_step3.tpl');
|
||||
$smarty->display('create_poll_step_3.tpl');
|
||||
exit;
|
||||
|
||||
case 4:
|
||||
// Step 4 : Data prepare before insert in DB
|
||||
// Step 4 : Do the poll creation
|
||||
|
||||
// Define expiration date
|
||||
$enddate = filter_input(INPUT_POST, 'enddate', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]{2}/[0-9]{2}/[0-9]{4}$#']]);
|
||||
// Read expiration date passed in POST parameters
|
||||
$end_date = filter_input(INPUT_POST, 'enddate', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '#^[0-9]{2}/[0-9]{2}/[0-9]{4}$#']]);
|
||||
|
||||
if (!empty($enddate)) {
|
||||
$registredate = explode('/', $enddate);
|
||||
$admin_poll_id = $pollService->doPollCreation($form, $end_date);
|
||||
|
||||
if (is_array($registredate) && count($registredate) === 3) {
|
||||
$time = mktime(0, 0, 0, $registredate[1], $registredate[0], $registredate[2]);
|
||||
|
||||
if ($time < $min_expiry_time) {
|
||||
$_SESSION['form']->end_date = $min_expiry_time;
|
||||
} elseif ($max_expiry_time < $time) {
|
||||
$_SESSION['form']->end_date = $max_expiry_time;
|
||||
} else {
|
||||
$_SESSION['form']->end_date = $time;
|
||||
}
|
||||
}
|
||||
if (!is_null($admin_poll_id)) {
|
||||
// Redirect to poll administration
|
||||
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
|
||||
} else {
|
||||
// Redirect to current page
|
||||
$referer = $_SERVER['HTTP_REFERER'];
|
||||
header("Location: $referer");
|
||||
}
|
||||
exit;
|
||||
|
||||
if (empty($_SESSION['form']->end_date)) {
|
||||
// By default, expiration date is 6 months after last day
|
||||
$_SESSION['form']->end_date = $max_expiry_time;
|
||||
}
|
||||
|
||||
// Insert poll in database
|
||||
$ids = $pollService->createPoll($_SESSION['form']);
|
||||
$poll_id = $ids[0];
|
||||
$admin_poll_id = $ids[1];
|
||||
|
||||
// Send confirmation by mail if enabled
|
||||
if ($config['use_smtp'] === true) {
|
||||
$message = __('Mail', "This is the message you have to send to the people you want to poll. \nNow, you have to send this message to everyone you want to poll.");
|
||||
$message .= '<br/><br/>';
|
||||
$message .= Utils::htmlEscape($_SESSION['form']->admin_name) . ' ' . __('Mail', 'hast just created a poll called') . ' : "' . Utils::htmlEscape($_SESSION['form']->title) . '".<br/>';
|
||||
$message .= __('Mail', 'Thanks for filling the poll at the link above') . ' :<br/><br/><a href="%1$s">%1$s</a>';
|
||||
|
||||
$message_admin = __('Mail', "This message should NOT be sent to the polled people. It is private for the poll's creator.\n\nYou can now modify it at the link above");
|
||||
$message_admin .= ' :<br/><br/><a href="%1$s">%1$s</a>';
|
||||
|
||||
$message = sprintf($message, Utils::getUrlSondage($poll_id));
|
||||
$message_admin = sprintf($message_admin, Utils::getUrlSondage($admin_poll_id, true));
|
||||
|
||||
if ($mailService->isValidEmail($_SESSION['form']->admin_mail)) {
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'Author\'s message') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($_SESSION['form']->title), $message_admin);
|
||||
$mailService->send($_SESSION['form']->admin_mail, '[' . NOMAPPLICATION . '][' . __('Mail', 'For sending to the polled users') . '] ' . __('Generic', 'Poll') . ': ' . Utils::htmlEscape($_SESSION['form']->title), $message);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean Form data in $_SESSION
|
||||
unset($_SESSION['form']);
|
||||
|
||||
// Delete old polls
|
||||
$purgeService->purgeOldPolls();
|
||||
|
||||
// creation message
|
||||
$sessionService->set("Framadate", "messagePollCreated", TRUE);
|
||||
|
||||
// Redirect to poll administration
|
||||
header('Location:' . Utils::getUrlSondage($admin_poll_id, true));
|
||||
case 1:
|
||||
default:
|
||||
// Step 1/4 : error if $_SESSION from info_sondage are not valid
|
||||
$smarty->assign('title', __('Error', 'Error!'));
|
||||
$smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation, or your session has expired.'));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
|
104
create_poll.php
104
create_poll.php
|
@ -20,7 +20,6 @@
|
|||
use Framadate\Form;
|
||||
use Framadate\Repositories\RepositoryFactory;
|
||||
use Framadate\Security\PasswordHasher;
|
||||
use Framadate\Services\InputService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
@ -30,25 +29,24 @@ const GO_TO_STEP_2 = 'gotostep2';
|
|||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$inputService = new InputService();
|
||||
$inputService = Services::input();
|
||||
$pollRepository = RepositoryFactory::pollRepository();
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
$form = isset($_SESSION['form']) ? unserialize($_SESSION['form']) : null;
|
||||
|
||||
if (!isset($_SESSION['form'])) {
|
||||
$_SESSION['form'] = new Form();
|
||||
if ($form === null || !($form instanceof Form)) {
|
||||
$form = new Form();
|
||||
}
|
||||
|
||||
// Type de sondage
|
||||
if (isset($_GET['type']) && $_GET['type'] === 'date' ||
|
||||
isset($_POST['type']) && $_POST['type'] === 'date'
|
||||
) {
|
||||
if (isset($_GET['type']) && $_GET['type'] === 'date') {
|
||||
$poll_type = 'date';
|
||||
$_SESSION['form']->choix_sondage = $poll_type;
|
||||
$form->choix_sondage = $poll_type;
|
||||
} else {
|
||||
$poll_type = 'classic';
|
||||
$_SESSION['form']->choix_sondage = $poll_type;
|
||||
$form->choix_sondage = $poll_type;
|
||||
}
|
||||
|
||||
// We clean the data
|
||||
|
@ -69,6 +67,8 @@ if ($goToStep2) {
|
|||
$receiveNewComments = isset($_POST['receiveNewComments']) ? $inputService->filterBoolean($_POST['receiveNewComments']) : false;
|
||||
$hidden = isset($_POST['hidden']) ? $inputService->filterBoolean($_POST['hidden']) : false;
|
||||
$use_password = filter_input(INPUT_POST, 'use_password', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
$collect_users_mail = $inputService->filterCollectMail($_POST['collect_users_mail']);
|
||||
$use_password = filter_input(INPUT_POST, 'use_password', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
$password = isset($_POST['password']) ? $_POST['password'] : null;
|
||||
$password_repeat = isset($_POST['password_repeat']) ? $_POST['password_repeat'] : null;
|
||||
$results_publicly_visible = filter_input(INPUT_POST, 'results_publicly_visible', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => BOOLEAN_REGEX]]);
|
||||
|
@ -83,20 +83,21 @@ if ($goToStep2) {
|
|||
$error_on_customized_url = false;
|
||||
$error_on_ValueMax = false;
|
||||
|
||||
$_SESSION['form']->title = $title;
|
||||
$_SESSION['form']->id = $customized_url;
|
||||
$_SESSION['form']->use_customized_url = $use_customized_url;
|
||||
$_SESSION['form']->use_ValueMax = $use_ValueMax;
|
||||
$_SESSION['form']->ValueMax = $ValueMax;
|
||||
$_SESSION['form']->admin_name = $name;
|
||||
$_SESSION['form']->admin_mail = $mail;
|
||||
$_SESSION['form']->description = $description;
|
||||
$_SESSION['form']->editable = $editable;
|
||||
$_SESSION['form']->receiveNewVotes = $receiveNewVotes;
|
||||
$_SESSION['form']->receiveNewComments = $receiveNewComments;
|
||||
$_SESSION['form']->hidden = $hidden;
|
||||
$_SESSION['form']->use_password = ($use_password !== null);
|
||||
$_SESSION['form']->results_publicly_visible = ($results_publicly_visible !== null);
|
||||
$form->title = $title;
|
||||
$form->id = $customized_url;
|
||||
$form->use_customized_url = $use_customized_url;
|
||||
$form->use_ValueMax = $use_ValueMax;
|
||||
$form->ValueMax = $ValueMax;
|
||||
$form->admin_name = $name;
|
||||
$form->admin_mail = $mail;
|
||||
$form->description = $description;
|
||||
$form->editable = $editable;
|
||||
$form->receiveNewVotes = $receiveNewVotes;
|
||||
$form->receiveNewComments = $receiveNewComments;
|
||||
$form->hidden = $hidden;
|
||||
$form->collect_users_mail = $collect_users_mail;
|
||||
$form->use_password = ($use_password !== null);
|
||||
$form->results_publicly_visible = ($results_publicly_visible !== null);
|
||||
|
||||
if ($config['use_smtp'] === true && empty($mail)) {
|
||||
$error_on_mail = true;
|
||||
|
@ -111,10 +112,10 @@ if ($goToStep2) {
|
|||
$error_on_customized_url = true;
|
||||
} else if ($pollRepository->existsById($customized_url)) {
|
||||
$error_on_customized_url = true;
|
||||
$error_on_customized_url_msg = __('Error', 'Poll id already used');
|
||||
$error_on_customized_url_msg = __('Error', 'Identifier is already used');
|
||||
} else if (in_array($customized_url, ['admin', 'vote', 'action'], true)) {
|
||||
$error_on_customized_url = true;
|
||||
$error_on_customized_url_msg = __('Error', 'This id is not allowed');
|
||||
$error_on_customized_url_msg = __('Error', 'This identifier is not allowed');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,13 +150,15 @@ if ($goToStep2) {
|
|||
&& !$error_on_password && !$error_on_password_repeat &&!$error_on_ValueMax
|
||||
) {
|
||||
// If no errors, we hash the password if needed
|
||||
if ($_SESSION['form']->use_password) {
|
||||
$_SESSION['form']->password_hash = PasswordHasher::hash($password);
|
||||
if ($form->use_password) {
|
||||
$form->password_hash = PasswordHasher::hash($password);
|
||||
} else {
|
||||
$_SESSION['form']->password_hash = null;
|
||||
$_SESSION['form']->results_publicly_visible = null;
|
||||
$form->password_hash = null;
|
||||
$form->results_publicly_visible = null;
|
||||
}
|
||||
|
||||
$_SESSION['form'] = serialize($form);
|
||||
|
||||
if ($goToStep2 === 'date') {
|
||||
header('Location:create_date_poll.php');
|
||||
exit();
|
||||
|
@ -167,11 +170,11 @@ if ($goToStep2) {
|
|||
}
|
||||
} else {
|
||||
// Title Erreur !
|
||||
$title = __('Error', 'Error!') . ' - ' . __('Step 1', 'Poll creation (1 on 3)');
|
||||
$title = __('Error', 'Error!') . ' - ' . __('Step 1', 'Poll creation (1 of 3)');
|
||||
}
|
||||
} else {
|
||||
// Title OK (formulaire pas encore rempli)
|
||||
$title = __('Step 1', 'Poll creation (1 on 3)');
|
||||
$title = __('Step 1', 'Poll creation (1 of 3)');
|
||||
}
|
||||
|
||||
// Prepare error messages
|
||||
|
@ -232,7 +235,7 @@ if (!empty($_POST[GO_TO_STEP_2])) {
|
|||
if ($error_on_customized_url) {
|
||||
$errors['customized_url']['aria'] = 'aria-describeby="customized_url" ';
|
||||
$errors['customized_url']['class'] = ' has-error';
|
||||
$errors['customized_url']['msg'] = isset($error_on_customized_url_msg) ? $error_on_customized_url_msg : __('Error', "Something is wrong with the format: customized urls should only consist of alphanumeric characters and hyphens.");
|
||||
$errors['customized_url']['msg'] = isset($error_on_customized_url_msg) ? $error_on_customized_url_msg : __('Error', "Something is wrong with the format: Customized URLs should only consist of alphanumeric characters and hyphens.");
|
||||
}
|
||||
|
||||
if ($error_on_description) {
|
||||
|
@ -264,17 +267,17 @@ if (!empty($_POST[GO_TO_STEP_2])) {
|
|||
if ($error_on_password) {
|
||||
$errors['password']['aria'] = 'aria-describeby="poll_password_error" ';
|
||||
$errors['password']['class'] = ' has-error';
|
||||
$errors['password']['msg'] = __('Error', 'Password is empty');
|
||||
$errors['password']['msg'] = __('Error', 'Password is empty.');
|
||||
}
|
||||
if ($error_on_password_repeat) {
|
||||
$errors['password_repeat']['aria'] = 'aria-describeby="poll_password_repeat_error" ';
|
||||
$errors['password_repeat']['class'] = ' has-error';
|
||||
$errors['password_repeat']['msg'] = __('Error', 'Passwords do not match');
|
||||
$errors['password_repeat']['msg'] = __('Error', 'Passwords do not match.');
|
||||
}
|
||||
if ($error_on_ValueMax) {
|
||||
$errors['ValueMax']['aria'] = 'aria-describeby="poll_ValueMax" ';
|
||||
$errors['ValueMax']['class'] = ' has-error';
|
||||
$errors['ValueMax']['msg'] = __('Error', 'Error on amount of voters limitation : value must be an integer greater than 0');
|
||||
$errors['ValueMax']['msg'] = __('Error', 'Error on amount of votes limitation: Value must be an integer greater than 0');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,20 +292,21 @@ $smarty->assign('default_to_marldown_editor', $config['markdown_editor_by_defaul
|
|||
$smarty->assign('goToStep2', GO_TO_STEP_2);
|
||||
|
||||
$smarty->assign('poll_type', $poll_type);
|
||||
$smarty->assign('poll_title', Utils::fromPostOrDefault('title', $_SESSION['form']->title));
|
||||
$smarty->assign('customized_url', Utils::fromPostOrDefault('customized_url', $_SESSION['form']->id));
|
||||
$smarty->assign('use_customized_url', Utils::fromPostOrDefault('use_customized_url', $_SESSION['form']->use_customized_url));
|
||||
$smarty->assign('ValueMax', Utils::fromPostOrDefault('ValueMax', $_SESSION['form']->ValueMax));
|
||||
$smarty->assign('use_ValueMax', Utils::fromPostOrDefault('use_ValueMax', $_SESSION['form']->use_ValueMax));
|
||||
$smarty->assign('poll_description', !empty($_POST['description']) ? $_POST['description'] : $_SESSION['form']->description);
|
||||
$smarty->assign('poll_name', Utils::fromPostOrDefault('name', $_SESSION['form']->admin_name));
|
||||
$smarty->assign('poll_mail', Utils::fromPostOrDefault('mail', $_SESSION['form']->admin_mail));
|
||||
$smarty->assign('poll_editable', Utils::fromPostOrDefault('editable', $_SESSION['form']->editable));
|
||||
$smarty->assign('poll_receiveNewVotes', Utils::fromPostOrDefault('receiveNewVotes', $_SESSION['form']->receiveNewVotes));
|
||||
$smarty->assign('poll_receiveNewComments', Utils::fromPostOrDefault('receiveNewComments', $_SESSION['form']->receiveNewComments));
|
||||
$smarty->assign('poll_hidden', Utils::fromPostOrDefault('hidden', $_SESSION['form']->hidden));
|
||||
$smarty->assign('poll_use_password', Utils::fromPostOrDefault('use_password', $_SESSION['form']->use_password));
|
||||
$smarty->assign('poll_results_publicly_visible', Utils::fromPostOrDefault('results_publicly_visible', $_SESSION['form']->results_publicly_visible));
|
||||
$smarty->assign('form', $_SESSION['form']);
|
||||
$smarty->assign('poll_title', Utils::fromPostOrDefault('title', $form->title));
|
||||
$smarty->assign('customized_url', Utils::fromPostOrDefault('customized_url', $form->id));
|
||||
$smarty->assign('use_customized_url', Utils::fromPostOrDefault('use_customized_url', $form->use_customized_url));
|
||||
$smarty->assign('ValueMax', Utils::fromPostOrDefault('ValueMax', $form->ValueMax));
|
||||
$smarty->assign('use_ValueMax', Utils::fromPostOrDefault('use_ValueMax', $form->use_ValueMax));
|
||||
$smarty->assign('collect_users_mail', Utils::fromPostOrDefault('collect_users_mail', $form->collect_users_mail));
|
||||
$smarty->assign('poll_description', !empty($_POST['description']) ? $_POST['description'] : $form->description);
|
||||
$smarty->assign('poll_name', Utils::fromPostOrDefault('name', $form->admin_name));
|
||||
$smarty->assign('poll_mail', Utils::fromPostOrDefault('mail', $form->admin_mail));
|
||||
$smarty->assign('poll_editable', Utils::fromPostOrDefault('editable', $form->editable));
|
||||
$smarty->assign('poll_receiveNewVotes', Utils::fromPostOrDefault('receiveNewVotes', $form->receiveNewVotes));
|
||||
$smarty->assign('poll_receiveNewComments', Utils::fromPostOrDefault('receiveNewComments', $form->receiveNewComments));
|
||||
$smarty->assign('poll_hidden', Utils::fromPostOrDefault('hidden', $form->hidden));
|
||||
$smarty->assign('poll_use_password', Utils::fromPostOrDefault('use_password', $form->use_password));
|
||||
$smarty->assign('poll_results_publicly_visible', Utils::fromPostOrDefault('results_publicly_visible', $form->results_publicly_visible));
|
||||
$smarty->assign('form', $form);
|
||||
|
||||
$smarty->display('create_poll.tpl');
|
||||
|
|
|
@ -24,6 +24,12 @@ body {
|
|||
background:#eee;
|
||||
}
|
||||
|
||||
.footer {
|
||||
text-align: right;
|
||||
margin-bottom: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
.trait { /* hr */
|
||||
background-color: #EEE;
|
||||
height: 5px;
|
||||
|
@ -449,19 +455,10 @@ span.edit-username-left {
|
|||
border-color: #949494 !important;
|
||||
}
|
||||
|
||||
table.results .bg-danger .glyphicon {
|
||||
/* TODO : Refactor me ! */
|
||||
table.results .bg-danger .glyphicon:not(.glyphicon-alert) {
|
||||
opacity:0;
|
||||
|
||||
-moz-animation-name: hideNoIcon;
|
||||
-moz-animation-iteration-count: 1;
|
||||
-moz-animation-timing-function: ease-in;
|
||||
-moz-animation-duration: 2s;
|
||||
|
||||
-webkit-animation-name: hideNoIcon;
|
||||
-webkit-animation-iteration-count: 1;
|
||||
-webkit-animation-timing-function: ease-in;
|
||||
-webkit-animation-duration: 2s;
|
||||
|
||||
animation-name: hideNoIcon;
|
||||
animation-iteration-count: 1;
|
||||
animation-timing-function: ease-in;
|
||||
|
@ -532,6 +529,11 @@ table.results > tbody > tr:hover > td .glyphicon {
|
|||
height: 33px;
|
||||
}
|
||||
|
||||
.datepicker {
|
||||
/* workaround for the bootstrap-datepicker appearing below the #add_days modal */
|
||||
z-index: 1060 !important;
|
||||
}
|
||||
|
||||
/* create_classic_poll.php */
|
||||
.md-a-img {
|
||||
text-decoration:none !important;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
version: '3'
|
||||
services:
|
||||
smtp:
|
||||
container_name: framadate-smtp
|
||||
image: jeanberu/mailcatcher
|
||||
ports:
|
||||
- "1080:1080"
|
||||
|
||||
db:
|
||||
container_name: framadate-db
|
||||
image: mysql:5.7
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=rootpassword
|
||||
- MYSQL_USER=framadate
|
||||
- MYSQL_PASSWORD=framadatedbpassword
|
||||
- MYSQL_DATABASE=framadate
|
||||
restart: always
|
||||
ports:
|
||||
- "3307:3306"
|
||||
|
||||
framadate:
|
||||
container_name: framadate
|
||||
build:
|
||||
dockerfile: ./docker/stretch/Dockerfile
|
||||
context: .
|
||||
depends_on:
|
||||
- db
|
||||
- smtp
|
||||
ports:
|
||||
- 80:80
|
||||
environment:
|
||||
- ENV=dev
|
||||
- APP_NAME=Framadate
|
||||
- ADMIN_MAIL=mon@email.fr
|
||||
- MYSQL_USER=framadate
|
||||
- MYSQL_PASSWORD=framadatedbpassword
|
||||
- MYSQL_DB=framadate
|
||||
- MYSQL_HOST=db
|
||||
- MYSQL_PORT=3307
|
||||
- ADMIN_USER=admin
|
||||
- ADMIN_PASSWORD=adminpassword
|
||||
- APACHE_RUN_USER=#1000
|
||||
- FRAMADATE_DEVMODE=1
|
||||
- SMTP_SERVER=smtp:1025
|
||||
restart: always
|
||||
volumes:
|
||||
- '.:/var/www/framadate'
|
|
@ -0,0 +1,30 @@
|
|||
FROM php:apache
|
||||
|
||||
MAINTAINER kyane@kyane.fr
|
||||
|
||||
RUN apt-get -y update && DEBIAN_FRONTEND=noninteractive apt-get install -y -qq zip unzip git zlib1g-dev libicu-dev g++ mysql-client
|
||||
RUN docker-php-ext-install intl && docker-php-ext-install pdo_mysql
|
||||
|
||||
RUN a2enmod rewrite
|
||||
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
||||
|
||||
COPY docker/stretch/php.ini /usr/local/etc/php/php.ini
|
||||
COPY docker/stretch/apache-framadate.conf /etc/apache2/sites-enabled/framadate.conf
|
||||
COPY docker/stretch/entrypoint.sh /usr/local/bin/entrypoint
|
||||
|
||||
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||
RUN set -eux; \
|
||||
composer global require "hirak/prestissimo:^0.3" --prefer-dist --no-progress --no-suggest --classmap-authoritative; \
|
||||
composer clear-cache
|
||||
ENV PATH="${PATH}:/root/.composer/vendor/bin"
|
||||
ENV COMPOSER_ALLOW_SUPERUSER 0
|
||||
|
||||
WORKDIR /var/www/framadate
|
||||
|
||||
# Some Apache and PHP configuration
|
||||
RUN if [ "$ENV" = "dev" ] ; then echo Using PHP production mode ; else echo Using PHP development mode && echo "error_reporting = E_ERROR | E_WARNING | E_PARSE\ndisplay_errors = On" > /usr/local/etc/php/conf.d/php.ini ; fi
|
||||
|
||||
RUN rm /etc/apache2/sites-enabled/000-default.conf
|
||||
EXPOSE 80
|
||||
ENTRYPOINT ["entrypoint"]
|
|
@ -0,0 +1,37 @@
|
|||
# Framadate
|
||||
**Cette image est en phase de test. NE PAS UTILISER EN PRODUCTION**
|
||||
|
||||
Image Docker pour le déploiement de Framadate
|
||||
|
||||
## Configuration
|
||||
### Base de données
|
||||
Pour fonctionner, Framadate a besoin d'une base de données. Dans notre cas nous utilisons MySQL, que l'on déploie avec Docker. Afin que Framadate fonctionne correctement, nous devons désactiver le *SQL MODE* `NO_ZERO_DATE` de MySQL. On peut donc déployer une base de données pour Framadate ainsi (avec Docker Compose):
|
||||
```
|
||||
framadate-db:
|
||||
image: mysql:5.7
|
||||
container_name: framadate-db
|
||||
command: --sql-mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
|
||||
volumes:
|
||||
- /path/to/data/volume:/var/lib/mysql
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=myrootpassword
|
||||
- MYSQL_USER=framadate
|
||||
- MYSQL_PASSWORD=myframadatepassword
|
||||
- MYSQL_DATABASE=framadate
|
||||
restart: always
|
||||
```
|
||||
|
||||
### Framadate
|
||||
Pour initialiser Framadate, on utilise plusieurs variables d'environnement :
|
||||
- `DOMAIN`: sous domaine du serveur Framadate (ex: `framadate.picasoft.net`)
|
||||
- `APP_NAME`: nom de l'application (`Framadate` par défaut)
|
||||
- `ADMIN_MAIL`: adresse mail de l'administrateur du serveur
|
||||
- `NO_REPLY_MAIL`: adresse mail qui servira à l'envoi des mails
|
||||
- `MYSQL_USER`: utilisateur MySQL
|
||||
- `MYSQL_PASSWORD`: mot de passe de l'utilisateur MySQL
|
||||
- `MYSQL_DB`: nom de la base de données
|
||||
- `MYSQL_HOST`: adresse du serveur de base de données
|
||||
- `MYSQL_PORT`: port du serveur MySQL (`3306` par défaut)
|
||||
- `ADMIN_USER`: utilisateur de l'interface d'administration
|
||||
- `ADMIN_PASSWORD`: mot de passe de l'interface d'administration
|
||||
- `DISABLE_SMTP`: mettre à `true` pour désactiver SMTP (sinon `false` par défaut)
|
|
@ -0,0 +1,28 @@
|
|||
<VirtualHost *:80>
|
||||
DocumentRoot /var/www/framadate
|
||||
|
||||
# URL rewrite
|
||||
<Directory "/">
|
||||
AllowOverride All
|
||||
</Directory>
|
||||
|
||||
# Admin folder
|
||||
<Directory "/var/www/framadate/admin/">
|
||||
AuthType Basic
|
||||
AuthName "Administration"
|
||||
AuthUserFile "/var/www/framadate/admin/.htpasswd"
|
||||
Require valid-user
|
||||
</Directory>
|
||||
|
||||
# Protection fichiers htpasswd et htaccess
|
||||
<FilesMatch "^\.ht.*">
|
||||
Deny from all
|
||||
Satisfy all
|
||||
ErrorDocument 403 "Accès refusé."
|
||||
</FilesMatch>
|
||||
|
||||
# Logs
|
||||
ErrorLog /dev/stdout
|
||||
CustomLog /dev/stdout combined
|
||||
|
||||
</VirtualHost>
|
|
@ -0,0 +1,89 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Read environment variables or set default values
|
||||
FRAMADATE_CONFIG=${FRAMADATE_CONFIG:-/var/www/framadate/app/inc/config.php}
|
||||
DOMAIN=${DOMAIN-localhost}
|
||||
FORCE_HTTPS=${FORCE_HTTPS-false}
|
||||
APP_NAME=${APP_NAME-Framadate}
|
||||
ADMIN_MAIL=${ADMIN_MAIL-}
|
||||
NO_REPLY_MAIL=${NO_REPLY_MAIL-}
|
||||
MYSQL_USER=${MYSQL_USER-user}
|
||||
MYSQL_PASSWORD=${MYSQL_PASSWORD-password}
|
||||
MYSQL_DB=${MYSQL_DB-framadate}
|
||||
MYSQL_HOST=${MYSQL_HOST-mysql}
|
||||
MYSQL_PORT=${MYSQL_PORT-3306}
|
||||
DISABLE_SMTP=${DISABLE_SMTP-false}
|
||||
|
||||
# Add configuration file if not exist
|
||||
if [ ! -f $FRAMADATE_CONFIG ]; then
|
||||
echo "There is no configuration file. Create one with environment variables"
|
||||
cp /var/www/framadate/tpl/admin/config.tpl $FRAMADATE_CONFIG
|
||||
# Set values on configuration file
|
||||
sed -i -E "s/^(\/\/ )?const APP_URL( )?=.*;/const APP_URL = '$DOMAIN';/g" $FRAMADATE_CONFIG
|
||||
if [ "$FORCE_HTTPS" = true ]; then
|
||||
sed -i -E "s/^(\/\/ )?const FORCE_HTTPS\\s*=.*;/const FORCE_HTTPS = true;/" $FRAMADATE_CONFIG
|
||||
fi
|
||||
sed -i -E "s/^(\/\/ )?const NOMAPPLICATION( )?=.*;/const NOMAPPLICATION = '$APP_NAME';/g" $FRAMADATE_CONFIG
|
||||
# Configure mail
|
||||
sed -i -E "s/^(\/\/ )?const ADRESSEMAILADMIN( )?=.*;/const ADRESSEMAILADMIN = '$ADMIN_MAIL';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const ADRESSEMAILREPONSEAUTO( )?=.*;/const ADRESSEMAILREPONSEAUTO = '$NO_REPLY_MAIL';/g" $FRAMADATE_CONFIG
|
||||
# Database configuration
|
||||
sed -i -E "s/^(\/\/ )?const DB_USER( )?=.*;/const DB_USER = '$MYSQL_USER';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const DB_PASSWORD( )?=.*;/const DB_PASSWORD = '$MYSQL_PASSWORD';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const DB_DRIVER( )?=.*;/const DB_DRIVER = 'pdo_mysql';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const DB_NAME( )?=.*;/const DB_NAME = '$MYSQL_DB';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const DB_HOST( )?=.*;/const DB_HOST = '$MYSQL_HOST';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const DB_PORT( )?=.*;/const DB_PORT = '$MYSQL_PORT';/g" $FRAMADATE_CONFIG
|
||||
# SMTP config
|
||||
if [ "$DISABLE_SMTP" = "true" ]; then
|
||||
sed -i -E "s/'use_smtp' => true,/'use_smtp' => false,/g" $FRAMADATE_CONFIG
|
||||
fi
|
||||
sed -i -E "s/SMTP_SERVER/${SMTP_SERVER:-localhost}/g" $FRAMADATE_CONFIG
|
||||
# Framadate internal config
|
||||
sed -i -E "s/^(\/\/ )?const TABLENAME_PREFIX( )?=.*;/const TABLENAME_PREFIX = 'fd_';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const MIGRATION_TABLE( )?=.*;/const MIGRATION_TABLE = 'framadate_migration';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const DEFAULT_LANGUAGE( )?=.*;/const DEFAULT_LANGUAGE = 'fr';/g" $FRAMADATE_CONFIG
|
||||
sed -i -E "s/^(\/\/ )?const URL_PROPRE( )?=.*;/const URL_PROPRE = true;/g" $FRAMADATE_CONFIG
|
||||
else
|
||||
echo "Using existing config file " $FRAMADATE_CONFIG
|
||||
fi
|
||||
|
||||
# Configure /admin basic auth
|
||||
if [ ! -f /var/www/framadate/admin/.htpasswd ]; then
|
||||
if [ "$ADMIN_USER" ] && [ "$ADMIN_PASSWORD" ]; then
|
||||
htpasswd -bc /var/www/framadate/admin/.htpasswd $ADMIN_USER $ADMIN_PASSWORD
|
||||
else
|
||||
echo "!!! You need to configure ADMIN_USER and ADMIN_PASSWORD environment variables !!!"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$ENV" = "dev" ]; then
|
||||
echo Installing PHP development dependencies
|
||||
composer install --no-interaction --no-progress
|
||||
else
|
||||
echo Installing PHP production dependencies
|
||||
composer install -o --no-interaction --no-progress --prefer-dist --no-dev
|
||||
composer dump-autoload --optimize --no-dev --classmap-authoritative
|
||||
fi
|
||||
|
||||
# Await MySQL Container being ready
|
||||
until /usr/bin/mysql --host=$MYSQL_HOST --user=$MYSQL_USER --password=$MYSQL_PASSWORD --silent --execute "SELECT 1;" $MYSQL_DB; do
|
||||
>&2 echo "MySQL is unavailable - sleeping"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
>&2 echo "Resuming setup"
|
||||
|
||||
echo "Setting up .htaccess"
|
||||
cp /var/www/framadate/htaccess.txt /var/www/framadate/.htaccess
|
||||
|
||||
# Run Database migrations
|
||||
echo "Running database migrations"
|
||||
php /var/www/framadate/bin/doctrine migrations:status --no-interaction -vvv
|
||||
php /var/www/framadate/bin/doctrine migrations:migrate --no-interaction -vvv
|
||||
|
||||
# Run apache server
|
||||
# chown -R www-data:www-data /var/www/framadate
|
||||
source /etc/apache2/envvars
|
||||
exec apache2 -D FOREGROUND
|
|
@ -0,0 +1,11 @@
|
|||
apc.enable_cli = 1
|
||||
date.timezone = UTC
|
||||
session.auto_start = Off
|
||||
short_open_tag = Off
|
||||
|
||||
# http://symfony.com/doc/current/performance.html
|
||||
opcache.interned_strings_buffer = 16
|
||||
opcache.max_accelerated_files = 20000
|
||||
opcache.memory_consumption = 256
|
||||
realpath_cache_size = 4096K
|
||||
realpath_cache_ttl = 600
|
|
@ -16,9 +16,6 @@
|
|||
* 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\LogService;
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Services\SecurityService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
@ -34,9 +31,8 @@ $poll = null;
|
|||
/* Services */
|
||||
/*----------*/
|
||||
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$securityService = new SecurityService();
|
||||
$pollService = Services::poll();
|
||||
$securityService = Services::security();
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
@ -53,7 +49,7 @@ if (!empty($_GET['poll'])) {
|
|||
}
|
||||
|
||||
if (!$poll) {
|
||||
$smarty->assign('error', __('Error', 'This poll doesn\'t exist !'));
|
||||
$smarty->assign('error', __('Error', "This poll doesn't exist!"));
|
||||
$smarty->display('error.tpl');
|
||||
exit;
|
||||
}
|
||||
|
@ -73,11 +69,12 @@ $slots = $pollService->allSlotsByPoll($poll);
|
|||
$votes = $pollService->allVotesByPollId($poll_id);
|
||||
|
||||
// CSV header
|
||||
echo "\xEF\xBB\xBF"; // BOM character for UTF-8
|
||||
if ($poll->format === 'D') {
|
||||
$titles_line = ',';
|
||||
$moments_line = ',';
|
||||
foreach ($slots as $slot) {
|
||||
$title = Utils::csvEscape(strftime($date_format['txt_date'], $slot->title));
|
||||
$title = Utils::csvEscape($dateFormatter->format($slot->title));
|
||||
$moments = explode(',', $slot->moments);
|
||||
|
||||
$titles_line .= str_repeat($title . ',', count($moments));
|
||||
|
@ -104,7 +101,7 @@ foreach ($votes as $vote) {
|
|||
$text = __('Generic', 'No');
|
||||
break;
|
||||
case 1:
|
||||
$text = __('Generic', 'Ifneedbe');
|
||||
$text = __('Generic', 'Under reserve');
|
||||
break;
|
||||
case 2:
|
||||
$text = __('Generic', 'Yes');
|
||||
|
|
|
@ -18,17 +18,14 @@
|
|||
*/
|
||||
|
||||
use Framadate\Message;
|
||||
use Framadate\Services\LogService;
|
||||
use Framadate\Services\MailService;
|
||||
use Framadate\Services\PollService;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
||||
/* SERVICES */
|
||||
/* -------- */
|
||||
$logService = new LogService();
|
||||
$pollService = new PollService($connect, $logService);
|
||||
$mailService = new MailService($config['use_smtp'], $config['smtp_options']);
|
||||
|
||||
$notificationService = Services::notification();
|
||||
$pollService = Services::poll();
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
@ -40,10 +37,7 @@ if (!empty($_POST['mail'])) {
|
|||
$polls = $pollService->findAllByAdminMail($mail);
|
||||
|
||||
if (count($polls) > 0) {
|
||||
$smarty->assign('polls', $polls);
|
||||
$body = $smarty->fetch('mail/find_polls.tpl');
|
||||
|
||||
$mailService->send($mail, __('FindPolls', 'List of your polls') . ' - ' . NOMAPPLICATION, $body, 'SEND_POLLS');
|
||||
$notificationService->sendFindPollsByMailNotification($mail, $polls);
|
||||
$message = new Message('success', __('FindPolls', 'Polls sent'));
|
||||
} else {
|
||||
$message = new Message('warning', __('Error', 'No polls found'));
|
||||
|
@ -53,7 +47,8 @@ if (!empty($_POST['mail'])) {
|
|||
}
|
||||
}
|
||||
|
||||
$smarty->assign('title', __('Homepage', 'Where are my polls'));
|
||||
$smarty->assign('title', __('Homepage', 'Where are my polls?'));
|
||||
$smarty->assign('message', $message);
|
||||
$smarty->assign('locale', $locale);
|
||||
|
||||
$smarty->display('find_polls.tpl');
|
||||
|
|
17
index.php
17
index.php
|
@ -17,7 +17,6 @@
|
|||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
|
||||
use Framadate\Services\PollService;
|
||||
use Framadate\Utils;
|
||||
|
||||
include_once __DIR__ . '/app/inc/init.php';
|
||||
|
@ -27,23 +26,23 @@ if (!is_file(CONF_FILENAME)) {
|
|||
exit;
|
||||
}
|
||||
|
||||
/* SERVICES */
|
||||
/* -------- */
|
||||
$logService = '\Framadate\Services\LogService';
|
||||
$pollService = new PollService($connect, new $logService());
|
||||
|
||||
/* PAGE */
|
||||
/* ---- */
|
||||
|
||||
$demoPoll = $pollService->findById('aqg259dth55iuhwm');
|
||||
$demoPollURL = "";
|
||||
|
||||
if (defined("DEMO_POLL_ID")) {
|
||||
$demoPollURL = Utils::getUrlSondage(DEMO_POLL_ID);
|
||||
}
|
||||
|
||||
$nbcol = max( $config['show_what_is_that'] + $config['show_the_software'] + $config['show_cultivate_your_garden'], 1 );
|
||||
|
||||
$smarty->assign('show_what_is_that', $config['show_what_is_that']);
|
||||
$smarty->assign('show_the_software', $config['show_the_software']);
|
||||
$smarty->assign('show_cultivate_your_garden', $config['show_cultivate_your_garden']);
|
||||
$smarty->assign('col_size', 12 / $nbcol);
|
||||
$smarty->assign('demo_poll', $demoPoll);
|
||||
$smarty->assign('demo_poll_url', $demoPollURL);
|
||||
|
||||
$smarty->assign('title', __('Generic', 'Make your polls'));
|
||||
$smarty->assign('title', __('Generic', 'Create your own polls'));
|
||||
|
||||
$smarty->display('index.tpl');
|
||||
|
|
|
@ -1,9 +1,67 @@
|
|||
$(document).ready(function() {
|
||||
|
||||
/**
|
||||
* Markdown Editor
|
||||
* @type {MDEWrapper}
|
||||
*/
|
||||
wrapper = new MDEWrapper($('.js-desc textarea')[0], $('#rich-editor-button'), $('#simple-editor-button'));
|
||||
var firstOpening = true;
|
||||
|
||||
/**
|
||||
* Save a list of admin polls inside LocalStorage
|
||||
* @param adminPolls
|
||||
*/
|
||||
function setAdminPolls(adminPolls) {
|
||||
localStorage.setItem('admin_polls', JSON.stringify(adminPolls));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an admin poll inside LocalStorage
|
||||
* @param adminPoll
|
||||
*/
|
||||
function addAdminPoll(adminPoll) {
|
||||
var adminPolls = localStorage.getItem('admin_polls');
|
||||
if (adminPolls === null) {
|
||||
adminPolls = [];
|
||||
} else {
|
||||
adminPolls = JSON.parse(adminPolls);
|
||||
}
|
||||
/**
|
||||
* Test if the poll is already inside the list
|
||||
*/
|
||||
var index = adminPolls.findIndex(function (existingPoll) {
|
||||
return existingPoll.url === adminPoll.url;
|
||||
});
|
||||
if (index === -1) {
|
||||
adminPolls.push(adminPoll);
|
||||
} else { // if the poll is already present, we need to update the last access date
|
||||
adminPolls[index] = adminPoll;
|
||||
}
|
||||
setAdminPolls(adminPolls);
|
||||
}
|
||||
|
||||
var adminPoll = {
|
||||
url: window.location.href,
|
||||
title: $('#title-form h3').get(0).childNodes[0].nodeValue,
|
||||
accessed: (new Date()).toISOString()
|
||||
};
|
||||
|
||||
if (!localStorage.getItem('admin_polls')) {
|
||||
setAdminPolls([adminPoll]);
|
||||
} else {
|
||||
addAdminPoll(adminPoll);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate popovers
|
||||
*/
|
||||
$('[data-toggle="popover"]').popover();
|
||||
|
||||
/**
|
||||
* Create node with text to use the Clipboard API
|
||||
* @param text
|
||||
* @returns {HTMLPreElement}
|
||||
*/
|
||||
function createNode(text) {
|
||||
var node = document.createElement('pre');
|
||||
node.style.width = '1px';
|
||||
|
@ -14,6 +72,10 @@ $(document).ready(function() {
|
|||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a Node to use for Clipboard API
|
||||
* @param node
|
||||
*/
|
||||
function copyNode(node) {
|
||||
var selection = getSelection();
|
||||
selection.removeAllRanges();
|
||||
|
@ -26,6 +88,10 @@ $(document).ready(function() {
|
|||
selection.removeAllRanges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a text inside the clipboard
|
||||
* @param text
|
||||
*/
|
||||
function copyText(text) {
|
||||
var node = createNode(text);
|
||||
document.body.appendChild(node);
|
||||
|
|
|
@ -15,75 +15,74 @@
|
|||
* Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ
|
||||
* Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft)
|
||||
*/
|
||||
(function () {
|
||||
|
||||
// 2 choices filled and you can submit
|
||||
|
||||
var submitChoicesAvalaible = function () {
|
||||
$(document).ready(function () {
|
||||
$(document.formulaire).on('submit', function (e) {
|
||||
if (!isSubmitChoicesAvalaible()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
var $next = $('button[name="fin_sondage_autre"]');
|
||||
var $removeAChoice = $('#remove-a-choice');
|
||||
var $addAChoice = $('#add-a-choice');
|
||||
|
||||
var updateButtonState = function() {
|
||||
var $choiceFields = $('.choice-field');
|
||||
$removeAChoice.prop('disabled', function() { return $choiceFields.length <= 2; });
|
||||
$next.prop('disabled', !isSubmitChoicesAvalaible());
|
||||
}
|
||||
|
||||
var isSubmitChoicesAvalaible = function () {
|
||||
return (countFilledChoices() >= 2);
|
||||
};
|
||||
|
||||
var countFilledChoices = function() {
|
||||
var nb_filled_choices = 0;
|
||||
$('.choice-field input').each(function () {
|
||||
if ($(this).val() != '') {
|
||||
nb_filled_choices++;
|
||||
}
|
||||
});
|
||||
if (nb_filled_choices >= 1) {
|
||||
$('button[name="fin_sondage_autre"]').removeClass('disabled');
|
||||
return true;
|
||||
} else {
|
||||
$('button[name="fin_sondage_autre"]').addClass('disabled');
|
||||
return false;
|
||||
}
|
||||
return nb_filled_choices;
|
||||
};
|
||||
|
||||
// Handle form submission
|
||||
$(document.formulaire).on('submit', function (e) {
|
||||
if (!submitChoicesAvalaible()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
$removeAChoice.on('click', function () {
|
||||
$('.choice-field:last').remove();
|
||||
updateButtonState();
|
||||
});
|
||||
|
||||
// Button "Add a choice"
|
||||
|
||||
$('#add-a-choice').on('click', function () {
|
||||
var nb_choices = $('.choice-field').length;
|
||||
var last_choice = $('.choice-field:last');
|
||||
|
||||
$addAChoice.on('click', function () {
|
||||
var $choiceFields = $('.choice-field');
|
||||
var nb_choices = $choiceFields.length;
|
||||
var last_choice = $choiceFields.last();
|
||||
|
||||
var new_choice = last_choice.html();
|
||||
|
||||
|
||||
// label
|
||||
var last_choice_label = last_choice.children('label').text();
|
||||
var choice_text = last_choice_label.substring(0, last_choice_label.indexOf(' '));
|
||||
|
||||
|
||||
// for and id
|
||||
var re_id_choice = new RegExp('"choice' + (nb_choices - 1) + '"', 'g');
|
||||
|
||||
|
||||
var new_choice_html = new_choice.replace(re_id_choice, '"choice' + nb_choices + '"')
|
||||
.replace(last_choice_label, choice_text + ' ' + (nb_choices + 1))
|
||||
.replace(/value="(.*?)"/g, 'value=""');
|
||||
|
||||
last_choice.after('<div class="form-group choice-field">' + new_choice_html + '</div>');
|
||||
|
||||
last_choice.after('<div class="form-group choice-field row">' + new_choice_html + '</div>');
|
||||
$('#choice' + nb_choices).focus();
|
||||
$('#remove-a-choice').removeClass('disabled');
|
||||
|
||||
});
|
||||
|
||||
// Button "Remove a choice"
|
||||
|
||||
$('#remove-a-choice').on('click', function () {
|
||||
$('.choice-field:last').remove();
|
||||
var nb_choices = $('.choice-field').length;
|
||||
$('#choice' + (nb_choices - 1)).focus();
|
||||
if (nb_choices == 1) {
|
||||
$('#remove-a-choice').addClass('disabled');
|
||||
}
|
||||
submitChoicesAvalaible();
|
||||
updateButtonState()
|
||||
|
||||
});
|
||||
|
||||
$(document).on('keyup, change', '.choice-field input', function () {
|
||||
submitChoicesAvalaible();
|
||||
updateButtonState();
|
||||
});
|
||||
submitChoicesAvalaible();
|
||||
|
||||
updateButtonState();
|
||||
|
||||
// Button to build markdown from: link + image-url + text
|
||||
|
||||
|
@ -92,7 +91,7 @@
|
|||
var md_img = $('#md-img');
|
||||
var md_val = $('#md-a');
|
||||
|
||||
$(document).on('click', '.md-a-img', function () {
|
||||
$('.md-a-img').on('click' , function () {
|
||||
md_a_imgModal.modal('show');
|
||||
md_a_imgModal.find('.btn-primary').attr('value', $(this).prev().attr('id'));
|
||||
$('#md-a-imgModalLabel').text($(this).attr('title'));
|
||||
|
@ -116,6 +115,6 @@
|
|||
md_img.val('');
|
||||
md_val.val('');
|
||||
md_text.val('');
|
||||
submitChoicesAvalaible();
|
||||
updateButtonState();
|
||||
});
|
||||
})();
|
||||
});
|
||||
|
|
|
@ -39,6 +39,17 @@ $(document).ready(function () {
|
|||
$("#use_customized_url").change(function () {
|
||||
if ($(this).prop("checked")) {
|
||||
$("#customized_url_options").removeClass("hidden");
|
||||
// Check url pattern
|
||||
$('#customized_url').on('input', function() {
|
||||
var regex_url = /^[a-zA-Z0-9-]*$/
|
||||
if (! regex_url.test(this.value)) {
|
||||
$(this).parent(".input-group").addClass("has-error");
|
||||
$(this).attr("aria-invalid", "true");
|
||||
} else {
|
||||
$(this).parent(".input-group").removeClass("has-error");
|
||||
$(this).attr("aria-invalid", "false");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$("#customized_url_options").addClass("hidden");
|
||||
}
|
||||
|
@ -49,9 +60,9 @@ $(document).ready(function () {
|
|||
*/
|
||||
$("#use_ValueMax").change(function () {
|
||||
if ($(this).prop("checked")) {
|
||||
$("#ValueMax").removeClass("hidden");
|
||||
$("#valueMaxWrapper").removeClass("hidden");
|
||||
} else {
|
||||
$("#ValueMax").addClass("hidden");
|
||||
$("#valueMaxWrapper").addClass("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -67,6 +78,25 @@ $(document).ready(function () {
|
|||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Hide/Show Warning collect_users_mail + editable by all
|
||||
*/
|
||||
$("input[name='collect_users_mail']").change(function(){
|
||||
if (($("input[name='collect_users_mail']:checked").val() != 0) && ($("input[name='editable']:checked").val() == 1)) {
|
||||
$("#collect_warning").removeClass("hidden");
|
||||
} else {
|
||||
$("#collect_warning").addClass("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
$("input[name='editable']").change(function(){
|
||||
if ($("input[name='collect_users_mail']:checked").val() != 0 && $("input[name='editable']:checked").val() == 1) {
|
||||
$("#collect_warning").removeClass("hidden");
|
||||
} else {
|
||||
$("#collect_warning").addClass("hidden");
|
||||
}
|
||||
});
|
||||
|
||||
// Check cookies are enabled too
|
||||
var cookieEnabled = function () {
|
||||
var cookieEnabled = navigator.cookieEnabled;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue