4 * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
\r
5 * Copyright (C) 2002-2004 The Nucleus Group
\r
7 * This program is free software; you can redistribute it and/or
\r
8 * modify it under the terms of the GNU General Public License
\r
9 * as published by the Free Software Foundation; either version 2
\r
10 * of the License, or (at your option) any later version.
\r
11 * (see nucleus/documentation/index.html#license for more info)
\r
13 * A class representing site members
\r
17 // 1 when authenticated, 0 when not
\r
19 var $password; // not the actual password, but rather a MD5 hash
\r
21 var $cookiekey; // value that should also be in the client cookie to allow authentication
\r
29 var $language; // name of the language file to use (e.g. 'english' -> english.php)
\r
30 var $admin; // (either 0 or 1)
\r
31 var $canlogin; // (either 0 or 1)
\r
40 function createFromName($displayname) {
\r
41 $mem = new MEMBER();
\r
42 $mem->readFromName($displayname);
\r
47 function createFromID($id) {
\r
48 $mem = new MEMBER();
\r
49 $mem->readFromID($id);
\r
53 function readFromName($displayname) {
\r
54 return $this->read("mname='".addslashes($displayname)."'");
\r
57 function readFromID($id) {
\r
58 return $this->read("mnumber=" . intval($id));
\r
62 * Tries to login as a given user. Returns true when succeeded,
\r
63 * returns false when failed
\r
65 function login($login, $password) {
\r
66 $this->loggedin = 0;
\r
67 if (!$this->readFromName($login))
\r
69 if (!$this->checkPassword($password))
\r
71 $this->loggedin = 1;
\r
72 return $this->isLoggedIn();
\r
75 // login using cookie key
\r
76 function cookielogin($login, $cookiekey) {
\r
77 $this->loggedin = 0;
\r
78 if (!$this->readFromName($login))
\r
80 if (!$this->checkCookieKey($cookiekey))
\r
82 $this->loggedin = 1;
\r
83 return $this->isLoggedIn();
\r
90 function isLoggedIn() {
\r
91 return $this->loggedin;
\r
94 function read($where) {
\r
96 $query = 'SELECT * FROM '.sql_table('member') . ' WHERE ' . $where;
\r
98 $res = sql_query($query);
\r
99 $obj = mysql_fetch_object($res);
\r
101 $this->setRealName($obj->mrealname);
\r
102 $this->setEmail($obj->memail);
\r
103 $this->password = $obj->mpassword;
\r
104 $this->setCookieKey($obj->mcookiekey);
\r
105 $this->setURL($obj->murl);
\r
106 $this->setDisplayName($obj->mname);
\r
107 $this->setAdmin($obj->madmin);
\r
108 $this->id = $obj->mnumber;
\r
109 $this->setCanLogin($obj->mcanlogin);
\r
110 $this->setNotes($obj->mnotes);
\r
111 $this->setLanguage($obj->deflang);
\r
113 return mysql_num_rows($res);
\r
118 * Returns true if member is an admin for the given blog
\r
119 * (returns false if not a team member)
\r
121 function isBlogAdmin($blogid) {
\r
122 $query = 'SELECT tadmin FROM '.sql_table('team').' WHERE'
\r
123 . ' tblog=' . intval($blogid)
\r
124 . ' and tmember='. $this->getID();
\r
125 $res = sql_query($query);
\r
126 if (mysql_num_rows($res) == 0)
\r
129 return (mysql_result($res,0,0) == 1) ;
\r
132 function blogAdminRights($blogid) {
\r
133 return ($this->isAdmin() || $this->isBlogAdmin($blogid));
\r
137 function teamRights($blogid) {
\r
138 return ($this->isAdmin() || $this->isTeamMember($blogid));
\r
142 * Returns true if this member is a team member of the given blog
\r
144 function isTeamMember($blogid) {
\r
145 $query = 'SELECT * FROM '.sql_table('team').' WHERE'
\r
146 . ' tblog=' . intval($blogid)
\r
147 . ' and tmember='. $this->getID();
\r
148 return (mysql_num_rows(sql_query($query)) != 0);
\r
152 * Returns true if this member can edit/delete a commentitem. This can be in the
\r
154 * - member is a super-admin
\r
155 * - member is the author of the comment
\r
156 * - member is admin of the blog associated with the comment
\r
157 * - member is author of the item associated with the comment
\r
159 function canAlterComment($commentid) {
\r
160 if ($this->isAdmin()) return 1;
\r
162 $query = 'SELECT citem as itemid, iblog as blogid, cmember as cauthor, iauthor'
\r
163 . ' FROM '.sql_table('comment') .', '.sql_table('item').', '.sql_table('blog')
\r
164 . ' WHERE citem=inumber and iblog=bnumber and cnumber=' . intval($commentid);
\r
165 $obj = mysql_fetch_object(sql_query($query));
\r
167 return ($obj->cauthor == $this->getID()) or $this->isBlogAdmin($obj->blogid) or ($obj->iauthor == $this->getID());
\r
171 * Returns true if this member can edit/delete an item. This is true in the following
\r
172 * cases: - member is a super-admin
\r
173 * - member is the author of the item
\r
174 * - member is admin of the the associated blog
\r
176 function canAlterItem($itemid) {
\r
177 if ($this->isAdmin()) return 1;
\r
179 $query = 'SELECT iblog, iauthor FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);
\r
180 $obj = mysql_fetch_object(sql_query($query));
\r
181 return ($obj->iauthor == $this->getID()) or $this->isBlogAdmin($obj->iblog);
\r
185 * returns true if this member can move/update an item to a given category,
\r
186 * false if not (see comments fot the tests that are executed)
\r
189 * @param newcat (can also be of form 'newcat-x' with x=blogid)
\r
191 function canUpdateItem($itemid, $newcat) {
\r
194 // item does not exists -> NOK
\r
195 if (!$manager->existsItem($itemid,1,1)) return 0;
\r
197 // cannot alter item -> NOK
\r
198 if (!$this->canAlterItem($itemid)) return 0;
\r
200 // if this is a 'newcat' style newcat
\r
201 // no blog admin of destination blog -> NOK
\r
202 // blog admin of destination blog -> OK
\r
203 if (strstr($newcat,'newcat')) {
\r
205 list($blogid) = sscanf($newcat,'newcat-%d');
\r
206 return $this->blogAdminRights($blogid);
\r
209 // category does not exist -> NOK
\r
210 if (!$manager->existsCategory($newcat)) return 0;
\r
214 $item =& $manager->getItem($itemid,1,1);
\r
216 // old catid = new catid -> OK
\r
217 if ($item['catid'] == $newcat) return 1;
\r
219 // not a valid category -> NOK
\r
220 $validCat = quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('category').' WHERE catid='.intval($newcat));
\r
221 if (!$validCat) return 0;
\r
223 // get destination blog
\r
224 $source_blogid = getBlogIDFromItemID($itemid);
\r
225 $dest_blogid = getBlogIDFromCatID($newcat);
\r
227 // not a team member of destination blog -> NOK
\r
228 if (!$this->teamRights($dest_blogid)) return 0;
\r
230 // if member is author of item -> OK
\r
231 if ($item['authorid'] == $this->getID()) return 1;
\r
233 // if member has admin rights on both blogs: OK
\r
234 if (($this->blogAdminRights($dest_blogid)) && ($this->blogAdminRights($source_blogid))) return 1;
\r
236 // all other cases: NOK
\r
241 function canAddItem($catid) {
\r
244 // if this is a 'newcat' style newcat
\r
245 // no blog admin of destination blog -> NOK
\r
246 // blog admin of destination blog -> OK
\r
247 if (strstr($catid,'newcat')) {
\r
249 list($blogid) = sscanf($catid,"newcat-%d");
\r
250 return $this->blogAdminRights($blogid);
\r
253 // category does not exist -> NOK
\r
254 if (!$manager->existsCategory($catid)) return 0;
\r
256 $blogid = getBlogIDFromCatID($catid);
\r
258 // no team rights for blog -> NOK
\r
259 if (!$this->teamRights($blogid)) return 0;
\r
261 // all other cases: OK
\r
266 * Return true if member can be deleted. This means that there are no items or comments
\r
267 * posted by the member
\r
269 function canBeDeleted() {
\r
270 $res = sql_query('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());
\r
271 $res2 = sql_query('SELECT * FROM '.sql_table('comment').' WHERE cmember=' . $this->getID());
\r
272 return ((mysql_num_rows($res) == 0) and (mysql_num_rows($res2)==0));
\r
276 * Sets the cookies for the member
\r
279 * set this to 1 when using a shared computer. Cookies will expire
\r
280 * at the end of the session in this case.
\r
282 function setCookies($shared = 0) {
\r
285 if ($CONF['SessionCookie'] || $shared)
\r
288 $lifetime = (time()+2592000);
\r
290 setcookie('user',$this->getDisplayName(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
291 setcookie('loginkey', $this->getCookieKey(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
293 // make sure cookies on shared pcs don't get renewed
\r
295 setcookie('sharedpc', '1',$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
\r
299 * Sends an email message containing the users password
\r
301 function sendPassword($password) {
\r
304 $message = "Someone, possibly you, requested a new password for your account at '" . $CONF['SiteName'] . "' (". $CONF['IndexURL']. ") to be sent out to you.\n Here is your new login information: \n\n";
\r
305 $message .= "\tLogin: " . $this->getDisplayName();
\r
306 $message .= "\n\tPassword: " . $password;
\r
307 $message .= getMailFooter();
\r
309 @mail($this->getEmail(),'Your password',$message,"From: " . $CONF['AdminEmail']);
\r
311 ACTIONLOG::add(INFO, _ACTIONLOG_PWDREMINDERSENT . $this->getDisplayName());
\r
315 * Returns an array of all blogids for which member has admin rights
\r
317 function getAdminBlogs() {
\r
320 if ($this->isAdmin())
\r
321 $query = 'SELECT bnumber as blogid from '.sql_table('blog');
\r
323 $query = 'SELECT tblog as blogid from '.sql_table('team').' where tadmin=1 and tmember=' . $this->getID();
\r
325 $res = sql_query($query);
\r
326 if (mysql_num_rows($res) > 0) {
\r
327 while ($obj = mysql_fetch_object($res)) {
\r
328 array_push($blogs, $obj->blogid);
\r
336 * Returns an email address from which notification of commenting/karma voting can
\r
337 * be sent. A suggestion can be given for when the member is not logged in
\r
339 function getNotifyFromMailAddress($suggest = "") {
\r
341 if ($this->isLoggedIn()) {
\r
342 return $this->getDisplayName() . " <" . $this->getEmail() . ">";
\r
343 } else if (isValidMailAddress($suggest)) {
\r
346 return $CONF['AdminEmail'];
\r
351 * Write data to database
\r
355 $query = 'UPDATE '.sql_table('member')
\r
356 . " SET mname='" . addslashes($this->getDisplayName()) . "',"
\r
357 . " mrealname='". addslashes($this->getRealName()) . "',"
\r
358 . " mpassword='". addslashes($this->getPassword()) . "',"
\r
359 . " mcookiekey='". addslashes($this->getCookieKey()) . "',"
\r
360 . " murl='" . addslashes($this->getURL()) . "',"
\r
361 . " memail='" . addslashes($this->getEmail()) . "',"
\r
362 . " madmin=" . $this->isAdmin() . ","
\r
363 . " mnotes='" . addslashes($this->getNotes()) . "',"
\r
364 . " mcanlogin=" . $this->canLogin() . ","
\r
365 . " deflang='" . addslashes($this->getLanguage()) . "'"
\r
366 . " WHERE mnumber=" . $this->getID();
\r
370 function checkPassword($pw) {
\r
371 return (md5($pw) == $this->getPassword());
\r
374 function checkCookieKey($key) {
\r
375 return (($key != '') && ($key == $this->getCookieKey()));
\r
378 function getRealName() {
\r
379 return $this->realname;
\r
382 function setRealName($name) {
\r
383 $this->realname = $name;
\r
386 function getEmail() {
\r
387 return $this->email;
\r
390 function setEmail($email) {
\r
391 $this->email = $email;
\r
394 function getPassword() {
\r
395 return $this->password;
\r
398 function setPassword($pwd) {
\r
399 $this->password = md5($pwd);
\r
402 function getCookieKey() {
\r
403 return $this->cookiekey;
\r
407 * Generate new cookiekey, save it, and return it
\r
409 function newCookieKey() {
\r
410 mt_srand( (double) microtime() * 1000000);
\r
411 $this->cookiekey = md5(uniqid(mt_rand()));
\r
413 return $this->cookiekey;
\r
416 function setCookieKey($val) {
\r
417 $this->cookiekey = $val;
\r
420 function getURL() {
\r
424 function setURL($site) {
\r
425 $this->url = $site;
\r
428 function getLanguage() {
\r
429 return $this->language;
\r
432 function setLanguage($lang) {
\r
433 $this->language = $lang;
\r
436 function setDisplayName($nick) {
\r
437 $this->displayname = $nick;
\r
440 function getDisplayName() {
\r
441 return $this->displayname;
\r
444 function isAdmin() {
\r
445 return $this->admin;
\r
448 function setAdmin($val) {
\r
449 $this->admin = $val;
\r
452 function canLogin() {
\r
453 return $this->canlogin;
\r
456 function setCanLogin($val) {
\r
457 $this->canlogin = $val;
\r
460 function getNotes() {
\r
461 return $this->notes;
\r
464 function setNotes($val) {
\r
465 $this->notes = $val;
\r
472 // returns true if there is a member with the given login name (static)
\r
473 function exists($name) {
\r
474 $r = sql_query('select * FROM '.sql_table('member')." WHERE mname='".addslashes($name)."'");
\r
475 return (mysql_num_rows($r) != 0);
\r
478 // returns true if there is a member with the given ID (static)
\r
479 function existsID($id) {
\r
480 $r = sql_query('select * FROM '.sql_table('member')." WHERE mnumber='".intval($id)."'");
\r
481 return (mysql_num_rows($r) != 0);
\r
484 // checks if a username is protected. If so, it can not be used on anonymous comments
\r
485 function isNameProtected($name) {
\r
488 $name = strip_tags($name);
\r
489 $name = trim($name);
\r
491 return MEMBER::exists($name);
\r
494 // adds a new member (static)
\r
495 function create($name, $realname, $password, $email, $url, $admin, $canlogin, $notes) {
\r
496 if (!isValidMailAddress($email))
\r
497 return _ERROR_BADMAILADDRESS;
\r
499 if (!isValidDisplayName($name))
\r
500 return _ERROR_BADNAME;
\r
502 if (MEMBER::exists($name))
\r
503 return _ERROR_NICKNAMEINUSE;
\r
506 return _ERROR_REALNAMEMISSING;
\r
509 return _ERROR_PASSWORDMISSING;
\r
511 // Sometimes user didn't prefix the URL with http://, this cause a malformed URL. Let's fix it.
\r
512 if (!eregi("^https?://", $url))
\r
513 $url = "http://".$url;
\r
515 $name = addslashes($name);
\r
516 $realname = addslashes($realname);
\r
517 $password = addslashes(md5($password));
\r
518 $email = addslashes($email);
\r
519 $url = addslashes($url);
\r
520 $admin = intval($admin);
\r
521 $canlogin = intval($canlogin);
\r
522 $notes = addslashes($notes);
\r
524 $query = 'INSERT INTO '.sql_table('member')." (MNAME,MREALNAME,MPASSWORD,MEMAIL,MURL, MADMIN, MCANLOGIN, MNOTES) "
\r
525 . "VALUES ('$name','$realname','$password','$email','$url',$admin, $canlogin, '$notes')";
\r
528 ACTIONLOG::add(INFO, _ACTIONLOG_NEWMEMBER . ' ' . $name);
\r