5 function &getInstance(&$db) {
7 if (!isset($instance)) {
8 $instance = new UserService($db);
15 'username' => 'username',
16 'password' => 'password'
22 var $cookietime = 1209600; // 2 weeks
24 function UserService(&$db) {
26 $this->tablename = $GLOBALS['tableprefix'] .'users';
27 $this->sessionkey = $GLOBALS['cookieprefix'] .'-currentuserid';
28 $this->cookiekey = $GLOBALS['cookieprefix'] .'-login';
29 $this->profileurl = createURL('profile', '%2$s');
32 function _checkdns($host) {
33 if (function_exists('checkdnsrr')) {
34 return checkdnsrr($host);
36 return $this->_checkdnsrr($host);
40 function _checkdnsrr($host, $type = "MX") {
42 @exec("nslookup -type=$type $host", $output);
43 while(list($k, $line) = each($output)) {
44 if(preg_match("/^$host/i", $line)) { //eregi("^$host", $line)
52 function _getuser($fieldname, $value) {
53 $query = 'SELECT * FROM '. $this->getTableName() .' WHERE '. $fieldname .' = "'. $this->db->sql_escape($value) .'"';
55 if (! ($dbresult =& $this->db->sql_query($query)) ) {
56 message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
60 if ($row =& $this->db->sql_fetchrow($dbresult))
66 function _in_regex_array($value, $array) {
67 foreach ($array as $key => $pattern) {
68 if (preg_match($pattern, $value)) {
75 function _randompassword() {
76 $password = mt_rand(1, 99999999);
77 $password = substr(md5($password), mt_rand(0, 19), mt_rand(6, 12));
81 function _updateuser($uId, $fieldname, $value) {
82 $updates = array ($fieldname => $value);
83 $sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
85 // Execute the statement.
86 $this->db->sql_transaction('begin');
87 if (!($dbresult = & $this->db->sql_query($sql))) {
88 $this->db->sql_transaction('rollback');
89 message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
92 $this->db->sql_transaction('commit');
94 // Everything worked out, so return true.
98 function getProfileUrl($id, $username) {
99 return sprintf($this->profileurl, urlencode($id), urlencode($username));
102 function getUserByUsername($username) {
103 return $this->_getuser($this->getFieldName('username'), $username);
106 function getUser($id) {
107 return $this->_getuser($this->getFieldName('primary'), $id);
110 function isLoggedOn() {
111 return ($this->getCurrentUserId() !== false);
114 function &getCurrentUser($refresh = FALSE, $newval = NULL) {
116 if (!is_null($newval)) //internal use only: reset currentuser
117 $currentuser = $newval;
118 else if ($refresh || !isset($currentuser)) {
119 if ($id = $this->getCurrentUserId())
120 $currentuser = $this->getUser($id);
127 function isAdmin($userid) {
128 return false; //not implemented yet
131 function getCurrentUserId() {
132 if (isset($_SESSION[$this->getSessionKey()])) {
133 return $_SESSION[$this->getSessionKey()];
134 } else if (isset($_COOKIE[$this->getCookieKey()])) {
135 $cook = explode(':', $_COOKIE[$this->getCookieKey()]); //split(':', $_COOKIE[$this->getCookieKey()]);
136 //cookie looks like this: 'id:md5(username+password)'
137 $query = 'SELECT * FROM '. $this->getTableName() .
138 ' WHERE MD5(CONCAT('.$this->getFieldName('username') .
139 ', '.$this->getFieldName('password') .
140 ')) = \''.$this->db->sql_escape($cook[1]).'\' AND '.
141 $this->getFieldName('primary'). ' = '. $this->db->sql_escape($cook[0]);
143 if (! ($dbresult =& $this->db->sql_query($query)) ) {
144 message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
148 if ($row = $this->db->sql_fetchrow($dbresult)) {
149 $_SESSION[$this->getSessionKey()] = $row[$this->getFieldName('primary')];
150 return $_SESSION[$this->getSessionKey()];
156 function login($username, $password, $remember = FALSE, $path = '/') {
157 $password = $this->sanitisePassword($password);
158 $query = 'SELECT '. $this->getFieldName('primary') .' FROM '. $this->getTableName() .' WHERE '. $this->getFieldName('username') .' = "'. $this->db->sql_escape($username) .'" AND '. $this->getFieldName('password') .' = "'. $this->db->sql_escape($password) .'"';
160 if (! ($dbresult =& $this->db->sql_query($query)) ) {
161 message_die(GENERAL_ERROR, 'Could not get user', '', __LINE__, __FILE__, $query, $this->db);
165 if ($row =& $this->db->sql_fetchrow($dbresult)) {
166 $id = $_SESSION[$this->getSessionKey()] = $row[$this->getFieldName('primary')];
168 $cookie = $id .':'. md5($username.$password);
169 setcookie($this->cookiekey, $cookie, time() + $this->cookietime, $path);
177 function logout($path = '/') {
178 @setcookie($this->cookiekey, NULL, time() - 1, $path);
179 unset($_COOKIE[$this->cookiekey]);
181 $this->getCurrentUser(TRUE, false);
184 function getWatchlist($uId) {
185 // Gets the list of user IDs being watched by the given user.
186 $query = 'SELECT watched FROM '. $GLOBALS['tableprefix'] .'watched WHERE uId = '. intval($uId);
188 if (! ($dbresult =& $this->db->sql_query($query)) ) {
189 message_die(GENERAL_ERROR, 'Could not get watchlist', '', __LINE__, __FILE__, $query, $this->db);
194 if ($this->db->sql_numrows($dbresult) == 0)
196 while ($row =& $this->db->sql_fetchrow($dbresult))
197 $arrWatch[] = $row['watched'];
201 function getWatchNames($uId, $watchedby = false) {
202 // Gets the list of user names being watched by the given user.
203 // - If $watchedby is false get the list of users that $uId watches
204 // - If $watchedby is true get the list of users that watch $uId
212 $query = 'SELECT '. $table1 .'.'. $this->getFieldName('username') .' FROM '. $GLOBALS['tableprefix'] .'watched AS W, '. $this->getTableName() .' AS a, '. $this->getTableName() .' AS b WHERE W.watched = a.'. $this->getFieldName('primary') .' AND W.uId = b.'. $this->getFieldName('primary') .' AND '. $table2 .'.'. $this->getFieldName('primary') .' = '. intval($uId) .' ORDER BY '. $table1 .'.'. $this->getFieldName('username');
214 if (!($dbresult =& $this->db->sql_query($query))) {
215 message_die(GENERAL_ERROR, 'Could not get watchlist', '', __LINE__, __FILE__, $query, $this->db);
220 if ($this->db->sql_numrows($dbresult) == 0) {
223 while ($row =& $this->db->sql_fetchrow($dbresult)) {
224 $arrWatch[] = $row[$this->getFieldName('username')];
229 function getWatchStatus($watcheduser, $currentuser) {
230 // Returns true if the current user is watching the given user, and false otherwise.
231 $query = 'SELECT watched FROM '. $GLOBALS['tableprefix'] .'watched AS W INNER JOIN '. $this->getTableName() .' AS U ON U.'. $this->getFieldName('primary') .' = W.watched WHERE U.'. $this->getFieldName('primary') .' = '. intval($watcheduser) .' AND W.uId = '. intval($currentuser);
233 if (! ($dbresult =& $this->db->sql_query($query)) ) {
234 message_die(GENERAL_ERROR, 'Could not get watchstatus', '', __LINE__, __FILE__, $query, $this->db);
239 if ($this->db->sql_numrows($dbresult) == 0)
245 function setWatchStatus($subjectUserID) {
246 if (!is_numeric($subjectUserID))
249 $currentUserID = $this->getCurrentUserId();
250 $watched = $this->getWatchStatus($subjectUserID, $currentUserID);
253 $sql = 'DELETE FROM '. $GLOBALS['tableprefix'] .'watched WHERE uId = '. intval($currentUserID) .' AND watched = '. intval($subjectUserID);
254 if (!($dbresult =& $this->db->sql_query($sql))) {
255 $this->db->sql_transaction('rollback');
256 message_die(GENERAL_ERROR, 'Could not add user to watch list', '', __LINE__, __FILE__, $sql, $this->db);
261 'uId' => intval($currentUserID),
262 'watched' => intval($subjectUserID)
264 $sql = 'INSERT INTO '. $GLOBALS['tableprefix'] .'watched '. $this->db->sql_build_array('INSERT', $values);
265 if (!($dbresult =& $this->db->sql_query($sql))) {
266 $this->db->sql_transaction('rollback');
267 message_die(GENERAL_ERROR, 'Could not add user to watch list', '', __LINE__, __FILE__, $sql, $this->db);
272 $this->db->sql_transaction('commit');
276 function addUser($username, $password, $email) {
277 // Set up the SQL UPDATE statement.
278 $datetime = gmdate('Y-m-d H:i:s', time());
279 $password = $this->sanitisePassword($password);
280 $values = array('username' => $username, 'password' => $password, 'email' => $email, 'uDatetime' => $datetime, 'uModified' => $datetime);
281 $sql = 'INSERT INTO '. $this->getTableName() .' '. $this->db->sql_build_array('INSERT', $values);
283 // Execute the statement.
284 $this->db->sql_transaction('begin');
285 if (!($dbresult = & $this->db->sql_query($sql))) {
286 $this->db->sql_transaction('rollback');
287 message_die(GENERAL_ERROR, 'Could not insert user', '', __LINE__, __FILE__, $sql, $this->db);
290 $this->db->sql_transaction('commit');
292 // Everything worked out, so return true.
296 function updateUser($uId, $password, $name, $email, $homepage, $uContent) {
297 if (!is_numeric($uId))
300 // Set up the SQL UPDATE statement.
301 $moddatetime = gmdate('Y-m-d H:i:s', time());
303 $updates = array ('uModified' => $moddatetime, 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
305 $updates = array ('uModified' => $moddatetime, 'password' => $this->sanitisePassword($password), 'name' => $name, 'email' => $email, 'homepage' => $homepage, 'uContent' => $uContent);
306 $sql = 'UPDATE '. $this->getTableName() .' SET '. $this->db->sql_build_array('UPDATE', $updates) .' WHERE '. $this->getFieldName('primary') .'='. intval($uId);
308 // Execute the statement.
309 $this->db->sql_transaction('begin');
310 if (!($dbresult = & $this->db->sql_query($sql))) {
311 $this->db->sql_transaction('rollback');
312 message_die(GENERAL_ERROR, 'Could not update user', '', __LINE__, __FILE__, $sql, $this->db);
315 $this->db->sql_transaction('commit');
317 // Everything worked out, so return true.
321 function sanitisePassword($password) {
322 return sha1(trim($password));
325 function generatePassword($uId) {
326 if (!is_numeric($uId))
329 $password = $this->_randompassword();
331 if ($this->_updateuser($uId, $this->getFieldName('password'), $this->sanitisePassword($password)))
337 function isBlockedEmail($email) {
339 $whitelist = $GLOBALS['email_whitelist'];
340 if (!is_null($whitelist) && is_array($whitelist)) {
341 if (!$this->_in_regex_array($email, $whitelist)) {
342 // Not in whitelist -> blocked
348 $blacklist = $GLOBALS['email_blacklist'];
349 if (!is_null($blacklist) && is_array($blacklist)) {
350 if ($this->_in_regex_array($email, $blacklist)) {
351 // In blacklist -> blocked
360 function isReserved($username) {
361 if (in_array($username, $GLOBALS['reservedusers'])) {
368 function isValidEmail($email) {
369 if (preg_match("/^((?:(?:(?:\w[\.\-\+_]?)*)\w)+)\@((?:(?:(?:\w[\.\-_]?){0,62})\w)+)\.(\w{2,6})$/i", $email) > 0) {
370 list($emailUser, $emailDomain) = explode("@", $email);
372 // Check if the email domain has a DNS record
373 if ($this->_checkdns($emailDomain)) {
381 function getTableName() { return $this->tablename; }
382 function setTableName($value) { $this->tablename = $value; }
384 function getFieldName($field) { return $this->fields[$field]; }
385 function setFieldName($field, $value) { $this->fields[$field] = $value; }
387 function getSessionKey() { return $this->sessionkey; }
388 function setSessionKey($value) { $this->sessionkey = $value; }
390 function getCookieKey() { return $this->cookiekey; }
391 function setCookieKey($value) { $this->cookiekey = $value; }