diff --git a/cache/lang/php_i18n_12a09906c155f7515030c2cdf5f84619_L_fr.cache.php b/cache/lang/php_i18n_12a09906c155f7515030c2cdf5f84619_L_fr.cache.php new file mode 100755 index 0000000..f232c7c --- /dev/null +++ b/cache/lang/php_i18n_12a09906c155f7515030c2cdf5f84619_L_fr.cache.php @@ -0,0 +1,40 @@ +visualiser le nuage de mots, il permet de voir le résultat.'; + const cloud_link_view_tooltip = 'Lien pour visualiser le nuage de mots'; + const cloud_link_vote_title = 'Voici le lien pour participer au nuage, c\'est le lien à partager avec les autres personnes.'; + const cloud_link_vote_tooltip = 'Lien pour participer au nuage'; + const save_message = 'Vous pouvez entrer ici un ou plusieurs mots, les mots vides ne seront pas pris en compte.'; + const save_submit = 'Enregistrer'; + const save_word = 'Mot %d'; + const save_success = 'Vos mots ont bien été enregistrés, merci de votre participation.'; + const duration_day = 'un jour'; + const duration_week = 'une semaine'; + const duration_week2 = 'deux semaines'; + const duration_month = 'un mois'; + const db_init_error = 'Error d\'initialisation de la base de données'; + const wordsList_title = 'Liste des mots du nuage'; + const wordsList_word = 'Mot'; + const wordsList_count = 'Nombre'; + const wordsList_percent = '%'; + public static function __callStatic($string, $args) { + if (defined("self::" . $string)) { + return vsprintf(constant("self::" . $string), $args); + } + } + function L($string, $args=NULL) { + $return = constant("L::".$string); + return $args ? vsprintf($return,$args) : $return; + } +} \ No newline at end of file diff --git a/cache/lang/php_i18n_d48a8e99b41edc1d5ed4bc4c7cc8cfe0_L_fr.cache.php b/cache/lang/php_i18n_d48a8e99b41edc1d5ed4bc4c7cc8cfe0_L_fr.cache.php new file mode 100755 index 0000000..7e653cb --- /dev/null +++ b/cache/lang/php_i18n_d48a8e99b41edc1d5ed4bc4c7cc8cfe0_L_fr.cache.php @@ -0,0 +1,13 @@ +
- - + +
- +
- - + + >
- +
isInit()) { - echo 'Error db init'; - return; -} - -$db->cleanCloud(); - -$length = 6; -$token = bin2hex(random_bytes($length)); -if (isset($_POST['fsize']) && is_numeric($_POST['fsize'])) { - $size = $_POST['fsize']; -} else { - $size = 3; -} -if (isset($_POST['ftext'])) { - $text = $_POST['ftext']; -} else { - $text = ''; -} -if (isset($_POST['fduration']) && in_array($_POST['fduration'], DataBase::OPTIONS_DURATION)) { - $duration = $_POST['fduration']; -} else { - $duration = DataBase::DEFAULT_DURATION; -} -$cpt = 0; -while (!$db->createCloud($token, $text, $size, $duration) && $cpt < 10) { + $length = 6; $token = bin2hex(random_bytes($length)); - $cpt++; -} -$viewUrl = 'result.php?id=' . $token; -$viewName = $_SERVER['HTTP_ORIGIN'] . '/'. $viewUrl; -$voteUrl = 'index.php?id=' . $token; -$voteName = $_SERVER['HTTP_ORIGIN'] . '/' . $voteUrl; + if (isset($_POST['fsize']) && is_numeric($_POST['fsize'])) { + $size = $_POST['fsize']; + } else { + $size = 3; + } + if (isset($_POST['ftext'])) { + $text = $_POST['ftext']; + } else { + $text = ''; + } + if (isset($_POST['fduration']) && in_array($_POST['fduration'], DataBase::OPTIONS_DURATION)) { + $duration = $_POST['fduration']; + } else { + $duration = DataBase::DEFAULT_DURATION; + } + $cpt = 0; + while (!$db->createCloud($token, $text, $size, $duration) && $cpt < 10) { + $token = bin2hex(random_bytes($length)); + $cpt++; + } + $viewUrl = 'result.php?id=' . $token; + $viewName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $viewUrl; + $voteUrl = 'index.php?id=' . $token; + $voteName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $voteUrl; ?> -

