From b65e0ceb1bc36394e91e512df4cd333db9ad9f28 Mon Sep 17 00:00:00 2001 From: hsur Date: Tue, 10 Jun 2008 14:35:12 +0000 Subject: [PATCH] v1.1.1 git-svn-id: https://svn.sourceforge.jp/svnroot/nucleus-jp/plugin@630 1ca29b6e-896d-4ea0-84a5-967f57386b96 --- trunk/NP_OpenId/NP_OpenId.php | 39 ++- trunk/NP_OpenId/openid/help.html | 4 +- trunk/NP_OpenId/openid/language/english.php | 4 + trunk/NP_OpenId/openid/language/japanese-euc.php | 4 + trunk/NP_OpenId/openid/language/japanese-utf8.php | 4 + .../template/np_openid/updatefailed_english.html | 1 - .../np_openid/updatesucceeded_english.html | 3 - .../np_openid/updatesucceeded_japanese-euc.html | 3 - .../np_openid/updatesucceeded_japanese-utf8.html | 3 - .../openid/template/np_openid/yui_english.html | 14 +- trunk/NP_OpenId/sharedlibs/Jsphon.php | 79 +++++ trunk/NP_OpenId/sharedlibs/Jsphon/Decoder.php | 377 +++++++++++++++++++++ .../sharedlibs/Jsphon/Decoder/Tokenizer.php | 143 ++++++++ trunk/NP_OpenId/sharedlibs/Jsphon/Encoder.php | 250 ++++++++++++++ trunk/NP_OpenId/sharedlibs/Jsphon/Error.php | 190 +++++++++++ trunk/NP_OpenId/sharedlibs/Jsphon/Exception.php | 56 +++ 16 files changed, 1141 insertions(+), 33 deletions(-) create mode 100644 trunk/NP_OpenId/openid/language/english.php create mode 100644 trunk/NP_OpenId/openid/language/japanese-euc.php create mode 100644 trunk/NP_OpenId/openid/language/japanese-utf8.php delete mode 100644 trunk/NP_OpenId/openid/template/np_openid/updatefailed_english.html delete mode 100644 trunk/NP_OpenId/openid/template/np_openid/updatesucceeded_english.html delete mode 100644 trunk/NP_OpenId/openid/template/np_openid/updatesucceeded_japanese-euc.html delete mode 100644 trunk/NP_OpenId/openid/template/np_openid/updatesucceeded_japanese-utf8.html create mode 100644 trunk/NP_OpenId/sharedlibs/Jsphon.php create mode 100644 trunk/NP_OpenId/sharedlibs/Jsphon/Decoder.php create mode 100644 trunk/NP_OpenId/sharedlibs/Jsphon/Decoder/Tokenizer.php create mode 100644 trunk/NP_OpenId/sharedlibs/Jsphon/Encoder.php create mode 100644 trunk/NP_OpenId/sharedlibs/Jsphon/Error.php create mode 100644 trunk/NP_OpenId/sharedlibs/Jsphon/Exception.php diff --git a/trunk/NP_OpenId/NP_OpenId.php b/trunk/NP_OpenId/NP_OpenId.php index f64f875..778f839 100644 --- a/trunk/NP_OpenId/NP_OpenId.php +++ b/trunk/NP_OpenId/NP_OpenId.php @@ -2,9 +2,9 @@ // vim: tabstop=2:shiftwidth=2 /** - * NP_OpenId ($Revision: 1.2 $) + * NP_OpenId ($Revision: 1.3 $) * by hsur ( http://blog.cles.jp/np_cles ) - * $Id: NP_OpenId.php,v 1.2 2008-06-07 19:33:43 hsur Exp $ + * $Id: NP_OpenId.php,v 1.3 2008-06-10 14:35:12 hsur Exp $ * */ @@ -50,6 +50,7 @@ require_once 'Auth/OpenID/Consumer.php'; require_once 'cles/SQLStoreForNucleus.php'; require_once 'Auth/OpenID/SReg.php'; require_once 'Auth/OpenID/PAPE.php'; +require_once 'Jsphon.php'; class NP_OpenId extends NucleusPlugin { @@ -63,7 +64,7 @@ class NP_OpenId extends NucleusPlugin { return 'http://blog.cles.jp/np_cles/category/31/subcatid/21'; } function getVersion() { - return '1.1.0'; + return '1.1.1'; } function getMinNucleusVersion() { return 330; @@ -84,7 +85,7 @@ class NP_OpenId extends NucleusPlugin { ); } function getDescription() { - return '[$Revision: 1.2 $]
Adds OpenID authentication to anonymous comment, to prevent robots from spamming.'; + return '[$Revision: 1.3 $]
Adds OpenID authentication to anonymous comment, to prevent robots from spamming.'; } function supportsFeature($what) { switch ($what) { @@ -107,6 +108,12 @@ class NP_OpenId extends NucleusPlugin { @mkdir($store_path); $this->store = new Auth_OpenID_FileStore($store_path); */ + // include language file for this plugin + $language = ereg_replace( '[\\|/]', '', getLanguageName()); + if (file_exists($this->getDirectory().'language/'.$language.'.php')) + @ include_once($this->getDirectory().'language/'.$language.'.php'); + else + @ include_once($this->getDirectory().'language/english.php'); $this->store = new cles_SQLStoreForNucleus(); $this->consumer = new Auth_OpenID_Consumer($this->store); @@ -198,7 +205,6 @@ class NP_OpenId extends NucleusPlugin { break; case 'updateProfile': - $te = $this->_getTemplateEngine(); $aVars = array(); if( $this->isLoggedin() ){ $profile = array(); @@ -206,11 +212,17 @@ class NP_OpenId extends NucleusPlugin { $aVars['email'] = requestVar('email'); $this->_doUpdateProfile($aVars); - echo $te->fetchAndFill('updatesucceeded', $aVars, strtolower(__CLASS__)); + + $aVars['message'] = NP_OPENID_updateSucceeded; + $aVars['result'] = 'succeeded'; } else { - $aVars['message'] = 'You aren\'t logged in.'; - echo $te->fetchAndFill('updatefailed', $aVars, strtolower(__CLASS__)); + $aVars['message'] = NP_OPENID_notloggedin; + $aVars['result'] = 'failure'; } + + // return JSON + if(_CHARSET != 'UTF-8') mb_convert_variables('UTF-8', _CHARSET, $aVars); + echo Jsphon::encode($aVars); exit; //break; default: @@ -281,9 +293,6 @@ class NP_OpenId extends NucleusPlugin { $this->loggedinUser['nick'] = $profile['nick']; $this->loggedinUser['email'] = $profile['email']; - - setcookie($CONF['CookiePrefix'] . 'comment_user', $this->loggedinUser['nick'], 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); - setcookie($CONF['CookiePrefix'] . 'comment_email', $this->loggedinUser['email'], 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); } function _doLoginLocal($name){ @@ -344,7 +353,7 @@ class NP_OpenId extends NucleusPlugin { function isLoggedin(){ global $CONF; - if( $this->loggedinUser ) return true; + if( $this->loggedinUser['identity'] ) return true; $cookie = cookieVar($CONF['CookiePrefix'] . NP_OPENID_AUTH_COOKIE); if( ! $cookie ) return false; @@ -410,8 +419,6 @@ class NP_OpenId extends NucleusPlugin { $this->loggedinUser = array_merge($this->loggedinUser, unserialize($this->loggedinUser['sreg'])); setcookie($CONF['CookiePrefix'] . NP_OPENID_AUTH_COOKIE , $cookie, 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); - setcookie($CONF['CookiePrefix'] . 'comment_user', $this->loggedinUser['nick'], 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); - setcookie($CONF['CookiePrefix'] . 'comment_email', $this->loggedinUser['email'], 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); return true; } @@ -422,8 +429,6 @@ class NP_OpenId extends NucleusPlugin { global $CONF; $this->loggedinUser = null; setcookie($CONF['CookiePrefix'] . NP_OPENID_AUTH_COOKIE, '', 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); - setcookie($CONF['CookiePrefix'] . 'comment_user', '', 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); - setcookie($CONF['CookiePrefix'] . 'comment_email', '', 0, $CONF['CookiePath'], $CONF['CookieDomain'], $CONF['CookieSecure']); return true; } @@ -608,4 +613,4 @@ class NP_OpenId extends NucleusPlugin { return $this->templateEngine; } -} +} \ No newline at end of file diff --git a/trunk/NP_OpenId/openid/help.html b/trunk/NP_OpenId/openid/help.html index 72bb8a5..79394f8 100644 --- a/trunk/NP_OpenId/openid/help.html +++ b/trunk/NP_OpenId/openid/help.html @@ -1,4 +1,4 @@ - +

