diff --git a/README.md b/README.md index 38f676d..a76c7db 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ # SimpleWordsCloud This site allows to create simple words cloud, without any registrations. There is nothing stored on the server except the words. + +## Database +Database config option is set in the dbconfig.php file, +example is in dbconfig_empty.php. diff --git a/common.php b/common.php new file mode 100644 index 0000000..177e45f --- /dev/null +++ b/common.php @@ -0,0 +1,16 @@ += 90 || $meta_perc >= 90 || $sndx_perc >= 90) { + return true; + } + if ($word_perc >= 80 && $meta_perc >= 80 && $sndx_perc >= 80) { + return true; + } + return false; +} diff --git a/create.php b/create.php index b047125..f24f899 100644 --- a/create.php +++ b/create.php @@ -29,9 +29,7 @@ if (empty($_POST)) { 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; + + if ($cloud = $db->createCloud($text, $size, $duration)) { + $viewUrl = 'result.php?id=' . $cloud['code']; + $viewName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $viewUrl; + $voteUrl = 'index.php?id=' . $cloud['code']; + $voteName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $voteUrl; ?>

@@ -74,5 +69,10 @@ if (empty($_POST)) { +

+ '+1 month' ); const DEFAULT_SIZE = 3; + const MAX_SIZE = 9; + const CLOUD_CODE_LENGTH = 6; private $db; + private $cloud; public function __construct() { $this->init(); } - + /** + * Initialize the database + * + * Store the PDO object in $db private class variable + */ public function init() { require_once 'dbconfig.php'; - $dsn = 'pgsql:dbname=' . $dbname - . ';host=' . $host - . ';port=' . $port; + $dsn = "$type:dbname=$dbname;host=$host;port=$port"; try { $this->db = new PDO($dsn, $username, $password); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); } catch (PDOException $e) { echo $e->getMessage(); - return null; } } - + /** + * Check if the database is initialized or not + * @return boolean True if db is inizialized + */ public function isInit() { return isset($this->db); } - + /** + * Build the database tables, only if not existing + */ public function buildTables() { $stmt = $this->db->prepare(" @@ -66,34 +76,38 @@ class DataBase "); $stmt->execute(); } - - public function addWord(string $cloud, string $word) + /** + * Add a word to a cloud + * + * If the cloud is specified, it will be loaded and the word + * will be added. + * If the cloud isn't specified, the already loaded cloud will be used. + * @param string $word Word to add + * @param string|int $cloud Id or code of the cloud + */ + public function addWord(string $word, $cloud = null) { if (empty($word)) { return false; } - $stmt = $this->db->prepare(" - SELECT * - FROM clouds - WHERE code = :id; - "); - $stmt->bindValue(':id', $cloud, PDO::PARAM_STR); - $stmt->execute(); - $cloudId = null; - if ($data = $stmt->fetch()) { - $cloudId = $data['id_cloud']; - } else { + if (isset($cloud)) { + if (!$this->loadCloud($cloud)) { + return false; + } + } + if (!$this->isCloudSet()) { return false; } + $stmt = $this->db->prepare(" SELECT * FROM words WHERE cloud_id = :cid; "); - $stmt->bindValue(':cid', $cloudId, PDO::PARAM_INT); + $stmt->bindValue(':cid', $this->cloud['id'], PDO::PARAM_INT); $stmt->execute(); while($data = $stmt->fetch()) { - if ($this->areWordsSimilar($data['word'], $word)) { + if (areWordsSimilar($data['word'], $word)) { $word = $data['word']; $wordId = $data['id_word']; break; @@ -113,7 +127,7 @@ class DataBase VALUES (:w, :cid); "); $stmt->bindValue(':w', $word, PDO::PARAM_STR); - $stmt->bindValue(':cid', $cloudId, PDO::PARAM_INT); + $stmt->bindValue(':cid', $this->cloud['id'], PDO::PARAM_INT); $stmt->execute(); } } @@ -149,63 +163,151 @@ class DataBase array_multisort($values, SORT_DESC, $words); return $words; } - - public function getWordsPercentage(string $id) - { - $words = $this->getWordsList($id); - $total = 0; - foreach ($words as $word) { - $total += $word[1]; - } - foreach ($words as $key => $word) { - $words[$key] = array($word[0], $word[1] / $total); - } - - return $words; - } - - public function getWordsRelative(string $id) - { - $words = $this->getWordsList($id); - $wordsClean = []; - foreach ($words as $key => $word) { - $wordsClean[] = array($word['word'], $word['relative']); - } - - return $wordsClean; - } - + /** + * Create a new cloud + * + * The function will try to generate a new code for the cloud, + * if it fails, the function will return false, otherwise the + * cloud local variable will save the new cloud. + * @param string $text Text associated to the cloud. + * @param int $size The number of words asked each time, + * must be between 1 and MAX_SIZE. + * @param string $duration Duration code, from OPTIONS_DURATION. + * @return False if error, the cloud if success + */ public function createCloud( - string $ref, string $text = '', - int $size = null, + int $size = null, string $duration = null) { if (!isset($size)) { $size = 3; + } elseif ($size < 1) { + $size = 1; + } elseif ($size > self::MAX_SIZE) { + $size = self::MAX_SIZE; } if (!isset($duration)) { $duration = self::DEFAULT_DURATION; - } elseif (!in_array($duration, self::OPTIONS_DURATION)) { + } elseif (!key_exists($duration, self::OPTIONS_DURATION)) { $duration = self::DEFAULT_DURATION; } - $duration = date('Y-m-d H:i:s', strtotime($duration)); + + $cpt = 0; + $codeIsUsed = true; + while ($codeIsUsed && $cpt < 0) { + $code = bin2hex(random_bytes(self::CLOUD_CODE_LENGTH)); + $stmt = $this->db->prepare(" + SELECT * + FROM clouds + WHERE code = :code; + "); + $stmt->bindValue(':code', $code); + $stmt->execute(); + if (!$data = $stmt->fetch()) { + $codeIsUsed = false; + } + $cpt++; + } + if ($codeIsUsed) { + return false; + } + $duration = date('Y-m-d H:i:s', strtotime(self::OPTIONS_DURATION[$duration])); $stmt = $this->db->prepare(" INSERT INTO clouds(code, text, size, delete_t) VALUES (:code, :text, :size, :duration); "); - $stmt->bindValue(':code', $ref); - $stmt->bindValue(':text', $text); - $stmt->bindValue(':size', $size); + $stmt->bindValue(':code', $code, PDO::PARAM_STR); + $stmt->bindValue(':text', $text, PDO::PARAM_STR); + $stmt->bindValue(':size', $size, PDO::PARAM_INT); $stmt->bindValue(':duration', $duration, PDO::PARAM_STR); try { $stmt->execute(); } catch (PDOEXception $e) { return false; } - return true; + $this->cloud = array( + 'id' => $this->db->lastInsertId(), + 'code' => $code, + 'size' => $size, + 'delete_t' => $duration, + 'text' => $text, + ); + return $this->cloud; + } + public function loadCloud($ref) + { + if (is_int($ref)) { + return $this->loadCloudById($ref); + } elseif (is_string($ref)) { + return $this->loadCloudByCode($ref); + } + } + /** + * Load the cloud by its id + * @param int $id code of the cloud + * @return boolean True if the loading is done, False otherwise + */ + public function loadCloudById(int $id) + { + $stmt = $this->db->prepare(" + SELECT * + FROM clouds + WHERE id_cloud = :id; + "); + $stmt->bindValue(':id', $id, PDO::PARAM_INT); + $stmt->execute(); + if ($data = $stmt->fetch()) { + $this->cloud = array( + 'id' => $data['id_cloud'], + 'code' => $data['code'], + 'size' => $data['size'], + 'delete_t' => $data['delete_t'], + 'text' => $data['text'], + ); + return true; + } + $this->cloud = null; + return false; + } + /** + * Load the cloud by its code + * @param string $code code of the cloud + * @return boolean True if the loading is done, False otherwise + */ + public function loadCloudByCode(string $code) + { + $stmt = $this->db->prepare(" + SELECT * + FROM clouds + WHERE code = :code; + "); + $stmt->bindValue(':code', $code, PDO::PARAM_STR); + $stmt->execute(); + if ($data = $stmt->fetch()) { + $this->cloud = array( + 'id' => $data['id_cloud'], + 'code' => $data['code'], + 'size' => $data['size'], + 'delete_t' => $data['delete_t'], + 'text' => $data['text'], + ); + return true; + } + $this->cloud = null; + return false; + } + public function isCloudSet() + { + return isset($this->cloud); + } + public function getCloudId() + { + if ($this->isCloudSet()) { + return $this->cloud['id']; + } + return null; } - public function getCloudSize(string $ref) { $stmt = $this->db->prepare(" @@ -278,18 +380,4 @@ class DataBase } return false; } - - function areWordsSimilar(string $word1, string $word2) - { - $word_sim = similar_text($word1, $word2, $word_perc); - $meta_sim = similar_text(metaphone($word1), metaphone($word2), $meta_perc); - $sndx_sim = similar_text(soundex_fr($word1), soundex_fr($word2), $sndx_perc); - if ($word_perc >= 90 || $meta_perc >= 90 || $sndx_perc >= 90) { - return true; - } - if ($word_perc >= 80 && $meta_perc >= 80 && $sndx_perc >= 80) { - return true; - } - return false; - } } diff --git a/dbconfig_empty.php b/dbconfig_empty.php index 9a4c838..d8a342e 100644 --- a/dbconfig_empty.php +++ b/dbconfig_empty.php @@ -1,5 +1,5 @@ getWordsRelative($id)) { - echo json_encode($words); +if ($words = $db->getWordsList($id)) { + $wordsClean = []; + foreach ($words as $key => $word) { + $wordsClean[] = array($word['word'], $word['relative']); + } + echo json_encode($wordsClean); } else { echo json_encode('No id'); } diff --git a/lang/lang_fr.ini b/lang/lang_fr.ini index d29e24e..fea109d 100644 --- a/lang/lang_fr.ini +++ b/lang/lang_fr.ini @@ -42,6 +42,11 @@ message = "Vous pouvez entrer ici un ou plusieurs mots, les mots vides ne seront submit = "Enregistrer" word = "Mot %d" success = "Vos mots ont bien été enregistrés, merci de votre participation." +missingId = "Le formulaire est mal formé, veuillez contacter la personne responsable du site." +cloudNotFound = "Le nuage %s n'a pas été trouvé, veuillez vérifier votre lien." + +[create] +errorCode = "Erreur lors de la création du nuage, désolé du dérangement." [duration] day = "un jour" diff --git a/save.php b/save.php index 00a8818..5a25fff 100644 --- a/save.php +++ b/save.php @@ -7,24 +7,28 @@ if (empty($_POST)) { } include 'templates/header.php'; -$id = null; -$cpt = 0; -$already_used = array(); -foreach ($_POST as $name => $value) { - $cpt; - if ($name == 'fid') { - $id = $value; - continue; - } - if (isset($id) && !in_array($value, $already_used)) { - $already_used[] = $value; - $value = trim(strtolower($value)); - $db->addWord($id, $value); - } - if ($cpt > 9) { - break; +if (!isset($_POST['fid'])) { + echo sprintf('

%s

', L::save_missingId); +} elseif (!$db->loadCloud($_POST['fid'])) { + echo sprintf('

%s

', L::save_cloudNotFound($_POST['fid'])); +} else { + $cpt = 0; + $already_used = array(); + foreach ($_POST as $name => $value) { + if ($name == 'fid') { + continue; + } + $cpt++; + if (!in_array($value, $already_used)) { + $already_used[] = $value; + $value = trim(strtolower($value)); + $db->addWord($value); + } + if ($cpt > 9) { + break; + } } + echo sprintf('

%s

', L::save_success); } -echo sprintf('

%s

', L::save_success); include 'templates/footer.php';