Attention, il n'y a aucun moyen de retrouver ces liens par la suite.

+

diff --git a/css/style.css b/css/style.css index 9d35d03..85fc92a 100644 --- a/css/style.css +++ b/css/style.css @@ -91,10 +91,19 @@ footer, #page-wrap:after { .cloud_words_input { margin: 1em; } +.cloud_words input:nth-of-type(2) { + margin-left: 0; +} +.cloud_words input:nth-last-of-type(2) { + margin-right: 0; +} #cloud_words_submit { display: block; margin-top: 1em; } +#cloud_create_submit { + margin-top: 1em; +} .cloud_link { margin-bottom: 1em; } @@ -102,3 +111,10 @@ footer, #page-wrap:after { #cloud_create #ftext_l{ vertical-align: top; } +#cloud_create label::after{ + content: '\00a0:'; +} + +summary:active, summary:focus { + outline: none; +} diff --git a/db.php b/db.php index a5ceb29..017be28 100644 --- a/db.php +++ b/db.php @@ -7,9 +7,10 @@ class DataBase const OPTIONS_DURATION = array( 'day' => '+1 day', 'week' => '+7 day', - '2week' => '+14 day', + 'week2' => '+14 day', 'month' => '+1 month' ); + const DEFAULT_SIZE = 3; private $db; @@ -123,12 +124,22 @@ class DataBase "); $stmt->bindValue(':id', $id); $stmt->execute(); - $words = []; + $words = []; $values = []; + $total = 0; + $max = 0; while ($data = $stmt->fetch()) { - $words[] = array($data['word'], $data['count']); + $words[] = array( + 'word' => $data['word'], + 'count' => $data['count'], + ); $values[] = $data['count']; $total += $data['count']; + $max = max($max, $data['count']); + } + foreach ($words as $key => $word) { + $words[$key]['relative'] = $word['count'] / $max; + $words[$key]['percent'] = $word['count'] / $total * 100; } array_multisort($values, SORT_DESC, $words); @@ -152,15 +163,12 @@ class DataBase public function getWordsRelative(string $id) { $words = $this->getWordsList($id); - $max = 0; - foreach ($words as $word) { - $max = max($max, $word[1]); - } + $wordsClean = []; foreach ($words as $key => $word) { - $words[$key] = array($word[0], $word[1] / $max); + $wordsClean[] = array($word['word'], $word['relative']); } - return $words; + return $wordsClean; } public function createCloud( @@ -206,7 +214,7 @@ class DataBase if ($data = $stmt->fetch()) { return $data['size']; } - return null; + return 0; } public function getCloudText(string $ref) @@ -214,7 +222,7 @@ class DataBase $stmt = $this->db->prepare(" SELECT * FROM clouds - WHERE code= :code; + WHERE code = :code; "); $stmt->bindValue(':code', $ref, PDO::PARAM_STR); $stmt->execute(); @@ -224,6 +232,23 @@ class DataBase return null; } + public function countWords(string $cloud) + { + $stmt = $this->db->prepare(" + SELECT count(*) as count + FROM clouds + JOIN words + ON id_cloud = cloud_id + WHERE code = :code; + "); + $stmt->bindValue(':code', $cloud, PDO::PARAM_STR); + $stmt->execute(); + if ($data = $stmt->fetch()) { + return $data['count']; + } + return null; + } + public function cleanCloud() { $stmt = $this->db->prepare(" diff --git a/i18n.php b/i18n.php new file mode 100644 index 0000000..5ac18af --- /dev/null +++ b/i18n.php @@ -0,0 +1,377 @@ +filePath = $filePath; + } + + if ($cachePath != NULL) { + $this->cachePath = $cachePath; + } + + if ($fallbackLang != NULL) { + $this->fallbackLang = $fallbackLang; + } + + if ($prefix != NULL) { + $this->prefix = $prefix; + } + } + + public function init() { + if ($this->isInitialized()) { + throw new BadMethodCallException( + 'This object from class ' . __CLASS__ . + ' is already initialized. ' . + 'It is not possible to init one object twice!'); + } + + $this->isInitialized = true; + + $this->userLangs = $this->getUserLangs(); + + // search for language file + $this->appliedLang = NULL; + foreach ($this->userLangs as $priority => $langcode) { + $this->langFilePath = $this->getConfigFilename($langcode); + if (file_exists($this->langFilePath)) { + $this->appliedLang = $langcode; + break; + } + } + if ($this->appliedLang == NULL) { + throw new RuntimeException('No language file was found.'); + } + + // search for cache file + $this->cacheFilePath = + $this->cachePath . '/php_i18n_' . md5_file(__FILE__) . '_' . + $this->prefix . '_' . $this->appliedLang . '.cache.php'; + + // whether we need to create a new cache file + $outdated = !file_exists($this->cacheFilePath) || + filemtime($this->cacheFilePath) < filemtime($this->langFilePath) || // the language config was updated + ($this->mergeFallback && filemtime($this->cacheFilePath) < filemtime($this->getConfigFilename($this->fallbackLang))); // the fallback language config was updated + + if ($outdated || true) { + $config = $this->load($this->langFilePath); + if ($this->mergeFallback) + $config = array_replace_recursive($this->load($this->getConfigFilename($this->fallbackLang)), $config); + + $compiled = + "prefix . " {\n" + . $this->compile($config) + . ' public static function __callStatic($string, $args) {' . "\n" + . ' if (defined("self::" . $string)) {' . "\n" + . ' return vsprintf(constant("self::" . $string), $args);' . "\n" + . " }\n" + . " }\n" + . " function ".$this->prefix .'($string, $args=NULL) {' . "\n" + . ' $return = constant("'.$this->prefix.'::".$string);' . "\n" + . ' return $args ? vsprintf($return,$args) : $return;' . "\n" + . " }\n" + . '}'; + + if( ! is_dir($this->cachePath)) { + mkdir($this->cachePath, 0755, true); + } + if (file_put_contents($this->cacheFilePath, $compiled) === FALSE) { + throw new Exception("Could not write cache file to path '" . $this->cacheFilePath . "'. Is it writable?"); + } + chmod($this->cacheFilePath, 0755); + + } + + require_once $this->cacheFilePath; + } + + public function isInitialized() { + return $this->isInitialized; + } + + public function getAppliedLang() { + return $this->appliedLang; + } + + public function getCachePath() { + return $this->cachePath; + } + + public function getFallbackLang() { + return $this->fallbackLang; + } + + public function setFilePath($filePath) { + $this->fail_after_init(); + $this->filePath = $filePath; + } + + public function setCachePath($cachePath) { + $this->fail_after_init(); + $this->cachePath = $cachePath; + } + + public function setFallbackLang($fallbackLang) { + $this->fail_after_init(); + $this->fallbackLang = $fallbackLang; + } + + public function setMergeFallback($mergeFallback) { + $this->fail_after_init(); + $this->mergeFallback = $mergeFallback; + } + + public function setPrefix($prefix) { + $this->fail_after_init(); + $this->prefix = $prefix; + } + + public function setForcedLang($forcedLang) { + $this->fail_after_init(); + $this->forcedLang = $forcedLang; + } + + public function setSectionSeparator($sectionSeparator) { + $this->fail_after_init(); + $this->sectionSeparator = $sectionSeparator; + } + + /** + * @deprecated Use setSectionSeparator. + */ + public function setSectionSeperator($sectionSeparator) { + $this->setSectionSeparator($sectionSeparator); + } + + /** + * Returns the user languages + * + * Normally it returns an array like this: + * 1. Forced language + * 2. Language in $_GET['lang'] + * 3. Language in $_SESSION['lang'] + * 4. HTTP_ACCEPT_LANGUAGE + * 5. Fallback language + * Note: duplicate values are deleted. + * + * @return array with the user languages sorted by priority. + */ + public function getUserLangs() { + $userLangs = array(); + + // Highest priority: forced language + if ($this->forcedLang != NULL) { + $userLangs[] = $this->forcedLang; + } + + // 2nd highest priority: GET parameter 'lang' + if (isset($_GET['lang']) && is_string($_GET['lang'])) { + $userLangs[] = $_GET['lang']; + } + + // 3rd highest priority: SESSION parameter 'lang' + if (isset($_SESSION['lang']) && is_string($_SESSION['lang'])) { + $userLangs[] = $_SESSION['lang']; + } + + // 4th highest priority: HTTP_ACCEPT_LANGUAGE + if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { + foreach (explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']) as $part) { + $userLangs[] = strtolower(substr($part, 0, 2)); + } + } + + // Lowest priority: fallback + $userLangs[] = $this->fallbackLang; + + // remove duplicate elements + $userLangs = array_unique($userLangs); + + // remove illegal userLangs + $userLangs2 = array(); + foreach ($userLangs as $key => $value) { + // only allow a-z, A-Z and 0-9 and _ and - + if (preg_match('/^[a-zA-Z0-9_-]*$/', $value) === 1) + $userLangs2[$key] = $value; + } + + return $userLangs2; + } + + protected function getConfigFilename($langcode) { + return str_replace('{LANGUAGE}', $langcode, $this->filePath); + } + + protected function load($filename) { + $ext = substr(strrchr($filename, '.'), 1); + switch ($ext) { + case 'properties': + case 'ini': + $config = parse_ini_file($filename, true); + break; + case 'yml': + case 'yaml': + $config = spyc_load_file($filename); + break; + case 'json': + $config = json_decode(file_get_contents($filename), true); + break; + default: + throw new InvalidArgumentException($ext . " is not a valid extension!"); + } + return $config; + } + + /** + * Recursively compile an associative array to PHP code. + */ + protected function compile($config, $prefix = '') { + $code = ''; + foreach ($config as $key => $value) { + if (is_array($value)) { + $code .= $this->compile($value, $prefix . $key . $this->sectionSeparator); + } else { + $fullName = $prefix . $key; + if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $fullName)) { + throw new InvalidArgumentException(__CLASS__ . ": Cannot compile translation key " . $fullName . " because it is not a valid PHP identifier."); + } + $code .= ' const ' . $fullName . ' = \'' . str_replace('\'', '\\\'', $value) . "';\n"; + } + } + return $code; + } + + protected function fail_after_init() { + if ($this->isInitialized()) { + throw new BadMethodCallException('This ' . __CLASS__ . ' object is already initalized, so you can not change any settings.'); + } + } +} diff --git a/index.php b/index.php index 5dccd58..144b679 100644 --- a/index.php +++ b/index.php @@ -1,18 +1,12 @@ isInit()) { - echo 'Error db init'; - return; -} $db->buildTables(); if (isset($_GET['id'])) { $id = $_GET['id']; if (!$db->isCloud($id)) { - echo 'NO CLOUD'; + echo L::cloud_noId; return; } $nbWords = $db->getCloudSize($id); @@ -23,17 +17,20 @@ if (isset($_GET['id'])) { ', $name, $name, $i+1); + echo sprintf('', + $name, $name, L::save_word($i + 1) + ); } ?> - + +

