Compare commits

...

8 commits

8 changed files with 226 additions and 105 deletions

View file

@ -1,3 +1,7 @@
# SimpleWordsCloud # SimpleWordsCloud
This site allows to create simple words cloud, without any registrations. This site allows to create simple words cloud, without any registrations.
There is nothing stored on the server except the words. 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.

16
common.php Normal file
View file

@ -0,0 +1,16 @@
<?php
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;
}

View file

@ -29,9 +29,7 @@ if (empty($_POST)) {
</div> </div>
<?php <?php
} else { } else {
/*$token = bin2hex(random_bytes(DataBase::CLOUD_CODE_LENGTH));*/
$length = 6;
$token = bin2hex(random_bytes($length));
if (isset($_POST['fsize']) && is_numeric($_POST['fsize'])) { if (isset($_POST['fsize']) && is_numeric($_POST['fsize'])) {
$size = $_POST['fsize']; $size = $_POST['fsize'];
} else { } else {
@ -42,19 +40,16 @@ if (empty($_POST)) {
} else { } else {
$text = ''; $text = '';
} }
if (isset($_POST['fduration']) && in_array($_POST['fduration'], DataBase::OPTIONS_DURATION)) { if (isset($_POST['fduration']) && key_exists($_POST['fduration'], DataBase::OPTIONS_DURATION)) {
$duration = $_POST['fduration']; $duration = $_POST['fduration'];
} else { } else {
$duration = DataBase::DEFAULT_DURATION; $duration = DataBase::DEFAULT_DURATION;
} }
$cpt = 0;
while (!$db->createCloud($token, $text, $size, $duration) && $cpt < 10) { if ($cloud = $db->createCloud($text, $size, $duration)) {
$token = bin2hex(random_bytes($length)); $viewUrl = 'result.php?id=' . $cloud['code'];
$cpt++;
}
$viewUrl = 'result.php?id=' . $token;
$viewName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $viewUrl; $viewName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $viewUrl;
$voteUrl = 'index.php?id=' . $token; $voteUrl = 'index.php?id=' . $cloud['code'];
$voteName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $voteUrl; $voteName = 'https://' . $_SERVER['HTTP_HOST'] . '/' . $voteUrl;
?> ?>
@ -74,5 +69,10 @@ if (empty($_POST)) {
</div> </div>
</div> </div>
<?php <?php
} else {
?>
<h2><?php echo L::create_errorCode ?></h2>
<?php
}
} }
include('templates/footer.php'); include('templates/footer.php');

228
db.php
View file

@ -1,5 +1,6 @@
<?php <?php
require_once 'soundex_fr.php'; require_once 'soundex_fr.php';
require_once 'common.php';
class DataBase class DataBase
{ {
@ -11,35 +12,44 @@ class DataBase
'month' => '+1 month' 'month' => '+1 month'
); );
const DEFAULT_SIZE = 3; const DEFAULT_SIZE = 3;
const MAX_SIZE = 9;
const CLOUD_CODE_LENGTH = 6;
private $db; private $db;
private $cloud;
public function __construct() public function __construct()
{ {
$this->init(); $this->init();
} }
/**
* Initialize the database
*
* Store the PDO object in $db private class variable
*/
public function init() public function init()
{ {
require_once 'dbconfig.php'; require_once 'dbconfig.php';
$dsn = 'pgsql:dbname=' . $dbname $dsn = "$type:dbname=$dbname;host=$host;port=$port";
. ';host=' . $host
. ';port=' . $port;
try { try {
$this->db = new PDO($dsn, $username, $password); $this->db = new PDO($dsn, $username, $password);
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) { } catch (PDOException $e) {
echo $e->getMessage(); echo $e->getMessage();
return null;
} }
} }
/**
* Check if the database is initialized or not
* @return boolean True if db is inizialized
*/
public function isInit() public function isInit()
{ {
return isset($this->db); return isset($this->db);
} }
/**
* Build the database tables, only if not existing
*/
public function buildTables() public function buildTables()
{ {
$stmt = $this->db->prepare(" $stmt = $this->db->prepare("
@ -66,34 +76,38 @@ class DataBase
"); ");
$stmt->execute(); $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)) { if (empty($word)) {
return false; return false;
} }
$stmt = $this->db->prepare(" if (isset($cloud)) {
SELECT * if (!$this->loadCloud($cloud)) {
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 {
return false; return false;
} }
}
if (!$this->isCloudSet()) {
return false;
}
$stmt = $this->db->prepare(" $stmt = $this->db->prepare("
SELECT * SELECT *
FROM words FROM words
WHERE cloud_id = :cid; WHERE cloud_id = :cid;
"); ");
$stmt->bindValue(':cid', $cloudId, PDO::PARAM_INT); $stmt->bindValue(':cid', $this->cloud['id'], PDO::PARAM_INT);
$stmt->execute(); $stmt->execute();
while($data = $stmt->fetch()) { while($data = $stmt->fetch()) {
if ($this->areWordsSimilar($data['word'], $word)) { if (areWordsSimilar($data['word'], $word)) {
$word = $data['word']; $word = $data['word'];
$wordId = $data['id_word']; $wordId = $data['id_word'];
break; break;
@ -113,7 +127,7 @@ class DataBase
VALUES (:w, :cid); VALUES (:w, :cid);
"); ");
$stmt->bindValue(':w', $word, PDO::PARAM_STR); $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(); $stmt->execute();
} }
} }
@ -149,63 +163,151 @@ class DataBase
array_multisort($values, SORT_DESC, $words); array_multisort($values, SORT_DESC, $words);
return $words; return $words;
} }
/**
public function getWordsPercentage(string $id) * Create a new cloud
{ *
$words = $this->getWordsList($id); * The function will try to generate a new code for the cloud,
$total = 0; * if it fails, the function will return false, otherwise the
foreach ($words as $word) { * cloud local variable will save the new cloud.
$total += $word[1]; * @param string $text Text associated to the cloud.
} * @param int $size The number of words asked each time,
foreach ($words as $key => $word) { * must be between 1 and MAX_SIZE.
$words[$key] = array($word[0], $word[1] / $total); * @param string $duration Duration code, from OPTIONS_DURATION.
} * @return False if error, the cloud if success
*/
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;
}
public function createCloud( public function createCloud(
string $ref,
string $text = '', string $text = '',
int $size = null, int $size = null,
string $duration = null) string $duration = null)
{ {
if (!isset($size)) { if (!isset($size)) {
$size = 3; $size = 3;
} elseif ($size < 1) {
$size = 1;
} elseif ($size > self::MAX_SIZE) {
$size = self::MAX_SIZE;
} }
if (!isset($duration)) { if (!isset($duration)) {
$duration = self::DEFAULT_DURATION; $duration = self::DEFAULT_DURATION;
} elseif (!in_array($duration, self::OPTIONS_DURATION)) { } elseif (!key_exists($duration, self::OPTIONS_DURATION)) {
$duration = self::DEFAULT_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(" $stmt = $this->db->prepare("
INSERT INTO clouds(code, text, size, delete_t) INSERT INTO clouds(code, text, size, delete_t)
VALUES (:code, :text, :size, :duration); VALUES (:code, :text, :size, :duration);
"); ");
$stmt->bindValue(':code', $ref); $stmt->bindValue(':code', $code, PDO::PARAM_STR);
$stmt->bindValue(':text', $text); $stmt->bindValue(':text', $text, PDO::PARAM_STR);
$stmt->bindValue(':size', $size); $stmt->bindValue(':size', $size, PDO::PARAM_INT);
$stmt->bindValue(':duration', $duration, PDO::PARAM_STR); $stmt->bindValue(':duration', $duration, PDO::PARAM_STR);
try { try {
$stmt->execute(); $stmt->execute();
} catch (PDOEXception $e) { } catch (PDOEXception $e) {
return false; return false;
} }
$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; 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) public function getCloudSize(string $ref)
{ {
$stmt = $this->db->prepare(" $stmt = $this->db->prepare("
@ -278,18 +380,4 @@ class DataBase
} }
return false; 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;
}
} }

View file

@ -1,5 +1,5 @@
<?php <?php
$type = 'pgsql';
$host = 'localhost'; $host = 'localhost';
$dbname = ''; $dbname = '';
$username = ''; $username = '';

View file

@ -12,8 +12,12 @@ if (!isset($_GET['id'])) {
} }
$id = $_GET['id']; $id = $_GET['id'];
if ($words = $db->getWordsRelative($id)) { if ($words = $db->getWordsList($id)) {
echo json_encode($words); $wordsClean = [];
foreach ($words as $key => $word) {
$wordsClean[] = array($word['word'], $word['relative']);
}
echo json_encode($wordsClean);
} else { } else {
echo json_encode('No id'); echo json_encode('No id');
} }

