OSDN Git Service

Shift_JIS support for mobile phone.
[nucleus-jp/nucleus-jp-ancient.git] / nucleus / libs / globalfunctions.php
index 607cfbb..bba7806 100755 (executable)
 /**
  * @license http://nucleuscms.org/license.txt GNU General Public License
  * @copyright Copyright (C) 2002-2007 The Nucleus Group
- * @version $Id: globalfunctions.php,v 1.20 2007-04-04 20:59:34 kmorimatsu Exp $
- * $NucleusJP: globalfunctions.php,v 1.19 2007/03/22 03:30:14 kmorimatsu Exp $
+ * @version $Id: globalfunctions.php,v 1.24 2008-02-08 09:31:22 kimitake Exp $
+ * $NucleusJP: globalfunctions.php,v 1.23.2.7 2008/02/05 08:30:08 kimitake Exp $
  */
 
 // needed if we include globalfunctions from install.php
 global $nucleus, $CONF, $DIR_LIBS, $DIR_LANG, $manager, $member;
 
-//$nucleus['version'] = 'v3.3SVN';
-//$nucleus['codename'] = 'Lithium';
-$nucleus['version'] = 'v3.3';
+$nucleus['version'] = 'v3.4';
 $nucleus['codename'] = '';
 
 checkVars(array('nucleus', 'CONF', 'DIR_LIBS', 'MYSQL_HOST', 'MYSQL_USER', 'MYSQL_PASSWORD', 'MYSQL_DATABASE', 'DIR_LANG', 'DIR_PLUGINS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_COOKIE_VARS', 'HTTP_ENV_VARS', 'HTTP_SESSION_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS', 'GLOBALS', 'argv', 'argc', '_GET', '_POST', '_COOKIE', '_ENV', '_SESSION', '_SERVER', '_FILES'));
