'+1 day', 'week' => '+7 day', 'week2' => '+14 day', 'month' => '+1 month' ); const DEFAULT_SIZE = 3; private $db; public function __construct() { $this->init(); } public function init() { require_once 'dbconfig.php'; $dsn = 'pgsql: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; } } public function isInit() { return isset($this->db); } 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(); } public function addWord(string $cloud, string $word) { 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 { return false; } $stmt = $this->db->prepare(" SELECT * FROM words WHERE cloud_id = :cid; "); $stmt->bindValue(':cid', $cloudId, PDO::PARAM_INT); $stmt->execute(); while($data = $stmt->fetch()) { if ($this->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', $cloudId, 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 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; } function areWordsSimilar(string $word1, string $word2) { $sim = similar_text($word1, $word2, $perc); $sim_meta = similar_text(metaphone($word1), metaphone($word2), $perc_meta); if ($perc >= 75 && $perc_meta >= 80) { return true; } return false; } }