-

Voulez-vous créer un nouveau nuage de mots?

+

- +
init(); + +include('db.php'); + +$db = new DataBase(); +if (!$db->isInit()) { + echo L::db_init_error; + return; +} +$db->cleanCloud(); diff --git a/lang/lang_fr.ini b/lang/lang_fr.ini new file mode 100644 index 0000000..fb7577d --- /dev/null +++ b/lang/lang_fr.ini @@ -0,0 +1,58 @@ +; Language file for french +; +; The id for each value can be either: +; * a generic value +; * a class value +; * a sub-class value, of the following type: +; * message, when it's used to display a message to the user +; * action, when it's generated by a user action +; * access, when it's related to an access +; * title, when it's a title +; * dataCheck, when it's caused by a data check (formular) +; * tooltip, for html tooltips +; * label, for formular labels +; * value, for formular values +; +; @author Gregory Trolliet +; + +title = "SimpleWordsCloud" +create = "Créer" + +[cloud] +description = "Description du nuage" +description_message = "Entrez ici le descriptif de votre nuage" +duration = "Durée de vie du nuage" +duration_tooltip = "Durée après laquelle le nuage sera supprimé" +size = "Nombre de mots maximum par entrée" +create_message = "Voulez-vous créer un nouveau nuage de mots?" +links_warning = "Attention, il n'y a aucun moyen de retrouver ces liens par la suite." +noId = "Aucun nuage se trouve à cet endroit, désolé." +empty = "Il n'y a pas encore de mots dans ce nuage." + +[cloud_link] +view_title = "Voici le lien pour visualiser le nuage de mots, il permet de voir le résultat." +view_tooltip = "Lien pour visualiser le nuage de mots" +vote_title = "Voici le lien pour participer au nuage, c'est le lien à partager avec les autres personnes." +vote_tooltip = "Lien pour participer au nuage" + +[save] +message = "Vous pouvez entrer ici un ou plusieurs mots, les mots vides ne seront pas pris en compte." +submit = "Enregistrer" +word = "Mot %d" +success = "Vos mots ont bien été enregistrés, merci de votre participation." + +[duration] +day = "un jour" +week = "une semaine" +week2 = "deux semaines" +month = "un mois" + +[db] +init_error = "Error d'initialisation de la base de données" + +[wordsList] +title = "Liste des mots du nuage" +word = "Mot" +count = "Nombre" +percent = "%" diff --git a/result.php b/result.php index 45261db..ce251f4 100644 --- a/result.php +++ b/result.php @@ -1,15 +1,57 @@ isCloud($id)) { + echo '

