OSDN Git Service

FIX: AdminActions::parse_commentnavlist()がSQL文による重複した問い合わせをしていたバグ
[nucleus-jp/nucleus-next.git] / nucleus / libs / MEMBER.php
index 66d72ab..add9899 100644 (file)
@@ -1,9 +1,9 @@
 <?php\r
 \r
-/*\r
+/* \r
  * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
  * Copyright (C) 2002-2009 The Nucleus Group\r
- *\r
+ * \r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License\r
  * as published by the Free Software Foundation; either version 2\r
  */\r
 /**\r
  * A class representing site members\r
- *\r
+ * \r
  * @license http://nucleuscms.org/license.txt GNU General Public License\r
  * @copyright Copyright (C) 2002-2009 The Nucleus Group\r
  * @version $Id: MEMBER.php 1616 2012-01-08 09:48:15Z sakamocchi $\r
  */\r
-class MEMBER\r
+class Member\r
 {\r
        // 1 when authenticated, 0 when not\r
        public $loggedin = 0;\r
@@ -25,6 +25,7 @@ class MEMBER
        private $algorism = 'md5';\r
        \r
        public $cookiekey;              // value that should also be in the client cookie to allow authentication\r
+       private $cookie_salt = FALSE;\r
        \r
        // member info\r
        public $id = -1;\r
@@ -39,7 +40,7 @@ class MEMBER
        private $locale = '';\r
        \r
        /**\r
-        * MEMBER::__construct()\r
+        * Member::__construct()\r
         * Constructor for a member object\r
         * \r
         * @param       Void\r
@@ -48,66 +49,41 @@ class MEMBER
         */\r
        public function __construct()\r
        {\r
-               global $CONF;\r
-               /* secure cookie key settings (either 'none', 0, 8, 16, 24, or 32) */\r
-               if ( !array_key_exists('secureCookieKey', $CONF) )\r
-               {\r
-                       $CONF['secureCookieKey'] = 24;\r
-               }\r
-               \r
-               switch( $CONF['secureCookieKey'] )\r
-               {\r
-                       case 8:\r
-                               $CONF['secureCookieKeyIP'] = preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
-                               break;\r
-                       case 16:\r
-                               $CONF['secureCookieKeyIP'] = preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
-                               break;\r
-                       case 24:\r
-                               $CONF['secureCookieKeyIP'] = preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));\r
-                               break;\r
-                       case 32:\r
-                               $CONF['secureCookieKeyIP'] = serverVar('REMOTE_ADDR');\r
-                               break;\r
-                       default:\r
-                               $CONF['secureCookieKeyIP'] = '';\r
-               }\r
-               \r
                return;\r
        }\r
        \r
        /**\r
-        * MEMBER::createFromName()\r
+        * Member::createFromName()\r
         * Create a member object for a given displayname\r
-        *\r
-        * @static      \r
+        * \r
+        * @static\r
         * @param       String  $displayname    login name\r
         * @return      Object  member object\r
         * \r
         */\r
        public static function &createFromName($displayname)\r
        {\r
-               $mem = new MEMBER();\r
+               $mem = new Member();\r
                $mem->readFromName($displayname);\r
                return $mem;\r
        }\r
-\r
+       \r
        /**\r
-        * MEMBER::createFromID()\r
+        * Member::createFromID()\r
         * Create a member object for a given ID\r
-        *\r
-        * @static      \r
+        * \r
+        * @static\r
         * @param       Integer $id     id for member\r
         */\r
        public static function &createFromID($id)\r
        {\r
-               $mem = new MEMBER();\r
+               $mem = new Member();\r
                $mem->readFromID($id);\r
                return $mem;\r
        }\r
        \r
        /**\r
-        * MEMBER::readFromName()\r
+        * Member::readFromName()\r
         * Read member table in database\r
         * \r
         * @param       String  $displayname    login name\r
@@ -116,11 +92,11 @@ class MEMBER
         */\r
        public function readFromName($displayname)\r
        {\r
-               return $this->read("mname='".sql_real_escape_string($displayname)."'");\r
+               return $this->read('mname='.DB::quoteValue($displayname));\r
        }\r
        \r
        /**\r
-        * MEMBER::readFromID()\r
+        * Member::readFromID()\r
         * Read member table in database\r
         * \r
         * @param       Integer $id     id for member\r
@@ -133,7 +109,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::hash()\r
+        * Member::hash()\r
         * hash the target string\r
         * \r
         * @param       String  $string target string\r
@@ -147,12 +123,45 @@ class MEMBER
                        default:\r
                                $string = md5($string);\r
                }\r
-               \r
                return $string;\r
        }\r
        \r
        /**\r
-        * MEMBER::login()\r
+        * Member::set_cookie_salt()\r
+        * \r
+        * @param       integer $key    secureCookieKey value\r
+        * @return      void\r
+        * \r
+        */\r
+       private function set_cookie_salt($key = 0)\r
+       {\r
+               if ( !$key )\r
+               {\r
+                       $key = 24;\r
+               }\r
+               \r
+               switch( $key )\r
+               {\r
+                       case 8:\r
+                               $this->cookie_salt = preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/', '', serverVar('REMOTE_ADDR'));\r
+                               break;\r
+                       case 16:\r
+                               $this->cookie_salt = preg_replace('/\.[0-9]+\.[0-9]+$/', '', serverVar('REMOTE_ADDR'));\r
+                               break;\r
+                       case 24:\r
+                               $this->cookie_salt = preg_replace('/\.[0-9]+$/', '', serverVar('REMOTE_ADDR'));\r
+                               break;\r
+                       case 32:\r
+                               $this->cookie_salt = serverVar('REMOTE_ADDR');\r
+                               break;\r
+                       default:\r
+                               $this->cookie_salt = 'none';\r
+               }\r
+               return;\r
+       }\r
+       \r
+       /**\r
+        * Member::login()\r
         * Tries to login as a given user.\r
         * Returns true when succeeded, returns false when failed\r
         * 3.40 adds CustomLogin event\r
@@ -174,6 +183,20 @@ class MEMBER
                /* limiting the length of password to avoid hash collision */\r
                $password=i18n::substr($password, 0, 40);\r
                \r
