# # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . class DB { var $socket; var $connected = false; var $queries = 0; /* MAIN FUNCTIONS */ function __construct($dbHost, $dbPort, $dbUser, $dbPassword) { $this->connected = false; if (!$dbPort) $dbPort = 3306; $this->socket = @mysql_connect($dbHost.':'.$dbPort, $dbUser, $dbPassword); if ($this->socket === false) { $this->connected = false; } else { $this->connected = true; $this->send("SET NAMES 'utf8'"); } return $this->socket; } function select($dbName) { return @mysql_select_db($dbName); } function isConnected() { return $this->connected; } function send($query) { if (DEBUG) $sql = mysql_query($query) or write_debug(mysql_error(), 'mysql'); else $sql = mysql_query($query); $this->queries = $this->queries + 1; return $sql; } /* Taken from "Partystic libraries" */ function clean($query, $vars) { $query_length = strlen($query); if (count($vars) > 0) { $result = ''; for ($i = 0, $varsParsed = 0; $i < $query_length; ++$i) { if ($query[$i] == "\\" and $query[$i + 1] == '%') { $result .= '%'; ++$i; } else if ($query[$i] != '%') { $result .= $query[$i]; } else { if ($query[$i + 1] == 'i') { $result .= (int)$vars[$varsParsed]; } else if ($query[$i + 1] == 's') { if ($query[$i - 1] == '`') { $toInclude = str_replace('`', '``', $vars[$varsParsed]); } else { $toInclude = str_replace("\\", "\\\\", $vars[$varsParsed]); $toInclude = str_replace($query[$i - 1], "\\" . $query[$i - 1], $toInclude); } $result .= $toInclude; } ++$varsParsed; ++$i; } } return $result; } return $query; } /* COMMON SELECT QUERIES */ function getNotes($where, $start = 0, $end, $userID = false, $username = false, $ignored = false) { if (is_array($ignored) && count($ignored) > 0) { $ignored = implode(',', $ignored); if(!empty($ignored)) { $s_post2id = ' AND `post2id`.`from` NOT IN('.$ignored.') AND `post2id`.`reply_user` NOT IN('.$ignored.')'; $s_notes = ' AND `notes`.`user_id` NOT IN('.$ignored.') AND `notes`.`reply_user` NOT IN('.$ignored.')'; } else { $s_post2id = ''; $s_notes = ''; } } switch ($where) { case 'tag': $query = "SELECT `tags_n`.`timestamp` AS `orderby`, `tags_n`.`note_id` AS id FROM `tags_n` WHERE `tags_n`.`tag` = '$userID'"; break; case 'public': $query = "SELECT `notes`.`timestamp` AS `orderby`, `notes`.`ID` AS id, `notes`.`type` FROM `notes` WHERE `notes`.`type` = 'public'".$s_notes; break; case 'archive': $query = "SELECT `notes`.`timestamp` AS `orderby`, `notes`.`ID` AS id, `notes`.`type` FROM `notes` WHERE `type` IN('public', 'personal') AND user_id = ".(int)$userID.$s_notes; break; case 'private': case 'private_sent': $query = "SELECT `notes`.`timestamp` AS `orderby`, `notes`.`ID` AS id, `notes`.`type` FROM `notes` WHERE `notes`.`type` = 'private' AND "; if ($where == 'private') $query .= "`notes`.`to` = '".mysql_escape_string($username)."'"; elseif ($where == 'private_sent') $query .= "`notes`.`user_id` = ".(int)$userID; break; case 'replies': $query = $this->clean("SELECT `notes`.`timestamp` AS `orderby`, `notes`.`ID` AS id, `notes`.`type` FROM `notes` WHERE `notes`.`type` IN('public','personal') AND `notes`.`to` = '%s'".$s_notes, array($username)); break; case 'friends': case 'friendsof': $query = "SELECT `post2id`.`timestamp` AS `orderby`, `post2id`.`note_id` AS id, `post2id`.`type` FROM `post2id` WHERE `post2id`.`type` "; if ($where == 'friends') $query .= "IN('public', 'personal')"; elseif ($where == 'friendsof') $query .= '= \'public\''; $query .= " AND `post2id`.`to`= ".(int)$userID . $s_post2id; break; case 'favorites': $query = "SELECT `favorites`.`note_id` AS id, `favorites`.`id` AS `orderby`, 'public' AS `type` FROM `favorites` WHERE `favorites`.`user_id` = ".(int)$userID; break; case 'all': case 'twitter': case 'twitter_replies': $query = "SELECT `timestamp` AS `orderby`, `note_id` AS id, `type` AS type FROM `post2id` WHERE `post2id`.`to` = ".(int)$userID . " AND type "; if ($where == 'all') $query .= "IN('public', 'twitter','twitter_reply','personal')".$s_post2id; elseif ($where == 'twitter') $query .= "IN('twitter','twitter_reply')"; elseif ($where == 'twitter_replies') $query .= "= 'twitter_reply'"; break; } $notesArray = array(); $query = $query." ORDER BY `orderby` DESC LIMIT ".(int)$start.", ".(int)$end; $result = $this->send($query); while ($note = @mysql_fetch_array($result)) array_push($notesArray, $note); return $notesArray; } function getNoteInfo($noteID) { $query = "SELECT * FROM `notes` WHERE `notes`.`ID` = ".(int)$noteID; $result = $this->send($query); if(!mysql_num_rows($result)) return false; $row = mysql_fetch_array($result); return $row; } function getNoteCombined($noteID) { $query = "SELECT `notes`.*, `users`.`username`, `users`.`realname`, `users`.`avatar`, `users`.`bio`, `users`.`location` FROM `notes`, `users` WHERE `users`.`ID` = `notes`.`user_id` AND `notes`.`ID` = ".(int)$noteID; $result = $this->send($query); if(!mysql_num_rows($result)) return false; $row = mysql_fetch_array($result); return $row; } function getTwit($twitID) { $query = "SELECT * FROM `twitter` WHERE `ID` = " . (int) $twitID; $result = mysql_query($query); if(!mysql_num_rows($result)) return false; return mysql_fetch_assoc($result); } function getUserInfo($userID = false, $username = false, $email = false) { if ($username) $query = $this->clean("SELECT `users`.* FROM users WHERE `users`.`username` = '%s' LIMIT 1", array($username)); elseif ($userID) $query = "SELECT `users`.* FROM `users` WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; elseif ($email) $query = $this->clean("SELECT `users`.* FROM users WHERE `users`.`email` = '%s' LIMIT 1", array($email)); $result = $this->send($query); if (!mysql_num_rows($result)) return false; else { $return = mysql_fetch_assoc($result); if (empty($return['ignored'])) $return['ignored'] = 'a:0:{}'; $return['ignored'] = unserialize($return['ignored']); if (!is_array($return['ignored'])) $return['ignored'] = unserialize('a:0:{}'); return $return; } } function getUser($info, $start, $end, $email = false) { if ($email == true) $query = "SELECT * FROM `users` WHERE (`email` = '".mysql_escape_string($info)."') LIMIT ".(int)$start.", ".(int)$end; else $query = "SELECT * FROM `users` WHERE (`username` = '".mysql_escape_string($info)."') OR (`username` LIKE '%".mysql_escape_string($info)."%') OR (`realname` LIKE '%".mysql_escape_string($info)."%') LIMIT ".(int)$start.", ".(int)$end; $result = $this->send($query); $rowArray = array(); if (mysql_num_rows($result)) { while ($row = mysql_fetch_array($result)) array_push($rowArray, $row); } return $rowArray; } function getIdByUser($username) { // correct name would be getIdFromUsername $query = $this->clean("SELECT `users`.`ID` FROM users WHERE `users`.`username` = '%s'", array($username)); $result = $this->send($query); if (!mysql_num_rows($result)) return false; return mysql_result($result, 0); } /*function getIdByGroup($group_name) { // correct name would be getIdFromGroup $query = $this->clean("SELECT `groups`.`ID` FROM `groups` WHERE `groups`.`name` = '%s'", array($group_name)); $result = $this->send($query); if (!mysql_num_rows($result)) return false; return mysql_result($result, 0); } function getUserInfoByUID($userID) { // correct name would be getIdFromUID $query = "SELECT `users`.* FROM `users` WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if(!mysql_num_rows($result)) return false; if ($userInfo = mysql_fetch_array($result)) return $userInfo; else return false; } function getUserInfoByEmail($email) { // correct name would be getIdFromEmail $query = $this->clean("SELECT `users`.* FROM `users` WHERE `users`.`email` = '%s' LIMIT 1", array($email)); $result = $this->send($query); if(!mysql_num_rows($result)) return false; if ($userInfo = mysql_fetch_array($result)) return array($userInfo); else return false; }*/ function getEmailFromKey($token, $userID) { $query = $this->clean("SELECT `keys`.`email` FROM `keys` WHERE `keys`.`token` = '%s' AND `keys`.`user_id` = ".(int)$userID." LIMIT 1", array($token)); $result = $this->send($query); if(!mysql_num_rows($result)) return false; if ($row = mysql_fetch_array($result)) return $row['email']; else return false; } function getEmail($username) { $query = $this->clean("SELECT `users`.`email` FROM `users` WHERE `users`.`username` = '%s' LIMIT 1", array($username)); $result = $this->send($query); if(!mysql_num_rows($result)) return false; if ($userInfo = mysql_fetch_array($result)) return $userInfo['email']; else return false; } function getUserInfoNote($userID) { $query = "SELECT `users`.`username`, `users`.`avatar` FROM `users` WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if(!mysql_num_rows($result)) return false; if ($userInfo = mysql_fetch_array($result)) return $userInfo; else return false; } function getUserInfoAPI($username = false, $email = false, $api) { if($username) $query = $this->clean("SELECT `users`.* FROM `users` WHERE `users`.`username` = '%s' AND `users`.`api` = '%s' LIMIT 1", array($username, $api)); if($email) $query = $this->clean("SELECT `users`.* FROM `users` WHERE `users`.`email` = '%s' AND `users`.`api` = '%s' LIMIT 1", array($email, $api)); $result = $this->send($query); if(!mysql_num_rows($result)) return false; if ($userInfo = mysql_fetch_array($result)) return $userInfo; else return false; } function getFromCookie($cookie) { $query = $this->clean("SELECT `sessions`.`user_id`, `sessions`.`hash`, `users`.* FROM `sessions`, `users` WHERE `sessions`.`hash` = '%s' AND `users`.`id` = `sessions`.`user_id` LIMIT 1", array($cookie)); $result = $this->send($query); if ($userInfo = @mysql_fetch_array($result)) return $userInfo; else return false; } function getFromCookieSessionType($cookie) { $query = $this->clean("SELECT `sessions`.`type` FROM `sessions` WHERE `sessions`.`hash` = '%s' LIMIT 1", array($cookie)); $result = $this->send($query); if ($row = mysql_fetch_array($result)) return $row['type']; } function getFollowing($userID, $start = 0, $items = -1) { if($items < 0) $items = NOTES_PER_PAGE; $query = "SELECT `users`.`avatar`, `users`.`username`, `users`.`ID` FROM `relationships` INNER JOIN `users` ON `users`.`ID` = `relationships`.`who` WHERE `relationships`.`creator` = ".(int)$userID." ORDER BY `users`.`username` ASC LIMIT $start, $items"; $result = $this->send($query); $rowArray = array(); while ($row = mysql_fetch_array($result)) array_push($rowArray, $row); return $rowArray; } function getFollowers($userID, $start = 0, $items = -1) { if($items < 0) $items = NOTES_PER_PAGE; $query = "SELECT `users`.`avatar`, `users`.`username`, `users`.`ID` FROM `relationships` INNER JOIN `users` ON `users`.`ID` = `relationships`.`creator` WHERE `relationships`.`who` = ".(int)$userID." ORDER BY `users`.`username` ASC LIMIT $start, $items"; $result = $this->send($query); $rowArray = array(); while ($row = mysql_fetch_array($result)) array_push($rowArray, $row); return $rowArray; } function getFriendCreator($userID, $both = false) { $query = "SELECT `relationships`.`creator` FROM `relationships` WHERE `relationships`.`who` = ".(int)$userID; if($both) { $query .= " AND `relationships`.`both` = 1"; } $result = $this->send($query); if (mysql_num_rows($result) == 0) return false; $creatorArray = array(); while ($creator = mysql_fetch_array($result)) array_push($creatorArray, $creator); return $creatorArray; } /*function getSalt($token) { $query = $this->clean("SELECT `users`.`salt` FROM `users` WHERE `users`.`tmp_key` = '%s' LIMIT 1", array($token)); $result = $this->send($query); $row = @mysql_fetch_array($result); return $row['salt']; } function getAvatarInfo($username) { $query = $this->clean("SELECT `users`.`username`, `users`.`avatar` FROM `users` WHERE `users`.`username` = '%s' LIMIT 1", array($username)); $result = $this->send($query); $row = mysql_fetch_array($result); if ($row) return $row; else return false; }*/ function getInvitations($userID) { $query = "SELECT `users`.`invitations` FROM `users` WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); $row = mysql_fetch_array($result); return $row['invitations']; } /*function getPosterID($noteID) { $query = "SELECT `notes`.`user_id` FROM `notes` WHERE `notes`.`ID` = ".(int)$noteID." LIMIT 1"; $result = $this->send($query); $row = mysql_fetch_array($result); return $row['user_id']; }*/ function getLastNotePermalink($username = false, $own = false) { if (!$own) $query = $this->clean("SELECT `users`.`ID`, `notes`.`ID` AS `permalink` FROM `users`, `notes` WHERE `users`.`username` = '%s' AND `notes`.`user_id` = `users`.`ID` AND `notes`.`type` = 'public' ORDER BY `notes`.`ID` DESC LIMIT 1", array($username)); else $query = $this->clean("SELECT `users`.`ID`, `notes`.`ID` AS `permalink` FROM `users`, `notes` WHERE `users`.`username` = '%s' AND `notes`.`user_id` = `users`.`ID` ORDER BY `notes`.`ID` DESC LIMIT 1", array($username)); $result = $this->send($query); if ($permalink = mysql_fetch_array($result)) return $permalink; else return false; } function getLastNotes($userID, $limit = 25) { $limit = min( (int) $limit, 25); $query = "SELECT * FROM `notes` WHERE `notes`.`user_id` = ".(int) $userID." AND type IN('public', 'personal') ORDER BY `notes`.`ID` DESC LIMIT 0,".(int)$limit; $result = $this->send($query); $inf = array(); while($row = mysql_fetch_assoc($result)) $inf[] = $row; return $inf; } function getReplying($noteID) { $query = "SELECT `notes`.`replying` FROM `notes` WHERE `notes`.`ID` = ".(int)$noteID." LIMIT 1"; $result = $this->send($query); if (mysql_num_rows($result)) { $row = mysql_fetch_array($result); $query = "SELECT `notes`.`note` FROM `notes` WHERE `notes`.`ID` = ".(int)$row[0]." LIMIT 1"; $result = $this->send($query); $row = mysql_fetch_array($result); } return $row[0]; } function getLastNoteOf($user, $timestamp, $me = 0){ $userID = (int) $this->getIdByUser($user); $timestamp = (int) $timestamp; if(!$userID) return false; $query = "SELECT `notes`.`ID` FROM `notes` WHERE `notes`.`user_id` = ". (int) $userID . " AND `notes`.`timestamp` < " . $timestamp. " AND"; if($me) { $follows = $this->checkFollowing($userID, $me); if($follows || $userID == $me) { $query .= " `notes`.`type` IN('public', 'personal')"; } else { $query .= " `notes`.`type` = 'public'"; } } else { $query .= " `notes`.`type` = 'public'"; } $query .= " ORDER BY `timestamp` DESC LIMIT 1"; $result = $this->send($query); if(!mysql_num_rows($result)) return false; $noteID = mysql_result($result, 0); $note = $this->getNoteCombined($noteID); return $note; } /* COMMON CHECKS */ function checkNote($note = 0, $userID = 0) { $query = "SELECT COUNT(*) FROM `notes` WHERE `user_id` = ".(int)$userID." AND `type` != 'private' AND `ID` = " . (int) $note; $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkFavorite($userID, $noteID) { $query = "SELECT COUNT(*) FROM `favorites` WHERE `favorites`.`user_id` = ".(int)$userID." AND `favorites`.`note_id` = ".(int)$noteID." LIMIT 1"; $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkFollowing($currentUserID, $userID) { $query = "SELECT COUNT(*) FROM `relationships` WHERE `relationships`.`creator` = ".(int)$currentUserID." AND `relationships`.`who` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkToken($token) { $query = $this->clean("SELECT COUNT(*) FROM `invitations` WHERE `invitations`.`token` = '%s' LIMIT 1", array($token)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkInvitations($userID) { $query = "SELECT COUNT(*) FROM `users` WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkUsername($username) { $query = $this->clean("SELECT COUNT(*) FROM `users` WHERE `users`.`username` = '%s' LIMIT 1", array($username)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkEmail($email, $userid = 0) { $query = $this->clean("SELECT COUNT(*) FROM `users` WHERE `users`.`email` = '%s' AND `users`.`ID` <> ".(int)$userid." LIMIT 1", array($email)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkJabber($jabber, $userid = 0) { $query = $this->clean("SELECT COUNT(*) FROM `users` WHERE `users`.`jabber` = '%s' AND `users`.`ID` <> ".(int)$userid." LIMIT 1", array($jabber)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkRegKey($key, $userID) { $query = $this->clean("SELECT COUNT(*) FROM `keys` WHERE `keys`.`user_id` = ".(int)$userID." AND `keys`.`token` = '%s' AND `keys`.`type` = 'activation' LIMIT 1", array($key)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkForgotKey($key, $userID) { $query = $this->clean("SELECT COUNT(*) FROM `keys` WHERE `keys`.`user_id` = ".(int)$userID." AND `keys`.`token` = '%s' AND `keys`.`type` = 'password' LIMIT 1", array($key)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkDropKey($key, $userID) { $query = $this->clean("SELECT COUNT(*) FROM `keys` WHERE `keys`.`user_id` = ".(int)$userID." AND `keys`.`token` = '%s' AND `keys`.`type` = 'drop' LIMIT 1", array($key)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } function checkEmailKey($key, $userID) { $query = $this->clean("SELECT COUNT(*) FROM `keys` WHERE `keys`.`user_id` = ".(int)$userID." AND `keys`.`token` = '%s' AND `keys`.`type` = 'email' LIMIT 1", array($key)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } /*function checkTmpKey($tmpKey) { $query = $this->clean("SELECT `users`.`tmp_key` FROM `users` WHERE `users`.`tmp_key` = '%s' LIMIT 1", array($tmpKey)); $result = $this->send($query); if (mysql_num_rows($result) > 0) return true; else return false; } function checkTmpKeyByUser($username, $tmpKey) { $query = $this->clean("SELECT `users`.`tmp_key` FROM `users` WHERE `users`.`username` = '%s' LIMIT 1", array($username)); $result = $this->send($query); $row = mysql_fetch_array($result); if ($tmpKey == $row['tmp_key']) return true; else return false; }*/ function checkAPIName($name) { $query = $this->clean("SELECT COUNT(*) FROM `api` WHERE `api`.`name` = '%s' LIMIT 1", array($name)); $result = $this->send($query); $count = mysql_result($result, 0); return (bool) $count; } /* COMMON INSERTS */ function newUser($username, $password, $api, $salt, $default_lang, $default_theme, $email, $ip, $token, $noc) { if ($noc == true) $noc = 'ok'; else $noc = 'nc'; $query = $this->clean("INSERT INTO `users` (`username`, `password`, `api`, `salt`, `language`, `theme`, `email`, `status`, `since`, `last_seen`, `ip`, `notification_level`) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), '%s', 3)", array($username, $password, $api, $salt, $default_lang, $default_theme, $email, $noc, $ip)); $result = $this->send($query); if (mysql_affected_rows()) { if ($noc == 'nc') { $insert = mysql_insert_id(); $query = $this->clean("INSERT INTO `keys` (`user_id`, `token`, `type`) VALUES ($insert, '%s', 'activation')", array($token)); $result = $this->send($query); return $insert; } } else { return false; } } function newSession($userID, $SID, $type = 'normal') { $query = $this->clean("INSERT INTO `sessions` (`user_id`, `time`, `hash`, `type`) VALUES (".(int)$userID.", UNIX_TIMESTAMP(), '%s', '%s')", array($SID, $type)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function newInvitation($userID, $email, $token) { $query = $this->clean("INSERT INTO `invitations` (`token`, `email`, `user_id`) VALUES ('%s', '%s', ".(int)$userID.")", array($token, $email)); $result = $this->send($query); if (mysql_affected_rows()) return $token; else return false; } function newPrivateNote($userID, $to = 0, $note, $attached_file = 0, $from, $ip) { $hash = md5('private_'.(int)$userID.time()); $result = $this->checkUsername($to); if ($result) { $query = $this->clean("INSERT INTO `notes` (`user_id`, `type`, `to`, `note`, `attached_file`, `from`, `timestamp`, `ip`, `hash`, `read`) VALUES (".(int)$userID.", 'private', '%s', '%s', '%s', '%s', UNIX_TIMESTAMP(), '%s', '%s', 'false')", array($to, $note, $attached_file, $from, $ip, $hash)); $result = $this->send($query); return true; } else { return false; } } function checkTag($name) { $name = mysql_escape_string($name); $query = $this->send("SELECT COUNT(*) FROM `tags_c` WHERE `name`='$name'"); if (!mysql_result($query, 0)) return false; else return true; } function createTag($name, $founder, $id, $timestamp) { if (!$this->checkTag($name)) $this->send("INSERT INTO `tags_c` SET `name`='$name', `timestamp`='$timestamp', `founder`='$founder'"); $this->send("INSERT INTO `tags_n` SET `note_id`='$id', `tag`='$name', `timestamp`='$timestamp', `poster`='$founder'"); } function getInfoTag($name, $full = false) { $result = array(); $query = $this->send("SELECT `timestamp`, `founder` FROM `tags_c` WHERE `name`='".mysql_escape_string($name)."'"); $row = mysql_fetch_row($query); if ($full) { $q = $this->send("SELECT `poster`, COUNT(*) FROM `tags_n` WHERE `tag`='$name' GROUP BY `poster` ORDER BY COUNT(*) DESC LIMIT 1"); $r = mysql_fetch_row($q); $abc = $this->getUserInfoNote($r[0]); $result['max_poster_username'] = $abc[0]; $result['max_poster_userid'] = $r[0]; $result['max_poster_quantity'] = $r[1]; } $abc = $this->getUserInfoNote($row[1]); $result['since'] = $row[0]; $result['founder'] = $abc[0]; return $result; } function newNote($userID, $to = 0, $type = 'public', $twitter = 0, $note, $attached_file = 0, $from, $replying = 0, $ip, $replyuser = 0) { $hash = md5('public_'.(int)$userID.time()); $query = $this->clean("INSERT INTO `notes` (`user_id`, `to`, `type`, `twitter`, `note`, `attached_file`, `from`, `replying`, `timestamp`, `ip`, `hash`, `reply_user`) VALUES (".(int)$userID.", '%s', '%s', ".(int)$twitter.", '%s', '%s', '%s', ".(int)$replying.", UNIX_TIMESTAMP(), '%s', '%s', ".(int)$replyuser.")", array($to, $type, $note, $attached_file, $from, $ip, $hash)); $result = $this->send($query); if (mysql_affected_rows()) { $insert = mysql_insert_id(); return $insert; } else { return false; } } function newTwit($userID, $note, $hash, $serial, $timestamp, $type = 'twitter') { $query = $this->clean("INSERT INTO `twitter` (`ID`,`hash`,`timestamp`,`note` ,`serial`) VALUES (NULL , '%s', '%s', '%s', '%s')", array($hash, $timestamp, $note, $serial)); $result = $this->send($query); if($result) { $insert_id = mysql_insert_id(); $query = $this->clean("INSERT INTO `post2id` (`ID`,`from`,`to`,`note_id`,`timestamp`,`reply_user`,`type`) VALUES (NULL , '0', '%i', '%i', '%i', '0', '".$type."')", array($userID, $insert_id, $timestamp)); $this->send($query); } } function newKey($uid, $type, $token, $email = false) { $query = $this->clean("DELETE FROM `keys` WHERE `keys`.`user_id` = $uid AND `keys`.`type` = '%s'", array($type)); $result = $this->send($query); if ($email) { $query = $this->clean("INSERT INTO `keys` (`user_id`, `type`, `token`, `email`, `timestamp`) VALUES ($uid, '%s', '%s', '%s', UNIX_TIMESTAMP())", array($type, $token, $email)); } else { $query = $this->clean("INSERT INTO `keys` (`user_id`, `type`, `token`, `timestamp`) VALUES ($uid, '%s', '%s', UNIX_TIMESTAMP())", array($type, $token)); } $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } /*function newTmpkeyByEmail($email, $tmpKey) { $query = $this->clean("UPDATE `users` SET `tmp_key` = '%s' WHERE `users`.`email` = '%s'", array($tmpKey, $email)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function newTmpkeyByUser($username, $tmpKey) { $query = $this->clean("UPDATE `users` SET `tmp_key` = '%s' WHERE `users`.`username` = '%s'", array($tmpKey, $username)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; }*/ function newFollowing($creator, $who) { $me = $this->getUserInfo($creator); $recipro = (bool) $this->checkFollowing($who, $creator); if($recipro) { $both = '1'; $query = "UPDATE `relationships` SET `relationships`.`both` = 1 WHERE `relationships`.`creator` = " . (int) $who . " AND `relationships`.`who` = ". (int) $creator; $this->send($query); } else { $both = '0'; } $query = "INSERT INTO `relationships` (`creator`, `who`, `both`) VALUES (".(int)$creator.", ".(int)$who.", ".(int)$both.")"; $this->send($query); return $recipro; } function newFavorite($userID, $noteID){ $query = "INSERT INTO `favorites` (`user_id`, `note_id`) VALUES (".(int)$userID.", ".(int)$noteID.")"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function post2id($bulk) { $sql = "INSERT INTO `post2id` (`from`, `to`, `note_id`, `timestamp`, `reply_user`, `type`) VALUES ".implode(', ', $bulk); $result = $this->send($sql); if (mysql_affected_rows() != 0) return true; else return false; } /* COMMON DELETES */ function deleteToken($token) { $query = $this->clean("DELETE FROM `invitations` WHERE `invitations`.`token` = '%s' LIMIT 1", array($token)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function deleteKey($token, $userID) { $query = $this->clean("DELETE FROM `keys` WHERE `keys`.`token` = '%s' LIMIT 1", array($token)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function deleteSession($userID) { $query = "DELETE FROM `sessions` WHERE `sessions`.`user_id` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function deleteFollowing($creator, $userID) { $query = $this->clean("DELETE FROM `relationships` WHERE `relationships`.`who` = %i AND `relationships`.`creator` = %i LIMIT 1", array($userID, $creator)); $result = $this->send($query); $query = "UPDATE `relationships` SET `relationships`.`both` = 0 WHERE `relationships`.`creator` = " . (int) $userID . " AND `relationships`.`who` = ".(int)$creator." LIMIT 1"; $this->send($query); if (mysql_affected_rows()) return true; else return false; } function deleteFavorite($userID, $noteID) { $query = "DELETE FROM `favorites` WHERE `favorites`.`user_id` = ".$userID." AND `favorites`.`note_id` = ".(int)$noteID." LIMIT 1"; $this->send($query); if (mysql_affected_rows()) return true; else return false; } function deleteNote($noteID, $userID, $username = false) { $row = $this->getNoteCombined($noteID); if ($row['user_id'] == $userID) { if (!$username) $file = './users_files/'.$row['username'].'/files/'.$row['attached_file']; else $file = './users_files/'.$username.'/files/'.$row['attached_file']; if(file_exists($file)) unlink($file); $query = "DELETE FROM `notes` WHERE `notes`.`ID` = ".(int)$noteID; $result = $this->send($query); $query = "DELETE FROM `favorites` WHERE `favorites`.`note_id` = ".(int)$noteID; $result = $this->send($query); $query = "DELETE FROM `post2id` WHERE `post2id`.`note_id` = ".(int)$noteID; $result = $this->send($query); return true; } else { return false; } } function deleteUser($userID) { $userinfo = $this->getUserInfo($userID); $username = $userinfo['username']; $dir = "./$username/"; //removeDir($dir, true); // catastrophist and not tested $notes = "SELECT ID FROM `notes` WHERE user_id = " . (int) $userID; $notes = $this->send($notes); $array = array(); while($row = mysql_fetch_assoc($notes)) $array[] = $row['ID']; $array = implode(',', $array); $query = "DELETE FROM `favorites` WHERE `favorites`.`note_id` IN($array)"; $query = "DELETE FROM `users` WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); $query = "DELETE FROM `notes` WHERE `notes`.`user_id` = ".(int)$userID; $result = $this->send($query); $query = "DELETE FROM `post2id` WHERE `post2id`.`from` = ".(int)$userID; $result = $this->send($query); $query = "DELETE FROM `post2id` WHERE `post2id`.`to` = ".(int)$userID; $result = $this->send($query); $query = "DELETE FROM `relationships` WHERE `relationships`.`creator` = ".(int)$userID; $result = $this->send($query); $query = "DELETE FROM `relationships` WHERE `relationships`.`who` = ".(int)$userID; $result = $this->send($query); $query = "DELETE FROM `sessions` WHERE `sessions`.`user_id` = ".(int)$userID; $result = $this->send($query); $query = "DELETE FROM `favorites` WHERE `favorites`.`user_id` = ".(int)$userID; $result = $this->send($query); } function cleanTwitter() { $query = "DELETE FROM `post2id` WHERE `post2id`.`type`='twitter'"; $result = $this->send($query); $query = "UPDATE `users` SET `users`.`twitter_key` = ''"; $result = $this->send($query); $query = "TRUNCATE TABLE `twitter`"; $result = $this->send($query); $query = "OPTIMIZE TABLE `notes`"; $result = $this->send($query); $query = "OPTIMIZE TABLE `post2id`"; $result = $this->send($query); $query = "OPTIMIZE TABLE `users`"; $result = $this->send($query); if (mysql_fetch_array($result)) return true; else return false; } /* COMMON UPDATES */ function updateLastFollow($userID) { $query = "UPDATE `users` SET `users`.`last_follow` = UNIX_TIMESTAMP() WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateLastNote($userID) { $query = "UPDATE `users` SET `users`.`last_note` = UNIX_TIMESTAMP() WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateShowTwits($user, $show) { $int = ($show) ? '1' : '0'; $query = "UPDATE `users` SET `users`.`show_twits` = $int WHERE `users`.`id` = $user LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updatePostTweets($user, $show) { $int = ($show) ? '1' : '0'; $query = "UPDATE `users` SET `users`.`post_tweets` = $int WHERE `users`.`id` = $user LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateProfile($userID, $realname = 0, $url = 0, $location = 0, $bio = 0, $show_followers = 0, $lang = 'en_EN', $private_profile = 0) { if($show_followers) $sf = '1'; else $sf = '0'; if($lang == 'def') $lang = DEFAULT_LANG; $query = $this->clean("UPDATE `users` SET `users`.`realname` = '%s', `users`.`url` = '%s', `users`.`location` = '%s', `users`.`bio` = '%s', `users`.`show_followers` = '%s', `users`.`private` = $private_profile WHERE `users`.`ID` = %i LIMIT 1", array($realname, $url, $location, $bio, $sf, $userID)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateShorterService($user, $value) { $value = mysql_escape_string($value); $this->send("UPDATE `users` SET `shorter_service`= '$value' WHERE `id` = $user"); } function updateProfileType($userID, $type) { if ($type == 'private') { $query = "UPDATE `users` SET `users`.`private` = 1 WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $this->send($query); $query = "UPDATE `notes` SET `notes`.`type` = 'personal' WHERE `notes`.`user_id` = ".(int)$userID." AND `notes`.`type` = 'public'"; $this->send($query); $query = "UPDATE `post2id` SET `post2id`.`type` = 'personal' WHERE `post2id`.`from` = ".(int)$userID; $this->send($query); } else { $query = "UPDATE `users` SET `users`.`private` = 0 WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $this->send($query); $query = "UPDATE `notes` SET `notes`.`type` = 'public' WHERE `notes`.`user_id` = ".(int)$userID." AND `notes`.`type` = 'personal'"; $this->send($query); $query = "UPDATE `post2id` SET `post2id`.`type` = 'public' WHERE `post2id`.`from` = ".(int)$userID; $this->send($query); } } function updatePassword($userID, $password, $salt) { $query = $this->clean("UPDATE `users` SET `users`.`password` = '$password', `users`.`salt` = '%s' WHERE ID = ".(int)$userID." LIMIT 1", array($salt)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateMail($userID, $mail) { $query = $this->clean("UPDATE `users` SET `users`.`email` = '%s' WHERE ID = %i LIMIT 1", array($mail, $userID)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateLanguage($userID, $lang) { $query = $this->clean("UPDATE `users` SET `users`.`language` = '%s' WHERE ID = %i LIMIT 1", array($lang, $userID)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateJabber($userID, $jabber) { $query = $this->clean("UPDATE `users` SET `users`.`jabber` = '%s' WHERE ID = %i LIMIT 1", array($jabber, $userID)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateAPI($userID, $api) { $query = $this->clean("UPDATE `users` SET `users`.`api` = '%s' WHERE ID = %i LIMIT 1", array($api, $userID)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateLevel($userID, $level) { $query = "UPDATE `users` SET `users`.`notification_level` = ".(int)$level." WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateBackground($userID, $extension) { global $_USER; $query = $this->clean("UPDATE `users` SET `users`.`background` = '%s' WHERE `users`.`ID` = ".(int)$userID." LIMIT 1", array($extension)); $result = $this->send($query); if($_USER['ID'] == $userID) $_USER['background'] = $extension; if (mysql_affected_rows()) return true; else return false; } function updateBackgroundStyle($userID, $style) { $query = $this->clean("UPDATE `users` SET `users`.`background_style` = '%s' WHERE `users`.`ID`= ".(int)$userID." LIMIT 1", array($style)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateInvitations($userID) { $result = $this->getInvitations($userID); $invitations = ($result - 1); $query = "UPDATE `users` SET `users`.`invitations` = ".(int)$invitations." WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateTheme($userID, $theme) { global $_USER; $query = $this->clean("UPDATE `users` SET `users`.`theme` = '%s' WHERE `users`.`ID` = ".(int)$userID." LIMIT 1", array($theme)); $result = $this->send($query); if($_USER['ID'] == $userID) $_USER['theme'] = $theme; if (mysql_affected_rows()) return true; else return false; } function updateIgnored($userID, $list) { global $_USER; $query = "UPDATE `users` SET `users`.`ignored` = '".serialize($list)."' WHERE `users`.`ID` = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateAvatar($userID, $avatar = NULL) { global $_USER; $query = $this->clean("UPDATE `users` SET `users`.`avatar` = '%s' WHERE `users`.`ID` = ".(int)$userID." LIMIT 1", array($avatar)); $result = $this->send($query); if($_USER['ID'] == $userID) $_USER['avatar'] = $avatar; if (mysql_affected_rows()) return true; else return false; } function updateStatus($userID, $status) { $query = $this->clean("UPDATE `users` SET `users`.`status` = '%s' WHERE `users`.`ID` = ".(int)$userID." LIMIT 1", array($status)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateTwitter($userID, $twitter_username, $twitter_password) { $this->updateLastTwitter($userID); $twitter_password = base64_encode($twitter_password); $query = $this->clean("UPDATE `users` SET `users`.`twitter_username` = '%s', `users`.`twitter_password` = '%s' WHERE `users`.`ID` = ".(int)$userID." LIMIT 1", array($twitter_username, $twitter_password)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateLastSeen($userID, $timestamp) { $this->send("UPDATE users SET `last_seen`= $timestamp WHERE `ID` = ".(int)$userID." LIMIT 1"); } function updateLastTwitter($userID) { $query = "UPDATE users SET last_twitter_update = UNIX_TIMESTAMP() WHERE id = ".(int)$userID." LIMIT 1"; $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateTwitterKey($userID, $key) { $query = $this->clean("UPDATE users SET twitter_key = '%s' WHERE id = ".(int)$userID." LIMIT 1", array($key)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } function updateUnreadPrivates($username) { $query = $this->clean("UPDATE `notes` SET `read` = 1 WHERE `to` = '%s' AND `type` = 'private' AND `read` = 0", array($username)); $result = $this->send($query); if (mysql_affected_rows()) return true; else return false; } /* COMMON COUNTS */ function countFollowers($userID) { $query = "SELECT COUNT(*) FROM `relationships` WHERE `relationships`.`who` = ".(int)$userID; $result = $this->send($query); $count = mysql_result($result, 0); return $count; } function countFollowing($userID) { $query = "SELECT COUNT(*) FROM `relationships` WHERE `relationships`.`creator` = ".(int)$userID; $result = $this->send($query); $count = mysql_result($result, 0); return $count; } // It returns the number of notes of each type // $type can be: private, archive, twitter, twitter_reply, favorites, public, reply, friends, friendsof, all // The user or the userID is stored in $data. function countNotes($type, $data = false, $ignored = false) { if (is_array($ignored) && count($ignored) > 0) { $ignored = implode(',', $ignored); if(!empty($ignored)) { $s_post2id = ' AND `post2id`.`from` NOT IN('.$ignored.') AND `post2id`.`reply_user` NOT IN('.$ignored.')'; $s_notes = ' AND `notes`.`user_id` NOT IN('.$ignored.') AND `notes`.`reply_user` NOT IN('.$ignored.')'; } else { $s_post2id = ''; $s_notes = ''; } } switch ($type) { case 'private': $query = $this->clean("SELECT COUNT(*) FROM `notes` WHERE (`notes`.`type` = 'private') AND (`notes`.`to` = '%s')", array($data)); break; case 'private_sent': $query = $this->clean("SELECT COUNT(*) FROM `notes` WHERE (`notes`.`type` = 'private') AND (`notes`.`user_id` = '%s')", array($data)); break; case 'unread_private': $query = $this->clean("SELECT COUNT(*) FROM `notes` WHERE `notes`.`type` = 'private' and `notes`.`read` = 0 and `notes`.`to` = '%s'", array($username)); break; case 'archive': $query = "SELECT COUNT(*) FROM `notes` WHERE `notes`.`type` IN('public', 'personal') AND `notes`.`user_id` = ".(int)$data; break; case 'twitter': case 'twitter_reply': $query = "SELECT COUNT(*) FROM `post2id` WHERE `post2id`.`type` = '$type' AND `post2id`.`to` = ".(int)$data; break; case 'favorites': $query = "SELECT COUNT(*) FROM `favorites` WHERE `favorites`.`user_id` = ".(int)$data; break; case 'tag': $query = "SELECT COUNT(*) FROM `tags_n` WHERE `tag`='$data'"; break; case 'public': $query = "SELECT count(*) FROM `notes` WHERE `notes`.`type` = 'public'".$s; break; case 'reply': $query = $this->clean("SELECT COUNT(*) FROM `notes` WHERE `notes`.`type` IN('public', 'personal') AND `notes`.`to` = '%s'" . $s, array($data)); break; case 'friends': $query = "SELECT COUNT(*) FROM `post2id` WHERE `post2id`.`type` IN('public', 'personal') AND `post2id`.`to` = ".(int)$data; break; case 'friendsof': $query = "SELECT COUNT(*) FROM `post2id` WHERE `post2id`.`type` = 'public' AND `post2id`.`to` = ".(int)$data; break; case 'all': $query = "SELECT COUNT(*) FROM `post2id` WHERE `post2id`.`to` = ".(int)$data . " AND `post2id`.`type` IN('public', 'twitter', 'personal')".$s; break; } $result = $this->send($query); $count = @mysql_result($result, 0); if ($count) return $count; else return 0; } function countUsers($info) { $query = $this->clean("SELECT COUNT(*) FROM `users` WHERE `users`.`username` = '%s' OR `users`.`realname` LIKE '\%%s\%'", array($info, $info)); $result = $this->send($query); $count = mysql_result($result, 0); return $count; } /* RELATIONSHIP */ function dumpRelationship($follows, $following) { $recipro = $this->newFollowing($follows, $following); $me = $this->getUserInfo($follows); $he = $this->getUserInfo($following); if($he['private'] == '0') { // no problem here $notes = $this->getLastNotes($following); $bulk = array(); $this->updateLastFollow($follows); foreach($notes as $note) $bulk[] = "(".(int)$following.", ".(int)$follows.", ".(int)$note['ID'].", ".(int)$note['timestamp'].", ".(int)$note['reply_user'].", '".$note['type']."')"; $this->post2id($bulk); } if($he['private'] == '1' && $recipro) { // he has a private profile and he's following me, I get messages $notes = $this->getLastNotes($following); $bulk = array(); $this->updateLastFollow($follows); foreach($notes as $note) $bulk[] = "(".(int)$following.", ".(int)$follows.", ".(int)$note['ID'].", ".(int)$note['timestamp'].", ".(int)$note['reply_user'].", '".$note['type']."')"; $this->post2id($bulk); } if($me['private'] == '1' && $recipro) { // here I'm accepting because I'm private and he's following me before (reciprocity) $notes = $this->getLastNotes($follows); $bulk = array(); $this->updateLastFollow($follows); foreach($notes as $note) $bulk[] = "(".(int)$follows.", ".(int)$following.", ".(int)$note['ID'].", ".(int)$note['timestamp'].", ".(int)$note['reply_user'].", '".$note['type']."')"; $this->post2id($bulk); } } function removeRelationship($follows, $following) { $me = $this->getUserInfo($follows); if($me['private']) { $query = "DELETE FROM `post2id` WHERE `post2id`.`from` = ".(int) $follows." AND `post2id`.`to` = ".(int) $following; $this->send($query); } $this->deleteFollowing($follows, $following); $query = "DELETE FROM `post2id` WHERE `post2id`.`from` = ".(int) $following." AND `post2id`.`to` = ".(int) $follows; $this->send($query); } } ?>