バージョン履歴

diff --git a/trunk/NP_OpenId/openid/language/english.php b/trunk/NP_OpenId/openid/language/english.php new file mode 100644 index 0000000..5d0c989 --- /dev/null +++ b/trunk/NP_OpenId/openid/language/english.php @@ -0,0 +1,4 @@ + | +// +--------------------------------------------------------------------+ +// +// + +define('JSPHON_ERROR_DECODE_SYNTAX', 1); + +require_once(dirname(__FILE__) .'/Jsphon/Error.php'); +require_once(dirname(__FILE__) .'/Jsphon/Decoder.php'); +require_once(dirname(__FILE__) .'/Jsphon/Encoder.php'); + +Jsphon_Error::singleton(); + +/** + * Jsphon - JSON in PHP + * + * example: + * + * //encode + * $value = array('foo', 'bar', array('hoge' => array(1,2))); + * $json = Jsphon::encode($value); + * echo $json; + * + * //decode + * $var = Jsphon::decode($json); + * echo $var[2]['hoge']; + * + * + * + * @author Hawk + */ +class Jsphon +{ + /** + * Encodes an arbitrary variables into JSON format. + * See Jsphon_Encoder::encode() for details. + * + * @param String $value + * @param boolean $escapeNonASCII + * @param boolean $escapeOverUCS2 + * @return String + */ + function encode($value, $escapeNonASCII=true, $escapeOverUCS2=false) + { + $encoder = new Jsphon_Encoder($escapeNonASCII, $escapeOverUCS2); + return $encoder->encode($value); + } + + + /** + * Decodes JSON-formatted string into appropriate PHP variable. + * See Jsphon_Decoder::decode() for details. + * + * @param String $json + * @param String $decodeOverUCS2 + * @return mixed + */ + function decode($json, $decodeOverUCS2=false) + { + $decoder = new Jsphon_Decoder($decodeOverUCS2); + return $decoder->decode($json); + } + +} + +?> diff --git a/trunk/NP_OpenId/sharedlibs/Jsphon/Decoder.php b/trunk/NP_OpenId/sharedlibs/Jsphon/Decoder.php new file mode 100644 index 0000000..9e60dc3 --- /dev/null +++ b/trunk/NP_OpenId/sharedlibs/Jsphon/Decoder.php @@ -0,0 +1,377 @@ + | +// +--------------------------------------------------------------------+ +// +// + +require_once(dirname(__FILE__) .'/Decoder/Tokenizer.php'); + +/** + * Converts JSON-formatted string to appropriate PHP variable + * + * example: + * + * //create a new instance of Jsphon_Decoder + * $json =& new Jsphon_Decoder(); + * + * //convert JSON-formatted string to PHP variable + * $value = '["foo","bar",{"hoge":[1,2]}]'; + * $var = $json->decode($value); + * + * print_r($var); + * //array('foo', 'bar', array('hoge' => array(1,2))) + * + * + * @author Hawk + */ +class Jsphon_Decoder +{ + var $_mbstring; + + var $_decodeOverUCS2; + + var $_internalError; + + var $_transTable = array( + '\b' => "\x08", + '\t' => "\x09", + '\n' => "\x0A", + '\f' => "\x0C", + '\r' => "\x0D", + '\"' => "\x22", + '\/' => "\x2F", + '\\\\' => "\x5C" + ); + + var $_allUESreg = '/\\\u([a-fA-F0-9]{4})/'; + + var $_utf16surUESreg = '/\\\u(D[89AB][A-F0-9]{2})\\\u(D[C-F][A-F0-9]{2})/i'; + + /** + * construct a new Jsphon_Decoder instance. + * + * @param bool $decodeOverUCS2 If true, decodeString() converts the whole + * Unicode escape sequences (\uXXXX) including surrogate pairs + * to corresponding characters in UTF-8. + */ + function Jsphon_Decoder($decodeOverUCS2=false) + { + $this->_decodeOverUCS2 = $decodeOverUCS2; + $this->_mbstring = extension_loaded('mbstring'); + } + + /** + * decodes a JSON string into appropriate variable + * + * @param String $json + * @return mixed + */ + function decode($json) + { + $tknz = new Jsphon_Decoder_Tokenizer($json, + array(&$this, 'handleInternalError')); + $this->_internalError = false; + + $result = null; + if($tknz->nextToken()) { + $result = $this->_decodeJSValue($tknz); + } + + $this->_internalError = false; + return $result; + } + + /** + * + * @param Object $tknz + * @return mixed + */ + function _decodeJSValue(&$tknz) + { + switch($tknz->getToken()) { + case JSPHON_TOKEN_DATUM: + if(is_string($r = $tknz->getTokenValue())) { + $r = $this->decodeString($r); + } + return $r; + + case JSPHON_TOKEN_LBRACKET: + return $this->_decodeArray($tknz); + + case JSPHON_TOKEN_LBRACE: + return $this->_decodeObject($tknz); + + default: + $this->_error("syntax error: Expecting '{', '[' or DAUM."); + return null; + } + } + + /** + * Decodes a JSON array format: + * [element, element2,...,elementN] + * + * @param Object $tknz + * @return array + */ + function _decodeArray(&$tknz) + { + $ret = array(); + if(!($token = $tknz->nextToken())) { + return null; + + } elseif($token == JSPHON_TOKEN_RBRACKET) { + return $ret; + } + + //if false, break + while( ($value = $this->_decodeJSValue($tknz) or true) + and !$this->_internalError + and ($ret[] = $value or true) + and $token = $tknz->nextToken() + and $token == JSPHON_TOKEN_COMMA + and $token = $tknz->nextToken() + ); + + if($this->_internalError) { + return null; + + } elseif($token == JSPHON_TOKEN_RBRACKET) { + return $ret; + } else { + $this->_error("Missing ',' or ']' in array encoding."); + return null; + } + } + + /** + * Decodes an object of the form: + * { "attribute: value, "attribute2" : value,...} + * + * _decodeObject() always converts a JSON-object to an associative array, + * because you can't access empty property in PHP5. + * + * // { "":"foo" } + * $obj->{""} = "foo"; //Fatal error: Cannot access empty property + * + * + * @param Object $tknz + * @return array + */ + function _decodeObject(&$tknz) + { + $ret = array(); + if(!($token = $tknz->nextToken())) { + return null; + + } elseif($token == JSPHON_TOKEN_RBRACE) { + return $ret; + } + + //if false, break + while( ($key = $this->_decodeJSValue($tknz) or true) + and !$this->_internalError + and $this->_checkObjectKey($key) + and $token = $tknz->nextToken() + and $this->_checkKeyValueSep($token) + and $token = $tknz->nextToken() + and ($value = $this->_decodeJSValue($tknz) or true) + and !$this->_internalError + and ($ret[$key] = $value or true) + and $token = $tknz->nextToken() + and $token == JSPHON_TOKEN_COMMA + and $token = $tknz->nextToken() + ); + + if($this->_internalError) { + return null; + + } elseif($token == JSPHON_TOKEN_RBRACE) { + return $ret; + } else { + $this->_error("Missing ',' or '}' in object encoding."); + return null; + } + } + + function _checkObjectKey($key) + { + if(!is_string($key)) { + $this->_error("Object's key must be a string, but is ". gettype($key)); + return false; + } + return true; + } + + function _checkKeyValueSep($token) + { + if($token != JSPHON_TOKEN_COLON) { + $this->_error("Missing ':' in object encoding."); + return false; + } + return true; + } + + + /** + * + * + * @param String $encoded + * @return String + */ + function decodeString($encoded) + { + $ret = strtr($encoded, $this->_transTable); + + if($this->_decodeOverUCS2) { + return $this->_decodeUESOverUCS2($ret); + } else { + //_decodeUESWithoutMbstring() fastar than _decodeUES()... + return $this->_decodeUESWithoutMbstring($ret); + } + + /* + if(!$this->_mbstring) { + return $this->_decodeUESWithoutMbstring($ret); + } elseif($this->_decodeOverUCS2) { + return $this->_decodeUESOverUCS2($ret); + } else { + return $this->_decodeUES($ret); + } + */ + } + + function _decodeUES($str) + { + $transTable = array(); + + if(!preg_match_all($this->_allUESreg, $str, $matches)) { + return $str; + } + + $codepoints = $matches[1]; + foreach($matches[0] as $i => $escSeq) { + if(isset($transTable[$escSeq])) { + continue; + } + $codepoint = hexdec($codepoints[$i]); + $transTable[$escSeq] = (0xD800 <= $codepoint && $codepoint <= 0xDFFF) ? "" + : mb_convert_encoding(pack('n', $codepoint), 'UTF-8', 'UCS-2'); + } + return strtr($str, $transTable); + } + + function _decodeUESOverUCS2($str) + { + $transTable = array(); + + if(!preg_match_all($this->_allUESreg, $str, $u16)) { + return $str; + } + + if(preg_match_all($this->_utf16surUESreg, $str, $u16sur)) { + $sur1st = $u16sur[1]; + $sur2nd = $u16sur[2]; + + foreach($u16sur[0] as $i => $escSeq) { + if(isset($transTable[$escSeq])) { + continue; + } + $transTable[$escSeq] = mb_convert_encoding( + pack('n2', hexdec($sur1st[$i]), hexdec($sur2nd[$i])), 'UTF-8', 'UTF-16BE'); + } + } + + $codepoints = $u16[1]; + foreach($u16[0] as $i => $escSeq) { + if(isset($transTable[$escSeq])) { + continue; + } + $codepoint = hexdec($codepoints[$i]); + $transTable[$escSeq] = (0xD800 <= $codepoint && $codepoint <= 0xDFFF) ? "" + : mb_convert_encoding(pack('n', $codepoint), 'UTF-8', 'UCS-2'); + } + return strtr($str, $transTable); + } + + function _decodeUESWithoutMbstring($str) + { + $transTable = array(); + + if(!preg_match_all($this->_allUESreg, $str, $matches)) { + return $str; + } + + $codepoints = $matches[1]; + foreach($matches[0] as $i => $escSeq) { + if(isset($transTable[$escSeq])) { + continue; + } + + $utf8char = ""; + + $cp = hexdec($codepoints[$i]); + switch(true) { + case ($cp < 0x80): + $utf8char = chr($cp); + break; + + case (0xD800 <= $cp && $cp <= 0xDFFF): + break; + + case ($cp < 0x800): + $utf8char = chr($cp >> 6 & 0x1F | 0xC0) . chr($cp & 0x3F | 0x80); + break; + + case ($cp < 0x10000): + $utf8char = chr($cp >> 12 & 0xF | 0xE0) . + chr($cp >> 6 & 0x3F | 0x80) . chr($cp & 0x3F | 0x80); + break; + + default: + } + $transTable[$escSeq] = $utf8char; + } + return strtr($str, $transTable); + } + + + /** + * a simple wrapper for PEAR_ErrorStack::push. + * + * @param String $message + * @param array $param + * @param string $level + * @param int $code + * @return String + */ + function _error($message, + $param= array(), + $level='error', + $code=JSPHON_ERROR_DECODE_SYNTAX) + { + $e = Jsphon_Error::push( + $code, $level, $param, $message, false, debug_backtrace()); + $this->_internalError = true; + return $e; + } + + function handleInternalError($err) + { + $this->_internalError = true; + } +} + +?> diff --git a/trunk/NP_OpenId/sharedlibs/Jsphon/Decoder/Tokenizer.php b/trunk/NP_OpenId/sharedlibs/Jsphon/Decoder/Tokenizer.php new file mode 100644 index 0000000..f422692 --- /dev/null +++ b/trunk/NP_OpenId/sharedlibs/Jsphon/Decoder/Tokenizer.php @@ -0,0 +1,143 @@ + | +// +--------------------------------------------------------------------+ +// +// + +define('JSPHON_TOKEN_EOF', 1); +define('JSPHON_TOKEN_DATUM', 2); +define('JSPHON_TOKEN_LBRACE', 3); +define('JSPHON_TOKEN_LBRACKET', 4); +define('JSPHON_TOKEN_RBRACE', 5); +define('JSPHON_TOKEN_RBRACKET', 6); +define('JSPHON_TOKEN_COMMA', 7); +define('JSPHON_TOKEN_COLON', 8); + +/** + * Jsphon_Decoder_Tokenizer + * + * @author Hawk + */ +class Jsphon_Decoder_Tokenizer +{ + var $_source; + + var $_token; + + var $_tokenValue; + + var $_tokenTable = array( + '{' => JSPHON_TOKEN_LBRACE, + '}' => JSPHON_TOKEN_RBRACE, + '[' => JSPHON_TOKEN_LBRACKET, + ']' => JSPHON_TOKEN_RBRACKET, + ',' => JSPHON_TOKEN_COMMA, + ':' => JSPHON_TOKEN_COLON + ); + + var $_tokenValueTable = array( + 'true' => true, + 'false' => false, + 'null' => null + ); + + var $_errorCallback; + + /** + * constructs a new Jsphon_Decoder_Tokenizer instance. + * + * @param String $source + */ + function Jsphon_Decoder_Tokenizer($source, $internalErrorCallback=null) + { + $this->_source = $source; + $this->_errorCallback = $internalErrorCallback; + } + + /** + * Retrieves the next token from the source stream. + * + * @return int or false + */ + function nextToken() + { + $src = ltrim($this->_source); + + $this->_tokenValue = null; + $this->_token = JSPHON_TOKEN_EOF; + + switch(true) + { + case $src === '': + break; + + case ($c = $src{0}) !== "" and isset($this->_tokenTable[$c]): + $this->_token = $this->_tokenTable[$c]; + $src = substr($src, 1); + break; + + case $c == '"' and preg_match('/^"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"/', $src, $m): + $this->_token = JSPHON_TOKEN_DATUM; + $this->_tokenValue = $m[1]; + $src = substr($src, strlen($m[0])); + break; + + case preg_match('/^(true|false|null)\b/', $src, $m): + $this->_token = JSPHON_TOKEN_DATUM; + $this->_tokenValue = $this->_tokenValueTable[$m[1]]; + $src = substr($src, ($m[1]{0} == 'f' ? 5 : 4)); + break; + + case preg_match('/^-?(?:[1-9]\d+|\d)(?:\.\d+)?(?:[eE][-+]?\d+)?/', $src, $m): + $this->_token = JSPHON_TOKEN_DATUM; + $intV = (int)$m[0]; + $floatV = (float)$m[0]; + $this->_tokenValue = ($intV == $floatV) ? $intV : $floatV; + $src = substr($src, strlen($m[0])); + break; + + default: + $err = Jsphon_Error::push( + JSPHON_ERROR_DECODE_SYNTAX, + 'error', + array(), + 'Illegal Token', + false, + debug_backtrace()); + + if(is_callable($this->_errorCallback)) { + call_user_func($this->_errorCallback, $err); + } + return false; + + } + + $this->_source = $src; + return $this->_token; + } + + function getToken() + { + return $this->_token; + } + + function getTokenValue() + { + return $this->_tokenValue; + } + +} + +?> diff --git a/trunk/NP_OpenId/sharedlibs/Jsphon/Encoder.php b/trunk/NP_OpenId/sharedlibs/Jsphon/Encoder.php new file mode 100644 index 0000000..7cf9689 --- /dev/null +++ b/trunk/NP_OpenId/sharedlibs/Jsphon/Encoder.php @@ -0,0 +1,250 @@ + | +// +--------------------------------------------------------------------+ +// +// + +/** + * Converts to JSON format. + * + * example: + * + * //create a new instance of Jsphon_Encoder + * $json =& new Jsphon_Encoder(); + * + * //convert a complex value to JSON notation, and send it to the browser + * $value = array('foo', 'bar', array('hoge' => array(1,2))); + * $output = $json->encode($value); + * + * print_r($output); + * //prints: ["foo","bar",{"hoge":[1,2]}] + * + * + * @author Hawk + */ +class Jsphon_Encoder +{ + var $_mbstring; + + var $_escapeNonASCII; + + var $_escapeOverUCS2; + + var $_transTable; + + var $_utf8UCS2reg; + + var $_utf8overUCS2reg; + + /** + * constructs a new Jsphon_Encoder instance. + * + * @param bool $escapeNonASCII If true, encode() converts non-ASCII characters + * to Unicode escape sequence (\uXXXX). + * @param bool $escapeOverUCS2 If true, encode() converts all the non-ASCII characters + * that is encodable in UTF-16 to Unicode escape sequence. + * This parameter affects the encoder's behavior + * only if $escapeNonASCII is set to true and + * the multibyte string extension is available. + * + */ + function Jsphon_Encoder($escapeNonASCII=true, $escapeOverUCS2=false) + { + $this->_escapeNonASCII = $escapeNonASCII; + $this->_escapeOverUCS2 = $escapeOverUCS2; + $this->_mbstring = extension_loaded('mbstring'); + + $this->_transTable = array( + "\x08" => '\b', + "\x09" => '\t', + "\x0A" => '\n', + "\x0C" => '\f', + "\x0D" => '\r', + "\x22" => '\"', + "\x2F" => '\/', + "\x5C" => '\\\\' + ); + + $utf8ucs2 = '[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}'; + $utf16sur = '[\xF0-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2}'; + $this->_utf8UCS2reg = "/{$utf8ucs2}/"; + $this->_utf8overUCS2reg = "/{$utf8ucs2}|{$utf16sur}/"; + } + + /** + * encodes an arbitrary variables into JSON format. + * + * If $_escapeNonASCII is set to true, + * encode() removes all non-ASCII characters to make sure that + * returning value dosen't contain any non-ASCII characters. + * + * @param mixed $value + * @return string + */ + function encode($value) + { + $json = $this->_encode($value); + if($this->_escapeNonASCII) { + $json = preg_replace('/[\x80-\xFF]/', '', $json); + } + return $json; + } + + function _encode($value) + { + if($value === null) { + return 'null'; + + } elseif(is_bool($value)) { + return $value ? 'true' : 'false'; + + } elseif(is_int($value)) { + return (int)$value; + + } elseif(is_float($value)) { + return (float)$value; + + } elseif(is_string($value)) { + return '"'. $this->_encodeString($value) .'"'; + + } elseif(is_array($value)) { + if(($len = count($value)) > 0 && + array_keys($value) !== range(0, $len - 1)) { + return $this->_encodeObject($value); + } else { + return '['. join(',', array_map(array(&$this, '_encode'), $value)) .']'; + } + + } elseif(is_object($value)) { + return $this->_encodeObject($value); + + } + + return 'null'; + } + + function _encodeObject($arr) + { + $result = array(); + foreach($arr as $name => $value) { + $result[] = $this->_encode((string)$name) .':'. $this->_encode($value); + } + return '{'. join(',', $result) ."}"; + } + + function _encodeString($str) + { + $str = strtr($str, $this->_transTable); + + if(!$this->_escapeNonASCII) { + return $str; + } + + if(!$this->_mbstring) { + return $this->_escapeNonASCIIWithoutMbstring($str); + } + + if($this->_escapeOverUCS2) { + return $this->_escapeNonASCIIOverUCS2($str); + } else { + return $this->_escapeNonASCII($str); + } + } + + function _escapeNonASCII($str) + { + $transTable = array(); + + if(!preg_match_all($this->_utf8UCS2reg, $str, $matches)) { + return $str; + } + + foreach($matches[0] as $utf8char) { + if(isset($transTable[$utf8char])) { + continue; + } + $transTable[$utf8char] = $this->_formatSeq( + mb_convert_encoding($utf8char, 'UTF-16', 'UTF-8')); + } + return strtr($str, $transTable); + } + + function _escapeNonASCIIOverUCS2($str) + { + $transTable = array(); + + if(!preg_match_all($this->_utf8overUCS2reg, $str, $matches)) { + return $str; + } + + foreach($matches[0] as $utf8char) { + if(isset($transTable[$utf8char])) { + continue; + } + $utf16char = mb_convert_encoding($utf8char, 'UTF-16', 'UTF-8'); + + if(($l = strlen($utf16char)) == 2) { + $transTable[$utf8char] = $this->_formatSeq($utf16char); + } elseif($l == 4) { + $transTable[$utf8char] = + $this->_formatSeq(substr($utf16char, 0, 2)) . $this->_formatSeq(substr($utf16char, 2)); + } + + } + return strtr($str, $transTable); + } + + function _escapeNonASCIIWithoutMbstring($str) + { + $transTable = array(); + + if(!preg_match_all($this->_utf8UCS2reg, $str, $matches)) { + return $str; + } + + foreach($matches[0] as $utf8char) { + if(isset($transTable[$utf8char])) { + continue; + } + + switch(strlen($utf8char)) { + case 2: + $code = ( + ((ord($utf8char{0}) & 0x1F) << 6) | + (ord($utf8char{1}) & 0x3F) + ); + break; + + case 3: + $code = ( + ((ord($utf8char{0}) & 0x0F) << 12) | + ((ord($utf8char{1}) & 0x3F) << 6 ) | + (ord($utf8char{2}) & 0x3F) + ); + break; + default: + } + $transTable[$utf8char] = '\u'. substr('0000'. dechex($code), -4); + } + return strtr($str, $transTable); + } + + function _formatSeq($u16) + { + return '\u'. substr('0000'. bin2hex($u16), -4); + } +} + +?> diff --git a/trunk/NP_OpenId/sharedlibs/Jsphon/Error.php b/trunk/NP_OpenId/sharedlibs/Jsphon/Error.php new file mode 100644 index 0000000..b2a5413 --- /dev/null +++ b/trunk/NP_OpenId/sharedlibs/Jsphon/Error.php @@ -0,0 +1,190 @@ + | +// +--------------------------------------------------------------------+ +// +// + +/** + * Jsphon_Error + * + * @author Hawk + */ +class Jsphon_Error +{ + var $_isPHP5; + + var $_existsPEAR; + + var $_throwException = true; + + var $_exceptionCreator; + + /** + * Constructor + * + * @access private + */ + function Jsphon_Error() + { + $this->_isPHP5 = version_compare(phpversion(), '5', '>='); + $this->_existsPEAR = (@include_once "PEAR/ErrorStack.php"); + + if($this->_isPHP5) { + if($this->_existsPEAR) { + require_once(dirname(__FILE__) .'/Exception.php'); + $method = '_createJsphonException'; + } else { + $method = '_createException'; + } + $this->_exceptionCreator = array(__CLASS__, $method); + } + } + + /** + * + * + * @since 06/09/05 13:21 + * @return Jsphon_Error + */ + function &singleton() + { + static $instance = null; + if($instance === null) { + $instance = new Jsphon_Error(); + } + return $instance; + } + + /** + * + * @static + * @param int $code + * @param string $level + * @param array $params + * @param string $msg + * @param mixed $repackage + * @param array $backtrace + * @return array + */ + function push($code, $level = 'error', $params = array(), $msg = false, + $repackage = false, $backtrace = false) + { + if (!$backtrace) { + $backtrace = debug_backtrace(); + } + + $self =& Jsphon_Error::singleton(); + + if(!$self->_isPHP5 || !$self->_throwException) { + return $self->_push( + $code, $level, $params, $msg, $repackage, $backtrace); + } + + $pushOnly = true; + $err = $self->_push( + $code, $level, $params, $msg, $repackage, $backtrace, $pushOnly); + + array_shift($backtrace); + throw (call_user_func($self->_exceptionCreator, $msg, $code, $backtrace)); + return ; + } + + /** + * + * + * @access private + * @static + * @param int $code + * @param string $level + * @param array $params + * @param string $msg + * @param mixed $repackage + * @param array $backtrace + * @param bool $pushOnly + * @return array or null unless PEAR_ErrorStack exists. + */ + function _push($code, $level='error', $params=array(), $msg=false, + $repackage=false, $backtrace=false, $pushOnly=false) + { + if(!$this->_existsPEAR) { + return; + } + + $stack =& PEAR_ErrorStack::singleton('Jsphon'); + if($pushOnly) { + $stack->pushCallback(array(__CLASS__, 'pushOnly')); + } + + $err = $stack->push($code, $level, $params, $msg, $repackage, $backtrace); + + if($pushOnly) { + $stack->popCallback(); + } + return $err; + } + + /** + * + * @since 06/09/05 13:34 + * @param String $bool + * @param String $exceptionClass + * @return String + */ + function setThrowException($bool) + { + $this->_throwException = $bool; + } + + /** + * error handler which do nothing + * + * @since 06/09/05 13:52 + * @param array $err + * @return int + */ + function pushOnly($err) + { + return PEAR_ERRORSTACK_PUSH; + } + + /** + * + * @static + * @param String $msg + * @param int $code + * @param array $trace + * @return Exception + */ + function _createJsphonException($msg, $code, $trace) + { + return new Jsphon_Exception($msg, $code, $trace); + } + + /** + * + * @static + * @param String $msg + * @param int $code + * @param array $trace + * @return Exception + */ + function _createException($msg, $code, $trace) + { + return new Exception($msg, $code); + } +} + + +?> diff --git a/trunk/NP_OpenId/sharedlibs/Jsphon/Exception.php b/trunk/NP_OpenId/sharedlibs/Jsphon/Exception.php new file mode 100644 index 0000000..3fc5f85 --- /dev/null +++ b/trunk/NP_OpenId/sharedlibs/Jsphon/Exception.php @@ -0,0 +1,56 @@ + | +// +--------------------------------------------------------------------+ +// +// + +require_once('PEAR/Exception.php'); + +/** + * Jsphon_Exception + * + * @author Hawk + */ +class Jsphon_Exception extends PEAR_Exception +{ + private $_outerTrace; + + /** + * Constructor + * + */ + public function __construct($msg, $code, $outerTrace) + { + $this->_outerTrace = $outerTrace; + parent::__construct($msg, $code); + } + + /** + * + * + * @override + * @return array + */ + public function getTraceSafe() + { + if(count($this->_outerTrace) > 0) { + return $this->_outerTrace; + } + return parent::getTraceSafe(); + } + +} + +?> -- 2.11.0