+               /* \r
+                * generate cookie salt from secure cookie key settings\r
+               * (either 'none', 0, 8, 16, 24, or 32)\r
+               */\r
+               if ( !$this->cookie_salt )\r
+               {\r
+                       $salt = 0;\r
+                       if ( array_key_exists('secureCookieKey', $CONF) )\r
+                       {\r
+                               $salt = $CONF['secureCookieKey'];\r
+                       }\r
+                       $this->set_cookie_salt($salt);\r
+               }\r
+               \r
                $success = 0;\r
                $allowlocal = 1;\r
                $manager->notify('CustomLogin', array('login' => &$login, 'password'=>&$password, 'success'=>&$success, 'allowlocal'=>&$allowlocal));\r
@@ -201,31 +224,37 @@ class MEMBER
                                $errormessage = 'Login failed for ' . $login;\r
                        }\r
                        $manager->notify('LoginFailed', array('username' => $login) );\r
-                       ACTIONLOG::add(INFO, $errormessage);\r
+                       ActionLog::add(INFO, $errormessage);\r
                }\r
                /* login success */\r
                else\r
                {\r
+                       /* For lower compatibility */\r
+                       if ( strlen($this->password) === 32 )\r
+                       {\r
+                               $this->password = $this->hash($password);\r
+                       }\r
+                       \r
                        $this->newCookieKey();\r
                        $this->setCookies($shared);\r
                        \r
-                       if ( $CONF['secureCookieKey'] !== 'none' )\r
+                       if ( $this->cookie_salt !== 'none' )\r
                        {\r
                                /* secure cookie key */\r
-                               $this->setCookieKey($this->hash($this->getCookieKey().$CONF['secureCookieKeyIP']));\r
+                               $this->setCookieKey($this->hash($this->getCookieKey() . $this->cookie_salt));\r
                                $this->write();\r
                        }\r
                        \r
                        $errormessage = '';\r
                        $manager->notify('LoginSuccess', array('member' => &$member, 'username' => $login) );\r
-                       ACTIONLOG::add(INFO, "Login successful for $login (sharedpc=$shared)");\r
+                       ActionLog::add(INFO, "Login successful for $login (sharedpc=$shared)");\r
                }\r
                \r
                return $this->loggedin;\r
        }\r
        \r
        /**\r
-        * MEMBER::cookielogin()\r
+        * Member::cookielogin()\r
         * Login using cookie key\r
         * \r
         * @param       String  $login  not used\r
@@ -240,18 +269,33 @@ class MEMBER
                {\r
                        /* Cookie Authentication */\r
                        $ck = cookieVar("{$CONF['CookiePrefix']}loginkey");\r
-                       \r
+                               \r
                        /* TODO: validation for each cookie values */\r
-                       \r
+                               \r
                        /* limiting the length of password to avoid hash collision */\r
                        $ck = i18n::substr($ck,0,32);\r
-                       if ( $CONF['secureCookieKey']!=='none' )\r
+                               \r
+                       /* \r
+                        * generate cookie salt from secure cookie key settings\r
+                       * (either 'none', 0, 8, 16, 24, or 32)\r
+                       */\r
+                       if ( !$this->cookie_salt )\r
+                       {\r
+                               $salt = 0;\r
+                               if ( array_key_exists('secureCookieKey', $CONF) )\r
+                               {\r
+                                       $salt = $CONF['secureCookieKey'];\r
+                               }\r
+                               $this->set_cookie_salt($salt);\r
+                       }\r
+                       \r
+                       if ( $this->cookie_salt !== 'none' )\r
                        {\r
-                               $ck = $this->hash("{$ck}{$CONF['secureCookieKeyIP']}");\r
+                               $ck = $this->hash($ck . $this->cookie_salt);\r
                        }\r
                        $this->loggedin = ( $this->readFromName(cookieVar("{$CONF['CookiePrefix']}user")) && $this->checkCookieKey($ck) );\r
                        unset($ck);\r