@@ -36,7 +34,7 @@ if ($CONF['debug']) {
 
 // Avoid notices
 if (!isset($CONF['Self'])) {
-       $CONF['Self'] = $_SERVER['PHP_SELF'];
+       $CONF['Self'] = htmlspecialchars($_SERVER['PHP_SELF'],ENT_QUOTES);
 }
 
 /*
@@ -171,6 +169,25 @@ if (($CONF['DisableJsTools'] == 0) && strstr(serverVar('HTTP_USER_AGENT'), 'Mozi
 // login if cookies set
 $member = new MEMBER();
 
+// secure cookie key settings (either 'none', 0, 8, 16, 24, or 32)
+if (!isset($CONF['secureCookieKey'])) $CONF['secureCookieKey']=24;
+switch($CONF['secureCookieKey']){
+case 8:
+       $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
+       break;
+case 16:
+       $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
+       break;
+case 24:
+       $CONF['secureCookieKeyIP']=preg_replace('/\.[0-9]+$/','',serverVar('REMOTE_ADDR'));
+       break;
+case 32:
+       $CONF['secureCookieKeyIP']=serverVar('REMOTE_ADDR');
+       break;
+default:
+       $CONF['secureCookieKeyIP']='';
+}
+
 // login/logout when required or renew cookies
 if ($action == 'login') {
        // Form Authentication
@@ -178,11 +195,19 @@ if ($action == 'login') {
        $pw = postVar('password');
        $shared = intPostVar('shared'); // shared computer or not
 
+       $pw=substr($pw,0,40); // avoid md5 collision by using a long key
+
        if ($member->login($login, $pw) ) {
 
                $member->newCookieKey();
                $member->setCookies($shared);
 
+               if ($CONF['secureCookieKey']!=='none') {
+                       // secure cookie key
+                       $member->setCookieKey(md5($member->getCookieKey().$CONF['secureCookieKeyIP']));
+                       $member->write();
+               }
+
                // allows direct access to parts of the admin area after logging in
                if ($nextaction) {
                        $action = $nextaction;
@@ -229,10 +254,16 @@ Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for det
        $manager->notify('Logout', array('username' => cookieVar($CONF['CookiePrefix'] . 'user') ) );
 } elseif (cookieVar($CONF['CookiePrefix'] . 'user') ) {
        // Cookie Authentication
-       $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), cookieVar($CONF['CookiePrefix'] . 'loginkey') );
+       $ck=cookieVar($CONF['CookiePrefix'] . 'loginkey');
+       // secure cookie key
+       $ck=substr($ck,0,32); // avoid md5 collision by using a long key
+       if ($CONF['secureCookieKey']!=='none') $ck=md5($ck.$CONF['secureCookieKeyIP']);
+       $res = $member->cookielogin(cookieVar($CONF['CookiePrefix'] . 'user'), $ck );
+       unset($ck);
 
        // renew cookies when not on a shared computer
        if ($res && (cookieVar($CONF['CookiePrefix'] . 'sharedpc') != 1) && (!headers_sent() ) ) {
+               $member->setCookieKey(cookieVar($CONF['CookiePrefix'] . 'loginkey'));
                $member->setCookies();
        }
 }
@@ -276,6 +307,13 @@ if (!headers_sent() ) {
 $language = getLanguageName();
 include($DIR_LANG . ereg_replace( '[\\|/]', '', $language) . '.php');
 
+// check if valid charset\r
+if (!encoding_check(false,false,_CHARSET)) {\r
+       foreach(array($_REQUEST, $_SERVER) as $input) {\r
+               array_walk($input, 'encoding_check');\r
+       }\r
+}\r
+\r
 /*
        Backed out for now: See http://forum.nucleuscms.org/viewtopic.php?t=3684 for details
 
@@ -432,7 +470,7 @@ function intCookieVar($name) {
   * returns the currently used version (100 = 1.00, 101 = 1.01, etc...)
   */
 function getNucleusVersion() {
-       return 330;
+       return 340;
 }
 
 /**
@@ -520,6 +558,13 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
                } else {
                        header('Content-Type: ' . $contenttype);
                }
+\r
+               // check if valid charset\r
+               if (!encoding_check(false,false,$charset)) {\r
+                       foreach(array($_REQUEST, $_SERVER) as $input) {\r
+                               array_walk($input, 'encoding_check');\r
+                       }\r
+               }\r
        }
 }
 
@@ -527,9 +572,11 @@ function sendContentType($contenttype, $pagetype = '', $charset = _CHARSET) {
  * Errors before the database connection has been made
  */
 function startUpError($msg, $title) {
+       if (!defined('_CHARSET')) define('_CHARSET','iso-8859-1');\r
+       header('Content-Type: text/html; charset=' . _CHARSET);\r
        ?>
        <html xmlns="http://www.w3.org/1999/xhtml">
-               <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+               <head><meta http-equiv="Content-Type" content="text/html; charset=<?php echo _CHARSET?>" />\r
                <title><?php echo htmlspecialchars($title)?></title></head>
                <body>
                        <h1><?php echo htmlspecialchars($title)?></h1>
@@ -753,7 +800,7 @@ function selector() {
 //             if ($blogid && (intval($blogid) != $obj->iblog) ) {
 //                     doError(_ERROR_NOSUCHITEM);
 //             }
-               if ($blogid && (intval($blogid) != $obj->iblog)) {
+               if ($blogid && (intval($blogid) != $obj->iblog) ) {
                        if (!headers_sent()) {
                                $b =& $manager->getBlog($obj->iblog);
                                $CONF['ItemURL'] = $b->getURL();
@@ -810,20 +857,20 @@ function selector() {
 
                // get next and prev month links ...
                global $archivenext, $archiveprev, $archivetype, $archivenextexists, $archiveprevexists;
-
+               
                // sql queries for the timestamp of the first and the last published item
-               $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 ORDER BY itime ASC";
-               $first_timestamp=quickQuery ($query); 
-               $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 ORDER BY itime DESC";
-               $last_timestamp=quickQuery ($query); 
+               $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 AND iblog=".(int)($blogid ? $blogid : $CONF['DefaultBlog'])." ORDER BY itime ASC";
+               $first_timestamp=quickQuery ($query);
+               $query = "SELECT UNIX_TIMESTAMP(itime) as result FROM ".sql_table('item')." WHERE idraft=0 AND iblog=".(int)($blogid ? $blogid : $CONF['DefaultBlog'])." ORDER BY itime DESC";
+               $last_timestamp=quickQuery ($query);
 
                sscanf($archive, '%d-%d-%d', $y, $m, $d);
 
                if ($d != 0) {
                        $archivetype = _ARCHIVETYPE_DAY;
                        $t = mktime(0, 0, 0, $m, $d, $y);
-
-                       $archiveprev = strftime('%Y-%m-%d', $t - (24 * 60 * 60) );
+                       // one day has 24 * 60 * 60 = 86400 seconds                     
+                       $archiveprev = strftime('%Y-%m-%d', $t - 86400 );
                        // check for published items                    
                        if ($t > $first_timestamp) {
                                $archiveprevexists = true;
@@ -831,31 +878,29 @@ function selector() {
                        else {
                                $archiveprevexists = false;
                        }
-
+                       
                        // one day later
-//                     $t += 86400; 
-//                     $archivenext = strftime('%Y-%m-%d', $t);
-                       $archivenext = strftime('%Y-%m-%d', $t + (24 * 60 * 60) );
-                       if ($t + (24 * 60 * 60) < $last_timestamp) {
+                       $t += 86400; 
+                       $archivenext = strftime('%Y-%m-%d', $t);
+                       if ($t < $last_timestamp) {
                                $archivenextexists = true;
                        }
                        else {
                                $archivenextexists = false;
                        }
-
+                       
                } else {
                        $archivetype = _ARCHIVETYPE_MONTH;
                        $t = mktime(0, 0, 0, $m, 1, $y);
-
-                       $archiveprev = strftime('%Y-%m', $t - (1 * 24 * 60 * 60) );
+                       // one day before is in the previous month
+                       $archiveprev = strftime('%Y-%m', $t - 86400);
                        if ($t > $first_timestamp) {
                                $archiveprevexists = true;
                        }
                        else {
                                $archiveprevexists = false;
                        }
-
-//                     $archivenext = strftime('%Y-%m', $t + (32 * 24 * 60 * 60) );
+                       
                        // timestamp for the next month                 
                        $t = mktime(0, 0, 0, $m+1, 1, $y);
                        $archivenext = strftime('%Y-%m', $t);
@@ -959,6 +1004,9 @@ function selector() {
 
        // parse the skin
        $skin->parse($type);
+
+       // check to see we should throw JustPosted event
+       $blog->checkJustPosted();
 }
 
 /**
@@ -1463,6 +1511,75 @@ function formatDate($format, $timestamp, $defaultFormat, &$blog) {
        }
 }
 
+function encoding_check($val, $key, $encoding=false, $exclude=false) {\r
+       /*\r
+         When 3rd argument is set, return if checked already.\r
+         When 4th argument is set, set the excluded key(s).\r
+       */\r
+       static $search=false, $checked=array(), $excludes=array();\r
+       if ($exclude!==false) {\r
+               if (is_array($exclude)) {\r
+                       foreach($exclude as $v) $excludes[$v]=true;\r
+               } else $excludes[$excludes]=true;\r
+               return;\r
+       }\r
+       if ($encoding!==false) {\r
+               switch($encoding=strtolower($encoding)){\r
+                       case 'utf-8':\r
+                               $search='/^([\x00-\x7F]+'.\r
+                                       '|[\xC2-\xDF][\x80-\xBF]'.\r
+                                       '|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]'.\r
+                                       '|[\xF0-\xF7][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.\r
+                                       '|[\xF8-\xFB][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF]'.\r
+                                       '|[\xFC-\xFD][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF][\x80-\xBF])*/';\r
+                                       break;\r
+                       case 'euc-jp':\r
+                               $search='/^([\x00-\x7F]+'.\r
+                                       '|[\x8E][\xA0-\xDF]'.\r
+                                       '|[\x8F]?[\xA1-\xFE][\xA1-\xFE])*/';\r
+                               break;\r
+                       case 'gb2312':\r
+                               $search='/^([\x00-\x7F]+'.\r
+                                       '|[\xA1-\xF7][\xA1-\xFE])*/';\r
+                               break;\r
+                       case 'shift_jis':\r
+                               // Note that shift_jis is only supported for output.\r
+                               // Using shift_jis in DB is prohibited.\r
+                               $search='/^([\x00-\x7F\xA1-\xDF]+'.\r
+                                       '|[\x81-\x9F\xE0-\xFC][\x40-\xFC])*/';\r
+                               break;\r
+                       default:\r
+                               $search=false;\r
+                               if (preg_match('/^iso\-8859\-[0-9]{1,2}$/',$encoding)) break;\r
+                               if (preg_match('/^windows\-125[0-8]$/',$encoding)) break;\r
+                               startUpError('<p>Unknown or non-supported encoding.</p>', 'Encoding Error');\r
+                               exit;\r
+               }\r
+               if (isset($checked[$encoding])) return true; // Already checked.\r
+               $checked[$encoding]=true;\r
+       }\r
+       if ($key===false) return false; // Not yet checked.\r
+       if ($search===false) return true; // non-multibyte encoding\r
+       if (isset($excludes[$key])) return true; // This key isn't checked.\r
+       if (is_array($val)) {\r
+               array_walk($val, 'encoding_check');\r
+       } else {\r
+               preg_match($search,$val,$m);\r
+               $val2 = (string)$m[0];\r
+               if (!($val2 === (string)$val)) {\r
+                       startUpError('<p>Invalid input.</p>', 'Input Error');\r
+                       exit;\r
+               }\r
+       }\r
+       preg_match($search,$key,$m);\r
+       $key2 = (string)$m[0];\r
+       if (!($key2 === (string)$key)) {\r
+               startUpError('<p>Invalid input.</p>', 'Input Error');\r
+               exit;\r
+       }\r
+       return true;\r
+}\r
+\r
 function checkVars($aVars) {
        global $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_POST_FILES, $HTTP_SESSION_VARS;
 
@@ -1760,7 +1877,7 @@ function sanitizeArray(&$array)
                if (!in_array($key, $excludeListForSanitization)) {
                                
                        // check value
-                       list($val, $tmp) = explode('\\', $val);
+                       @list($val, $tmp) = explode('\\', $val);
                        
                        // remove control code etc.
                        $val = strtr($val, "\0\r\n<>'\"", "       ");
@@ -1928,7 +2045,7 @@ function getBookmarklet($blogid) {
        $document = 'document';
        $bookmarkletline = "javascript:Q='';x=".$document.";y=window;if(x.selection){Q=x.selection.createRange().text;}else if(y.getSelection){Q=y.getSelection();}else if(x.getSelection){Q=x.getSelection();}wingm=window.open('";
        $bookmarkletline .= $CONF['AdminURL'] . "bookmarklet.php?blogid=$blogid";
-       $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+escape(x.location.href)+'&loglinktitle='+escape(x.title),'nucleusbm','scrollbars=yes,width=600,height=500,left=10,top=10,status=yes,resizable=yes');wingm.focus();";
+       $bookmarkletline .="&logtext='+escape(Q)+'&loglink='+escape(x.location.href)+'&loglinktitle='+escape(x.title),'nucleusbm','scrollbars=yes,width=600,height=550,left=10,top=10,status=yes,resizable=yes');wingm.focus();";
 
        return $bookmarkletline;
 }
@@ -1948,4 +2065,17 @@ function ifset(&$var) {
        return null;
 }
 
-?>
\ No newline at end of file
+/**
+ * Returns number of subscriber to an event
+ *
+ * @param event
+ * @return number of subscriber(s)
+ */
+function numberOfEventSubscriber($event) {
+       $query = 'SELECT COUNT(*) as count FROM ' . sql_table('plugin_event') . ' WHERE event=\'' . $event . '\'';
+       $res = sql_query($query);
+       $obj = mysql_fetch_object($res);
+       return $obj->count;
+}
+
+?>