simpleWordsCloud/db.php

373 lines
8.1 KiB
PHP
Raw Normal View History

2020-11-15 21:51:28 +01:00
<?php
require_once 'soundex_fr.php';
require_once 'common.php';
2020-11-22 15:09:31 +01:00
2020-11-15 21:51:28 +01:00
class DataBase
{
2020-11-16 21:31:59 +01:00
const DEFAULT_DURATION = '+7 day';
const OPTIONS_DURATION = array(
'day' => '+1 day',
'week' => '+7 day',
2020-11-23 11:01:37 +01:00
'week2' => '+14 day',
2020-11-16 21:31:59 +01:00
'month' => '+1 month'
);
2020-11-23 11:01:37 +01:00
const DEFAULT_SIZE = 3;
2020-11-16 21:31:59 +01:00
2020-11-15 21:51:28 +01:00
private $db;
2020-11-25 22:13:59 +01:00
private $cloud;
2020-11-15 21:51:28 +01:00
public function __construct()
{
$this->init();
}
2020-11-25 22:13:59 +01:00
/**
* Initialize the database
*
* Store the PDO object in $db private class variable
*/
2020-11-15 21:51:28 +01:00
public function init()
{
2020-11-22 15:09:31 +01:00
require_once 'dbconfig.php';
2020-11-25 19:43:40 +01:00
$dsn = "$type:dbname=$dbname;host=$host;port=$port";
2020-11-15 21:51:28 +01:00
try {
2020-11-22 15:09:31 +01:00
$this->db = new PDO($dsn, $username, $password);
2020-11-15 21:51:28 +01:00
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
2020-11-22 15:09:31 +01:00
$this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
2020-11-15 21:51:28 +01:00
} catch (PDOException $e) {
echo $e->getMessage();
}
}
2020-11-25 22:13:59 +01:00
/**
* Check if the database is initialized or not
* @return boolean True if db is inizialized
*/
2020-11-15 21:51:28 +01:00
public function isInit()
{
return isset($this->db);
}
2020-11-25 22:13:59 +01:00
/**
* Build the database tables, only if not existing
*/
2020-11-15 21:51:28 +01:00
public function buildTables()
{
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
CREATE TABLE IF NOT EXISTS clouds(
2020-11-22 15:09:31 +01:00
id_cloud serial PRIMARY KEY,
2020-11-16 21:31:59 +01:00
code TEXT NOT NULL UNIQUE,
size INTEGER NOT NULL DEFAULT 3,
text TEXT,
delete_t TIMESTAMP DEFAULT
2020-11-22 15:09:31 +01:00
(CURRENT_TIMESTAMP + INTERVAL '" . self::DEFAULT_DURATION . "')
2020-11-16 21:31:59 +01:00
);
");
2020-11-15 21:51:28 +01:00
$stmt->execute();
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
CREATE TABLE IF NOT EXISTS words(
2020-11-22 15:09:31 +01:00
id_word serial PRIMARY KEY,
2020-11-16 21:31:59 +01:00
word TEXT NOT NULL,
count INT DEFAULT 1,
cloud_id INT NOT NULL,
FOREIGN KEY (cloud_id)
REFERENCES clouds(id_cloud) ON UPDATE CASCADE
ON DELETE CASCADE
);
");
2020-11-15 21:51:28 +01:00
$stmt->execute();
}
2020-11-25 22:13:59 +01:00
/**
* 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)
2020-11-15 21:51:28 +01:00
{
if (empty($word)) {
return false;
}
2020-11-25 22:13:59 +01:00
if (isset($cloud)) {
if (!$this->loadCloud($cloud)) {
return false;
}
}
if (!$this->isCloudSet()) {
2020-11-15 21:51:28 +01:00
return false;
}
2020-11-25 22:13:59 +01:00
$stmt = $this->db->prepare("
SELECT *
FROM words
WHERE cloud_id = :cid;
");
2020-11-25 22:13:59 +01:00
$stmt->bindValue(':cid', $this->cloud['id'], PDO::PARAM_INT);
$stmt->execute();
while($data = $stmt->fetch()) {
if (areWordsSimilar($data['word'], $word)) {
$word = $data['word'];
2020-11-23 22:32:31 +01:00
$wordId = $data['id_word'];
break;
}
}
2020-11-23 22:32:31 +01:00
if (isset($wordId)) {
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
UPDATE words
SET count = count + 1
WHERE id_word = :id;
");
2020-11-15 21:51:28 +01:00
$stmt->bindValue(':id', $wordId, PDO::PARAM_INT);
$stmt->execute();
} else {
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
INSERT INTO words(word, cloud_id)
VALUES (:w, :cid);
");
2020-11-15 21:51:28 +01:00
$stmt->bindValue(':w', $word, PDO::PARAM_STR);
2020-11-25 22:13:59 +01:00
$stmt->bindValue(':cid', $this->cloud['id'], PDO::PARAM_INT);
2020-11-15 21:51:28 +01:00
$stmt->execute();
}
}
2020-11-22 15:09:31 +01:00
public function getWordsList(string $id)
2020-11-15 21:51:28 +01:00
{
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
SELECT *
FROM words
JOIN clouds
ON words.cloud_id = clouds.id_cloud
WHERE code = :id;
");
2020-11-15 21:51:28 +01:00
$stmt->bindValue(':id', $id);
$stmt->execute();
2020-11-23 11:01:37 +01:00
$words = [];
2020-11-15 21:51:28 +01:00
$values = [];
2020-11-23 11:01:37 +01:00
$total = 0;
$max = 0;
2020-11-15 21:51:28 +01:00
while ($data = $stmt->fetch()) {
2020-11-23 11:01:37 +01:00
$words[] = array(
'word' => $data['word'],
'count' => $data['count'],
);
2020-11-15 21:51:28 +01:00
$values[] = $data['count'];
$total += $data['count'];
2020-11-23 11:01:37 +01:00
$max = max($max, $data['count']);
}
foreach ($words as $key => $word) {
$words[$key]['relative'] = $word['count'] / $max;
$words[$key]['percent'] = $word['count'] / $total * 100;
2020-11-15 21:51:28 +01:00
}
array_multisort($values, SORT_DESC, $words);
return $words;
}
public function getWordsPercentage(string $id)
{
2020-11-22 15:09:31 +01:00
$words = $this->getWordsList($id);
2020-11-15 21:51:28 +01:00
$total = 0;
foreach ($words as $word) {
$total += $word[1];
}
foreach ($words as $key => $word) {
$words[$key] = array($word[0], $word[1] / $total);
}
return $words;
}
2020-11-22 15:09:31 +01:00
public function getWordsRelative(string $id)
2020-11-15 21:51:28 +01:00
{
2020-11-22 15:09:31 +01:00
$words = $this->getWordsList($id);
2020-11-23 11:01:37 +01:00
$wordsClean = [];
2020-11-15 21:51:28 +01:00
foreach ($words as $key => $word) {
2020-11-23 11:01:37 +01:00
$wordsClean[] = array($word['word'], $word['relative']);
2020-11-15 21:51:28 +01:00
}
2020-11-23 11:01:37 +01:00
return $wordsClean;
2020-11-15 21:51:28 +01:00
}
2020-11-16 21:31:59 +01:00
public function createCloud(
string $ref,
string $text = '',
int $size = null,
string $duration = null)
2020-11-15 21:51:28 +01:00
{
2020-11-16 21:31:59 +01:00
if (!isset($size)) {
$size = 3;
}
if (!isset($duration)) {
$duration = self::DEFAULT_DURATION;
2020-11-25 22:35:28 +01:00
} elseif (!key_exists($duration, self::OPTIONS_DURATION)) {
2020-11-16 21:31:59 +01:00
$duration = self::DEFAULT_DURATION;
}
2020-11-25 22:35:28 +01:00
$duration = date('Y-m-d H:i:s', strtotime(self::OPTIONS_DURATION[$duration]));
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
INSERT INTO clouds(code, text, size, delete_t)
VALUES (:code, :text, :size, :duration);
");
2020-11-15 21:51:28 +01:00
$stmt->bindValue(':code', $ref);
2020-11-16 21:31:59 +01:00
$stmt->bindValue(':text', $text);
$stmt->bindValue(':size', $size);
$stmt->bindValue(':duration', $duration, PDO::PARAM_STR);
2020-11-15 21:51:28 +01:00
try {
$stmt->execute();
} catch (PDOEXception $e) {
return false;
}
2020-11-25 22:28:36 +01:00
$this->cloud = array(
'id' => $this->db->lastInsertId(),
'code' => $ref,
'size' => $size,
'delete_t' => $duration,
'text' => $text,
);
2020-11-15 21:51:28 +01:00
return true;
}
2020-11-25 22:13:59 +01:00
public function loadCloud($ref)
{
if (is_int($ref)) {
return $this->loadCloudById($ref);
} elseif (is_string($ref)) {
return $this->loadCloudByCode($ref);
}
}
2020-11-25 22:28:36 +01:00
/**
* Load the cloud by its id
* @param int $id code of the cloud
* @return boolean True if the loading is done, False otherwise
*/
2020-11-25 22:13:59 +01:00
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'],
2020-11-25 22:28:36 +01:00
'text' => $data['text'],
2020-11-25 22:13:59 +01:00
);
return true;
}
$this->cloud = null;
return false;
}
2020-11-25 22:28:36 +01:00
/**
* Load the cloud by its code
* @param string $code code of the cloud
* @return boolean True if the loading is done, False otherwise
*/
2020-11-25 22:13:59 +01:00
public function loadCloudByCode(string $code)
{
$stmt = $this->db->prepare("
SELECT *
FROM clouds
2020-11-25 22:28:36 +01:00
WHERE code = :code;
2020-11-25 22:13:59 +01:00
");
$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'],
2020-11-25 22:28:36 +01:00
'text' => $data['text'],
2020-11-25 22:13:59 +01:00
);
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;
}
2020-11-16 21:31:59 +01:00
public function getCloudSize(string $ref)
{
$stmt = $this->db->prepare("
SELECT *
FROM clouds
WHERE code= :code;
");
$stmt->bindValue(':code', $ref, PDO::PARAM_STR);
$stmt->execute();
if ($data = $stmt->fetch()) {
return $data['size'];
}
2020-11-23 11:01:37 +01:00
return 0;
2020-11-16 21:31:59 +01:00
}
public function getCloudText(string $ref)
{
$stmt = $this->db->prepare("
SELECT *
FROM clouds
2020-11-23 11:01:37 +01:00
WHERE code = :code;
2020-11-16 21:31:59 +01:00
");
$stmt->bindValue(':code', $ref, PDO::PARAM_STR);
$stmt->execute();
if ($data = $stmt->fetch()) {
return $data['text'];
}
return null;
}
2020-11-23 11:01:37 +01:00
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;
}
2020-11-15 21:51:28 +01:00
public function cleanCloud()
{
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
DELETE
FROM clouds
WHERE delete_t < CURRENT_TIMESTAMP;
");
2020-11-15 21:51:28 +01:00
$stmt->execute();
return true;
}
public function isCloud(string $id)
{
2020-11-16 21:31:59 +01:00
$stmt = $this->db->prepare("
SELECT *
FROM clouds
WHERE code = :id;
");
2020-11-15 21:51:28 +01:00
$stmt->bindValue(':id', $id, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->fetch()) {
return true;
}
return false;
}
}