View file

@ -42,6 +42,11 @@ message = "Vous pouvez entrer ici un ou plusieurs mots, les mots vides ne seront
submit = "Enregistrer" submit = "Enregistrer"
word = "Mot %d" word = "Mot %d"
success = "Vos mots ont bien été enregistrés, merci de votre participation." 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 <em>%s</em> 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] [duration]
day = "un jour" day = "un jour"

View file

@ -7,24 +7,28 @@ if (empty($_POST)) {
} }
include 'templates/header.php'; include 'templates/header.php';
$id = null; if (!isset($_POST['fid'])) {
$cpt = 0; echo sprintf('<h3>%s</h3>', L::save_missingId);
$already_used = array(); } elseif (!$db->loadCloud($_POST['fid'])) {
foreach ($_POST as $name => $value) { echo sprintf('<h3>%s</h3>', L::save_cloudNotFound($_POST['fid']));
$cpt; } else {
$cpt = 0;
$already_used = array();
foreach ($_POST as $name => $value) {
if ($name == 'fid') { if ($name == 'fid') {
$id = $value;
continue; continue;
} }
if (isset($id) && !in_array($value, $already_used)) { $cpt++;
if (!in_array($value, $already_used)) {
$already_used[] = $value; $already_used[] = $value;
$value = trim(strtolower($value)); $value = trim(strtolower($value));
$db->addWord($id, $value); $db->addWord($value);
} }
if ($cpt > 9) { if ($cpt > 9) {
break; break;
} }
}
echo sprintf('<h3>%s</h3>', L::save_success);
} }
echo sprintf('<h3>%s</h3>', L::save_success);
include 'templates/footer.php'; include 'templates/footer.php';