-                       \r
+                               \r
                        /* renew cookies when not on a shared computer */\r
                        if ( $this->loggedin && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) )\r
                        {\r
@@ -263,7 +307,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::logout()\r
+        * Member::logout()\r
         * logout and expire cookie\r
         * \r
         * @param       Void\r
@@ -286,7 +330,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::isLoggedIn()\r
+        * Member::isLoggedIn()\r
         * return member is loggedin or not\r
         * \r
         * @param       Void\r
@@ -299,7 +343,7 @@ class MEMBER
        \r
        /**\r
         * MEMBER:read()\r
-        * Read member information from the database \r
+        * Read member information from the database\r
         * \r
         * @param       String  $where  where statement\r
         * @return      Resource        SQL resource\r
@@ -310,27 +354,26 @@ class MEMBER
                // read info\r
                $query =  'SELECT * FROM '.sql_table('member') . ' WHERE ' . $where;\r
                \r
-               $res = sql_query($query);\r
-               $obj = sql_fetch_object($res);\r
-               \r
-               $this->setRealName($obj->mrealname);\r
-               $this->setEmail($obj->memail);\r
-               $this->password = $obj->mpassword;\r
-               $this->setCookieKey($obj->mcookiekey);\r
-               $this->setURL($obj->murl);\r
-               $this->setDisplayName($obj->mname);\r
-               $this->setAdmin($obj->madmin);\r
-               $this->id = $obj->mnumber;\r
-               $this->setCanLogin($obj->mcanlogin);\r
-               $this->setNotes($obj->mnotes);\r
-               $this->setLocale($obj->mlocale);\r
-               $this->setAutosave($obj->mautosave);\r
-               \r
-               return sql_num_rows($res);\r
+               $row = DB::getRow($query);\r
+               \r
+               $this->setRealName($row['mrealname']);\r
+               $this->setEmail($row['memail']);\r
+               $this->password = $row['mpassword'];\r
+               $this->setCookieKey($row['mcookiekey']);\r
+               $this->setURL($row['murl']);\r
+               $this->setDisplayName($row['mname']);\r
+               $this->setAdmin($row['madmin']);\r
+               $this->id = $row['mnumber'];\r
+               $this->setCanLogin($row['mcanlogin']);\r
+               $this->setNotes($row['mnotes']);\r
+               $this->setLocale($row['mlocale']);\r
+               $this->setAutosave($row['mautosave']);\r
+               \r
+               return $row ? TRUE : FALSE;\r
        }\r
        \r
        /**\r
-        * MEMBER::isBlogAdmin()\r
+        * Member::isBlogAdmin()\r
         * Returns true if member is an admin for the given blog\r
         * (returns false if not a team member)\r
         * \r
@@ -341,17 +384,17 @@ class MEMBER
        public function isBlogAdmin($blogid)\r
        {\r
                $query = 'SELECT tadmin FROM '.sql_table('team').' WHERE'\r
-                          . ' tblog=' . intval($blogid)\r
-                          . ' and tmember='. $this->getID();\r
-               $res = sql_query($query);\r
-               if ( sql_num_rows($res) == 0 )\r
-                       return 0;\r
+               . ' tblog=' . intval($blogid)\r
+               . ' and tmember='. $this->getID();\r
+               $res = DB::getValue($query);\r
+               if ( $res )\r
+                       return ($res == 1);\r
                else\r
-                       return ( sql_result($res,0,0) == 1 );\r
+                       return 0;\r
        }\r
        \r
        /**\r
-        * MEMBER::blogAdminRights()\r
+        * Member::blogAdminRights()\r
         * \r
         * @param       integer $blogid ID of target weblog\r
         * @return      boolean whether to have admin rights to the weblog or not\r
@@ -363,7 +406,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::teamRights()\r
+        * Member::teamRights()\r
         * \r
         * @param       integer $blogid ID of target weblog\r
         * @return      boolean whether to have admin right to the weblog or not\r
@@ -373,9 +416,9 @@ class MEMBER
        {\r
                return ($this->isAdmin() || $this->isTeamMember($blogid));\r
        }\r
-\r
+       \r
        /**\r
-        * MEMBER::isTeamMember()\r
+        * Member::isTeamMember()\r
         * Returns true if this member is a team member of the given blog\r
         * \r
         * @param       integer $blogid ID of target weblog\r
@@ -387,12 +430,12 @@ class MEMBER
                $query = 'SELECT * FROM '.sql_table('team').' WHERE'\r
                           . ' tblog=' . intval($blogid)\r
                           . ' and tmember='. $this->getID();\r
-               $res = sql_query($query);\r
-               return (sql_num_rows($res) != 0);\r
+               $res = DB::getResult($query);\r
+               return ($res->rowCount() != 0);\r
        }\r
        \r
        /**\r
-        * MEMBER::canAddItem()\r
+        * Member::canAddItem()\r
         * \r
         * @param       integer $catid  ID of target category\r
         * @return      boolean whether to be able to add items to the category or not\r
@@ -405,7 +448,7 @@ class MEMBER
                // if this is a 'newcat' style newcat\r
                // no blog admin of destination blog -> NOK\r
                // blog admin of destination blog -> OK\r
-               if ( strstr($catid,'newcat') )\r
+               if ( i18n::strpos($catid,'newcat') === 0 )\r
                {\r
                        // get blogid\r
                        list($blogid) = sscanf($catid,"newcat-%d");\r
@@ -431,7 +474,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::canAlterComment()\r
+        * Member::canAlterComment()\r
         * Returns true if this member can edit/delete a commentitem. This can be in the\r
         * following cases:\r
         *        - member is a super-admin\r
@@ -449,18 +492,17 @@ class MEMBER
                {\r
                        return 1;\r
                }\r
-       \r
+               \r
                $query =  'SELECT citem as itemid, iblog as blogid, cmember as cauthor, iauthor'\r
                           . ' FROM '.sql_table('comment') .', '.sql_table('item').', '.sql_table('blog')\r
                           . ' WHERE citem=inumber and iblog=bnumber and cnumber=' . intval($commentid);\r
-               $res = sql_query($query);\r
-               $obj = sql_fetch_object($res);\r
-       \r
-               return ($obj->cauthor == $this->getID()) or $this->isBlogAdmin($obj->blogid) or ($obj->iauthor == $this->getID());\r
+               $res = DB::getRow($query);\r
+               \r
+               return ($res['cauthor'] == $this->getID()) or $this->isBlogAdmin($res['blogid']) or ($res['iauthor'] == $this->getID());\r
        }\r
        \r
        /**\r
-        * MEMBER::canAlterItem()\r
+        * Member::canAlterItem()\r
         * Returns true if this member can edit/delete an item. This is true in the following\r
         * cases: - member is a super-admin\r
         *             - member is the author of the item\r
@@ -473,15 +515,14 @@ class MEMBER
        public function canAlterItem($itemid)\r
        {\r
                if ($this->isAdmin()) return 1;\r
-\r
+               \r
                $query =  'SELECT iblog, iauthor FROM '.sql_table('item').' WHERE inumber=' . intval($itemid);\r
-               $res = sql_query($query);\r
-               $obj = sql_fetch_object($res);\r
-               return ($obj->iauthor == $this->getID()) or $this->isBlogAdmin($obj->iblog);\r
+               $res = DB::getRow($query);\r
+               return ($res['iauthor'] == $this->getID()) or $this->isBlogAdmin($res['iblog']);\r
        }\r
-\r
+       \r
        /**\r
-        * MEMBER::canBeDeleted()\r
+        * Member::canBeDeleted()\r
         * Return true if member can be deleted. This means that there are no items posted by the member left\r
         * \r
         * @param       void\r
@@ -490,15 +531,15 @@ class MEMBER
         */\r
        public function canBeDeleted()\r
        {\r
-               $res = sql_query('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());\r
-               return ( sql_num_rows($res) == 0 );\r
+               $res = DB::getResult('SELECT * FROM '.sql_table('item').' WHERE iauthor=' . $this->getID());\r
+               return ( $res->rowCount() == 0 );\r
        }\r
-\r
+       \r
        /**\r
-        * MEMBER::canUpdateItem()\r
+        * Member::canUpdateItem()\r
         * returns true if this member can move/update an item to a given category,\r
         * false if not (see comments fot the tests that are executed)\r
-        *\r
+        * \r
         * @param       integer $itemid\r
         * @param       string  $newcat (can also be of form 'newcat-x' with x=blogid)\r
         * @return      boolean whether being able to update the item or not\r
@@ -507,9 +548,9 @@ class MEMBER
        public function canUpdateItem($itemid, $newcat)\r
        {\r
                global $manager;\r
-\r
+               \r
                // item does not exists -> NOK\r
-               if ( !$manager->existsItem($itemid,1,1) )\r
+               if ( !$manager->existsItem($itemid, 1, 1) )\r
                {\r
                        return 0;\r
                }\r
@@ -523,10 +564,10 @@ class MEMBER
                // if this is a 'newcat' style newcat\r
                // no blog admin of destination blog -> NOK\r
                // blog admin of destination blog -> OK\r
-               if (strstr($newcat,'newcat'))\r
+               if ( i18n::strpos($newcat, 'newcat') === 0 )\r
                {\r
                        // get blogid\r
-                       list($blogid) = sscanf($newcat,'newcat-%d');\r
+                       list($blogid) = sscanf($newcat, 'newcat-%d');\r
                        return $this->blogAdminRights($blogid);\r
                }\r
                \r
@@ -537,7 +578,7 @@ class MEMBER
                }\r
                \r
                // get item\r
-               $item =& $manager->getItem($itemid,1,1);\r
+               $item =& $manager->getItem($itemid, 1, 1);\r
                \r
                // old catid = new catid -> OK\r
                if ($item['catid'] == $newcat)\r
@@ -546,14 +587,15 @@ class MEMBER
                }\r
                \r
                // not a valid category -> NOK\r
-               $validCat = quickQuery('SELECT COUNT(*) AS result FROM '.sql_table('category').' WHERE catid='.intval($newcat));\r
+               $validCat = DB::getValue('SELECT COUNT(*) AS result FROM '.sql_table('category').' WHERE catid='.intval($newcat));\r
                if ( !$validCat )\r
                {\r
                        return 0;\r
                }\r
                \r
                // get destination blog\r
-               $source_blogid = getBlogIDFromItemID($itemid);\r
+               $item =& $manager->getItem($itemid, 1, 1);\r
+               $source_blogid = $item['blogid'];\r
                $dest_blogid = getBlogIDFromCatID($newcat);\r
                \r
                // not a team member of destination blog -> NOK\r
@@ -579,9 +621,9 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::setCookies()\r
+        * Member::setCookies()\r
         * Sets the cookies for the member\r
-        *\r
+        * \r
         * @param boolean       $shared set this to 1 when using a shared computer. Cookies will expire\r
         *                              at the end of the session in this case.\r
         * @return      void\r
@@ -612,7 +654,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::sendActivationLink()\r
+        * Member::sendActivationLink()\r
         * Send activation mail\r
         * \r
         * @param       string  $type   activation type\r
@@ -659,18 +701,18 @@ class MEMBER
                        'activationDays' => $CONF['ActivationDays']\r
                );\r
                \r
-               $message = TEMPLATE::fill($message, $aVars);\r
-               $subject = TEMPLATE::fill($subject, $aVars);\r
+               $message = Template::fill($message, $aVars);\r
+               $subject = Template::fill($subject, $aVars);\r
                \r
                // send mail\r
                NOTIFICATION::mail($this->getEmail(), $subject ,$message, $CONF['AdminEmail'], i18n::get_current_charset());\r
                \r
-               ACTIONLOG::add(INFO, _ACTIONLOG_ACTIVATIONLINK . ' (' . $this->getDisplayName() . ' / type: ' . $type . ')');\r
+               ActionLog::add(INFO, _ACTIONLOG_ACTIVATIONLINK . ' (' . $this->getDisplayName() . ' / type: ' . $type . ')');\r
                return;\r
        }\r
        \r
        /**\r
-        * MEMBER::getAdminBlogs()\r
+        * Member::getAdminBlogs()\r
         * Returns an array of all blogids for which member has admin rights\r
         * \r
         * @param       void\r
@@ -690,19 +732,19 @@ class MEMBER
                        $query = 'SELECT tblog as blogid from '.sql_table('team').' where tadmin=1 and tmember=' . $this->getID();\r
                }\r
                \r
-               $res = sql_query($query);\r
-               if ( sql_num_rows($res) > 0 )\r
+               $res = DB::getResult($query);\r
+               if ( $res->rowCount() > 0 )\r
                {\r
-                       while ( $obj = sql_fetch_object($res) )\r
+                       foreach ( $res as $row )\r
                        {\r
-                               array_push($blogs, $obj->blogid);\r
+                               array_push($blogs, $row['blogid']);\r
                        }\r
                }\r
                return $blogs;\r
        }\r
        \r
        /**\r
-        * MEMBER::getTeamBlogs()\r
+        * Member::getTeamBlogs()\r
         * Returns an array of all blogids for which member has team rights\r
         * \r
         * @param       boolean $incAdmin       whether checking weblog admin rights or not\r
@@ -723,24 +765,24 @@ class MEMBER
                        $query = 'SELECT tblog as blogid from '.sql_table('team').' where tmember=' . $this->getID();\r
                }\r
                \r
-               $res = sql_query($query);\r
-               if ( sql_num_rows($res) > 0 )\r
+               $res = DB::getResult($query);\r
+               if ( $res->rowCount() > 0 )\r
                {\r
-                       while ( $obj = sql_fetch_object($res) )\r
+                       foreach ( $res as $row )\r
                        {\r
-                               array_push($blogs, $obj->blogid);\r
+                               array_push($blogs, $row['blogid']);\r
                        }\r
                }\r
                return $blogs;\r
        }\r
        \r
        /**\r
-        * MEMBER::getNotifyFromMailAddress()\r
+        * Member::getNotifyFromMailAddress()\r
         * \r
         * Returns an email address from which notification of commenting/karma voting can\r
         * be sent. A suggestion can be given for when the member is not logged in\r
         * \r
-        * @param       String  $suggest        \r
+        * @param       String  $suggest\r
         * @return      String  mail address or suggestion\r
         */\r
        public function getNotifyFromMailAddress($suggest = "")\r
@@ -758,9 +800,9 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::write()\r
+        * Member::write()\r
         * Write data to database\r
-        *\r
+        * \r
         * @param       void\r
         * @return      void\r
         * \r
@@ -768,19 +810,19 @@ class MEMBER
        public function write()\r
        {\r
                $query =  'UPDATE '.sql_table('member')\r
-                       . " SET mname='" . sql_real_escape_string($this->getDisplayName()) . "', "\r
-                          . "mrealname='". sql_real_escape_string($this->getRealName()) . "', "\r
-                          . "mpassword='". sql_real_escape_string($this->getPassword()) . "', "\r
-                          . "mcookiekey='". sql_real_escape_string($this->getCookieKey()) . "', "\r
-                          . "murl='" . sql_real_escape_string($this->getURL()) . "', "\r
-                          . "memail='" . sql_real_escape_string($this->getEmail()) . "', "\r
-                          . "madmin=" . $this->isAdmin() . ", "\r
-                          . "mnotes='" . sql_real_escape_string($this->getNotes()) . "', "\r
-                          . "mcanlogin=" . $this->canLogin() . ", "\r
-                          . "mlocale='" . sql_real_escape_string($this->getLocale()) . "', "\r
-                          . "mautosave=" . intval($this->getAutosave()) . " "\r
-                       . "WHERE mnumber=" . $this->getID();\r
-               sql_query($query);\r
+                       . ' SET mname=' . DB::quoteValue($this->displayname) . ', '\r
+                          . 'mrealname='. DB::quoteValue($this->realname) . ', '\r
+                          . 'mpassword='. DB::quoteValue($this->password) . ', '\r
+                          . 'mcookiekey='. DB::quoteValue($this->cookiekey) . ', '\r
+                          . 'murl=' . DB::quoteValue($this->url) . ', '\r
+                          . 'memail=' . DB::quoteValue($this->email) . ', '\r
+                          . 'madmin=' . intval($this->admin) . ', '\r
+                          . 'mnotes=' . DB::quoteValue($this->notes) . ', '\r
+                          . 'mcanlogin=' . intval($this->canlogin) . ', '\r
+                          . 'mlocale=' . DB::quoteValue($this->locale) . ', '\r
+                          . 'mautosave=' . intval($this->autosave) . ' '\r
+                       . 'WHERE mnumber=' . intval($this->id);\r
+               DB::execute($query);\r
                return;\r
        }\r
        \r
@@ -791,7 +833,12 @@ class MEMBER
        \r
        public function checkPassword($pw)\r
        {\r
-               return ($this->hash($pw) == $this->getPassword());\r
+               /* for lower compatibility (md5) */\r
+               if ( strlen($this->password) === 32 )\r
+               {\r
+                       return (md5($pw) == $this->password);\r
+               }\r
+               return ($this->hash($pw) == $this->password);\r
        }\r
        \r
        public function getRealName()\r
@@ -830,7 +877,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::newCookieKey()\r
+        * Member::newCookieKey()\r
         * Generate new cookiekey, save it, and return it\r
         * \r
         * @param       void\r
@@ -867,7 +914,7 @@ class MEMBER
        \r
        public function setLocale($locale)\r
        {\r
-               if ( !!preg_match('#^(.+)_(.+)_(.+)$#', $locale)\r
+               if ( !preg_match('#^(.+)_(.+)_(.+)$#', $locale)\r
                 && ($locale = i18n::convert_old_language_file_name_to_locale($locale)) === FALSE )\r
                {\r
                        $locale = '';\r
@@ -928,7 +975,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::getID()\r
+        * Member::getID()\r
         * \r
         * @param       void\r
         * @return      integer id of this member object\r
@@ -940,7 +987,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::exists()\r
+        * Member::exists()\r
         * Returns true if there is a member with the given login name\r
         * \r
         * @static\r
@@ -949,14 +996,14 @@ class MEMBER
         */\r
        public static function exists($name)\r
        {\r
-               $r = sql_query('select * FROM '.sql_table('member')." WHERE mname='".sql_real_escape_string($name)."'");\r
-               return ( sql_num_rows($r) != 0 );\r
+               $r = DB::getResult('SELECT * FROM ' . sql_table('member') . ' WHERE mname=' . DB::quoteValue($name));\r
+               return ( $r->rowCount() != 0 );\r
        }\r
        \r
        /**\r
-        * MEMBER::existsID()\r
+        * Member::existsID()\r
         * Returns true if there is a member with the given ID\r
-        *\r
+        * \r
         * @static\r
         * @param       integer $id     target id\r
         * @return      boolean whether target id exists or not\r
@@ -964,12 +1011,12 @@ class MEMBER
         */\r
        public static function existsID($id)\r
        {\r
-               $r = sql_query('select * FROM '.sql_table('member')." WHERE mnumber='".intval($id)."'");\r
-               return (sql_num_rows($r) != 0);\r
+               $r = DB::getResult('SELECT * FROM ' . sql_table('member') . ' WHERE mnumber=' . intval($id));\r
+               return ( $r->rowCount() != 0 );\r
        }\r
        \r
        /**\r
-        * MEMBER::isNameProtected()\r
+        * Member::isNameProtected()\r
         *  Checks if a username is protected.\r
         *  If so, it can not be used on anonymous comments\r
         * \r
@@ -982,11 +1029,11 @@ class MEMBER
                // extract name\r
                $name = strip_tags($name);\r
                $name = trim($name);\r
-               return MEMBER::exists($name);\r
+               return self::exists($name);\r
        }\r
        \r
        /**\r
-        * MEMBER::create()\r
+        * Member::create()\r
         * Adds a new member\r
         * \r
         * @static\r
@@ -1000,19 +1047,20 @@ class MEMBER
         * @param       String  $notes\r
         * @return      String  1 if success, others if fail\r
         */\r
-       static public  function create($name, $realname, $password, $email, $url, $admin, $canlogin, $notes)\r
+       static public function create($name, $realname, $password, $email, $url, $admin, $canlogin, $notes)\r
        {\r
                if ( !NOTIFICATION::address_validation($email) )\r
                {\r
                        return _ERROR_BADMAILADDRESS;\r
                }\r
                \r
+               /* TODO: this method should be in MEMBER class, not globalfunctions */\r
                if ( !isValidDisplayName($name) )\r
                {\r
                        return _ERROR_BADNAME;\r
                }\r
                \r
-               if ( MEMBER::exists($name) )\r
+               if ( self::exists($name) )\r
                {\r
                        return _ERROR_NICKNAMEINUSE;\r
                }\r
@@ -1022,12 +1070,13 @@ class MEMBER
                        return _ERROR_REALNAMEMISSING;\r
                }\r
                \r
+               /* TODO: check the number of characters */\r
                if ( !$password )\r
                {\r
                        return _ERROR_PASSWORDMISSING;\r
                }\r
                \r
-               /*\r
+               /* \r
                 *  begin if: sometimes user didn't prefix the URL with http:// or https://,\r
                 *  this cause a malformed URL. Let's fix it.\r
                 */\r
@@ -1037,29 +1086,31 @@ class MEMBER
                        $url = 'http://' . $url;\r
                }\r
                \r
-               $name           = sql_real_escape_string($name);\r
-               $realname       = sql_real_escape_string($realname);\r
-               $password       = sql_real_escape_string($this->hash($password));\r
-               $email          = sql_real_escape_string($email);\r
-               $url            = sql_real_escape_string($url);\r
+               $name           = DB::quoteValue($name);\r
+               $realname       = DB::quoteValue($realname);\r
+               /* NOTE: hashed password is automatically updated if the length is 32 bytes when logging in */\r
+               $password       = DB::quoteValue(md5($password));\r
+               $email          = DB::quoteValue($email);\r
+               $url            = DB::quoteValue($url);\r
                $admin          = (integer) $admin;\r
                $canlogin       = (integer) $canlogin;\r
-               $notes          = sql_real_escape_string($notes);\r
+               $notes          = DB::quoteValue($notes);\r
                \r
-               $query = 'INSERT INTO ' . sql_table('member')\r
-                      . " (MNAME,MREALNAME,MPASSWORD,MEMAIL,MURL, MADMIN, MCANLOGIN, MNOTES) "\r
-                      . "VALUES ('$name','$realname','$password','$email','$url',$admin, $canlogin, '$notes')";\r
-               sql_query($query);\r
+               $query = "INSERT INTO %s"\r
+                      . " (MNAME,MREALNAME,MPASSWORD,MEMAIL,MURL, MADMIN, MCANLOGIN, MNOTES)"\r
+                      . " VALUES (%s, %s, %s, %s, %s, %d, %d, %s)";\r
+               $query = sprintf($query, sql_table('member'), $name, $realname, $password, $email, $url, $admin, $canlogin, $notes);\r
+               DB::execute($query);\r
                \r
-               ACTIONLOG::add(INFO, _ACTIONLOG_NEWMEMBER . ' ' . $name);\r
+               ActionLog::add(INFO, _ACTIONLOG_NEWMEMBER . ' ' . $name);\r
                \r
                return 1;\r
        }\r
        \r
        /**\r
-        * MEMBER::getActivationInfo()\r
+        * Member::getActivationInfo()\r
         * Returns activation info for a certain key (an object with properties vkey, vmember, ...)\r
-        *\r
+        * \r
         * @static\r
         * @param       string  $key    activation key\r
         * @return      mixed   return 0 if failed, else return activation table object\r
@@ -1067,21 +1118,21 @@ class MEMBER
         */\r
        public static function getActivationInfo($key)\r
        {\r
-               $query = 'SELECT * FROM ' . sql_table('activation') . ' WHERE vkey=\'' . sql_real_escape_string($key). '\'';\r
-               $res = sql_query($query);\r
+               $query = 'SELECT * FROM ' . sql_table('activation') . ' WHERE vkey=' . DB::quoteValue($key);\r
+               $res = DB::getResult($query);\r
                \r
-               if ( !$res || (sql_num_rows($res) == 0) )\r
+               if ( !$res || ($res->rowCount() == 0) )\r
                {\r
                        return 0;\r
                }\r
-               return sql_fetch_object($res);\r
+               return $res->fetch();\r
        }\r
        \r
        /**\r
-        * MEMBER::generateActivationEntry()\r
+        * Member::generateActivationEntry()\r
         * Creates an account activation key\r
         * addresschange -> old email address\r
-        *\r
+        * \r
         * @param       string  $type   one of the following values (determines what to do when activation expires)\r
         *                              'register'      (new member registration)\r
         *                              'forgot'        (forgotton password)\r
@@ -1096,7 +1147,7 @@ class MEMBER
                \r
                // kill any existing entries for the current member (delete is ok)\r
                // (only one outstanding activation key can be present for a member)\r
-               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vmember=' . intval($this->getID()));\r
+               DB::execute('DELETE FROM ' . sql_table('activation') . ' WHERE vmember=' . intval($this->getID()));\r
                \r
                // indicates if the member can log in while the link is active\r
                $canLoginWhileActive = false;\r
@@ -1121,9 +1172,16 @@ class MEMBER
                        \r
                        // attempt to add entry in database\r
                        // add in database as non-active\r
-                       $query = 'INSERT INTO ' . sql_table('activation'). ' (vkey, vtime, vmember, vtype, vextra) ';\r
-                       $query .= 'VALUES (\'' . sql_real_escape_string($key). '\', \'' . date('Y-m-d H:i:s',time()) . '\', \'' . intval($this->getID()). '\', \'' . sql_real_escape_string($type). '\', \'' . sql_real_escape_string($extra). '\')';\r
-                       if ( sql_query($query) )\r
+                       $query = 'INSERT INTO %s (vkey, vtime, vmember, vtype, vextra) VALUES (%s, %s, %d, %s, %s)';\r
+                       $query = sprintf($query\r
+                               , sql_table('activation')\r
+                               , DB::quoteValue($key)\r
+                               , DB::formatDateTime()\r
+                               , intval($this->getID())\r
+                               , DB::quoteValue($type)\r
+                               , DB::quoteValue($extra)\r
+                       );\r
+                       if ( DB::execute($query) !== FALSE )\r
                                $ok = true;\r
                }\r
                \r
@@ -1139,7 +1197,7 @@ class MEMBER
        }\r
        \r
        /**\r
-        * MEMBER::activate()\r
+        * Member::activate()\r
         * Inidicates that an activation link has been clicked and any forms displayed\r
         * there have been successfully filled out.\r
         * \r
@@ -1150,7 +1208,7 @@ class MEMBER
        public function activate($key)\r
        {\r
                // get activate info\r
-               $info = MEMBER::getActivationInfo($key);\r
+               $info = self::getActivationInfo($key);\r
                \r
                // no active key\r
                if ( !$info )\r
@@ -1158,7 +1216,7 @@ class MEMBER
                        return false;\r
                }\r
                \r
-               switch ( $info->vtype )\r
+               switch ( $info['vtype'] )\r
                {\r
                        case 'forgot':\r
                                // nothing to do\r
@@ -1166,27 +1224,27 @@ class MEMBER
                        case 'register':\r
                                // set canlogin value\r
                                global $CONF;\r
-                               sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($CONF['NewMemberCanLogon']). ' WHERE mnumber=' . intval($info->vmember));\r
+                               DB::execute('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($CONF['NewMemberCanLogon']). ' WHERE mnumber=' . intval($info['vmember']));\r
                                break;\r
                        case 'addresschange':\r
                                // reset old 'canlogin' value\r
-                               list($oldEmail, $oldCanLogin) = i18n::explode('/', $info->vextra);\r
-                               sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ' WHERE mnumber=' . intval($info->vmember));\r
+                               list($oldEmail, $oldCanLogin) = preg_split('#/#', $info['vextra']);\r
+                               DB::execute('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ' WHERE mnumber=' . intval($info['vmember']));\r
                                break;\r
                }\r
                \r
                // delete from activation table\r
-               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vkey=\'' . sql_real_escape_string($key) . '\'');\r
+               DB::execute('DELETE FROM ' . sql_table('activation') . ' WHERE vkey=' . DB::quoteValue($key));\r
                \r
                // success!\r
                return true;\r
        }\r
        \r
        /**\r
-        * MEMBER::cleanupActivationTable()\r
+        * Member::cleanupActivationTable()\r
         * Cleans up entries in the activation table. All entries older than 2 days are removed.\r
         * (static)\r
-        *\r
+        * \r
         * @param       void\r
         * @return      void\r
         */\r
@@ -1204,22 +1262,23 @@ class MEMBER
                $boundary = time() - (60 * 60 * 24 * $actdays);\r
                \r
                // 1. walk over all entries, and see if special actions need to be performed\r
-               $res = sql_query('SELECT * FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');\r
+               $query = sprintf('SELECT * FROM %s WHERE vtime < %s', sql_table('activation'), DB::formatDateTime($boundary));\r
+               $res = DB::getResult($query);\r
                \r
-               while ( $o = sql_fetch_object($res) )\r
+               foreach ( $res as $row )\r
                {\r
-                       switch ( $o->vtype )\r
+                       switch ( $row['vtype'] )\r
                        {\r
                                case 'register':\r
                                        // delete all information about this site member. registration is undone because there was\r
                                        // no timely activation\r
                                        include_once($DIR_LIBS . 'ADMIN.php');\r
-                                       ADMIN::deleteOneMember(intval($o->vmember));\r
+                                       Admin::deleteOneMember(intval($row['vmember']));\r
                                        break;\r
                                case 'addresschange':\r
                                        // revert the e-mail address of the member back to old address\r
-                                       list($oldEmail, $oldCanLogin) = i18n::explode('/', $o->vextra);\r
-                                       sql_query('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ', memail=\'' . sql_real_escape_string($oldEmail). '\' WHERE mnumber=' . intval($o->vmember));\r
+                                       list($oldEmail, $oldCanLogin) = preg_split('#/#', $row['vextra']);\r
+                                       DB::execute('UPDATE ' . sql_table('member') . ' SET mcanlogin=' . intval($oldCanLogin). ', memail=' . DB::quoteValue($oldEmail). ' WHERE mnumber=' . intval($row['vmember']));\r
                                        break;\r
                                case 'forgot':\r
                                        // delete the activation link and ignore. member can request a new password using the\r
@@ -1229,12 +1288,13 @@ class MEMBER
                }\r
                \r
                // 2. delete activation entries for real\r
-               sql_query('DELETE FROM ' . sql_table('activation') . ' WHERE vtime < \'' . date('Y-m-d H:i:s',$boundary) . '\'');\r
+               $query = sprintf('DELETE FROM %s WHERE vtime < %s', sql_table('activation'), DB::formatDateTime($boundary));\r
+               DB::execute($query);\r
                return;\r
        }\r
        \r
        /**\r
-        * MEMBER::$language\r
+        * Member::$language\r
         * \r
         * @obsolete\r
         * @param       void\r
@@ -1243,7 +1303,7 @@ class MEMBER
         */\r
        public $language = '';\r
        /**\r
-        * MEMBER::getLanguage()\r
+        * Member::getLanguage()\r
         * \r
         * @obsolete\r
         * @param       void\r
@@ -1259,4 +1319,3 @@ class MEMBER
                return $language;\r
        }\r
 }\r
-\r