get('id')).'" AND uri = "'.DB::esc($uri).'";'); if (!empty($res[0][0])) { $uri = date('Y-m-d-') . $uri; $res = DB::aQuery('SELECT 1 FROM forums WHERE journal = "'.DB::esc($journal->get('id')).'" AND uri = "'.DB::esc($uri).'";'); if (!empty($res[0][0])) { $uri = date('Y-m-d-His'); } } } else { $post = DB::aQuery('SELECT uri FROM forums WHERE journal = "'.DB::esc($journal->get('id')).'" AND id = "'.(int)$parent.'";', false, DB::FETCH_NUM); if (empty($post[0])) { throw new userException('Impossible de trouver le message auquel vous répondez.'); } $uri_parent = $post[0][0]; $uri = ''; } $ip = utils::getIP(); DB::startMultipleQueries(); DB::uQuery('INSERT INTO forums (journal, parent, titre, nom, contact, date, dernier_message, reponses, status, uri, ip) VALUES ("'.DB::esc($journal->get('id')).'", "'.(int)$parent.'", "'.DB::esc(trim($titre)).'", "'.DB::esc(trim($nom)).'", "'.DB::esc(trim($contact)).'", "'.time().'", '.(!$parent ? time() : 'NULL').', 0, '.self::ONLINE.', "'.DB::esc($uri).'", "'.DB::esc($ip).'");'); $id = DB::getInsertId(); DB::uQuery('INSERT INTO forums_textes (id, texte) VALUES ("'.(int)$id.'", "'.DB::esc(trim($texte)).'");'); if ($parent > 0) { DB::uQuery('UPDATE forums SET dernier_message = "'.time().'", reponses = reponses + 1 WHERE id = '.(int)$parent.' AND journal = "'.DB::esc($journal->get('id')).'"'); } if ($notify && $journal->get('notifications') & Journal::NOTIFICATIONS_FORUM) { notifications::notifyForum($journal, array( 'parent' => $parent, 'id' => $id, 'uri' => $uri, 'nom' => $nom, 'contact' => $contact, 'titre' => $titre, 'texte' => $texte, ) ); } DB::endMultipleQueries(); return array($id, $parent ? $uri_parent : $uri); } static protected function _deleteThread($journal, $id) { $extra = ''; if (!is_null($journal)) $extra = 'forums.journal = "'.DB::esc($journal).'" AND'; DB::uQuery('DELETE forums, forums_textes FROM forums, forums_textes WHERE '.$extra.' forums.id = forums_textes.id AND (forums.parent = '.(int)$id.' OR forums.id = '.(int)$id.');'); return true; } static protected function _deletePost($journal, $id) { DB::startMultipleQueries(); $extra = ''; if (!is_null($journal)) $extra = 'journal = "'.DB::esc($journal).'" AND'; $parent = DB::aQuery('SELECT id, reponses FROM forums WHERE '.$extra.' id = (SELECT * FROM (SELECT parent FROM forums WHERE id = '.(int)$id.') AS tmp);'); if (!empty($parent[0][0])) { $nb_reponses = $parent[0][1]; $parent = $parent[0][0]; if ($nb_reponses <= 1) { DB::uQuery('UPDATE forums SET reponses = 0, dernier_message = date WHERE id = '.(int)$parent.';'); } else { DB::uQuery('UPDATE forums SET reponses = reponses - 1, dernier_message = (SELECT * FROM (SELECT date FROM forums WHERE parent = '.(int)$parent.' AND id != '.(int)$id.' ORDER BY date DESC LIMIT 1) AS tmp) WHERE id = '.(int)$parent.';'); } } if (!is_null($journal)) $extra = 'forums.journal = "'.DB::esc($journal).'" AND'; DB::uQuery('DELETE forums, forums_textes FROM forums, forums_textes WHERE '.$extra.' forums.id = forums_textes.id AND forums.id = '.(int)$id.';'); DB::endMultipleQueries(); return true; } static public function deleteAdmin($ids) { DB::startMultipleQueries(); foreach ($ids as $id) { $parent = DB::aQuery('SELECT parent FROM forums WHERE id = '.(int)$id.';'); if (empty($parent[0][0])) self::_deleteThread(null, $id); else self::_deletePost(null, $id); } DB::endMultipleQueries(); return true; } static public function searchPosts($field, $operator, $query) { if (!in_array($field, array('id', 'ip', 'parent', 'titre', 'journal', 'nom', 'contact'))) throw new UnexpectedValue($field.' is not expected as field'); if ($operator != '=' && $operator != '!=') $operator = 'LIKE'; return DB::aQuery('SELECT * FROM forums WHERE '.$field.' '.$operator.' "'.DB::esc($query).'" ORDER BY '.$field.' LIMIT 1000;'); } /** * Checks that the current user can post (flood limit) * @return bool true if user has to wait */ static public function checkFlood() { $ip = utils::getIP(); $res = DB::aQuery('SELECT date FROM forums WHERE ip = "' . DB::esc($ip) . '" ORDER BY date DESC LIMIT 1;', false, DB::FETCH_ASSOC); if (empty($res)) return false; $last = $res[0]['date']; if(($last + self::FLOOD_LIMIT) > time()) return true; return false; } /** * Checks message against spam * @param string $content description * @param string $title description * @param string $name description * @param string $contact description * @return bool true if message is spam */ static public function checkSpam($content, $title, $name, $contact) { if (preg_match('!(?:\[/?(?:url|link)||(?:https?://.*){3,})!si', $content)) return true; if (preg_match('!damien.*lanne!i', $contact)) { mail(LENCRIER_ADMIN_EMAIL, 'Relou?!', print_r($_SERVER, true) . print_r(func_get_args(), true)); return self::IGNORE; } $ip = utils::getIP(); if ($ip == '90.34.223.132' || $ip == '110.81.154.116') { user::userSetBanned(); return self::IGNORE; } if (user::userIsBanned()) { return self::IGNORE; } return false; } /** * Get last active thread URI for $journal * @param string $journal * @return mixed URI string or false if no thread exists in this forum */ static public function getLastURI($journal) { $res = DB::aQuery('SELECT uri FROM forums WHERE journal = "'.DB::esc($journal).'" AND parent = 0 ORDER BY dernier_message DESC LIMIT 1;'); if (!empty($res[0]['uri'])) return $res[0]['uri']; return false; } /** * Instance of Forum for a specific diary * @param Journal $journal */ public function __construct(Journal $journal) { $this->journal = $journal; } /** * Lists threads per page * @param int $page Page asked for * @return array */ public function listPerPage($page = 1) { $begin = ($page - 1) * self::NB_THREADS_PER_PAGE; return DB::aQuery('SELECT * FROM forums WHERE journal="'.DB::esc($this->journal->get('id')).'" AND parent = 0 ORDER BY dernier_message DESC LIMIT '.(int)$begin.','.self::NB_THREADS_PER_PAGE.';'); } /** * Lists replies to a thread * @param int $parent Thread ID * @return array */ public function getReplies($parent) { return DB::aQuery('SELECT forums.*, forums_textes.texte AS texte FROM forums INNER JOIN forums_textes ON forums.id = forums_textes.id WHERE forums.journal = "'.DB::esc($this->journal->get('id')).'" AND forums.parent = '.(int)$parent.' ORDER BY forums.date ASC;'); } /** * Returns a specific post only * @param int $id Post ID * @return array */ public function getPost($id) { $res = DB::aQuery('SELECT forums.*, forums_textes.texte AS texte FROM forums INNER JOIN forums_textes ON forums.id = forums_textes.id WHERE forums.journal="'.DB::esc($this->journal->get('id')).'" AND forums.id = '.(int)$id.';'); if (empty($res[0])) return false; return $res[0]; } /** * Edit a post content * @param integer $id Post ID * @param string $texte Post content * @param integer $parent Post parent thread * @param string $titre Post title * @param string $nom Post author name * @param string $contact Post author contact address (email or http) * @param bool $status Post status (ONLINE or OFFLINE) * @return bool */ public function editPost($id, $texte, $parent = 0, $titre = null, $nom = null, $contact = null, $status = self::ONLINE) { DB::uQuery('UPDATE forums SET titre = "'.DB::esc(trim($titre)).'", nom = "'.DB::esc(trim($nom)).'", contact = "'.DB::esc(trim($contact)).'", status = '.(int)(bool)$status.' WHERE journal = "'.DB::esc($this->journal->get('id')).'" AND id = "'.(int)$id.'";'); DB::uQuery('UPDATE forums_textes SET texte = "'.DB::esc(trim($texte)).'" WHERE id = "'.(int)$id.'";'); return true; } public function countThreads() { $res = DB::aQuery('SELECT COUNT(*) FROM forums WHERE journal = "'.DB::esc($this->journal->get('id')).'" AND parent = 0;', false, DB::FETCH_NUM); return $res[0][0]; } public function deleteThread($id) { return self::_deleteThread($this->journal->get('id'), $id); } public function deletePost($id) { return self::_deletePost($this->journal->get('id'), $id); } public function reply($id, $texte, $nom = null, $contact = null) { return self::post($this->journal, $texte, (int)$id, null, $nom, $contact); } public function add($texte, $titre = null, $nom = null, $contact = null) { return self::post($this->journal, $texte, 0, $titre, $nom, $contact); } } ?>