├── .editorconfig
├── .gitignore
├── .gitlab-ci.yml
├── .php_cs
├── AUTHORS.md
├── CHANGELOG.md
├── INSTALL.md
├── LICENCE.fr.txt
├── LICENSE.en.txt
├── README.md
├── action
├── add_comment.php
└── send_edit_link_by_email_action.php
├── admin
├── check.php
├── index.php
├── install.php
├── logs.php
├── migration.php
├── polls.php
└── purge.php
├── adminstuds.php
├── app
├── classes
│ └── Framadate
│ │ ├── Choice.php
│ │ ├── Editable.php
│ │ ├── Exception
│ │ ├── AlreadyExistsException.php
│ │ ├── ConcurrentEditionException.php
│ │ ├── ConcurrentVoteException.php
│ │ └── MomentAlreadyExistsException.php
│ │ ├── Form.php
│ │ ├── FramaDB.php
│ │ ├── Message.php
│ │ ├── Migration
│ │ ├── AddColumn_ValueMax_In_poll_For_1_1.php
│ │ ├── AddColumn_hidden_In_poll_For_0_9.php
│ │ ├── AddColumn_receiveNewComments_For_0_9.php
│ │ ├── AddColumn_uniqId_In_vote_For_0_9.php
│ │ ├── AddColumns_password_hash_And_results_publicly_visible_In_poll_For_0_9.php
│ │ ├── Alter_Comment_table_adding_date.php
│ │ ├── Alter_Comment_table_for_name_length.php
│ │ ├── From_0_0_to_0_8_Migration.php
│ │ ├── From_0_8_to_0_9_Migration.php
│ │ ├── Generate_uniqId_for_old_votes.php
│ │ ├── Increase_pollId_size.php
│ │ ├── Migration.php
│ │ └── RPadVotes_from_0_8.php
│ │ ├── Repositories
│ │ ├── AbstractRepository.php
│ │ ├── CommentRepository.php
│ │ ├── PollRepository.php
│ │ ├── RepositoryFactory.php
│ │ ├── SlotRepository.php
│ │ └── VoteRepository.php
│ │ ├── Security
│ │ ├── PasswordHasher.php
│ │ └── Token.php
│ │ ├── Services
│ │ ├── AdminPollService.php
│ │ ├── InputService.php
│ │ ├── InstallService.php
│ │ ├── LogService.php
│ │ ├── MailService.php
│ │ ├── NotificationService.php
│ │ ├── PollService.php
│ │ ├── PurgeService.php
│ │ ├── SecurityService.php
│ │ ├── SessionService.php
│ │ └── SuperAdminService.php
│ │ └── Utils.php
├── inc
│ ├── config.template.php
│ ├── constants.php
│ ├── i18n.php
│ ├── init.php
│ └── smarty.php
└── tests
│ ├── Framadate
│ ├── FramaTestCase.php
│ └── Services
│ │ └── MailServiceUnitTest.php
│ └── bootstrap.php
├── bandeaux.php
├── buildlang.php
├── compare.php
├── composer.json
├── composer.lock
├── create_classic_poll.php
├── create_date_poll.php
├── create_poll.php
├── css
├── app
│ └── create_poll.css
├── bootstrap-theme.css
├── bootstrap-theme.css.map
├── bootstrap-theme.min.css
├── bootstrap-theme.min.css.map
├── bootstrap.css
├── bootstrap.css.map
├── bootstrap.min.css
├── bootstrap.min.css.map
├── datepicker.css
├── datepicker3.css
├── frama.css
├── jquery-ui.min.css
├── print.css
├── simplemde.min.css
└── style.css
├── doc
├── TECHNICAL.md
└── TREEVIEW.md
├── exportcsv.php
├── favicon.ico
├── find_polls.php
├── fonts
├── DejaVu Fonts License.txt
├── DejaVuSans-Bold.ttf
├── DejaVuSans-BoldOblique.ttf
├── DejaVuSans-ExtraLight.ttf
├── DejaVuSans-Oblique.ttf
├── DejaVuSans.ttf
├── glyphicons-halflings-regular.eot
├── glyphicons-halflings-regular.svg
├── glyphicons-halflings-regular.ttf
├── glyphicons-halflings-regular.woff
└── glyphicons-halflings-regular.woff2
├── htaccess.txt
├── images
├── classic.png
├── date.png
└── logo-framadate.png
├── index.php
├── js
├── Chart.StackedBar.js
├── Chart.min.js
├── app
│ ├── admin
│ │ └── polls.js
│ ├── adminstuds.js
│ ├── classic_poll.js
│ ├── create_poll.js
│ ├── date_poll.js
│ ├── framadatepicker.js
│ └── studs.js
├── bootstrap-datepicker.js
├── bootstrap.js
├── bootstrap.min.js
├── core.js
├── jquery-1.12.4.js
├── jquery-1.12.4.min.js
├── jquery-ui.min.js
├── locales
│ ├── bootstrap-datepicker.ar.js
│ ├── bootstrap-datepicker.az.js
│ ├── bootstrap-datepicker.bg.js
│ ├── bootstrap-datepicker.ca.js
│ ├── bootstrap-datepicker.cs.js
│ ├── bootstrap-datepicker.cy.js
│ ├── bootstrap-datepicker.da.js
│ ├── bootstrap-datepicker.de.js
│ ├── bootstrap-datepicker.el.js
│ ├── bootstrap-datepicker.es.js
│ ├── bootstrap-datepicker.et.js
│ ├── bootstrap-datepicker.fa.js
│ ├── bootstrap-datepicker.fi.js
│ ├── bootstrap-datepicker.fr.js
│ ├── bootstrap-datepicker.gl.js
│ ├── bootstrap-datepicker.he.js
│ ├── bootstrap-datepicker.hr.js
│ ├── bootstrap-datepicker.hu.js
│ ├── bootstrap-datepicker.id.js
│ ├── bootstrap-datepicker.is.js
│ ├── bootstrap-datepicker.it.js
│ ├── bootstrap-datepicker.ja.js
│ ├── bootstrap-datepicker.ka.js
│ ├── bootstrap-datepicker.kk.js
│ ├── bootstrap-datepicker.kr.js
│ ├── bootstrap-datepicker.lt.js
│ ├── bootstrap-datepicker.lv.js
│ ├── bootstrap-datepicker.mk.js
│ ├── bootstrap-datepicker.ms.js
│ ├── bootstrap-datepicker.nb.js
│ ├── bootstrap-datepicker.nl-BE.js
│ ├── bootstrap-datepicker.nl.js
│ ├── bootstrap-datepicker.no.js
│ ├── bootstrap-datepicker.pl.js
│ ├── bootstrap-datepicker.pt-BR.js
│ ├── bootstrap-datepicker.pt.js
│ ├── bootstrap-datepicker.ro.js
│ ├── bootstrap-datepicker.rs-latin.js
│ ├── bootstrap-datepicker.rs.js
│ ├── bootstrap-datepicker.ru.js
│ ├── bootstrap-datepicker.sk.js
│ ├── bootstrap-datepicker.sl.js
│ ├── bootstrap-datepicker.sq.js
│ ├── bootstrap-datepicker.sv.js
│ ├── bootstrap-datepicker.sw.js
│ ├── bootstrap-datepicker.th.js
│ ├── bootstrap-datepicker.tr.js
│ ├── bootstrap-datepicker.ua.js
│ ├── bootstrap-datepicker.vi.js
│ ├── bootstrap-datepicker.zh-CN.js
│ └── bootstrap-datepicker.zh-TW.js
├── mde-wrapper.js
└── simplemde.min.js
├── locale.bat
├── locale
├── br.json
├── de.json
├── en.json
├── es.json
├── fr.json
├── it.json
├── nl.json
└── oc.json
├── maintenance.php
├── php.ini
├── phpunit.bat
├── phpunit.sh
├── po2json.php
├── robots.txt
├── scripts
├── .htaccess
└── packaging.php
├── studs.php
└── tpl
├── add_column.tpl
├── admin
├── admin_page.tpl
├── config.tpl
├── index.tpl
├── install.tpl
├── logs.tpl
├── migration.tpl
├── polls.tpl
└── purge.tpl
├── confirm
├── delete_comments.tpl
├── delete_poll.tpl
└── delete_votes.tpl
├── create_classic_poll_step3.tpl
├── create_date_poll_step_2.tpl
├── create_poll.tpl
├── error.tpl
├── find_polls.tpl
├── header.tpl
├── index.tpl
├── mail
├── find_polls.tpl
└── remember_edit_link.tpl
├── maintenance.tpl
├── page.tpl
├── part
├── comments.tpl
├── comments_list.tpl
├── description_markdown.tpl
├── form_remember_edit_link.tpl
├── messages.tpl
├── password_request.tpl
├── poll_hint.tpl
├── poll_hint_admin.tpl
├── poll_info.tpl
├── scroll_left_right.tpl
├── vote_table_classic.tpl
└── vote_table_date.tpl
├── poll_deleted.tpl
└── studs.tpl
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .htaccess
2 | .htdigest
3 | .htpasswd
4 | admin/stdout.log
5 | composer.phar
6 | framanav
7 | nav
8 | app/inc/config.php
9 | vendor
10 | cache/
11 | tpl_c/
12 | .php_cs.cache
13 |
14 | # Temp files
15 | *~
16 | \#*\#
17 |
18 | # Cache
19 | Thumbs.db
20 |
21 | # IDE
22 | .settings/
23 | .project
24 | .idea/
25 | *.iml
26 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: php
2 | stages:
3 | - test
4 | - deploy
5 | - funky
6 |
7 | # install zip, git, composer on each build
8 | before_script:
9 | - apt-get update -yqq
10 | - apt-get install zip unzip git -yqq
11 | - curl --silent --show-error https://getcomposer.org/installer | php
12 |
13 | # Run php-cs-fixer and phpunit on all branches
14 | test:
15 | stage: test
16 | script:
17 | - php composer.phar install -o --no-interaction --no-progress --prefer-dist
18 | - mkdir tpl_c
19 | - php vendor/bin/php-cs-fixer fix --verbose --dry-run
20 | - vendor/bin/phpunit --bootstrap app/tests/bootstrap.php --debug app/tests
21 | cache:
22 | paths:
23 | - vendor/
24 |
25 | # Create artifacts on master
26 | pages:
27 | stage: deploy
28 | script:
29 | - latesttag=$(git describe --tags)
30 | - git checkout ${latesttag}
31 | - php composer.phar install -o --no-interaction --no-progress --prefer-dist --no-dev
32 | - php composer.phar dump-autoload --optimize --no-dev --classmap-authoritative
33 | - mkdir tpl_c
34 | - zip -r latest.zip .
35 | - mkdir .public
36 | - cp latest.zip .public
37 | - mv .public public
38 | artifacts:
39 | paths:
40 | - public
41 | only:
42 | - master
43 |
44 | # Deploy on funky
45 | funky:
46 | stage: funky
47 | script:
48 | - git checkout funky
49 | - php composer.phar install
50 | - mkdir tpl_c
51 | - mkdir .public
52 | - cp -r * .public
53 | - mv .public public
54 | - mkdir "${HOME}/.ssh"
55 | - chmod 700 "${HOME}/.ssh"
56 | - if [ ! -z ${DEPLOYEMENT_KNOWN_HOSTS+x} ]; then echo -e "${DEPLOYEMENT_KNOWN_HOSTS}" > ${HOME}/.ssh/known_hosts; fi
57 | - eval `ssh-agent -s`
58 | - if [ ! -z ${DEPLOYEMENT_KEY+x} ]; then ssh-add <(echo "${DEPLOYEMENT_KEY}" | base64 --decode -i); fi
59 | - if [ ! -z ${DEPLOYEMENT_KEY+x} ]; then rsync -a --delete --exclude admin/.stdout.log --exclude admin/.htpasswd --exclude app/inc/config.php --exclude stats/ --exclude errors/ public/ ${DEPLOYEMENT_USER}@${DEPLOYEMENT_HOST}:../../web/; fi
60 | only:
61 | - funky
62 |
--------------------------------------------------------------------------------
/.php_cs:
--------------------------------------------------------------------------------
1 | setRiskyAllowed(true)
5 | ->setRules([
6 | 'array_syntax' => [
7 | 'syntax' => 'short'
8 | ],
9 | 'combine_consecutive_unsets' => true,
10 | 'heredoc_to_nowdoc' => true,
11 | 'no_extra_consecutive_blank_lines' => [
12 | 'break',
13 | 'continue',
14 | 'extra',
15 | 'return',
16 | 'throw',
17 | 'use',
18 | 'parenthesis_brace_block',
19 | 'square_brace_block',
20 | 'curly_brace_block'
21 | ],
22 | 'no_unreachable_default_argument_value' => true,
23 | 'no_useless_else' => true,
24 | 'no_useless_return' => true,
25 | 'ordered_class_elements' => true,
26 | 'ordered_imports' => true,
27 | 'php_unit_strict' => true,
28 | 'phpdoc_order' => true,
29 | // 'psr4' => true,
30 | 'strict_comparison' => true,
31 | 'strict_param' => true,
32 | 'concat_space' => [
33 | 'spacing' => 'one'
34 | ],
35 | ])
36 | ->setFinder(
37 | PhpCsFixer\Finder::create()
38 | ->exclude([
39 | 'vendor',
40 | 'var',
41 | 'web'
42 | ])
43 | ->in(__DIR__)
44 | )
45 | ;
46 |
--------------------------------------------------------------------------------
/AUTHORS.md:
--------------------------------------------------------------------------------
1 | # [OpenSondage](https://opensondage.leblanc.io)
2 | * Simon Leblanc (development)
3 |
4 | # [Framasoft](http://framadate.org)
5 | * Pierre-Yves Gosset (development, graphism)
6 | * Pascal Chevrel (development)
7 | * Armony Altinier (accessibility)
8 | * JosephK (development)
9 | * Framasoft community
10 | *For a list of people who have contributed to the codebase, see [GitHub's list of contributors](https://github.com/framasoft/OpenSondage/graphs/contributors).*
11 |
12 | ## [STUdS](http://studs.u-strasbg.fr)
13 | * Guilhem Borghesi (borghesi@unistra.fr)
14 | * Raphaël Droz
15 | * Contributors from the University of Strasbourg: Guy, Christophe, Julien, Pierre, Romaric, Matthieu, Catherine, Christine, Olivier, Emmanuel and Florence
16 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | Un fichier est dédié à l'installation de OpenSondage : [INSTALL.md](INSTALL.md).
4 |
5 | # Comment contribuer
6 |
7 | ## Comprendre le code
8 |
9 | Un fichier est dédié à l'appréhension du code de OpenSondage : [Document technique](doc/TECHNICAL.md).
10 |
11 | # Traductions
12 |
13 | Les traductions se trouvent dans le dossier `locale`. Chaque langue est dans un fichier JSON différent organisé par section.
14 |
15 | # Synthèses des librairies utilisées
16 |
17 | [Smarty](http://www.smarty.net/),
18 | gestion des templates pour PHP
19 |
20 | [o80-i18n](https://github.com/olivierperez/o80-i18n),
21 | système d'internationalisation
22 |
23 | [PHP 5.4.4](http://php.net)
24 |
25 | PostgreSQL ou [MySQL 5.5](https://dev.mysql.com/downloads/mysql/5.5.html)
26 |
27 | ---
28 |
29 | OpenSondage est un fork du projet [STUdS](https://sourcesup.cru.fr/projects/studs/)
30 |
31 | Les auteurs principaux de OpenSondage sont :
32 | * Simon LEBLANC
33 | * Pierre-Yves GOSSET
34 |
35 | Les auteurs principaux du projet STUdS sont :
36 | * Guilhem BORGHESI
37 | * Raphaël DROZ
38 |
39 | ---
40 |
41 | Université de Strasbourg - Direction Informatique
42 | Auteur : Guilhem BORGHESI
43 | Création : Février 2008
44 |
45 | borghesi@unistra.fr
46 |
47 | Ce logiciel est régi par la licence CeCILL-B soumise au droit français et
48 | respectant les principes de diffusion des logiciels libres. Vous pouvez
49 | utiliser, modifier et/ou redistribuer ce programme sous les conditions
50 | de la licence CeCILL-B telle que diffusée par le CEA, le CNRS et l'INRIA
51 | sur le site "http://www.cecill.info".
52 |
53 | Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
54 | pris connaissance de la licence CeCILL-B, et que vous en avez accepté les
55 | termes. Vous pouvez trouver une copie de la licence dans le fichier LICENCE.
56 |
57 | ---
58 |
59 | Université de Strasbourg - Direction Informatique
60 | Author : Guilhem BORGHESI
61 | Creation : Feb 2008
62 |
63 | borghesi@unistra.fr
64 |
65 | This software is governed by the CeCILL-B license under French law and
66 | abiding by the rules of distribution of free software. You can use,
67 | modify and/ or redistribute the software under the terms of the CeCILL-B
68 | license as circulated by CEA, CNRS and INRIA at the following URL
69 | "http://www.cecill.info".
70 |
71 | The fact that you are presently reading this means that you have had
72 | knowledge of the CeCILL-B license and that you accept its terms. You can
73 | find a copy of this license in the file LICENSE.
74 |
75 | ---
76 |
77 | Janvier 2008
78 | Guilhem BORGHESI
79 | Université de Strasbourg
80 |
81 | Mai 2010
82 | Raphaël DROZ, raphael.droz@gmail.com
83 |
84 |
--------------------------------------------------------------------------------
/action/add_comment.php:
--------------------------------------------------------------------------------
1 | ['regexp' => POLL_REGEX]]);
54 | $poll = $pollService->findById($poll_id);
55 | }
56 |
57 | if (!empty($_POST['poll_admin'])) {
58 | $admin_poll_id = filter_input(INPUT_POST, 'poll_admin', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
59 | if (strlen($admin_poll_id) === 24) {
60 | $is_admin = ($pollService->findByAdminId($admin_poll_id) !== null);
61 | }
62 | }
63 |
64 | if (!$poll) {
65 | $message = new Message('error', __('Error', 'This poll doesn\'t exist !'));
66 | } else if ($poll && !$securityService->canAccessPoll($poll) && !$is_admin) {
67 | $message = new Message('error', __('Password', 'Wrong password'));
68 | } else {
69 | $name = $inputService->filterName($_POST['name']);
70 | $comment = $inputService->filterComment($_POST['comment']);
71 |
72 | if ($name === null) {
73 | $message = new Message('danger', __('Error', 'The name is invalid.'));
74 | }
75 |
76 | if ($message === null) {
77 | // Add comment
78 | $result = $pollService->addComment($poll_id, $name, $comment);
79 | if ($result) {
80 | $message = new Message('success', __('Comments', 'Comment added'));
81 | $notificationService->sendUpdateNotification($poll, NotificationService::ADD_COMMENT, $name);
82 | } else {
83 | $message = new Message('danger', __('Error', 'Comment failed'));
84 | }
85 | }
86 | $comments = $pollService->allCommentsByPollId($poll_id);
87 | }
88 |
89 | $smarty->error_reporting = E_ALL & ~E_NOTICE;
90 | $smarty->assign('comments', $comments);
91 | $comments_html = $smarty->fetch('part/comments_list.tpl');
92 |
93 | $response = ['result' => $result, 'message' => $message, 'comments' => $comments_html];
94 |
95 | echo json_encode($response);
96 |
--------------------------------------------------------------------------------
/action/send_edit_link_by_email_action.php:
--------------------------------------------------------------------------------
1 | ['regexp' => POLL_REGEX]]);
42 | $poll = $pollService->findById($poll_id);
43 | }
44 |
45 | $token = $sessionService->get("Common", SESSION_EDIT_LINK_TOKEN);
46 | $token_form_value = empty($_POST['token']) ? null : $_POST['token'];
47 | $editedVoteUniqueId = filter_input(INPUT_POST, 'editedVoteUniqueId', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
48 | if (is_null($poll) || $config['use_smtp'] === false || is_null($token) || is_null($token_form_value)
49 | || !$token->check($token_form_value) || is_null($editedVoteUniqueId)) {
50 | $message = new Message('error', __('Error', 'Something is going wrong...'));
51 | }
52 |
53 | if (is_null($message)) {
54 | $email = $mailService->isValidEmail($_POST['email']);
55 | if (is_null($email)) {
56 | $message = new Message('error', __('EditLink', 'The email address is not correct.'));
57 | }
58 | }
59 |
60 | if (is_null($message)) {
61 | $time = $sessionService->get("Common", SESSION_EDIT_LINK_TIME);
62 |
63 | if (!empty($time)) {
64 | $remainingTime = TIME_EDIT_LINK_EMAIL - (time() - $time);
65 |
66 | if ($remainingTime > 0) {
67 | $message = new Message('error', __f('EditLink', 'Please wait %d seconds before we can send an email to you then try again.', $remainingTime));
68 | }
69 | }
70 | }
71 |
72 | if (is_null($message)) {
73 | $url = Utils::getUrlSondage($poll_id, false, $editedVoteUniqueId);
74 |
75 | $smarty->assign('poll', $poll);
76 | $smarty->assign('poll_id', $poll_id);
77 | $smarty->assign('editedVoteUniqueId', $editedVoteUniqueId);
78 | $body = $smarty->fetch('mail/remember_edit_link.tpl');
79 |
80 | $subject = '[' . NOMAPPLICATION . '][' . __('EditLink', 'REMINDER') . '] ' . __f('EditLink', 'Edit link for poll "%s"', $poll->title);
81 |
82 | //$mailService->send($email, $subject, $body);
83 | $sessionService->remove("Common", SESSION_EDIT_LINK_TOKEN);
84 | $sessionService->set("Common", SESSION_EDIT_LINK_TIME, time());
85 |
86 | $message = new Message('success', __('EditLink', 'Your reminder has been successfully sent!'));
87 | $result = true;
88 | }
89 |
90 | $smarty->error_reporting = E_ALL & ~E_NOTICE;
91 |
92 | $response = ['result' => $result, 'message' => $message];
93 |
94 | echo json_encode($response);
--------------------------------------------------------------------------------
/admin/index.php:
--------------------------------------------------------------------------------
1 | assign('title', __('Admin', 'Administration'));
23 | $smarty->assign('logsAreReadable', is_readable('../' . LOG_FILE));
24 | $smarty->display('admin/index.tpl');
--------------------------------------------------------------------------------
/admin/install.php:
--------------------------------------------------------------------------------
1 | updateFields($_POST);
35 | $result = $installService->install($smarty);
36 |
37 | if ($result['status'] === 'OK') {
38 | header(('Location: ' . Utils::get_server_name() . 'admin/migration.php'));
39 | exit;
40 | }
41 | $error = __('Error', $result['code']);
42 | }
43 |
44 | $smarty->assign('error', $error);
45 | $smarty->assign('title', __('Admin', 'Installation'));
46 | $smarty->assign('fields', $installService->getFields());
47 | $smarty->display('admin/install.tpl');
--------------------------------------------------------------------------------
/admin/logs.php:
--------------------------------------------------------------------------------
1 | assign('logs', $content);
27 | $smarty->assign('title', __('Admin', 'Logs'));
28 |
29 | $smarty->display('admin/logs.tpl');
--------------------------------------------------------------------------------
/admin/polls.php:
--------------------------------------------------------------------------------
1 | $value) {
36 | $query .= $key . '=' . urlencode($value) . '&';
37 | }
38 | return substr($query, 0, -1);
39 | }
40 |
41 | /* --------- */
42 |
43 | /* Variables */
44 | /* --------- */
45 |
46 | $polls = null;
47 | $poll_to_delete = null;
48 |
49 | /* Services */
50 | /*----------*/
51 |
52 | $logService = new LogService();
53 | $pollService = new PollService($connect, $logService);
54 | $adminPollService = new AdminPollService($connect, $pollService, $logService);
55 | $superAdminService = new SuperAdminService();
56 | $securityService = new SecurityService();
57 |
58 | /* GET */
59 | /*-----*/
60 | $page = (int)filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT);
61 | $page = ($page >= 1) ? $page : 1;
62 |
63 | // Search
64 | $search['poll'] = filter_input(INPUT_GET, 'poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
65 | $search['title'] = filter_input(INPUT_GET, 'title', FILTER_SANITIZE_STRING);
66 | $search['name'] = filter_input(INPUT_GET, 'name', FILTER_SANITIZE_STRING);
67 | $search['mail'] = filter_input(INPUT_GET, 'mail', FILTER_SANITIZE_STRING);
68 |
69 | /* PAGE */
70 | /* ---- */
71 |
72 | if (!empty($_POST['delete_poll']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
73 | $delete_id = filter_input(INPUT_POST, 'delete_poll', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
74 | $poll_to_delete = $pollService->findById($delete_id);
75 | }
76 |
77 | // Traitement de la confirmation de suppression
78 | if (!empty($_POST['delete_confirm']) && $securityService->checkCsrf('admin', $_POST['csrf'])) {
79 | $poll_id = filter_input(INPUT_POST, 'delete_confirm', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]);
80 | $adminPollService->deleteEntirePoll($poll_id);
81 | }
82 |
83 | $found = $superAdminService->findAllPolls($search, $page - 1, POLLS_PER_PAGE);
84 | $polls = $found['polls'];
85 | $count = $found['count'];
86 | $total = $found['total'];
87 |
88 | // Assign data to template
89 | $smarty->assign('polls', $polls);
90 | $smarty->assign('count', $count);
91 | $smarty->assign('total', $total);
92 | $smarty->assign('page', $page);
93 | $smarty->assign('pages', ceil($count / POLLS_PER_PAGE));
94 | $smarty->assign('poll_to_delete', $poll_to_delete);
95 | $smarty->assign('crsf', $securityService->getToken('admin'));
96 | $smarty->assign('search', $search);
97 | $smarty->assign('search_query', buildSearchQuery($search));
98 |
99 | $smarty->assign('title', __('Admin', 'Polls'));
100 |
101 | $smarty->display('admin/polls.tpl');
102 |
--------------------------------------------------------------------------------
/admin/purge.php:
--------------------------------------------------------------------------------
1 | filterName(isset($_POST['action']) ? $_POST['action'] : null);
45 |
46 | /* PAGE */
47 | /* ---- */
48 |
49 | if ($action === 'purge' && $securityService->checkCsrf('admin', $_POST['csrf'])) {
50 | $count = $purgeService->purgeOldPolls();
51 | $message = __('Admin', 'Purged:') . ' ' . $count;
52 | }
53 |
54 | // Assign data to template
55 | $smarty->assign('message', $message);
56 | $smarty->assign('crsf', $securityService->getToken('admin'));
57 |
58 | $smarty->assign('title', __('Admin', 'Purge'));
59 |
60 | $smarty->display('admin/purge.tpl');
--------------------------------------------------------------------------------
/app/classes/Framadate/Choice.php:
--------------------------------------------------------------------------------
1 | name = $name;
36 | $this->slots = [];
37 | }
38 |
39 | public function addSlot($slot)
40 | {
41 | $this->slots[] = $slot;
42 | }
43 |
44 | public function getName()
45 | {
46 | return $this->name;
47 | }
48 |
49 | public function getSlots()
50 | {
51 | return $this->slots;
52 | }
53 |
54 | static function compare(Choice $a, Choice $b)
55 | {
56 | return strcmp($a->name, $b->name);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Editable.php:
--------------------------------------------------------------------------------
1 | editable = Editable::EDITABLE_BY_ALL;
92 | $this->clearChoices();
93 | }
94 |
95 | public function clearChoices() {
96 | $this->choices = [];
97 | }
98 |
99 | public function addChoice(Choice $choice)
100 | {
101 | $this->choices[] = $choice;
102 | }
103 |
104 | public function getChoices()
105 | {
106 | return $this->choices;
107 | }
108 |
109 | public function sortChoices()
110 | {
111 | usort($this->choices, ['Framadate\Choice', 'compare']);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/app/classes/Framadate/FramaDB.php:
--------------------------------------------------------------------------------
1 | pdo = new \PDO($connection_string, $user, $password);
31 | $this->pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
32 | $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
33 | }
34 |
35 | /**
36 | * @return \PDO Connection to database
37 | */
38 | function getPDO() {
39 | return $this->pdo;
40 | }
41 |
42 | /**
43 | * Find all tables in database.
44 | *
45 | * @return array The array of table names
46 | */
47 | function allTables() {
48 | $result = $this->pdo->query('SHOW TABLES');
49 | $schemas = $result->fetchAll(\PDO::FETCH_COLUMN);
50 |
51 | return $schemas;
52 | }
53 |
54 | function prepare($sql) {
55 | return $this->pdo->prepare($sql);
56 | }
57 |
58 | function beginTransaction() {
59 | $this->pdo->beginTransaction();
60 | }
61 |
62 | function commit() {
63 | $this->pdo->commit();
64 | }
65 |
66 | function rollback() {
67 | $this->pdo->rollback();
68 | }
69 |
70 | function errorCode() {
71 | return $this->pdo->errorCode();
72 | }
73 |
74 | function errorInfo() {
75 | return $this->pdo->errorInfo();
76 | }
77 |
78 | function query($sql) {
79 | return $this->pdo->query($sql);
80 | }
81 |
82 | public function lastInsertId() {
83 | return $this->pdo->lastInsertId();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Message.php:
--------------------------------------------------------------------------------
1 | type = $type;
31 | $this->message = $message;
32 | $this->link = $link;
33 | $this->linkTitle = $linkTitle;
34 | $this->linkIcon = $linkIcon;
35 | $this->includeTemplate = $includeTemplate;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/AddColumn_ValueMax_In_poll_For_1_1.php:
--------------------------------------------------------------------------------
1 | alterPollTable($pdo);
61 |
62 | return true;
63 | }
64 |
65 | private function alterPollTable(\PDO $pdo) {
66 | $pdo->exec('
67 | ALTER TABLE `' . Utils::table('poll') . '`
68 | ADD `ValueMax` TINYINT,
69 | ADD CHECK (ValueMax > 0)');
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/AddColumn_hidden_In_poll_For_0_9.php:
--------------------------------------------------------------------------------
1 | query('SHOW TABLES');
51 | $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
52 |
53 | // Check if tables of v0.9 are presents
54 | $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
55 | return count($diff) === 0;
56 | }
57 |
58 | /**
59 | * This method is called only one time in the migration page.
60 | *
61 | * @param \PDO $pdo The connection to database
62 | * @return bool true is the execution succeeded
63 | */
64 | function execute(\PDO $pdo) {
65 | $this->alterPollTable($pdo);
66 |
67 | return true;
68 | }
69 |
70 | private function alterPollTable(\PDO $pdo) {
71 | $pdo->exec('
72 | ALTER TABLE `' . Utils::table('poll') . '`
73 | ADD `hidden` TINYINT( 1 ) NOT NULL DEFAULT "0"');
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/AddColumn_receiveNewComments_For_0_9.php:
--------------------------------------------------------------------------------
1 | query('SHOW TABLES');
51 | $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
52 |
53 | // Check if tables of v0.9 are presents
54 | $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
55 | return count($diff) === 0;
56 | }
57 |
58 | /**
59 | * This method is called only one time in the migration page.
60 | *
61 | * @param \PDO $pdo The connection to database
62 | * @return bool true is the execution succeeded
63 | */
64 | function execute(\PDO $pdo) {
65 | $this->alterPollTable($pdo);
66 |
67 | return true;
68 | }
69 |
70 | private function alterPollTable(\PDO $pdo) {
71 | $pdo->exec('
72 | ALTER TABLE `' . Utils::table('poll') . '`
73 | ADD `receiveNewComments` TINYINT(1) DEFAULT \'0\'
74 | AFTER `receiveNewVotes`');
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/AddColumn_uniqId_In_vote_For_0_9.php:
--------------------------------------------------------------------------------
1 | query('SHOW TABLES');
51 | $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
52 |
53 | // Check if tables of v0.9 are presents
54 | $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
55 | return count($diff) === 0;
56 | }
57 |
58 | /**
59 | * This method is called only one time in the migration page.
60 | *
61 | * @param \PDO $pdo The connection to database
62 | * @return bool true is the execution succeeded
63 | */
64 | function execute(\PDO $pdo) {
65 | $this->alterPollTable($pdo);
66 |
67 | return true;
68 | }
69 |
70 | private function alterPollTable(\PDO $pdo) {
71 | $pdo->exec('
72 | ALTER TABLE `' . Utils::table('vote') . '`
73 | ADD `uniqId` CHAR(16) NOT NULL
74 | AFTER `id`,
75 | ADD INDEX (`uniqId`) ;');
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/AddColumns_password_hash_And_results_publicly_visible_In_poll_For_0_9.php:
--------------------------------------------------------------------------------
1 | query('SHOW TABLES');
51 | $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
52 |
53 | // Check if tables of v0.9 are presents
54 | $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
55 | return count($diff) === 0;
56 | }
57 |
58 | /**
59 | * This method is called only one time in the migration page.
60 | *
61 | * @param \PDO $pdo The connection to database
62 | * @return bool true is the execution succeeded
63 | */
64 | function execute(\PDO $pdo) {
65 | $this->alterPollTable($pdo);
66 |
67 | return true;
68 | }
69 |
70 | private function alterPollTable(\PDO $pdo) {
71 | $pdo->exec('
72 | ALTER TABLE `' . Utils::table('poll') . '`
73 | ADD `password_hash` VARCHAR(255) NULL DEFAULT NULL ,
74 | ADD `results_publicly_visible` TINYINT(1) NULL DEFAULT NULL');
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/Alter_Comment_table_adding_date.php:
--------------------------------------------------------------------------------
1 | alterCommentTable($pdo);
61 |
62 | return true;
63 | }
64 |
65 | private function alterCommentTable(\PDO $pdo) {
66 | $pdo->exec('
67 | ALTER TABLE `' . Utils::table('comment') . '`
68 | ADD `date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ;');
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/Alter_Comment_table_for_name_length.php:
--------------------------------------------------------------------------------
1 | alterCommentTable($pdo);
61 |
62 | return true;
63 | }
64 |
65 | private function alterCommentTable(\PDO $pdo) {
66 | $pdo->exec('
67 | ALTER TABLE `' . Utils::table('comment') . '`
68 | CHANGE `name` `name` VARCHAR( 64 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ;');
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/Generate_uniqId_for_old_votes.php:
--------------------------------------------------------------------------------
1 | query('SHOW TABLES');
40 | $tables = $stmt->fetchAll(\PDO::FETCH_COLUMN);
41 |
42 | // Check if tables of v0.9 are presents
43 | $diff = array_diff([Utils::table('poll'), Utils::table('slot'), Utils::table('vote'), Utils::table('comment')], $tables);
44 | return count($diff) === 0;
45 | }
46 |
47 | /**
48 | * This methode is called only one time in the migration page.
49 | *
50 | * @param \PDO $pdo The connection to database
51 | * @return bool true is the execution succeeded
52 | */
53 | function execute(\PDO $pdo) {
54 | $pdo->beginTransaction();
55 | $this->generateUniqIdsForEmptyOnes($pdo);
56 | $pdo->commit();
57 |
58 | return true;
59 | }
60 |
61 | private function generateUniqIdsForEmptyOnes($pdo) {
62 | $select = $pdo->query('
63 | SELECT `id`
64 | FROM `' . Utils::table('vote') . '`
65 | WHERE `uniqid` = \'\'');
66 |
67 | $update = $pdo->prepare('
68 | UPDATE `' . Utils::table('vote') . '`
69 | SET `uniqid` = :uniqid
70 | WHERE `id` = :id');
71 |
72 | while ($row = $select->fetch(\PDO::FETCH_OBJ)) {
73 | $token = Token::getToken(16);
74 | $update->execute([
75 | 'uniqid' => $token,
76 | 'id' => $row->id
77 | ]);
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/Increase_pollId_size.php:
--------------------------------------------------------------------------------
1 | alterCommentTable($pdo);
38 | $this->alterPollTable($pdo);
39 | $this->alterSlotTable($pdo);
40 | $this->alterVoteTable($pdo);
41 | }
42 |
43 | private function alterCommentTable(\PDO $pdo) {
44 | $pdo->exec('
45 | ALTER TABLE `' . Utils::table('comment') . '`
46 | CHANGE `poll_id` `poll_id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
47 | }
48 |
49 | private function alterPollTable(\PDO $pdo) {
50 | $pdo->exec('
51 | ALTER TABLE `' . Utils::table('poll') . '`
52 | CHANGE `id` `id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
53 | }
54 |
55 | private function alterSlotTable(\PDO $pdo) {
56 | $pdo->exec('
57 | ALTER TABLE `' . Utils::table('slot') . '`
58 | CHANGE `poll_id` `poll_id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
59 | }
60 |
61 | private function alterVoteTable(\PDO $pdo) {
62 | $pdo->exec('
63 | ALTER TABLE `' . Utils::table('vote') . '`
64 | CHANGE `poll_id` `poll_id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;');
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Migration/Migration.php:
--------------------------------------------------------------------------------
1 | connect = $connect;
18 | }
19 |
20 | public function beginTransaction() {
21 | $this->connect->beginTransaction();
22 | }
23 |
24 | public function commit() {
25 | $this->connect->commit();
26 | }
27 |
28 | function rollback() {
29 | $this->connect->rollback();
30 | }
31 |
32 | public function prepare($sql) {
33 | return $this->connect->prepare($sql);
34 | }
35 |
36 | function query($sql) {
37 | return $this->connect->query($sql);
38 | }
39 |
40 | function lastInsertId() {
41 | return $this->connect->lastInsertId();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Repositories/CommentRepository.php:
--------------------------------------------------------------------------------
1 | prepare('SELECT * FROM `' . Utils::table('comment') . '` WHERE poll_id = ? ORDER BY id');
14 | $prepared->execute([$poll_id]);
15 |
16 | return $prepared->fetchAll();
17 | }
18 |
19 | /**
20 | * Insert a new comment.
21 | *
22 | * @param $poll_id
23 | * @param $name
24 | * @param $comment
25 | * @return bool
26 | */
27 | function insert($poll_id, $name, $comment) {
28 | $prepared = $this->prepare('INSERT INTO `' . Utils::table('comment') . '` (poll_id, name, comment) VALUES (?,?,?)');
29 |
30 | return $prepared->execute([$poll_id, $name, $comment]);
31 | }
32 |
33 | function deleteById($poll_id, $comment_id) {
34 | $prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND id = ?');
35 |
36 | return $prepared->execute([$poll_id, $comment_id]);
37 | }
38 |
39 | /**
40 | * Delete all comments of a given poll.
41 | *
42 | * @param $poll_id int The ID of the given poll.
43 | * @return bool|null true if action succeeded.
44 | */
45 | function deleteByPollId($poll_id) {
46 | $prepared = $this->prepare('DELETE FROM `' . Utils::table('comment') . '` WHERE poll_id = ?');
47 |
48 | return $prepared->execute([$poll_id]);
49 | }
50 |
51 | public function exists($poll_id, $name, $comment) {
52 | $prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('comment') . '` WHERE poll_id = ? AND name = ? AND comment = ?');
53 | $prepared->execute([$poll_id, $name, $comment]);
54 |
55 | return $prepared->rowCount() > 0;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Repositories/RepositoryFactory.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leblanc-simon/OpenSondage/d9263f0a58c3174bb9921306455b55dbdc9e05b2/app/classes/Framadate/Repositories/RepositoryFactory.php
--------------------------------------------------------------------------------
/app/classes/Framadate/Repositories/SlotRepository.php:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leblanc-simon/OpenSondage/d9263f0a58c3174bb9921306455b55dbdc9e05b2/app/classes/Framadate/Repositories/SlotRepository.php
--------------------------------------------------------------------------------
/app/classes/Framadate/Repositories/VoteRepository.php:
--------------------------------------------------------------------------------
1 | prepare('SELECT * FROM `' . Utils::table('vote') . '` WHERE poll_id = ? ORDER BY id');
14 | $prepared->execute([$poll_id]);
15 |
16 | return $prepared->fetchAll();
17 | }
18 |
19 | function insertDefault($poll_id, $insert_position) {
20 | $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTRING(choices, 1, ?), " ", SUBSTRING(choices, ?)) WHERE poll_id = ?'); //#51 : default value for unselected vote
21 |
22 | return $prepared->execute([$insert_position, $insert_position + 1, $poll_id]);
23 | }
24 |
25 | function insert($poll_id, $name, $choices, $token) {
26 | $prepared = $this->prepare('INSERT INTO `' . Utils::table('vote') . '` (poll_id, name, choices, uniqId) VALUES (?,?,?,?)');
27 | $prepared->execute([$poll_id, $name, $choices, $token]);
28 |
29 | $newVote = new \stdClass();
30 | $newVote->poll_id = $poll_id;
31 | $newVote->id = $this->lastInsertId();
32 | $newVote->name = $name;
33 | $newVote->choices = $choices;
34 | $newVote->uniqId = $token;
35 |
36 | return $newVote;
37 | }
38 |
39 | function deleteById($poll_id, $vote_id) {
40 | $prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND id = ?');
41 |
42 | return $prepared->execute([$poll_id, $vote_id]);
43 | }
44 |
45 | /**
46 | * Delete all votes of a given poll.
47 | *
48 | * @param $poll_id int The ID of the given poll.
49 | * @return bool|null true if action succeeded.
50 | */
51 | function deleteByPollId($poll_id) {
52 | $prepared = $this->prepare('DELETE FROM `' . Utils::table('vote') . '` WHERE poll_id = ?');
53 |
54 | return $prepared->execute([$poll_id]);
55 | }
56 |
57 | /**
58 | * Delete all votes made on given moment index.
59 | *
60 | * @param $poll_id int The ID of the poll
61 | * @param $index int The index of the vote into the poll
62 | * @return bool|null true if action succeeded.
63 | */
64 | function deleteByIndex($poll_id, $index) {
65 | $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = CONCAT(SUBSTR(choices, 1, ?), SUBSTR(choices, ?)) WHERE poll_id = ?');
66 |
67 | return $prepared->execute([$index, $index + 2, $poll_id]);
68 | }
69 |
70 | function update($poll_id, $vote_id, $name, $choices) {
71 | $prepared = $this->prepare('UPDATE `' . Utils::table('vote') . '` SET choices = ?, name = ? WHERE poll_id = ? AND id = ?');
72 |
73 | return $prepared->execute([$choices, $name, $poll_id, $vote_id]);
74 | }
75 |
76 | /**
77 | * Check if name is already used for the given poll.
78 | *
79 | * @param int $poll_id ID of the poll
80 | * @param string $name Name of the vote
81 | * @return bool true if vote already exists
82 | */
83 | public function existsByPollIdAndName($poll_id, $name) {
84 | $prepared = $this->prepare('SELECT 1 FROM `' . Utils::table('vote') . '` WHERE poll_id = ? AND name = ?');
85 | $prepared->execute([$poll_id, $name]);
86 | return $prepared->rowCount() > 0;
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Security/PasswordHasher.php:
--------------------------------------------------------------------------------
1 | length = $length;
13 | $this->time = time() + TOKEN_TIME;
14 | $this->value = $this->generate();
15 | }
16 |
17 | public function getTime() {
18 | return $this->time;
19 | }
20 |
21 | public function getValue() {
22 | return $this->value;
23 | }
24 |
25 | public function isGone() {
26 | return $this->time < time();
27 | }
28 |
29 | public function check($value) {
30 | return $value === $this->value;
31 | }
32 |
33 | /**
34 | * Get a secure token if possible, or a less secure one if not.
35 | *
36 | * @param int $length The token length
37 | * @param bool $crypto_strong If passed, tells if the token is "cryptographically strong" or not.
38 | * @return string
39 | */
40 | public static function getToken($length = self::DEFAULT_LENGTH, &$crypto_strong = false) {
41 | if (function_exists('openssl_random_pseudo_bytes')) {
42 | openssl_random_pseudo_bytes(1, $crypto_strong); // Fake use to see if the algorithm used was "cryptographically strong"
43 | return self::getSecureToken($length);
44 | }
45 | return self::getUnsecureToken($length);
46 | }
47 |
48 | public static function getUnsecureToken($length) {
49 | $string = '';
50 | mt_srand();
51 | for ($i = 0; $i < $length; $i++) {
52 | $string .= self::$codeAlphabet[mt_rand() % strlen(self::$codeAlphabet)];
53 | }
54 |
55 | return $string;
56 | }
57 |
58 | /**
59 | * @author http://stackoverflow.com/a/13733588
60 | */
61 | public static function getSecureToken($length){
62 | $token = "";
63 | for($i=0;$i<$length;$i++){
64 | $token .= self::$codeAlphabet[self::crypto_rand_secure(0,strlen(self::$codeAlphabet))];
65 | }
66 | return $token;
67 | }
68 |
69 | private function generate() {
70 | return self::getToken($this->length);
71 | }
72 |
73 | /**
74 | * @author http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
75 | */
76 | private static function crypto_rand_secure($min, $max) {
77 | $range = $max - $min;
78 | if ($range < 0) return $min; // not so random...
79 | $log = log($range, 2);
80 | $bytes = (int) ($log / 8) + 1; // length in bytes
81 | $bits = (int) $log + 1; // length in bits
82 | $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
83 | do {
84 | $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
85 | $rnd = $rnd & $filter; // discard irrelevant bits
86 | } while ($rnd >= $range);
87 | return $min + $rnd;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/app/classes/Framadate/Services/LogService.php:
--------------------------------------------------------------------------------
1 | logService = new LogService();
22 | $this->smtp_allowed = $smtp_allowed;
23 | if (true === is_array($smtp_options)) {
24 | $this->smtp_options = $smtp_options;
25 | }
26 | }
27 |
28 | public function isValidEmail($email) {
29 | return filter_var($email, FILTER_VALIDATE_EMAIL);
30 | }
31 |
32 | function send($to, $subject, $body, $msgKey = null) {
33 | if ($this->smtp_allowed === true && $this->canSendMsg($msgKey)) {
34 | $mail = new PHPMailer(true);
35 | $this->configureMailer($mail);
36 |
37 | // From
38 | $mail->FromName = NOMAPPLICATION;
39 | $mail->From = ADRESSEMAILADMIN;
40 | if ($this->isValidEmail(ADRESSEMAILREPONSEAUTO)) {
41 | $mail->addReplyTo(ADRESSEMAILREPONSEAUTO);
42 | }
43 |
44 | // To
45 | $mail->addAddress($to);
46 |
47 | // Subject
48 | $mail->Subject = $subject;
49 |
50 | // Bodies
51 | $body = $body . '
' . __('Mail', 'Thanks for your trust.') . '
' . NOMAPPLICATION . '