'+1 day', 'week' => '+7 day', 'week2' => '+14 day', 'month' => '+1 month' ); const DEFAULT_SIZE = 3; 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 = "$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(); } } /** * 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(" CREATE TABLE IF NOT EXISTS clouds( id_cloud serial PRIMARY KEY, code TEXT NOT NULL UNIQUE, size INTEGER NOT NULL DEFAULT 3, text TEXT, delete_t TIMESTAMP DEFAULT (CURRENT_TIMESTAMP + INTERVAL '" . self::DEFAULT_DURATION . "') ); "); $stmt->execute(); $stmt = $this->db->prepare(" CREATE TABLE IF NOT EXISTS words( id_word serial PRIMARY KEY, 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 ); "); $stmt->execute(); } /** * 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; } 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', $this->cloud['id'], PDO::PARAM_INT); $stmt->execute(); while($data = $stmt->fetch()) { if (areWordsSimilar($data['word'], $word)) { $word = $data['word']; $wordId = $data['id_word']; break; } } if (isset($wordId)) { $stmt = $this->db->prepare(" UPDATE words SET count = count + 1 WHERE id_word = :id; "); $stmt->bindValue(':id', $wordId, PDO::PARAM_INT); $stmt->execute(); } else { $stmt = $this->db->prepare(" INSERT INTO words(word, cloud_id) VALUES (:w, :cid); "); $stmt->bindValue(':w', $word, PDO::PARAM_STR); $stmt->bindValue(':cid', $this->cloud['id'], PDO::PARAM_INT); $stmt->execute(); } } public function getWordsList(string $id) { $stmt = $this->db->prepare(" SELECT * FROM words JOIN clouds ON words.cloud_id = clouds.id_cloud WHERE code = :id; "); $stmt->bindValue(':id', $id); $stmt->execute(); $words = []; $values = []; $total = 0; $max = 0; while ($data = $stmt->fetch()) { $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); 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; } public function createCloud( string $ref, string $text = '', int $size = null, string $duration = null) { if (!isset($size)) { $size = 3; } if (!isset($duration)) { $duration = self::DEFAULT_DURATION; } elseif (!in_array($duration, self::OPTIONS_DURATION)) { $duration = self::DEFAULT_DURATION; } $duration = date('Y-m-d H:i:s', strtotime($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(':duration', $duration, PDO::PARAM_STR); try { $stmt->execute(); } catch (PDOEXception $e) { return false; } return true; } public function loadCloud($ref) { if (is_int($ref)) { return $this->loadCloudById($ref); } elseif (is_string($ref)) { return $this->loadCloudByCode($ref); } } 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['test'], ); return true; } $this->cloud = null; return false; } 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['test'], ); 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(" SELECT * FROM clouds WHERE code= :code; "); $stmt->bindValue(':code', $ref, PDO::PARAM_STR); $stmt->execute(); if ($data = $stmt->fetch()) { return $data['size']; } return 0; } public function getCloudText(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['text']; } 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(" DELETE FROM clouds WHERE delete_t < CURRENT_TIMESTAMP; "); $stmt->execute(); return true; } public function isCloud(string $id) { $stmt = $this->db->prepare(" SELECT * FROM clouds WHERE code = :id; "); $stmt->bindValue(':id', $id, PDO::PARAM_STR); $stmt->execute(); if ($stmt->fetch()) { return true; } return false; } }