diff --git a/action/add_comment.php b/action/add_comment.php index df75385..81c75db 100644 --- a/action/add_comment.php +++ b/action/add_comment.php @@ -40,7 +40,7 @@ $is_admin = false; /*----------*/ $logService = new LogService(); -$pollService = new PollService($connect, $logService); +$pollService = new PollService($logService); $inputService = new InputService(); $mailService = new MailService($config['use_smtp'], $config['smtp_options']); $notificationService = new NotificationService($mailService); @@ -63,7 +63,7 @@ if (!empty($_POST['poll_admin'])) { if (!$poll) { $message = new Message('error', __('Error', 'This poll doesn\'t exist !')); -} else if ($poll && !$securityService->canAccessPoll($poll) && !$is_admin) { +} else if (!$is_admin && !$securityService->canAccessPoll($poll)) { $message = new Message('error', __('Password', 'Wrong password')); } else { $name = $inputService->filterName($_POST['name']); @@ -88,8 +88,10 @@ if (!$poll) { $smarty->error_reporting = E_ALL & ~E_NOTICE; $smarty->assign('comments', $comments); +$smarty->assign('poll_id', $poll_id); +$smarty->assign('admin_poll_id', $admin_poll_id); $comments_html = $smarty->fetch('part/comments_list.tpl'); $response = ['result' => $result, 'message' => $message, 'comments' => $comments_html]; -echo json_encode($response); +echo json_encode($response, JSON_THROW_ON_ERROR); diff --git a/action/send_edit_link_by_email_action.php b/action/send_edit_link_by_email_action.php index a2ac204..9f6cb23 100644 --- a/action/send_edit_link_by_email_action.php +++ b/action/send_edit_link_by_email_action.php @@ -29,7 +29,7 @@ include_once __DIR__ . '/../app/inc/init.php'; $logService = new LogService(); $sessionService = new SessionService(); $mailService = new MailService($config['use_smtp'], $config['smtp_options']); -$pollService = new PollService($connect, $logService); +$pollService = new PollService($logService); $result = false; $message = null; @@ -45,7 +45,7 @@ if (!empty($_POST['poll'])) { $token = $sessionService->get("Common", SESSION_EDIT_LINK_TOKEN); $token_form_value = empty($_POST['token']) ? null : $_POST['token']; $editedVoteUniqueId = filter_input(INPUT_POST, 'editedVoteUniqueId', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); -if (is_null($poll) || $config['use_smtp'] === false || is_null($token) || is_null($token_form_value) +if ($config['use_smtp'] === false || is_null($poll) || is_null($token) || is_null($token_form_value) || !$token->check($token_form_value) || is_null($editedVoteUniqueId)) { $message = new Message('error', __('Error', 'Something is going wrong...')); } @@ -91,4 +91,4 @@ $smarty->error_reporting = E_ALL & ~E_NOTICE; $response = ['result' => $result, 'message' => $message]; -echo json_encode($response); +echo json_encode($response, JSON_THROW_ON_ERROR); diff --git a/admin/check.php b/admin/check.php index 018f2e2..dca7b5f 100644 --- a/admin/check.php +++ b/admin/check.php @@ -20,7 +20,7 @@ use Framadate\Message; use Framadate\Utils; -define('ROOT_DIR', __DIR__ . '/../'); +const ROOT_DIR = __DIR__ . '/../'; /** * Checking for missing vendors. @@ -58,7 +58,7 @@ require_once ROOT_DIR . 'app/inc/i18n.php'; * @param Message $b * @return int */ -function compareCheckMessage(Message $a, Message $b) +function compareCheckMessage(Message $a, Message $b): int { $values = [ 'danger' => 0, @@ -90,7 +90,7 @@ $conf_filename = $inc_directory . 'config.php'; if (version_compare(PHP_VERSION, PHP_NEEDED_VERSION) >= 0) { $messages[] = new Message('info', __f('Check','PHP version %s is enough (needed at least PHP %s).', PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION, PHP_NEEDED_VERSION)); } else { - $messages[] = new Message('danger', __f('Check','Your PHP version (%s) is too old. This application needs at least PHP %s.', phpversion(), PHP_NEEDED_VERSION)); + $messages[] = new Message('danger', __f('Check','Your PHP version (%s) is too old. This application needs at least PHP %s.', PHP_VERSION, PHP_NEEDED_VERSION)); } // INTL extension @@ -120,7 +120,7 @@ if (!file_exists(ROOT_DIR . COMPILE_DIR)) { if (file_exists($conf_filename)) { $messages[] = new Message('info', __('Check','The config file exists.')); } elseif (is_writable($inc_directory)) { - $messages[] = new Message('info', __('Check','The config file directory (%s) is writable.', $inc_directory)); + $messages[] = new Message('info', __f('Check','The config file directory (%s) is writable.', $inc_directory)); } else { $messages[] = new Message('danger', __f('Check','The config file directory (%s) is not writable and the config file (%s) does not exists.', $inc_directory, $conf_filename)); } @@ -187,7 +187,7 @@ usort($messages, 'compareCheckMessage');
'; print_r($object); echo ''; } - public static function table($tableName) { + public static function table(string $tableName): string + { return TABLENAME_PREFIX . $tableName; } - public static function markdown($md, $clear=false, $line=true) { + public static function markdown(string $md, bool $clear=false, bool $line=true): string + { $parseDown = new Parsedown(); $parseDown @@ -155,7 +160,7 @@ class Utils { } else { $md = preg_replace_callback( '#( ){2,}#', - function ($m) { + static function ($m) { return str_repeat(' ', strlen($m[0])); }, $md @@ -168,39 +173,38 @@ class Utils { return $clear ? $text : $html; } - public static function htmlEscape($html) { + public static function htmlEscape(string $html): string { return htmlentities($html, ENT_HTML5 | ENT_QUOTES); } - public static function htmlMailEscape($html) { + public static function htmlMailEscape(string $html): string + { return htmlspecialchars($html, ENT_HTML5 | ENT_QUOTES); } - public static function csvEscape($text) { - $escaped = str_replace('"', '""', $text); - $escaped = str_replace("\r\n", '', $escaped); - $escaped = str_replace("\n", '', $escaped); + public static function csvEscape(string $text): string + { + $escaped = str_replace(['"', "\r\n", "\n"], ['""', '', ''], $text); $escaped = preg_replace("/^(=|\+|\-|\@)/", "'$1", $escaped); return '"' . $escaped . '"'; } - public static function cleanFilename($title) { + public static function cleanFilename(string $title): string { $cleaned = preg_replace('[^a-zA-Z0-9._-]', '_', $title); - $cleaned = preg_replace(' {2,}', ' ', $cleaned); - - return $cleaned; + return preg_replace(' {2,}', ' ', $cleaned); } - public static function fromPostOrDefault($postKey, $default = '') { + public static function fromPostOrDefault(string $postKey, ?string $default = '') { return !empty($_POST[$postKey]) ? $_POST[$postKey] : $default; } - public static function base64url_encode($input) { + public static function base64url_encode(string $input): string + { return rtrim(strtr(base64_encode($input), '+/', '-_'), '='); } - public static function base64url_decode($input) { + public static function base64url_decode(string $input): string { return base64_decode(str_pad(strtr($input, '-_', '+/'), strlen($input) % 4, '=', STR_PAD_RIGHT), true); } } diff --git a/app/inc/i18n.php b/app/inc/i18n.php index 14a28cb..928ac28 100644 --- a/app/inc/i18n.php +++ b/app/inc/i18n.php @@ -18,12 +18,14 @@ */ // Prepare I18N instance -$i18n = \o80\i18n\I18N::instance(); +use o80\i18n\I18N; + +$i18n = I18N::instance(); $i18n->setDefaultLang(DEFAULT_LANGUAGE); $i18n->setPath(__DIR__ . '/../../locale'); -// Change langauge when user asked for it -if (isset($_POST['lang']) && is_string($_POST['lang']) && in_array($_POST['lang'], array_keys($ALLOWED_LANGUAGES), true)) { +// Change language when user asked for it +if (isset($_POST['lang']) && is_string($_POST['lang']) && array_key_exists($_POST['lang'], $ALLOWED_LANGUAGES)) { $_SESSION['lang'] = $_POST['lang']; } @@ -38,7 +40,7 @@ $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 +if (PHP_OS_FAMILY === 'Windows') { //%e can't be used on Windows platform, use %#d instead foreach ($date_format as $k => $v) { $date_format[$k] = preg_replace('#(?getMessage(); + } } else { define('NOMAPPLICATION', 'Framadate'); define('DEFAULT_LANGUAGE', 'fr'); diff --git a/app/inc/smarty.php b/app/inc/smarty.php index db17c51..7c5f259 100644 --- a/app/inc/smarty.php +++ b/app/inc/smarty.php @@ -50,9 +50,10 @@ if (isset($_SERVER['FRAMADATE_DEVMODE']) && $_SERVER['FRAMADATE_DEVMODE']) { $smarty->compile_check = false; } -function smarty_function_poll_url($params, Smarty_Internal_Template $template) { +function smarty_function_poll_url($params, Smarty_Internal_Template $template): string +{ $poll_id = filter_var($params['id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]); - $admin = (isset($params['admin']) && $params['admin']) ? true : false; + $admin = isset($params['admin']) && $params['admin']; $action = (isset($params['action']) && !empty($params['action'])) ? Utils::htmlEscape($params['action']) : false; $action_value = (isset($params['action_value']) && !empty($params['action_value'])) ? $params['action_value'] : false; $vote_unique_id = isset($params['vote_id']) ? filter_var($params['vote_id'], FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => POLL_REGEX]]) : ''; @@ -62,30 +63,40 @@ function smarty_function_poll_url($params, Smarty_Internal_Template $template) { return Utils::getUrlSondage($poll_id, $admin, $vote_unique_id, $action, $action_value); } -function smarty_modifier_markdown($md, $clear = false, $inline=true) { +function smarty_modifier_markdown(string $md, bool $clear = false, bool $inline=true): string +{ return Utils::markdown($md, $clear, $inline); } -function smarty_modifier_resource($link) { +function smarty_modifier_resource(string $link): string +{ return Utils::get_server_name() . $link; } -function smarty_modifier_addslashes_single_quote($string) { +function smarty_modifier_addslashes_single_quote(string $string): string +{ return addcslashes($string, '\\\''); } -function smarty_modifier_addslashes($string) { +function smarty_modifier_addslashes(string $string): string +{ return addslashes($string); } -function smarty_modifier_html($html) { +function smarty_modifier_html(?string $html): string +{ + if (!$html) { + return ''; + } return Utils::htmlEscape($html); } -function smarty_modifier_html_special_chars($html) { +function smarty_modifier_html_special_chars(string $html): string +{ return Utils::htmlMailEscape($html); } -function smarty_modifier_datepicker_path($lang) { +function smarty_modifier_datepicker_path(string $lang): string +{ $i = 0; while (!is_file(path_for_datepicker_locale($lang)) && $i < 3) { $lang_arr = explode('-', $lang); @@ -94,12 +105,13 @@ function smarty_modifier_datepicker_path($lang) { } else { $lang = 'en'; } - $i += 1; + ++$i; } return 'js/locales/bootstrap-datepicker.' . $lang . '.js'; } -function smarty_modifier_locale_2_lang($locale) { +function smarty_modifier_locale_2_lang(string $locale): string +{ $lang_arr = explode('-', $locale); if ($lang_arr && count($lang_arr) > 1) { return $lang_arr[0]; @@ -107,6 +119,7 @@ function smarty_modifier_locale_2_lang($locale) { return $locale; } -function path_for_datepicker_locale($lang) { +function path_for_datepicker_locale(string $lang): string +{ return __DIR__ . '/../../js/locales/bootstrap-datepicker.' . $lang . '.js'; } diff --git a/app/tests/Framadate/FramaTestCase.php b/app/tests/Framadate/FramaTestCase.php index 6210a31..7195049 100644 --- a/app/tests/Framadate/FramaTestCase.php +++ b/app/tests/Framadate/FramaTestCase.php @@ -4,11 +4,12 @@ namespace Framadate; use PHPUnit\Framework\TestCase; abstract class FramaTestCase extends TestCase { - protected function getTestResourcePath($resourcepath) { + protected function getTestResourcePath(string $resourcepath): string + { return __DIR__ . '/../resources/' . $resourcepath; } - protected function readTestResource($resourcepath) { + protected function readTestResource(string $resourcepath) { return file_get_contents($this->getTestResourcePath($resourcepath)); } diff --git a/app/tests/Framadate/Services/InputServiceUnitTest.php b/app/tests/Framadate/Services/InputServiceUnitTest.php index 8857951..bcd9680 100644 --- a/app/tests/Framadate/Services/InputServiceUnitTest.php +++ b/app/tests/Framadate/Services/InputServiceUnitTest.php @@ -5,7 +5,8 @@ use Framadate\FramaTestCase; class InputServiceUnitTest extends FramaTestCase { - public function liste_emails() { + public function liste_emails(): array + { return [ // valids addresses "valid address" => ["example@example.com", "example@example.com"], @@ -23,7 +24,8 @@ class InputServiceUnitTest extends FramaTestCase /** * @dataProvider liste_emails */ - public function test_filterMail($email, $expected) { + public function test_filterMail($email, $expected): void + { $inputService = new InputService(); $filtered = $inputService->filterMail($email); diff --git a/app/tests/Framadate/Services/MailServiceUnitTest.php b/app/tests/Framadate/Services/MailServiceUnitTest.php index f70e687..7246d3c 100644 --- a/app/tests/Framadate/Services/MailServiceUnitTest.php +++ b/app/tests/Framadate/Services/MailServiceUnitTest.php @@ -4,9 +4,10 @@ namespace Framadate\Services; use Framadate\FramaTestCase; class MailServiceUnitTest extends FramaTestCase { - const MSG_KEY = '666'; + public const MSG_KEY = '666'; - public function test_should_send_a_2nd_mail_after_a_good_interval() { + public function test_should_send_a_2nd_mail_after_a_good_interval(): void + { // Given $mailService = new MailService(true); $_SESSION[MailService::MAILSERVICE_KEY] = [self::MSG_KEY => time() - 1000]; @@ -15,10 +16,11 @@ class MailServiceUnitTest extends FramaTestCase { $canSendMsg = $mailService->canSendMsg(self::MSG_KEY); // Then - $this->assertSame(true, $canSendMsg); + $this->assertTrue($canSendMsg); } - public function test_should_not_send_2_mails_in_a_short_interval() { + public function test_should_not_send_2_mails_in_a_short_interval(): void + { // Given $mailService = new MailService(true); $_SESSION[MailService::MAILSERVICE_KEY] = [self::MSG_KEY => time()]; @@ -27,6 +29,6 @@ class MailServiceUnitTest extends FramaTestCase { $canSendMsg = $mailService->canSendMsg(self::MSG_KEY); // Then - $this->assertSame(false, $canSendMsg); + $this->assertFalse($canSendMsg); } } diff --git a/bandeaux.php b/bandeaux.php index 869aace..e1d460a 100644 --- a/bandeaux.php +++ b/bandeaux.php @@ -54,14 +54,14 @@ function bandeau_titre($titre) } } -function liste_lang() +function liste_lang(): string { global $ALLOWED_LANGUAGES; global $locale; $str = ''; foreach ($ALLOWED_LANGUAGES as $k => $v ) { - if (substr($k,0,2)===$locale) { + if (strpos($k, $locale) === 0) { $str .= '' . "\n" ; } else { $str .= '' . "\n" ; diff --git a/buildlang.php b/buildlang.php index 9677f40..4afe6f9 100644 --- a/buildlang.php +++ b/buildlang.php @@ -10,8 +10,8 @@ include_once __DIR__ . '/app/inc/init.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); + $good = json_decode(file_get_contents(__DIR__ . '/locale/' . $goodLang . '.json'), true, 512, JSON_THROW_ON_ERROR); + $other = json_decode(file_get_contents(__DIR__ . '/locale/' . $otherLang . '.json'), true, 512, JSON_THROW_ON_ERROR); foreach ($good as $sectionName => $section) { foreach ($section as $key => $value) { @@ -19,15 +19,15 @@ include_once __DIR__ . '/app/inc/init.php'; } } - echo json_encode($good, JSON_PRETTY_PRINT | ~(JSON_ERROR_UTF8 | JSON_HEX_QUOT | JSON_HEX_APOS)); + echo json_encode($good, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT | ~(JSON_ERROR_UTF8 | JSON_HEX_QUOT | JSON_HEX_APOS)); - function getFromOther($other, $goodKey, $default, $otherLang) { + function getFromOther($other, $goodKey, $default, $otherLang): string { foreach ($other as $sectionName => $section) { foreach ($section as $key => $value) { if ( strtolower($key) === strtolower($goodKey) || + stripos($key, strtolower($goodKey)) === 0 || 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; diff --git a/compare.php b/compare.php index aaa7067..57d16a4 100644 --- a/compare.php +++ b/compare.php @@ -10,8 +10,8 @@ include_once __DIR__ . '/app/inc/init.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); + $good = json_decode(file_get_contents(__DIR__ . '/locale/' . $goodLang . '.json'), true, 512, JSON_THROW_ON_ERROR); + $test = json_decode(file_get_contents(__DIR__ . '/locale/' . $testLang . '.json'), true, 512, JSON_THROW_ON_ERROR); $diffSection = false; @@ -46,8 +46,8 @@ include_once __DIR__ . '/app/inc/init.php'; } } - if (!$diffSection and array_keys($good[$sectionName]) !== array_keys($test[$sectionName])) { - $diff[$sectionName]['order_good'] = array_keys($good[$sectionName]); + if (!$diffSection and array_keys($section) !== array_keys($test[$sectionName])) { + $diff[$sectionName]['order_good'] = array_keys($section); $diff[$sectionName]['order_test'] = array_keys($test[$sectionName]); } } diff --git a/composer.json b/composer.json index ec738ee..abe47d1 100644 --- a/composer.json +++ b/composer.json @@ -62,6 +62,7 @@ "require": { "php": ">=7.3.0", "ext-pdo": "*", + "ext-json": "*", "smarty/smarty": "^4.0", "o80/i18n": "dev-develop", "phpmailer/phpmailer": "~6.2", @@ -73,8 +74,15 @@ }, "require-dev": { "phpunit/phpunit": "^9", - "friendsofphp/php-cs-fixer": "^3.2" + "friendsofphp/php-cs-fixer": "^3.2", + "vimeo/psalm": "^4.15" }, + "repositories": [ + { + "type": "git", + "url": "https://framagit.org/framasoft/framadate/o80-i18n" + } + ], "autoload": { "psr-4": { "Framadate\\": "app/classes/Framadate/" diff --git a/composer.lock b/composer.lock index 6d65232..98aafbc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fac62d4321ada86d9ed4b66d6e160df4", + "content-hash": "4cab1ad093ed4a0fc4a2ae861ba5bc5a", "packages": [ { "name": "doctrine/lexer", @@ -256,20 +256,17 @@ "version": "dev-develop", "source": { "type": "git", - "url": "git@github.com:olivierperez/o80-i18n.git", - "reference": "ef98bd7bd733d23729999ac148f79ea1d7b9008c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/olivierperez/o80-i18n/zipball/ef98bd7bd733d23729999ac148f79ea1d7b9008c", - "reference": "ef98bd7bd733d23729999ac148f79ea1d7b9008c", - "shasum": "" + "url": "https://framagit.org/framasoft/framadate/o80-i18n", + "reference": "7b59cf9b2bc47b1084ac7e754d41ca595ff6c33d" }, "require": { - "php": ">=5.3.0" + "ext-intl": "*", + "ext-json": "*", + "php": ">=7.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.5" + "friendsofphp/php-cs-fixer": "^3.4", + "phpunit/phpunit": "^9.5.10" }, "default-branch": true, "type": "library", @@ -278,7 +275,20 @@ "o80\\": "src/o80" } }, - "notification-url": "https://packagist.org/downloads/", + "scripts": { + "cs:check": [ + "php-cs-fixer fix --dry-run --diff" + ], + "cs:fix": [ + "php-cs-fixer fix" + ], + "lint": [ + "find . -name \\*.php -not -path './vendor/*' -not -path './build/*' -not -path './tests/integration/vendor/*' -print0 | xargs -0 -n1 php -l" + ], + "test": [ + "phpunit --bootstrap tests/bootstrap.php tests" + ] + }, "license": [ "Apache License 2.0" ], @@ -296,7 +306,7 @@ "internationalization", "php" ], - "time": "2020-10-05T17:26:16+00:00" + "time": "2021-12-20T15:31:54+00:00" }, { "name": "phpmailer/phpmailer", @@ -382,12 +392,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "b9421ed9de7b2a5f54f637a064dcd31922a82405" + "reference": "fff53639bf1fa25f311c3e54932ac8c827f9a343" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/b9421ed9de7b2a5f54f637a064dcd31922a82405", - "reference": "b9421ed9de7b2a5f54f637a064dcd31922a82405", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/fff53639bf1fa25f311c3e54932ac8c827f9a343", + "reference": "fff53639bf1fa25f311c3e54932ac8c827f9a343", "shasum": "" }, "conflict": { @@ -617,7 +627,7 @@ "pusher/pusher-php-server": "<2.2.1", "pwweb/laravel-core": "<=0.3.6-beta", "rainlab/debugbar-plugin": "<3.1", - "remdex/livehelperchat": "<=2", + "remdex/livehelperchat": "<=3.90", "rmccue/requests": ">=1.6,<1.8", "robrichards/xmlseclibs": "<3.0.4", "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", @@ -806,7 +816,7 @@ "type": "tidelift" } ], - "time": "2021-12-16T20:16:03+00:00" + "time": "2021-12-17T20:13:17+00:00" }, { "name": "sabre/uri", @@ -1353,6 +1363,245 @@ } ], "packages-dev": [ + { + "name": "amphp/amp", + "version": "v2.6.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/amp.git", + "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/amp/zipball/c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", + "reference": "c5fc66a78ee38d7ac9195a37bacaf940eb3f65ae", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1", + "ext-json": "*", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^7 | ^8 | ^9", + "psalm/phar": "^3.11@dev", + "react/promise": "^2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\": "lib" + }, + "files": [ + "lib/functions.php", + "lib/Internal/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A non-blocking concurrency framework for PHP applications.", + "homepage": "http://amphp.org/amp", + "keywords": [ + "async", + "asynchronous", + "awaitable", + "concurrency", + "event", + "event-loop", + "future", + "non-blocking", + "promise" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/amp/issues", + "source": "https://github.com/amphp/amp/tree/v2.6.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2021-09-23T18:43:08+00:00" + }, + { + "name": "amphp/byte-stream", + "version": "v1.8.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/byte-stream.git", + "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd", + "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd", + "shasum": "" + }, + "require": { + "amphp/amp": "^2", + "php": ">=7.1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "dev-master", + "amphp/phpunit-util": "^1.4", + "friendsofphp/php-cs-fixer": "^2.3", + "jetbrains/phpstorm-stubs": "^2019.3", + "phpunit/phpunit": "^6 || ^7 || ^8", + "psalm/phar": "^3.11.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Amp\\ByteStream\\": "lib" + }, + "files": [ + "lib/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A stream abstraction to make working with non-blocking I/O simple.", + "homepage": "http://amphp.org/byte-stream", + "keywords": [ + "amp", + "amphp", + "async", + "io", + "non-blocking", + "stream" + ], + "support": { + "irc": "irc://irc.freenode.org/amphp", + "issues": "https://github.com/amphp/byte-stream/issues", + "source": "https://github.com/amphp/byte-stream/tree/v1.8.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2021-03-30T17:13:30+00:00" + }, + { + "name": "composer/package-versions-deprecated", + "version": "1.11.99.4", + "source": { + "type": "git", + "url": "https://github.com/composer/package-versions-deprecated.git", + "reference": "b174585d1fe49ceed21928a945138948cb394600" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", + "reference": "b174585d1fe49ceed21928a945138948cb394600", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1.0 || ^2.0", + "php": "^7 || ^8" + }, + "replace": { + "ocramius/package-versions": "1.11.99" + }, + "require-dev": { + "composer/composer": "^1.9.3 || ^2.0@dev", + "ext-zip": "^1.13", + "phpunit/phpunit": "^6.5 || ^7" + }, + "type": "composer-plugin", + "extra": { + "class": "PackageVersions\\Installer", + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "PackageVersions\\": "src/PackageVersions" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be" + } + ], + "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-09-13T08:41:34+00:00" + }, { "name": "composer/pcre", "version": "1.0.0", @@ -1571,6 +1820,43 @@ ], "time": "2021-12-08T13:07:32+00:00" }, + { + "name": "dnoegel/php-xdg-base-dir", + "version": "v0.1.1", + "source": { + "type": "git", + "url": "https://github.com/dnoegel/php-xdg-base-dir.git", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "XdgBaseDir\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "implementation of xdg base directory specification for php", + "support": { + "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues", + "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1" + }, + "time": "2019-12-04T15:06:13+00:00" + }, { "name": "doctrine/annotations", "version": "1.13.2", @@ -1712,6 +1998,107 @@ ], "time": "2020-11-10T18:47:58+00:00" }, + { + "name": "felixfbecker/advanced-json-rpc", + "version": "v3.2.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447", + "shasum": "" + }, + "require": { + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0", + "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "AdvancedJsonRpc\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "A more advanced JSONRPC implementation", + "support": { + "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues", + "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1" + }, + "time": "2021-06-11T22:34:44+00:00" + }, + { + "name": "felixfbecker/language-server-protocol", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/felixfbecker/php-language-server-protocol.git", + "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/9d846d1f5cf101deee7a61c8ba7caa0a975cd730", + "reference": "9d846d1f5cf101deee7a61c8ba7caa0a975cd730", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "^3.1", + "vimeo/psalm": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "LanguageServerProtocol\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "ISC" + ], + "authors": [ + { + "name": "Felix Becker", + "email": "felix.b@outlook.com" + } + ], + "description": "PHP classes for the Language Server Protocol", + "keywords": [ + "language", + "microsoft", + "php", + "server" + ], + "support": { + "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues", + "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/1.5.1" + }, + "time": "2021-02-22T14:02:09+00:00" + }, { "name": "friendsofphp/php-cs-fixer", "version": "v3.4.0", @@ -1859,6 +2246,57 @@ ], "time": "2020-11-13T09:40:50+00:00" }, + { + "name": "netresearch/jsonmapper", + "version": "v4.0.0", + "source": { + "type": "git", + "url": "https://github.com/cweiske/jsonmapper.git", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-pcre": "*", + "ext-reflection": "*", + "ext-spl": "*", + "php": ">=7.1" + }, + "require-dev": { + "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0", + "squizlabs/php_codesniffer": "~3.5" + }, + "type": "library", + "autoload": { + "psr-0": { + "JsonMapper": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "OSL-3.0" + ], + "authors": [ + { + "name": "Christian Weiske", + "email": "cweiske@cweiske.de", + "homepage": "http://github.com/cweiske/jsonmapper/", + "role": "Developer" + } + ], + "description": "Map nested JSON structures onto PHP classes", + "support": { + "email": "cweiske@cweiske.de", + "issues": "https://github.com/cweiske/jsonmapper/issues", + "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0" + }, + "time": "2020-12-01T19:48:11+00:00" + }, { "name": "nikic/php-parser", "version": "v4.13.2", @@ -1915,6 +2353,59 @@ }, "time": "2021-11-30T19:35:32+00:00" }, + { + "name": "openlss/lib-array2xml", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nullivex/lib-array2xml.git", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nullivex/lib-array2xml/zipball/a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "reference": "a91f18a8dfc69ffabe5f9b068bc39bb202c81d90", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "type": "library", + "autoload": { + "psr-0": { + "LSS": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bryan Tong", + "email": "bryan@nullivex.com", + "homepage": "https://www.nullivex.com" + }, + { + "name": "Tony Butler", + "email": "spudz76@gmail.com", + "homepage": "https://www.nullivex.com" + } + ], + "description": "Array2XML conversion library credit to lalit.org", + "homepage": "https://www.nullivex.com", + "keywords": [ + "array", + "array conversion", + "xml", + "xml conversion" + ], + "support": { + "issues": "https://github.com/nullivex/lib-array2xml/issues", + "source": "https://github.com/nullivex/lib-array2xml/tree/master" + }, + "time": "2019-03-29T20:06:56+00:00" + }, { "name": "phar-io/manifest", "version": "2.0.3", @@ -5237,6 +5728,112 @@ ], "time": "2021-07-28T10:34:58+00:00" }, + { + "name": "vimeo/psalm", + "version": "v4.15.0", + "source": { + "type": "git", + "url": "https://github.com/vimeo/psalm.git", + "reference": "a1b5e489e6fcebe40cb804793d964e99fc347820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/a1b5e489e6fcebe40cb804793d964e99fc347820", + "reference": "a1b5e489e6fcebe40cb804793d964e99fc347820", + "shasum": "" + }, + "require": { + "amphp/amp": "^2.4.2", + "amphp/byte-stream": "^1.5", + "composer/package-versions-deprecated": "^1.8.0", + "composer/semver": "^1.4 || ^2.0 || ^3.0", + "composer/xdebug-handler": "^1.1 || ^2.0", + "dnoegel/php-xdg-base-dir": "^0.1.1", + "ext-ctype": "*", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-simplexml": "*", + "ext-tokenizer": "*", + "felixfbecker/advanced-json-rpc": "^3.0.3", + "felixfbecker/language-server-protocol": "^1.5", + "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", + "nikic/php-parser": "^4.13", + "openlss/lib-array2xml": "^1.0", + "php": "^7.1|^8", + "sebastian/diff": "^3.0 || ^4.0", + "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0 || ^6.0", + "webmozart/path-util": "^2.3" + }, + "provide": { + "psalm/psalm": "self.version" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "brianium/paratest": "^4.0||^6.0", + "ext-curl": "*", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpdocumentor/reflection-docblock": "^5", + "phpmyadmin/sql-parser": "5.1.0||dev-master", + "phpspec/prophecy": ">=1.9.0", + "phpunit/phpunit": "^9.0", + "psalm/plugin-phpunit": "^0.16", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.5", + "symfony/process": "^4.3 || ^5.0 || ^6.0", + "weirdan/prophecy-shim": "^1.0 || ^2.0" + }, + "suggest": { + "ext-curl": "In order to send data to shepherd", + "ext-igbinary": "^2.0.5 is required, used to serialize caching data" + }, + "bin": [ + "psalm", + "psalm-language-server", + "psalm-plugin", + "psalm-refactor", + "psalter" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev", + "dev-3.x": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psalm\\": "src/Psalm/" + }, + "files": [ + "src/functions.php", + "src/spl_object_id.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthew Brown" + } + ], + "description": "A static analysis tool for finding errors in PHP applications", + "keywords": [ + "code", + "inspection", + "php" + ], + "support": { + "issues": "https://github.com/vimeo/psalm/issues", + "source": "https://github.com/vimeo/psalm/tree/v4.15.0" + }, + "time": "2021-12-07T11:25:29+00:00" + }, { "name": "webmozart/assert", "version": "1.10.0", @@ -5294,6 +5891,57 @@ "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, "time": "2021-03-09T10:59:23+00:00" + }, + { + "name": "webmozart/path-util", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/path-util.git", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "webmozart/assert": "~1.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\PathUtil\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.", + "support": { + "issues": "https://github.com/webmozart/path-util/issues", + "source": "https://github.com/webmozart/path-util/tree/2.3.0" + }, + "abandoned": "symfony/filesystem", + "time": "2015-12-17T08:42:14+00:00" } ], "aliases": [], @@ -5307,7 +5955,8 @@ "prefer-lowest": false, "platform": { "php": ">=7.3.0", - "ext-pdo": "*" + "ext-pdo": "*", + "ext-json": "*" }, "platform-dev": [], "platform-overrides": { diff --git a/create_classic_poll.php b/create_classic_poll.php index 8acb076..fe30725 100644 --- a/create_classic_poll.php +++ b/create_classic_poll.php @@ -30,9 +30,9 @@ include_once __DIR__ . '/app/inc/init.php'; /* Service */ /*---------*/ $logService = new LogService(); -$pollService = new PollService($connect, $logService); +$pollService = new PollService($logService); $mailService = new MailService($config['use_smtp'], $config['smtp_options']); -$purgeService = new PurgeService($connect, $logService); +$purgeService = new PurgeService($logService); $sessionService = new SessionService(); $inputService = new InputService(); @@ -45,7 +45,7 @@ if (is_file('bandeaux_local.php')) { $form = unserialize($_SESSION['form']); // Step 1/4 : error if $_SESSION from info_sondage are not valid -if (empty($form->title) || empty($form->admin_name) || (($config['use_smtp']) ? empty($form->admin_mail) : false)) { +if (empty($form->title) || empty($form->admin_name) || ($config['use_smtp'] && empty($form->admin_mail))) { $smarty->assign('title', __('Error', 'Error!')); $smarty->assign('error', __('Error', 'You haven\'t filled the first section of the poll creation.')); $smarty->display('error.tpl'); @@ -64,8 +64,8 @@ if (empty($form->title) || empty($form->admin_name) || (($config['use_smtp']) ? // Step 4 : Data prepare before insert in DB if (isset($_POST['confirmation'])) { // Define expiration date - $expiration_date = $inputService->validateDate($_POST['expiration_date'], $pollService->minExpiryDate(), $pollService->maxExpiryDate()); - $form->end_date = $expiration_date->getTimestamp(); + $expiration_date = $inputService->parseDate($_POST['enddate']); + $form->end_date = $inputService->validateDate($expiration_date, $pollService->minExpiryDate(), $pollService->maxExpiryDate())->getTimestamp(); // Insert poll in database $ids = $pollService->createPoll($form); @@ -123,7 +123,7 @@ if (empty($form->title) || empty($form->admin_name) || (($config['use_smtp']) ? 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) - if (isset($md_a_img[2][0]) && $md_a_img[2][0] !== '' && isset($md_a_img[3][0]) && $md_a_img[3][0] !== '') { // [![alt](src)](href) + if (isset($md_a_img[2][0], $md_a_img[3][0]) && $md_a_img[2][0] !== '' && $md_a_img[3][0] !== '') { // [![alt](src)](href) $li_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0] !== '') ? stripslashes($md_a_img[1][0]) : __('Generic', 'Choice') . ' ' . ($i + 1); $li_subject_html = ''; } elseif (isset($md_img[2][0]) && $md_img[2][0] !== '') { // ![alt](src) @@ -175,7 +175,7 @@ if (empty($form->title) || empty($form->admin_name) || (($config['use_smtp']) ? $choices = $form->getChoices(); $nb_choices = max(count($choices), 5); for ($i = 0; $i < $nb_choices; $i++) { - $choice = isset($choices[$i]) ? $choices[$i] : new Choice(); + $choice = $choices[$i] ?? new Choice(); echo '