' . L::cloud_noId . '

'; + $id = null; + } +} + +if (isset($id)) { + $nbWords = $db->countWords($id); + if ($nbWords == 0) { + echo sprintf('

%s

', L::cloud_empty); + } else { + $jsWordcloud = true; + } + $voteUrl = 'index.php?id=' . $id; + $voteName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $voteUrl; ?> - -
-










-










+
+ +
- - 0) { +?> +
+ + + + + + + + + +getWordsList($id) as $key => $word) { + echo ''; + echo sprintf('', $word['word']); + echo sprintf('', $word['count']); + echo sprintf('', $word['percent']); + echo ''; + } +?> + +
%s%.0f%.1f
+
+isInit()) { - echo 'Error db init'; - return; -} +include('init.php'); if (empty($_POST)) { header('Location: index.php'); die(); } +include 'templates/header.php'; $id = null; +$cpt = 0; foreach ($_POST as $name => $value) { + $cpt; if ($name == 'fid') { $id = $value; continue; @@ -22,11 +19,10 @@ foreach ($_POST as $name => $value) { $value = trim(strtolower($value)); $db->addWord($id, $value); } + if ($cpt > 9) { + break; + } } +echo sprintf('

%s

', L::save_success); -if (empty($id)) { - header('Location: index.php'); - die(); -} -header('Location: index.php'); -die(); +include 'templates/footer.php'; diff --git a/templates/header.php b/templates/header.php index 3d2a429..4ebee4b 100644 --- a/templates/header.php +++ b/templates/header.php @@ -4,7 +4,7 @@ - Change_me + <?php echo L::title ?> @@ -14,6 +14,6 @@