MEMBER.php

Go to the documentation of this file.
00001 <?php
00002 
00003 /*
00004  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)
00005  * Copyright (C) 2002-2007 The Nucleus Group
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * (see nucleus/documentation/index.html#license for more info)
00012  */
00021 class MEMBER {
00022 
00023         // 1 when authenticated, 0 when not
00024         var $loggedin = 0;
00025         var $password;          // not the actual password, but rather a MD5 hash
00026 
00027         var $cookiekey;         // value that should also be in the client cookie to allow authentication
00028 
00029         // member info
00030         var $id = -1;
00031         var $realname;
00032         var $displayname;
00033         var $email;
00034         var $url;
00035         var $language = '';             // name of the language file to use (e.g. 'english' -> english.php)
00036         var $admin = 0;                 // (either 0 or 1)
00037         var $canlogin = 0;              // (either 0 or 1)
00038         var $notes;
00039 
00040         // (private)
00041         function MEMBER() {
00042 
00043         }
00044 
00045         // (static)
00046         function &createFromName($displayname) {
00047                 $mem =& new MEMBER();
00048                 $mem->readFromName($displayname);
00049                 return $mem;
00050         }
00051 
00052         // (static)
00053         function &createFromID($id) {
00054                 $mem =& new MEMBER();
00055                 $mem->readFromID($id);
00056                 return $mem;
00057         }
00058 
00059         function readFromName($displayname) {
00060                 return $this->read("mname='".addslashes($displayname)."'");
00061         }
00062 
00063         function readFromID($id) {
00064                 return $this->read("mnumber=" . intval($id));
00065         }
00066 
00071         function login($login, $password) {
00072                 $this->loggedin = 0;
00073                 if (!$this->readFromName($login))
00074                         return 0;
00075                 if (!$this->checkPassword($password))
00076                         return 0;
00077                 $this->loggedin = 1;
00078                 return $this->isLoggedIn();
00079         }
00080 
00081         // login using cookie key
00082         function cookielogin($login, $cookiekey) {
00083                 $this->loggedin = 0;
00084                 if (!$this->readFromName($login))
00085                         return 0;
00086                 if (!$this->checkCookieKey($cookiekey))
00087                         return 0;
00088                 $this->loggedin = 1;
00089                 return $this->isLoggedIn();
00090         }
00091 
00092         function logout() {
00093                 $this->loggedin=0;
00094         }
00095 
00096         function isLoggedIn() {
00097                 return $this->loggedin;
00098         }
00099 
00100         function read($where) {
00101                 // read info
00102                 $query =  'SELECT * FROM '.sql_table('member') . ' WHERE ' . $where;
00103 
00104                 $res = sql_query($query);
00105                 $obj = mysql_fetch_object($res);
00106 
00107                 $this->setRealName($obj->mrealname);
00108                 $this->setEmail($obj->memail);
00109                 $this->password = $obj->mpassword;
00110                 $this->setCookieKey($obj->mcookiekey);
00111                 $this->setURL($obj->murl);
00112                 $this->setDisplayName($obj->mname);
00113                 $this->setAdmin($obj->madmin);
00114                 $this->id = $obj->mnumber;
00115                 $this->setCanLogin($obj->mcanlogin);
00116                 $this->setNotes($obj->mnotes);
00117                 $this->setLanguage($obj->deflang);
00118 
00119                 return mysql_num_rows($res);
00120         }
00121 
00122 
00127         function isBlogAdmin($blogid) {
00128                 $query = 'SELECT tadmin FROM '.sql_table('team').' WHERE'
00129                            . ' tblog=' . intval($blogid)
00130                            . ' and tmember='. $this->getID();
00131                 $res = sql_query($query);
00132                 if (mysql_num_rows($res) == 0)
00133                         return 0;
00134                 else
00135                         return (mysql_result($res,0,0) == 1) ;
00136         }
00137 
00138         function blogAdminRights($blogid) {
00139                 return ($this->isAdmin() || $this->isBlogAdmin($blogid));
00140         }
00141 
00142 
00143         function teamRights($blogid) {
00144                 return ($this->isAdmin() || $this->isTeamMember($blogid));
00145         }
00146 
00150         function isTeamMember($blogid) {
00151                 $query = 'SELECT * FROM '.sql_table('team').' WHERE'
00152                            . ' tblog=' . intval($blogid)
00153                            . ' and tmember='. $this->getID();
00154                 $res = sql_query($query);
00155                 return (mysql_num_rows($res) != 0);
00156         }
00157 
00166         function canAlterComment($commentid) {
00167                 if ($this->isAdmin()) return 1;
00168 
00169                 $query =  'SELECT citem as itemid, iblog as blogid, cmember as cauthor, iauthor'
00170                            . ' FROM '.sql_table('comment') .', '.sql_table('item').', '.sql_table('blog')
00171                            . ' WHERE citem=inumber and iblog=bnumber and cnumber=' . intval($commentid);
00172                 $res = sql_query($query);
00173                 $obj = mysql_fetch_object($res);
00174 
00175                 return ($obj->cauthor == $this->getID()) or $this->isBlogAdmin($obj->blogid) or ($obj->iauthor == $this->getID());
00176         }
00177 
00184         function canAlterItem($itemid) {
00185                 if ($this->isAdmin()) return 1;
00186 
00187                 $query =  'SELECT iblog, iauthor FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);
00188                 $res = sql_query($query);
00189                 $obj = mysql_fetch_object($res);
00190                 return ($obj->iauthor == $this->getID()) or $this->isBlogAdmin($obj->iblog);
00191         }
00192 
00200         function canUpdateItem($itemid, $newcat) {
00201                 global $manager;
00202 
00203                 // item does not exists -> NOK
00204                 if (!$manager->existsItem($itemid,1,1)) return 0;
00205 
00206                 // cannot alter item -> NOK
00207                 if (!$this->canAlterItem($itemid)) return 0;
00208 
00209                 // if this is a 'newcat' style newcat
00210                 // no blog admin of destination blog -> NOK
00211                 // blog admin of destination blog -> OK
00212                 if (strstr($newcat,'newcat')) {
00213                         // get blogid
00214                         list($blogid) = sscanf($newcat,'newcat-%d');
00215                         return $this->blogAdminRights($blogid);
00216                 }
00217 
00218                 // category does not exist -> NOK
00219                 if (!$manager->existsCategory($newcat)) return 0;
00220 
00221 
00222                 // get item
00223                 $item =& $manager->getItem($itemid,1,1);
00224 
00225                 // old catid = new catid -> OK
00226                 if ($item['catid'] == $newcat) return 1;
00227 
00228                 // not a valid category -> NOK
00229                 $validCat = quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('category').' WHERE catid='.intval($newcat));
00230                 if (!$validCat) return 0;
00231 
00232                 // get destination blog
00233                 $source_blogid = getBlogIDFromItemID($itemid);
00234                 $dest_blogid = getBlogIDFromCatID($newcat);
00235 
00236                 // not a team member of destination blog -> NOK
00237                 if (!$this->teamRights($dest_blogid)) return 0;
00238 
00239                 // if member is author of item -> OK
00240                 if ($item['authorid'] == $this->getID()) return 1;
00241 
00242                 // if member has admin rights on both blogs: OK
00243                 if (($this->blogAdminRights($dest_blogid)) && ($this->blogAdminRights($source_blogid))) return 1;
00244 
00245                 // all other cases: NOK
00246                 return 0;
00247 
00248         }
00249 
00250         function canAddItem($catid) {
00251                 global $manager;
00252 
00253                 // if this is a 'newcat' style newcat
00254                 // no blog admin of destination blog -> NOK
00255                 // blog admin of destination blog -> OK
00256                 if (strstr($catid,'newcat')) {
00257                         // get blogid
00258                         list($blogid) = sscanf($catid,"newcat-%d");
00259                         return $this->blogAdminRights($blogid);
00260                 }
00261 
00262                 // category does not exist -> NOK
00263                 if (!$manager->existsCategory($catid)) return 0;
00264 
00265                 $blogid = getBlogIDFromCatID($catid);
00266 
00267                 // no team rights for blog -> NOK
00268                 if (!$this->teamRights($blogid)) return 0;
00269 
00270                 // all other cases: OK
00271                 return 1;
00272         }
00273 
00278         function canBeDeleted() {
00279                 $res = sql_query('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());
00280                 return (mysql_num_rows($res) == 0);
00281         }
00282 
00290         function setCookies($shared = 0) {
00291                 global $CONF;
00292 
00293                 if ($CONF['SessionCookie'] || $shared)
00294                         $lifetime = 0;
00295                 else
00296                         $lifetime = (time()+2592000);
00297 
00298                 setcookie($CONF['CookiePrefix'] .'user',$this->getDisplayName(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
00299                 setcookie($CONF['CookiePrefix'] .'loginkey', $this->getCookieKey(),$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
00300 
00301                 // make sure cookies on shared pcs don't get renewed
00302                 if ($shared)
00303                         setcookie($CONF['CookiePrefix'] .'sharedpc', '1',$lifetime,$CONF['CookiePath'],$CONF['CookieDomain'],$CONF['CookieSecure']);
00304         }
00305 
00306         function sendActivationLink($type, $extra='')
00307         {
00308                 global $CONF;
00309 
00310                 // generate key and URL
00311                 $key = $this->generateActivationEntry($type, $extra);
00312                 $url = $CONF['AdminURL'] . 'index.php?action=activate&key=' . $key;
00313 
00314                 // choose text to use in mail
00315                 switch ($type)
00316                 {
00317                         case 'register':
00318                                 $message = _ACTIVATE_REGISTER_MAIL;
00319                                 $title = _ACTIVATE_REGISTER_MAILTITLE;
00320                                 break;
00321                         case 'forgot':
00322                                 $message = _ACTIVATE_FORGOT_MAIL;
00323                                 $title = _ACTIVATE_FORGOT_MAILTITLE;
00324                                 break;
00325                         case 'addresschange':
00326                                 $message = _ACTIVATE_CHANGE_MAIL;
00327                                 $title = _ACTIVATE_CHANGE_MAILTITLE;
00328                                 break;
00329                         default;
00330                 }
00331 
00332                 // fill out variables in text
00333 
00334                 $aVars = array(
00335                         'siteName' => $CONF['SiteName'],
00336                         'siteUrl' => $CONF['IndexURL'],
00337                         'memberName' => $this->getDisplayName(),
00338                         'activationUrl' => $url
00339                 );
00340 
00341                 $message = TEMPLATE::fill($message, $aVars);
00342                 $title = TEMPLATE::fill($title, $aVars);
00343 
00344                 // send mail
00345 
00346                 mb_language('ja');
00347                 mb_internal_encoding(_CHARSET);
00348                 @mb_send_mail($this->getEmail(), $title ,$message,'From: ' . $CONF['AdminEmail']);
00349 
00350                 ACTIONLOG::add(INFO, _ACTIONLOG_ACTIVATIONLINK . ' (' . $this->getDisplayName() . ' / type: ' . $type . ')');
00351 
00352 
00353         }
00354 
00358         function getAdminBlogs() {
00359                 $blogs = array();
00360 
00361                 if ($this->isAdmin())
00362                         $query = 'SELECT bnumber as blogid from '.sql_table('blog');
00363                 else
00364                         $query = 'SELECT tblog as blogid from '.sql_table('team').' where tadmin=1 and tmember=' . $this->getID();
00365 
00366                 $res = sql_query($query);
00367                 if (mysql_num_rows($res) > 0) {
00368                         while ($obj = mysql_fetch_object($res)) {
00369                                 array_push($blogs, $obj->blogid);
00370                         }
00371                 }
00372 
00373                 return $blogs;
00374         }
00375 
00380         function getNotifyFromMailAddress($suggest = "") {
00381                 global $CONF;
00382                 if ($this->isLoggedIn()) {
00383                         return $this->getDisplayName() . " <" . $this->getEmail() . ">";
00384                 } else if (isValidMailAddress($suggest)) {
00385                         return $suggest;
00386                 } else {
00387                         return $CONF['AdminEmail'];
00388                 }
00389         }
00390 
00394         function write() {
00395 
00396                 $query =  'UPDATE '.sql_table('member')
00397                            . " SET mname='" . addslashes($this->getDisplayName()) . "',"
00398                            . "     mrealname='". addslashes($this->getRealName()) . "',"
00399                            . "     mpassword='". addslashes($this->getPassword()) . "',"
00400                            . "     mcookiekey='". addslashes($this->getCookieKey()) . "',"
00401                            . "     murl='" . addslashes($this->getURL()) . "',"
00402                            . "     memail='" . addslashes($this->getEmail()) . "',"
00403                            . "     madmin=" . $this->isAdmin() . ","
00404                            . "     mnotes='" . addslashes($this->getNotes()) . "',"
00405                            . "     mcanlogin=" . $this->canLogin() . ","
00406                            . "     deflang='" . addslashes($this->getLanguage()) . "'"
00407                            . " WHERE mnumber=" . $this->getID();
00408                 sql_query($query);
00409         }
00410 
00411         function checkPassword($pw) {
00412                 return (md5($pw) == $this->getPassword());
00413         }
00414 
00415         function checkCookieKey($key) {
00416                 return (($key != '') && ($key == $this->getCookieKey()));
00417         }
00418 
00419         function getRealName() {
00420                 return $this->realname;
00421         }
00422 
00423         function setRealName($name) {
00424                 $this->realname = $name;
00425         }
00426 
00427         function getEmail() {
00428                 return $this->email;
00429         }
00430 
00431         function setEmail($email) {
00432                 $this->email = $email;
00433         }
00434 
00435         function getPassword() {
00436                 return $this->password;
00437         }
00438 
00439         function setPassword($pwd) {
00440                 $this->password = md5($pwd);
00441         }
00442 
00443         function getCookieKey() {
00444                 return $this->cookiekey;
00445         }
00446 
00450         function newCookieKey() {
00451                 mt_srand( (double) microtime() * 1000000);
00452                 $this->cookiekey = md5(uniqid(mt_rand()));
00453                 $this->write();
00454                 return $this->cookiekey;
00455         }
00456 
00457         function setCookieKey($val) {
00458                 $this->cookiekey = $val;
00459         }
00460 
00461         function getURL() {
00462                 return $this->url;
00463         }
00464 
00465         function setURL($site) {
00466                 $this->url = $site;
00467         }
00468 
00469         function getLanguage() {
00470                 return $this->language;
00471         }
00472 
00473         function setLanguage($lang) {
00474                 $this->language = $lang;
00475         }
00476 
00477         function setDisplayName($nick) {
00478                 $this->displayname = $nick;
00479         }
00480 
00481         function getDisplayName() {
00482                 return $this->displayname;
00483         }
00484 
00485         function isAdmin() {
00486                 return $this->admin;
00487         }
00488 
00489         function setAdmin($val) {
00490                 $this->admin = $val;
00491         }
00492 
00493         function canLogin() {
00494                 return $this->canlogin;
00495         }
00496 
00497         function setCanLogin($val) {
00498                 $this->canlogin = $val;
00499         }
00500 
00501         function getNotes() {
00502                 return $this->notes;
00503         }
00504 
00505         function setNotes($val) {
00506                 $this->notes = $val;
00507         }
00508 
00509         function getID() {
00510                 return $this->id;
00511         }
00512 
00513         // returns true if there is a member with the given login name (static)
00514         function exists($name) {
00515                 $r = sql_query('select * FROM '.sql_table('member')." WHERE mname='".addslashes($name)."'");
00516                 return (mysql_num_rows($r) != 0);
00517         }
00518 
00519         // returns true if there is a member with the given ID (static)
00520         function existsID($id) {
00521                 $r = sql_query('select * FROM '.sql_table('member')." WHERE mnumber='".intval($id)."'");
00522                 return (mysql_num_rows($r) != 0);
00523         }
00524 
00525         // checks if a username is protected. If so, it can not be used on anonymous comments
00526         function isNameProtected($name) {
00527 
00528                 // extract name
00529                 $name = strip_tags($name);
00530                 $name = trim($name);
00531 
00532                 return MEMBER::exists($name);
00533         }
00534 
00535         // adds a new member (static)
00536         function create($name, $realname, $password, $email, $url, $admin, $canlogin, $notes) {
00537                 if (!isValidMailAddress($email))
00538                         return _ERROR_BADMAILADDRESS;
00539 
00540                 if (!isValidDisplayName($name))
00541                         return _ERROR_BADNAME;
00542 
00543                 if (MEMBER::exists($name))
00544                         return _ERROR_NICKNAMEINUSE;
00545 
00546                 if (!$realname)
00547                         return _ERROR_REALNAMEMISSING;
00548 
00549                 if (!$password)
00550                         return _ERROR_PASSWORDMISSING;
00551 
00552                 // Sometimes user didn't prefix the URL with http://, this cause a malformed URL. Let's fix it.
00553                 if (!eregi("^https?://", $url))
00554                         $url = "http://".$url;
00555 
00556                 $name = addslashes($name);
00557                 $realname = addslashes($realname);
00558                 $password = addslashes(md5($password));
00559                 $email = addslashes($email);
00560                 $url = addslashes($url);
00561                 $admin = intval($admin);
00562                 $canlogin = intval($canlogin);
00563                 $notes = addslashes($notes);
00564 
00565                 $query = 'INSERT INTO '.sql_table('member')." (MNAME,MREALNAME,MPASSWORD,MEMAIL,MURL, MADMIN, MCANLOGIN, MNOTES) "
00566                            . "VALUES ('$name','$realname','$password','$email','$url',$admin, $canlogin, '$notes')";
00567                 sql_query($query);
00568 
00569                 ACTIONLOG::add(INFO, _ACTIONLOG_NEWMEMBER . ' ' . $name);
00570 
00571                 return 1;
00572         }
00573 
00580         function getActivationInfo($key)
00581         {
00582                 $query = 'SELECT * FROM ' . sql_table('activation') . ' WHERE vkey=\'' . addslashes($key). '\'';
00583                 $res = sql_query($query);
00584 
00585                 if (!$res || (mysql_num_rows($res) == 0))
00586                         return 0;
00587                 else
00588                         return mysql_fetch_object($res);
00589         }
00590 
00602         function generateActivationEntry($type, $extra = '')
00603         {
00604                 // clean up old entries
00605                 $this->cleanupActivationTable();
00606 
00607                 // kill any existing entries for the current member (delete is ok)
00608                 // (only one outstanding activation key can be present for a member)
00609                 sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vmember=' . intval($this->getID()));
00610 
00611                 $canLoginWhileActive = false; // indicates if the member can log in while the link is active
00612                 switch ($type)
00613                 {
00614                         case 'forgot':
00615                                 $canLoginWhileActive = true;
00616                                 break;
00617                         case 'register':
00618                                 break;
00619                         case 'addresschange':
00620                                 $extra = $extra . '/' . ($this->canLogin() ? '1' : '0');
00621                                 break;
00622                 }
00623 
00624                 $ok = false;
00625                 while (!$ok)
00626                 {
00627                         // generate a random key
00628                         srand((double)microtime()*1000000);
00629                         $key = md5(uniqid(rand(), true));
00630 
00631                         // attempt to add entry in database
00632                         // add in database as non-active
00633                         $query = 'INSERT INTO ' . sql_table('activation'). ' (vkey, vtime, vmember, vtype, vextra) ';
00634                         $query .= 'VALUES (\'' . addslashes($key). '\', \'' . date('Y-m-d H:i:s',time()) . '\', \'' . intval($this->getID()). '\', \'' . addslashes($type). '\', \'' . addslashes($extra). '\')';
00635                         if (sql_query($query))
00636                                 $ok = true;
00637                 }
00638 
00639                 // mark member as not allowed to log in
00640                 if (!$canLoginWhileActive)
00641                 {
00642                         $this->setCanLogin(0);
00643                         $this->write();
00644                 }
00645 
00646                 // return the key
00647                 return $key;
00648         }
00649 
00655         function activate($key)
00656         {
00657                 // get activate info
00658                 $info = MEMBER::getActivationInfo($key);
00659 
00660                 // no active key
00661                 if (!$info)
00662                         return false;
00663 
00664                 switch ($info->vtype)
00665                 {
00666                         case 'forgot':
00667                                 // nothing to do
00668                                 break;
00669                         case 'register':
00670                                 // set canlogin value
00671                                 global $CONF;
00672                                 sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($CONF['NewMemberCanLogon']). ' WHERE mnumber=' . intval($info->vmember));
00673                                 break;
00674                         case 'addresschange':
00675                                 // reset old 'canlogin' value
00676                                 list($oldEmail, $oldCanLogin) = explode('/', $info->vextra);
00677                                 sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ' WHERE mnumber=' . intval($info->vmember));
00678                                 break;
00679                 }
00680 
00681                 // delete from activation table
00682                 sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vkey=\'' . addslashes($key) . '\'');
00683 
00684                 // success!
00685                 return true;
00686         }
00687 
00694         function cleanupActivationTable()
00695         {
00696                 $boundary = time() - (60 * 60 * 24 * 2);
00697 
00698                 // 1. walk over all entries, and see if special actions need to be performed
00699                 $res = sql_query('SELECT * FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');
00700 
00701                 while ($o = mysql_fetch_object($res))
00702                 {
00703                         switch ($o->vtype)
00704                         {
00705                                 case 'register':
00706                                         // delete all information about this site member. registration is undone because there was
00707                                         // no timely activation
00708                                         include_once($DIR_LIBS . 'ADMIN.php');
00709                                         ADMIN::deleteOneMember(intval($o->vmember));
00710                                         break;
00711                                 case 'addresschange':
00712                                         // revert the e-mail address of the member back to old address
00713                                         list($oldEmail, $oldCanLogin) = explode('/', $o->vextra);
00714                                         sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ', memail=\'' . addslashes($oldEmail). '\' WHERE mnumber=' . intval($o->vmember));
00715                                         break;
00716                                 case 'forgot':
00717                                         // delete the activation link and ignore. member can request a new password using the
00718                                         // forgot password link
00719                                         break;
00720                         }
00721                 }
00722 
00723                 // 2. delete activation entries for real
00724                 sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');
00725         }
00726 
00727 }
00728 
00729 ?>



Generated on Wed Jun 25 17:25:59 2008 by  doxygen 1.5.5