Showing
17 changed files
with
4767 additions
and
0 deletions
Too many changes to show.
To preserve performance only 17 of 17+ files are displayed.
.htaccess
0 → 100644
cancellation.htm
0 → 100644
| 1 | +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" | ||
| 2 | +"http://www.w3.org/TR/html4/loose.dtd"> | ||
| 3 | +<html> | ||
| 4 | +<head> | ||
| 5 | +<meta http-equiv="Content-Type" content="text/html; charset=euc-jp"> | ||
| 6 | +<title>クレジット決済 中止</title> | ||
| 7 | +<link href="css/style.css" rel="stylesheet" type="text/css"> | ||
| 8 | +<script> | ||
| 9 | +{literal} | ||
| 10 | + | ||
| 11 | +{/literal} | ||
| 12 | +</script> | ||
| 13 | +</head> | ||
| 14 | +<body> | ||
| 15 | +<h1>クレジット決済 中止ページ</h1> | ||
| 16 | +<hr><br> | ||
| 17 | + | ||
| 18 | +<p>クレジット決済処理を中止しました。</p><br> | ||
| 19 | + | ||
| 20 | +<p>この画面を閉じて、はじめからやり直してください。</p><br> | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + <input type="button" value="閉じる" onClick="window.close();"> | ||
| 24 | + | ||
| 25 | +</body> | ||
| 26 | +</html> |
complete.php
0 → 100644
| 1 | +<?php | ||
| 2 | +//***************************************************************************** | ||
| 3 | +//* プログラムID:complete.php | ||
| 4 | +//* 機能 :決済完了処理 | ||
| 5 | +//***************************************************************************** | ||
| 6 | +header( "Content-type: text/html; charset=EUC-JP"); | ||
| 7 | + | ||
| 8 | +include('./inc/smarty.conf'); | ||
| 9 | + | ||
| 10 | +// EPSILON クレジットカード認証完了、コンビニ受付番号発行完了 | ||
| 11 | +// クライアント側プログラム(PHP版) | ||
| 12 | +// | ||
| 13 | +// このプログラムの実行には、以下のモジュールが必要です。 | ||
| 14 | +// ・PHP(ver5,,,,, | ||
| 15 | +// ・PEAR: | ||
| 16 | +// ・PEAR:HTTP_Request: | ||
| 17 | +// ・PEAR:Net_URL: | ||
| 18 | +// ・PEAR:Net_Socket: | ||
| 19 | +// ・PEAR:XML_Parser: | ||
| 20 | +// ・PEAR:XML_Serializer: | ||
| 21 | +// | ||
| 22 | + | ||
| 23 | +//include Libraly | ||
| 24 | +//PEAR拡張モジュールの読み込み。 | ||
| 25 | +//既に該当のモジュールをインストール済みの場合は適宜読み込み先パスを変更してください。 | ||
| 26 | +require_once "./lib/http/Request.php"; | ||
| 27 | +require_once "./lib/xml/Unserializer.php"; | ||
| 28 | + | ||
| 29 | +//char setting | ||
| 30 | +//サーバ環境に応じ適宜変更してください。 | ||
| 31 | +mb_language("Japanese"); | ||
| 32 | +mb_internal_encoding("EUC-JP"); | ||
| 33 | + | ||
| 34 | +// 変数の設定 | ||
| 35 | + | ||
| 36 | +// オーダー情報確認CGIのURL(試験用) | ||
| 37 | +// オーダー情報確認CGIについては2種類ありますのでご注意お願いいたします。 | ||
| 38 | +// 詳細はCGI設定マニュアルの「オーダー情報確認CGI-1,2」をご確認願います。 | ||
| 39 | +// 各CGIの説明 | ||
| 40 | +// CGI-1:認証にパスワード要/発信元IP無制限 | ||
| 41 | +// CGI-2:認証にパスワード不要/発信元IPの制限有 | ||
| 42 | + | ||
| 43 | +// 以下にはCGI-1と2で設定パラメータが相違しますので利用されるCGIによって変更してください。 | ||
| 44 | + | ||
| 45 | +// 接続先URLの設定 | ||
| 46 | + | ||
| 47 | +// CGI-1利用の場合 本番環境への接続の場合は契約後弊社からご連絡いたしますURLに変更してください | ||
| 48 | +//$getsales_url = 'http://beta.epsilon.jp/client/getsales.cgi'; | ||
| 49 | +$getsales_url = 'https://secure.epsilon.jp/client/getsales.cgi'; | ||
| 50 | +// CGI-2利用の場合 本番環境への接続の場合は契約後弊社からご連絡いたしますURLに変更してください | ||
| 51 | +//my $getsales_url = 'https://beta.epsilon.jp/cgi-bin/order/getsales2.cgi'; | ||
| 52 | + | ||
| 53 | +// 発行されたユーザーID(契約コード)を入力してください | ||
| 54 | +// CGI-1,2共通 | ||
| 55 | +$user_id = '33317000'; | ||
| 56 | + | ||
| 57 | +// 発行されたパスワードを入力してください。 | ||
| 58 | +// CGI-1利用の場合 弊社からお知らせしたパスワードを設定してください。 | ||
| 59 | +// CGI-2利用の場合 当値は利用しませんので適当な値を設定してください。txZaDA9o,j6ralKCA | ||
| 60 | +$passwd = '0yTJkjCd'; | ||
| 61 | + | ||
| 62 | +// エラーが発生した場合のメッセージ | ||
| 63 | +$err_msg; | ||
| 64 | + | ||
| 65 | +// オーダー情報取得CGIを実行した結果を格納する連想配列 | ||
| 66 | +$responce = array(); | ||
| 67 | + | ||
| 68 | +// 各支払い方法 | ||
| 69 | +$payment_name = array( | ||
| 70 | + 1 => "クレジットカード決済", | ||
| 71 | + 2 => "クレジットカード決済", | ||
| 72 | + 3 => "コンビニ決済", | ||
| 73 | + 4 => "ネット銀行決済(ジャパンネット銀行)", | ||
| 74 | + 5 => "ネット銀行決済(e-bank)", | ||
| 75 | + 7 => "ペイジー", | ||
| 76 | + 8 => "WebMoney", | ||
| 77 | + 9 => "Do-Link決済", | ||
| 78 | + 12 => "BitCash決済", | ||
| 79 | + 13 => "電子マネーちょコム"); | ||
| 80 | + | ||
| 81 | +// コンビニ・ペイジー支払の場合の支払い方法の簡単な説明 | ||
| 82 | +$setsumei = array( | ||
| 83 | + # セブンイレブン | ||
| 84 | + 11 => "以下の払込票ページをプリントアウトされるか、払込票番号をメモして<br>" . | ||
| 85 | + "最寄りのセブンイレブンのレジにてお支払いください。<br>" , | ||
| 86 | + # ファミリーマート | ||
| 87 | + 21 => "ファミリーマート店頭にございます Famiポート/ファミネットにて<br>" . | ||
| 88 | + "以下の2つの数字をご入力頂き、発行されるFamiポート申込券をレジまで<br>" . | ||
| 89 | + "お持ちになり代金をお支払いください。<br>", | ||
| 90 | + # ローソン | ||
| 91 | + 31 => "ローソンの店内に設置してあるLoppiのトップ画面の中から、「インターネット受付」<br>" . | ||
| 92 | + "をお選びください。次画面のジャンルの中から「インターネット受付」をお選び頂き、<br>" . | ||
| 93 | + "画面に従って以下の「お支払い受付番号」と、ご登録頂いた「電話番号」をご入力下さい。<br>" , | ||
| 94 | + # セイコーマート | ||
| 95 | + 32 => "セイコーマートの店内に設置してあるセイコーマートクラブステーション(情報端末)の<br>" . | ||
| 96 | + "トップ画面の中から、「インターネット受付」をお選び下さい。画面に従って以下の<br>" . | ||
| 97 | + "「お支払い受付番号」と、ご登録頂いた「電話番号」をご入力下さい。<br>" , | ||
| 98 | + # ペイジー | ||
| 99 | + 88 => "ペイジーでお支払い頂く際には銀行のATMもしくはオンラインバンキングで<br>お支払いただく方法がございます。<BR>" . | ||
| 100 | + "ご利用可能な銀行につきましては以下リンクでご確認お願いいたします。<BR><BR>". | ||
| 101 | + "<a href='http://www.epsilon.jp/service/payeasy_list.html' target='_blank'>ペイジーお支払可能銀行一覧</a><BR><BR>". | ||
| 102 | + "お支払可能な銀行、オンラインバンキングで「収納機関番号」、「確認番号」、<br>ご登録いただいた「電話番号」を入力の上ご入金お願いします。" ); | ||
| 103 | + | ||
| 104 | +// パラメータとして渡される(GET)トランザクションコードを取得します。 | ||
| 105 | +$trans_code = $_REQUEST['trans_code']; | ||
| 106 | + | ||
| 107 | + | ||
| 108 | +// 結果問い合わせ用HTTPリクエスト送信 | ||
| 109 | + | ||
| 110 | +// CGI-1利用の場合 | ||
| 111 | +// ※オーダー情報確認CGIの実行にはベーシック認証が必要です。 | ||
| 112 | +$request = new HTTP_Request($getsales_url); | ||
| 113 | +$request->setMethod(HTTP_REQUEST_METHOD_POST); | ||
| 114 | +$request->addHeader("Content-Type","application/x-www-form-urlencoded"); | ||
| 115 | +$request->setBody("trans_code=" . $trans_code); | ||
| 116 | + | ||
| 117 | +$request->setBasicAuth($user_id, $passwd); | ||
| 118 | +$response = $request->sendRequest(); | ||
| 119 | + | ||
| 120 | +// CGI-2利用の場合 | ||
| 121 | +//$request = new HTTP_Request($getsales_url); | ||
| 122 | +//$request->setMethod(HTTP_REQUEST_METHOD_POST); | ||
| 123 | +//$request->addHeader("Content-Type","application/x-www-form-urlencoded"); | ||
| 124 | +//$request->setBody("trans_code=" . $trans_code . "&contract_code=" . $user_id); | ||
| 125 | +//$response = $request->sendRequest(); | ||
| 126 | + | ||
| 127 | +// 以降はCGI-1,2どちらも共通です。 | ||
| 128 | + | ||
| 129 | +if (PEAR::isError($response)) { | ||
| 130 | + // インターフェイスCGIの実行に失敗した場合 | ||
| 131 | + $err_msg = "データの送信に失敗しました<br><br>"; | ||
| 132 | + $err_msg .= "<br />res_statusCd=" . $request->getResponseCode(); | ||
| 133 | + $err_msg .= "<br />res_status=" . $request->getResponseHeader('Status'); | ||
| 134 | + echo $err_msg; | ||
| 135 | + exit; | ||
| 136 | +} | ||
| 137 | + | ||
| 138 | + | ||
| 139 | +// CGIの実行に成功した場合、応答内容(XML)を解析します | ||
| 140 | + // 応答内容(XML)の解析 | ||
| 141 | + | ||
| 142 | +$res_code = $request->getResponseCode(); | ||
| 143 | +$res_content = $request->getResponseBody(); | ||
| 144 | + | ||
| 145 | +//xml unserializer | ||
| 146 | +$temp_xml_res = str_replace("x-sjis-cp932", "EUC-JP", $res_content); | ||
| 147 | +$unserializer =& new XML_Unserializer(); | ||
| 148 | +$unserializer->setOption('parseAttributes', TRUE); | ||
| 149 | +$unseriliz_st = $unserializer->unserialize($temp_xml_res); | ||
| 150 | +if ($unseriliz_st === true) { | ||
| 151 | + //xmlを解析 | ||
| 152 | + $res_array = $unserializer->getUnserializedData(); | ||
| 153 | + //error check | ||
| 154 | + if($res_array['result']['result'] == "0"){ | ||
| 155 | + echo "処理に失敗しました<br><br>"; | ||
| 156 | + exit(1); | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + $res_param_array = array(); | ||
| 160 | + //pram setting | ||
| 161 | + foreach($res_array['result'] as $uns_k => $uns_v){ | ||
| 162 | + list($result_atr_key, $result_atr_val) = each($uns_v); | ||
| 163 | + $res_param_array[$result_atr_key] = mb_convert_encoding(urldecode($result_atr_val), "EUC-JP" ,"auto"); | ||
| 164 | + } | ||
| 165 | + $debug_printj .= "<br />xml_memo2_msg=" . $xml_memo2_msg; | ||
| 166 | + | ||
| 167 | +}else{ | ||
| 168 | + //xml parser error | ||
| 169 | + echo "xml parser error<br><br>"; | ||
| 170 | + exit(1); | ||
| 171 | +} | ||
| 172 | +$result_html; | ||
| 173 | + | ||
| 174 | +if ($res_param_array['payment_code'] == 3){ | ||
| 175 | + // コンビニ支払の場合 | ||
| 176 | + if ($res_param_array['conveni_code'] == 11){ | ||
| 177 | + // セブンイレブンの場合 | ||
| 178 | + $result_html = $setsumei[11] . "<br><br>\n"; | ||
| 179 | + $result_html .= "払込票 : <a href=\"" . $res_param_array['haraikomi_url'] . "\">ここをクリック</a> <br>\n"; | ||
| 180 | + $result_html .= "払込票番号 : " . $res_param_array['receipt_no'] . "<br>\n"; | ||
| 181 | + } | ||
| 182 | + elseif ($res_param_array['conveni_code'] == 21){ | ||
| 183 | + // ファミリーマートの場合 | ||
| 184 | + $result_html = $setsumei[21] . "<br><br>\n"; | ||
| 185 | + $result_html .="企業コード: " . $res_param_array['kigyou_code'] . "<br>\n"; | ||
| 186 | + $result_html .= "注文番号 : " . $res_param_array['receipt_no'] . "<br>\n"; | ||
| 187 | + } | ||
| 188 | + elseif (($res_param_array['conveni_code'] == 31) || ($res_param_array['conveni_code'] == 32)){ | ||
| 189 | + // ローソン、セイコーマートの場合 | ||
| 190 | + $result_html = $setsumei{$res_param_array{'conveni_code'}} . "<br><br>\n"; | ||
| 191 | + $result_html .= "お支払い受付番号 : " . $res_param_array['receipt_no'] . "<br>\n"; | ||
| 192 | + } | ||
| 193 | + else { // 不明(異常) | ||
| 194 | + $err_msg = "支払情報の取得に失敗しました $res_param_array{'conveni_code'}"; | ||
| 195 | + exit(0); | ||
| 196 | + } | ||
| 197 | + $conveni_limit_date = split("-",$res_param_array['conveni_limit']); | ||
| 198 | + $result_html .= "<br>支払期限:" . $conveni_limit_date[0] . "年" | ||
| 199 | + . $conveni_limit_date[1] . "月" . $conveni_limit_date[2] . "日<br>\n"; | ||
| 200 | + $payment_name = $payment_name[$res_param_array['payment_code']]; | ||
| 201 | + $item_name = mb_convert_encoding(urldecode($res_param_array['item_name']), "EUC-JP" ,"auto"); | ||
| 202 | + $item_price = $res_param_array['item_price']; | ||
| 203 | +} | ||
| 204 | +elseif ($res_param_array['payment_code'] == 7 ){ | ||
| 205 | + // ペイジーの場合 | ||
| 206 | + $result_html = $setsumei[88] . "<br><br>\n"; | ||
| 207 | + $result_html .= "収納機関番号: " . $res_param_array['kigyou_code'] . "<br>\n"; | ||
| 208 | + $result_html .= "確認番号 : " . $res_param_array['receipt_no'] . "<br>\n"; | ||
| 209 | + $payment_name = $payment_name[$res_param_array['payment_code']]; | ||
| 210 | + $item_name = mb_convert_encoding(urldecode($res_param_array['item_name']), "EUC-JP" ,"auto"); | ||
| 211 | + $item_price = $res_param_array['item_price']; | ||
| 212 | +} | ||
| 213 | +else { | ||
| 214 | + // それ以外の決済の場合 | ||
| 215 | + $result_html = "ご注文ありがとうございました。"; | ||
| 216 | + $payment_name = $payment_name[$res_param_array['payment_code']]; | ||
| 217 | + $item_name = mb_convert_encoding(urldecode($res_param_array['item_name']), "EUC-JP" ,"auto"); | ||
| 218 | + $item_price = $res_param_array['item_price']; | ||
| 219 | + | ||
| 220 | +} | ||
| 221 | + | ||
| 222 | +//め〜るNiポン!の場合 | ||
| 223 | +if($res_param_array['memo1'] == "1"){ | ||
| 224 | + | ||
| 225 | + //登録済みチェック(F5回避) | ||
| 226 | + include("./inc/dbcon_PAY_ADM.inc"); | ||
| 227 | + $strSQL = "SELECT * FROM log_data_tbl WHERE order_number = '".$res_param_array['order_number']."'"; | ||
| 228 | +//echo $strSQL."<hr>"; | ||
| 229 | + $objRec = pg_exec($strSQL); | ||
| 230 | + if($objRec==false){ | ||
| 231 | + echo("SQL実行に失敗しました(SELECT)"); | ||
| 232 | + exit; | ||
| 233 | + } | ||
| 234 | + $dataCnt = pg_numrows($objRec); | ||
| 235 | + if($dataCnt <= 0){ | ||
| 236 | + //データがない場合のみ更新処理 | ||
| 237 | + | ||
| 238 | + //ポイント確認 | ||
| 239 | + include("./inc/dbcon_MLP_ADM.inc"); | ||
| 240 | + $strSQL = "SELECT * FROM point_tbl WHERE user_id = '".$res_param_array['user_id']."'"; | ||
| 241 | +//echo $strSQL."<hr>"; | ||
| 242 | + $objRec = pg_exec($strSQL); | ||
| 243 | + if($objRec==false){ | ||
| 244 | + echo("SQL実行に失敗しました(SELECT)"); | ||
| 245 | + exit; | ||
| 246 | + } | ||
| 247 | + if(pg_numrows($objRec) > 0){ | ||
| 248 | + $objF = pg_fetch_object($objRec, 0); | ||
| 249 | + $pointOLD = $objF->use_point; | ||
| 250 | + }else{ | ||
| 251 | + echo("該当データなし"); | ||
| 252 | + exit; | ||
| 253 | + } | ||
| 254 | + $strMEMO1 = "購入ポイント:".$res_param_array['memo2']; | ||
| 255 | + $strMEMO2 = "更新前ポイント:".$pointOLD; | ||
| 256 | + $strPointUPDATE = intval($res_param_array['memo2']) + intval($pointOLD); | ||
| 257 | + | ||
| 258 | + //団体名取得 | ||
| 259 | + $strSQL = "SELECT * FROM mst_kanri WHERE user_id = '".$res_param_array['user_id']."'"; | ||
| 260 | + $objRec = pg_exec($strSQL); | ||
| 261 | + if($objRec==false){ | ||
| 262 | + echo("SQL実行に失敗しました(SELECT)"); | ||
| 263 | + exit; | ||
| 264 | + } | ||
| 265 | + if(pg_numrows($objRec) > 0){ | ||
| 266 | + $objF = pg_fetch_object($objRec, 0); | ||
| 267 | + $pg_user_name = $objF->user_name; | ||
| 268 | + }else{ | ||
| 269 | + echo("該当データなし"); | ||
| 270 | + exit; | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + //クレジット決済ログ | ||
| 274 | + include("./inc/dbcon_PAY_ADM.inc"); | ||
| 275 | + $strSQL = ""; | ||
| 276 | + $strSQL .= "INSERT INTO log_data_tbl "; | ||
| 277 | + $strSQL .= " ( "; | ||
| 278 | + $strSQL .= " order_number, "; | ||
| 279 | + $strSQL .= " contract_code, "; | ||
| 280 | + $strSQL .= " user_id, "; | ||
| 281 | + $strSQL .= " user_name, "; | ||
| 282 | + $strSQL .= " user_mail_add, "; | ||
| 283 | + $strSQL .= " item_code, "; | ||
| 284 | + $strSQL .= " item_name, "; | ||
| 285 | + $strSQL .= " mission_code, "; | ||
| 286 | + $strSQL .= " item_price, "; | ||
| 287 | + $strSQL .= " process_code, "; | ||
| 288 | + $strSQL .= " yobi1, "; | ||
| 289 | + $strSQL .= " yobi2, "; | ||
| 290 | + $strSQL .= " yobi3, "; | ||
| 291 | + $strSQL .= " service_flg, "; | ||
| 292 | + $strSQL .= " pg_group_id, "; | ||
| 293 | + $strSQL .= " pg_user_id, "; | ||
| 294 | + $strSQL .= " update_datetime "; | ||
| 295 | + $strSQL .= " ) "; | ||
| 296 | + $strSQL .= " VALUES( "; | ||
| 297 | + $strSQL .= " '".$res_param_array['order_number']."', "; | ||
| 298 | + $strSQL .= " '".$res_param_array['contract_code']."', "; | ||
| 299 | + $strSQL .= " '".$res_param_array['user_id']."', "; | ||
| 300 | + $strSQL .= " '".$res_param_array['user_name']."', "; | ||
| 301 | + $strSQL .= " '".$res_param_array['user_mail_add']."', "; | ||
| 302 | + $strSQL .= " '".$res_param_array['item_code']."', "; | ||
| 303 | + $strSQL .= " '".mb_convert_encoding(urldecode($res_param_array['item_name']), "EUC-JP" ,"auto")."', "; | ||
| 304 | + $strSQL .= " '".$res_param_array['mission_code']."', "; | ||
| 305 | + $strSQL .= " '".$res_param_array['item_price']."', "; | ||
| 306 | + $strSQL .= " '".$res_param_array['process_code']."', "; | ||
| 307 | + $strSQL .= " '".$strMEMO1."', "; | ||
| 308 | + $strSQL .= " '".$strMEMO2."', "; | ||
| 309 | + $strSQL .= " '', "; | ||
| 310 | + $strSQL .= " '".$res_param_array['memo1']."', "; | ||
| 311 | + $strSQL .= " '".$res_param_array['user_id']."', "; | ||
| 312 | + $strSQL .= " '', "; | ||
| 313 | + $strSQL .= " '".date("Y/m/d H:i:s")."' "; | ||
| 314 | + $strSQL .= " ) "; | ||
| 315 | +//echo $strSQL."<hr>"; | ||
| 316 | + $objRec = pg_exec($strSQL); | ||
| 317 | + if($objRec==false){ | ||
| 318 | + echo("SQL実行に失敗しました(INSERT)"); | ||
| 319 | + exit; | ||
| 320 | + } | ||
| 321 | + | ||
| 322 | + //ポイント更新 | ||
| 323 | + include("./inc/dbcon_MLP_ADM.inc"); | ||
| 324 | + $strSQL = ""; | ||
| 325 | + $strSQL .= "UPDATE point_tbl "; | ||
| 326 | + $strSQL .= "SET use_point = ".$strPointUPDATE." "; | ||
| 327 | + $strSQL .= "WHERE user_id = '".$res_param_array['user_id']."'"; | ||
| 328 | +//echo $strSQL."<hr>"; | ||
| 329 | + $objRec = pg_exec($strSQL); | ||
| 330 | + if($objRec==false){ | ||
| 331 | + echo("SQL実行に失敗しました(UPDATE)"); | ||
| 332 | + exit; | ||
| 333 | + } | ||
| 334 | + | ||
| 335 | + //メール送信 | ||
| 336 | + //各種設定-----------// | ||
| 337 | + include("./inc/jcode.php"); | ||
| 338 | + $strFrom = "From: support@media-tek.co.jp\n"; | ||
| 339 | + $strSubject = "【め〜るNiポン】ポイントご購入完了のお知らせ"; | ||
| 340 | + $strSubject = "=?iso-2022-jp?B?" . base64_encode(jcodeconvert($strSubject, 0, 3)) . "?="; | ||
| 341 | + $GMT = date("Z"); | ||
| 342 | + $GMT_ABS = abs($GMT); | ||
| 343 | + $GMT_HOUR = floor($GMT_ABS / 3600); | ||
| 344 | + $GMT_MIN = floor(($GMT_ABS - $GMT_HOUR * 3600) / 60); | ||
| 345 | + if ($GMT >= 0) $GMT_FLG = "+"; else $GMT_FLG = "-"; | ||
| 346 | + $GMT_RFC = date("D, d M Y H:i:s ").sprintf($GMT_FLG."%02d%02d", $GMT_HOUR, $GMT_MIN); | ||
| 347 | + $Headers = "Date: ".$GMT_RFC."\n"; | ||
| 348 | + $Headers .= $strFrom; | ||
| 349 | + $Headers .= "Bcc: support@media-tek.co.jp\n"; | ||
| 350 | + $Headers .= "Subject: $strSubject\n"; | ||
| 351 | + $Headers .= "MIME-Version: 1.0\n"; | ||
| 352 | + $Headers .= "X-Mailer: PHP/".phpversion()."\n"; | ||
| 353 | + $Headers .= "Content-type: text/plain; charset=ISO-2022-JP\n"; | ||
| 354 | + $Headers .= "Content-Transfer-Encoding: 7bit"; | ||
| 355 | + //本文 | ||
| 356 | + $strComment = ""; | ||
| 357 | + $strComment .= $res_param_array['user_name']." 様\n"; | ||
| 358 | + $strComment .= "\n"; | ||
| 359 | + $strComment .= "この度は【め〜るNiポン】のポイントをご購入いただき、ありがとうございます。\n"; | ||
| 360 | + $strComment .= "\n"; | ||
| 361 | + $strComment .= "ご購入内容------------------------------------------------------------------\n"; | ||
| 362 | + $strComment .= "■ご利用団体名 :".$pg_user_name." 様\n"; | ||
| 363 | + $strComment .= "■ご購入ポイント:".number_format($res_param_array['memo2'])."ポイント\n"; | ||
| 364 | + $strComment .= "■ご購入価格合計:".number_format($res_param_array['item_price'])."円\n"; | ||
| 365 | + $strComment .= "\n"; | ||
| 366 | + $strComment .= "■お支払い方法 :".$payment_name."\n"; | ||
| 367 | + $strComment .= "----------------------------------------------------------------------------\n"; | ||
| 368 | + $strComment .= "\n"; | ||
| 369 | + $strComment .= "■ご利用可能ポイント数(".date("Y年m月d日 H時i分")." 現在)\n"; | ||
| 370 | + $strComment .= " ".number_format($strPointUPDATE)."ポイント\n"; | ||
| 371 | + $strComment .= "\n"; | ||
| 372 | + $strComment .= "※ご購入されたポイントは即時追加させていただいております\n"; | ||
| 373 | + $strComment .= " サービスの性質上、返品・返金は出来ません。\n"; | ||
| 374 | + $strComment .= "\n"; | ||
| 375 | + $strComment .= "※このメールに心当たりのない場合、<support@media-tek.co.jp>までご連絡ください。\n"; | ||
| 376 | + $strComment .= "\n"; | ||
| 377 | + $strComment .= "今後とも【め〜るNiポン】をよろしくお願いいたします。\n"; | ||
| 378 | + $strComment .= "----------------------------------------------------------------------------\n"; | ||
| 379 | + $strComment .= "め〜るNiポン:http://www.mail-ni-pon.net\n"; | ||
| 380 | + $strComment .= "メディアテック株式会社:http://www.media-tek.co.jp\n"; | ||
| 381 | + $strComment .= "----------------------------------------------------------------------------\n"; | ||
| 382 | + //エンコード設定 | ||
| 383 | + $strComment = mb_convert_encoding($strComment, "JIS", "auto"); | ||
| 384 | + //メール送信プログラム | ||
| 385 | + $intBool = mail($res_param_array['user_mail_add'], $strSubject, $strComment, $Headers); | ||
| 386 | + | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + $result_html .= "<br>(め〜るNiポン!での画面を更新、または別ページへの移動でポイント表示が更新されます)"; | ||
| 390 | +} | ||
| 391 | + | ||
| 392 | +$o_smarty->assign('payment_name' , $payment_name); | ||
| 393 | +$o_smarty->assign('item_name' , $item_name); | ||
| 394 | +$o_smarty->assign('item_price' , number_format($item_price)); | ||
| 395 | +$o_smarty->assign('result_html' , $result_html); | ||
| 396 | +$o_smarty->assign('err_msg' , $err_msg); | ||
| 397 | + | ||
| 398 | +$o_smarty->display('complete.tpl'); | ||
| 399 | + | ||
| 400 | +?> |
confirmation.php
0 → 100644
| 1 | +<?php | ||
| 2 | +//***************************************************************************** | ||
| 3 | +//* プログラムID:confirmation.php | ||
| 4 | +//* 機能 :クレジット決済確認画面(イプシロン登録ページ!!) | ||
| 5 | +//***************************************************************************** | ||
| 6 | +header( "Content-type: text/html; charset=EUC-JP"); | ||
| 7 | + | ||
| 8 | +include('./inc/smarty.conf'); | ||
| 9 | + | ||
| 10 | +$SrvcCD = $_POST["SrvcCD"]; | ||
| 11 | +$RetPage = $_POST["RetPage"]; | ||
| 12 | +$hidName = $_POST["hidName"]; | ||
| 13 | +$hidPoint = $_POST["hidPoint"]; | ||
| 14 | +$hidMoney = $_POST["hidMoney"]; | ||
| 15 | +$selPoint = $_POST["selPoint"]; | ||
| 16 | +$pg_user_id = $_POST["pg_user_id"]; | ||
| 17 | +$pg_user_name = $_POST["pg_user_name"]; | ||
| 18 | +$inpMail = $_POST["inpMail"]; | ||
| 19 | +$inpName = $_POST["inpName"]; | ||
| 20 | +if($SrvcCD == "1"){ | ||
| 21 | +//め〜るNiポン! | ||
| 22 | + $SERVICE_NAME = "め〜るNiポン!"; //サービス名 | ||
| 23 | + $srvcName = $hidName; //商品名 | ||
| 24 | + $srvcMoney = number_format($hidMoney)."円"; //金額(表示) | ||
| 25 | + $srvcOrderNumber = "MLP".date("Ymd").sprintf("%05d",rand(0,99999)); //オーダー番号 | ||
| 26 | + $srvcMissionCode = 1; //一回のみ | ||
| 27 | + $srvcProcessCode = 1; //初回課金 | ||
| 28 | + $srvcItemCode = "MLP-".$hidPoint; //商品コード | ||
| 29 | + $srvcItemName = $SERVICE_NAME.$srvcName; //商品名 | ||
| 30 | + $srvcItemPrice = $hidMoney; //金額 | ||
| 31 | + $srvcUserID = $pg_user_id; //ユーザID | ||
| 32 | + $srvcUserName = $inpName; //ユーザ名 | ||
| 33 | + $srvcUserMail = $inpMail; //ユーザメールアドレス | ||
| 34 | + $srvcMemo1 = $SrvcCD; //サービスコード | ||
| 35 | + $srvcMemo2 = $hidPoint; //購入ポイント | ||
| 36 | + | ||
| 37 | +} | ||
| 38 | +//クレジット決済お決まりコード | ||
| 39 | +// EPSILON オーダー情報送信プログラム(PHP版) | ||
| 40 | +// このプログラムの実行には、以下のモジュールが必要です。 | ||
| 41 | +// ・PHP(ver5,,,,, | ||
| 42 | +// ・PEAR: | ||
| 43 | +// ・PEAR:HTTP_Request: | ||
| 44 | +// ・PEAR:Net_URL: | ||
| 45 | +// ・PEAR:Net_Socket: | ||
| 46 | +// ・PEAR:XML_Parser: | ||
| 47 | +// ・PEAR:XML_Serializer: | ||
| 48 | +//include Libraly | ||
| 49 | +//PEAR拡張モジュールの読み込み。 | ||
| 50 | +//既に該当のモジュールをインストール済みの場合は適宜読み込み先パスを変更してください。 | ||
| 51 | +require_once "./lib/http/Request.php"; | ||
| 52 | +require_once "./lib/xml/Unserializer.php"; | ||
| 53 | +//char setting | ||
| 54 | +//サーバ環境に応じ適宜変更してください。 | ||
| 55 | +mb_language("Japanese"); | ||
| 56 | +mb_internal_encoding("EUC-JP"); | ||
| 57 | +// 変数の初期化 | ||
| 58 | +// FORMで送信した内容をこのプログラムファイルで受け取るために、プログラムファイルの名前を設定します。 | ||
| 59 | +$my_self = "confirmation.php"; | ||
| 60 | +// オーダー情報送信先URL(試験用) | ||
| 61 | +// 本番環境でご利用の場合は契約時に弊社からお送りするURLに変更してください。 | ||
| 62 | +//$order_url = "http://beta.epsilon.jp/cgi-bin/order/receive_order3.cgi"; | ||
| 63 | +$order_url = "https://secure.epsilon.jp/cgi-bin/order/receive_order3.cgi"; | ||
| 64 | + | ||
| 65 | +//// 以下の各項目についてご利用環境に沿った設定に変更してください | ||
| 66 | +// 契約番号(8桁) オンライン登録時に発行された契約番号を入力してください。 | ||
| 67 | +$contract_code = "33317000"; | ||
| 68 | +// 注文番号(注文毎にユニークな番号を割り当てます。ここでは仮に乱数を使用しています。) | ||
| 69 | +$order_number =$srvcOrderNumber; | ||
| 70 | +// 決済区分 (使用したい決済方法を指定してください。登録時に申し込まれていない決済方法は指定できません。) | ||
| 71 | +$st_code = '10000-0000-00000'; // 指定方法はCGI設定マニュアルの「決済区分について」を参照してください。 | ||
| 72 | +// 課金区分 (1:一回のみ 2〜10:月次課金) | ||
| 73 | +// 月次課金について契約がない場合は利用できません。また、月次課金を設定した場合決済区分はクレジットカード決済のみとなります。 | ||
| 74 | +$mission_code = $srvcMissionCode; | ||
| 75 | +// 処理区分 (1:初回課金 2:登録済み課金 3:登録のみ 4:登録変更 8:月次課金解除 9:退会) | ||
| 76 | +// 月次課金をご利用にならない場合は1:初回課金をご利用ください。 | ||
| 77 | +// 各処理区分のご利用に関してはCGI設定マニュアルの「処理区分について」を参照してください。 | ||
| 78 | +$process_code = $srvcProcessCode; | ||
| 79 | +// 追加情報 1,2 (入力は必須ではありません) | ||
| 80 | +$memo1 = $srvcMemo1; | ||
| 81 | +$memo2 = $srvcMemo2; | ||
| 82 | +// 商品コード (商品毎に識別コードを指定してください。ここでは仮に固定の値を指定しています。) | ||
| 83 | +$item_code = $srvcItemCode; | ||
| 84 | +//// 変更設定ここまで | ||
| 85 | +// エラーが発生した場合のメッセージ | ||
| 86 | +$err_msg; | ||
| 87 | +// オーダー情報を送信した結果を格納する連想配列 | ||
| 88 | +$responce = array(); | ||
| 89 | +// 商品名と価格 | ||
| 90 | +$item_name = $srvcItemName; | ||
| 91 | +$item_price = $srvcItemPrice; | ||
| 92 | +//echo $item_price."<hr>"; | ||
| 93 | + | ||
| 94 | +// ユーザー固有情報 | ||
| 95 | +// ここでは仮にフォームに入力してもらっていますが、ユーザーID等の値はクライアント様側で | ||
| 96 | +// 管理されている値を使用してください。 | ||
| 97 | +$user_id = $srvcUserID; // ユーザーID | ||
| 98 | +$user_name = $srvcUserName; // ユーザー氏名 | ||
| 99 | +$user_mail_add = $srvcUserMail ;// メールアドレス | ||
| 100 | + | ||
| 101 | +// CGIの状態(入力画面から実行されたか、確認画面から実行されたか)を判別する値 | ||
| 102 | +$come_from = $_REQUEST['come_from']; // CGIの状態設定 | ||
| 103 | + | ||
| 104 | +if ($come_from == 'kakunin'){ // 購入確認画面で[確認]ボタンを押した場合 | ||
| 105 | + | ||
| 106 | + //EPSILONに情報を送信します。 | ||
| 107 | + | ||
| 108 | + // httpリクエスト用のオプションを指定 | ||
| 109 | + $option = array( | ||
| 110 | + "timeout" => "20", // タイムアウトの秒数指定 | ||
| 111 | + // "allowRedirects" => true, // リダイレクトの許可設定(true/false) | ||
| 112 | + // "maxRedirects" => 3, // リダイレクトの最大回数 | ||
| 113 | + ); | ||
| 114 | + | ||
| 115 | + // HTTP_Requestの初期化 | ||
| 116 | + $request = new HTTP_Request($order_url, $option); | ||
| 117 | + | ||
| 118 | + // HTTPのヘッダー設定 | ||
| 119 | + //$http->addHeader("User-Agent", "xxxxx"); | ||
| 120 | + //$http->addHeader("Referer", "xxxxxx"); | ||
| 121 | + | ||
| 122 | + //set method | ||
| 123 | + $request->setMethod(HTTP_REQUEST_METHOD_POST); | ||
| 124 | + //set post data | ||
| 125 | + $request->addPostData('contract_code', $contract_code); | ||
| 126 | + $request->addPostData('user_id', $user_id); | ||
| 127 | + $request->addPostData('user_name', mb_convert_encoding($user_name, "EUC-JP", "auto")); | ||
| 128 | + $request->addPostData('user_mail_add', $user_mail_add); | ||
| 129 | + $request->addPostData('item_code', $item_code); | ||
| 130 | + $request->addPostData('item_name', mb_convert_encoding($item_name, "EUC-JP", "auto")); | ||
| 131 | + $request->addPostData('order_number', $order_number); | ||
| 132 | + $request->addPostData('st_code', $st_code); | ||
| 133 | + | ||
| 134 | + $request->addPostData('mission_code', $mission_code); | ||
| 135 | + $request->addPostData('item_price', $item_price); | ||
| 136 | + $request->addPostData('process_code', $process_code); | ||
| 137 | + $request->addPostData('memo1', $memo1); | ||
| 138 | + $request->addPostData('memo2', $memo2); | ||
| 139 | + $request->addPostData('xml', '1'); | ||
| 140 | + | ||
| 141 | + // HTTPリクエスト実行 | ||
| 142 | + $response = $request->sendRequest(); | ||
| 143 | + if (!PEAR::isError($response)) { | ||
| 144 | + | ||
| 145 | + // 応答内容(XML)の解析 | ||
| 146 | + | ||
| 147 | + $res_code = $request->getResponseCode(); | ||
| 148 | + $res_content = $request->getResponseBody(); | ||
| 149 | + | ||
| 150 | + //xml unserializer | ||
| 151 | + $temp_xml_res = str_replace("x-sjis-cp932", "EUC-JP", $res_content); | ||
| 152 | + $unserializer =& new XML_Unserializer(); | ||
| 153 | + $unserializer->setOption('parseAttributes', TRUE); | ||
| 154 | + $unseriliz_st = $unserializer->unserialize($temp_xml_res); | ||
| 155 | + if ($unseriliz_st === true) { | ||
| 156 | + //xmlを解析 | ||
| 157 | + $res_array = $unserializer->getUnserializedData(); | ||
| 158 | + $is_xml_error = false; | ||
| 159 | + $xml_redirect_url = ""; | ||
| 160 | + $xml_error_cd = ""; | ||
| 161 | + $xml_error_msg = ""; | ||
| 162 | + $xml_memo1_msg = ""; | ||
| 163 | + $xml_memo2_msg = ""; | ||
| 164 | + foreach($res_array['result'] as $uns_k => $uns_v){ | ||
| 165 | + //$debug_printj .= "<br />k=" . $uns_k; | ||
| 166 | + list($result_atr_key, $result_atr_val) = each($uns_v); | ||
| 167 | + //$debug_printj .= "<br />result_atr_key=" . $result_atr_key; | ||
| 168 | + //$debug_printj .= "<br />result_atr_val=" . $result_atr_val; | ||
| 169 | + | ||
| 170 | + switch ($result_atr_key) { | ||
| 171 | + case 'redirect': | ||
| 172 | + $xml_redirect_url = rawurldecode($result_atr_val); | ||
| 173 | + break; | ||
| 174 | + case 'err_code': | ||
| 175 | + $is_xml_error = true; | ||
| 176 | + $xml_error_cd = $result_atr_val; | ||
| 177 | + break; | ||
| 178 | + case 'err_detail': | ||
| 179 | + $xml_error_msg = mb_convert_encoding(urldecode($result_atr_val), "EUC-JP" ,"auto"); | ||
| 180 | + break; | ||
| 181 | + case 'memo1': | ||
| 182 | + $xml_memo1_msg = mb_convert_encoding(urldecode($result_atr_val), "EUC-JP" ,"auto"); | ||
| 183 | + break; | ||
| 184 | + case 'memo2': | ||
| 185 | + $xml_memo2_msg = mb_convert_encoding(urldecode($result_atr_val), "EUC-JP" ,"auto"); | ||
| 186 | + break; | ||
| 187 | + default: | ||
| 188 | + break; | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + }else{ | ||
| 193 | + //xml parser error | ||
| 194 | + $err_msg = "xml parser error<br><br>"; | ||
| 195 | + //exit(1); | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + | ||
| 199 | + | ||
| 200 | + }else{ //http error | ||
| 201 | + | ||
| 202 | + //$debug_printj .= "http error"; | ||
| 203 | + $err_msg = "データの送信に失敗しました<br><br>"; | ||
| 204 | + $err_msg .= "<br />res_statusCd=" . $request->getResponseCode(); | ||
| 205 | + $err_msg .= "<br />res_status=" . $request->getResponseHeader('Status'); | ||
| 206 | + | ||
| 207 | + //exit(1); | ||
| 208 | + | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + if($err_msg <> ""){ | ||
| 212 | + // | ||
| 213 | + }elseif($is_xml_error){ | ||
| 214 | + // データ送信結果が失敗だった場合、オーダー入力画面に戻し、エラーメッセージを表示します。 | ||
| 215 | + $err_msg = "error_cd:" . $xml_error_cd . "error_msg:" . $xml_error_msg; | ||
| 216 | + //exit(1); | ||
| 217 | + }else{ | ||
| 218 | + // データ送信に成功した場合、リダイレクト先URLへリダイレクトさせてください。 | ||
| 219 | + header("Location: " . $xml_redirect_url); | ||
| 220 | + //exit(0); | ||
| 221 | + } | ||
| 222 | + | ||
| 223 | +} | ||
| 224 | +//ここまで | ||
| 225 | + | ||
| 226 | + | ||
| 227 | + | ||
| 228 | +$o_smarty->assign('SrvcCD' , $SrvcCD); | ||
| 229 | +$o_smarty->assign('SERVICE_NAME' , $SERVICE_NAME); | ||
| 230 | +$o_smarty->assign('RetPage' ,$RetPage); | ||
| 231 | +$o_smarty->assign('srvcName' , $srvcName); | ||
| 232 | +$o_smarty->assign('srvcMoney' , $srvcMoney); | ||
| 233 | +$o_smarty->assign('hidMoney' , $hidMoney); | ||
| 234 | +$o_smarty->assign('hidPoint' , $hidPoint); | ||
| 235 | +$o_smarty->assign('selPoint' , $selPoint); | ||
| 236 | +$o_smarty->assign('inpMail' , $_POST["inpMail"]); | ||
| 237 | +$o_smarty->assign('inpName' , $_POST["inpName"]); | ||
| 238 | + | ||
| 239 | +$o_smarty->assign('pg_user_id',$pg_user_id); | ||
| 240 | +$o_smarty->assign('pg_user_name',$pg_user_name); | ||
| 241 | + | ||
| 242 | +$o_smarty->assign('err_msg' , $err_msg); | ||
| 243 | + | ||
| 244 | +//イプシロン決済用データ | ||
| 245 | +$o_smarty->assign('contract_code', $contract_code); | ||
| 246 | +$o_smarty->assign('user_id', $user_id); | ||
| 247 | +$o_smarty->assign('user_name', $user_name); | ||
| 248 | +$o_smarty->assign('user_mail_add', $user_mail_add); | ||
| 249 | +$o_smarty->assign('item_code', $item_code); | ||
| 250 | +$o_smarty->assign('item_name', $item_name); | ||
| 251 | +$o_smarty->assign('order_number', $order_number); | ||
| 252 | +$o_smarty->assign('st_code', $st_code); | ||
| 253 | +$o_smarty->assign('mission_code', $mission_code); | ||
| 254 | +$o_smarty->assign('item_price', $item_price); | ||
| 255 | +$o_smarty->assign('process_code', $process_code); | ||
| 256 | +$o_smarty->assign('memo1', $memo1); | ||
| 257 | +$o_smarty->assign('memo2', $memo2); | ||
| 258 | + | ||
| 259 | +$o_smarty->display('confirmation.tpl'); | ||
| 260 | + | ||
| 261 | + | ||
| 262 | +?> |
css/style.css
0 → 100644
| 1 | +/* CSS Document */ | ||
| 2 | + | ||
| 3 | +* { | ||
| 4 | + margin: 0; | ||
| 5 | + padding: 0; | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +h1{ | ||
| 9 | + font-size: 0.9em; | ||
| 10 | + padding: 7px 0 7px 7px; | ||
| 11 | + width: auto; | ||
| 12 | + background-color: #FF9999; | ||
| 13 | + | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +h2{ | ||
| 17 | + font-size: 0.9em; | ||
| 18 | + padding: 7px 0 7px 7px; | ||
| 19 | +} | ||
| 20 | + | ||
| 21 | +h3{ | ||
| 22 | + font-size: 0.9em; | ||
| 23 | + padding: 7px 0 7px 7px; | ||
| 24 | +} | ||
| 25 | + | ||
| 26 | + | ||
| 27 | +p{ | ||
| 28 | + font-size: 0.85em; | ||
| 29 | + line-height: 130%; | ||
| 30 | + margin-top: 0; | ||
| 31 | + margin-left: 10px; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +.page_font{ | ||
| 35 | + font-size: 0.85em; | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +.page_sfont{ | ||
| 39 | + font-size: 0.75em; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +hr.line_b{ | ||
| 43 | + margin: 0; | ||
| 44 | + padding: 0; | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | + | ||
| 48 | +/* クレジット決済ページ */ | ||
| 49 | + | ||
| 50 | +#waku{ | ||
| 51 | + border: 1px solid #333; | ||
| 52 | + width: 257px; | ||
| 53 | + padding: 7px; | ||
| 54 | + /* | ||
| 55 | + line-height: 120%; | ||
| 56 | + */ | ||
| 57 | + margin-left: 7px; | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +div.kadom { | ||
| 61 | + border-radius: 10px; /* CSS3 */ | ||
| 62 | + -moz-border-radius: 10px; /* Firefox */ | ||
| 63 | + -webkit-border-radius: 10px; /* Safari,Chrome */ | ||
| 64 | + | ||
| 65 | + border: 2px #FFB417 solid; /* 枠線の装飾 */ | ||
| 66 | + background-color: #FFCC66; /* 背景色 */ | ||
| 67 | + width: 260px; | ||
| 68 | + margin-left: 7px; | ||
| 69 | + padding: 5px; | ||
| 70 | + line-height: 120%; | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +/* クレジット決済 確認ページ */ | ||
| 74 | + | ||
| 75 | +#ta_bor table{ | ||
| 76 | + border: 1px solid #333; | ||
| 77 | + border-collapse: collapse; | ||
| 78 | + margin-left: 7px; | ||
| 79 | + margin-bottom: 7px; | ||
| 80 | +} | ||
| 81 | + | ||
| 82 | +#ta_bor th{ | ||
| 83 | + border: 1px solid #333; | ||
| 84 | + background-color: #FFE6B0; | ||
| 85 | + font-size: 0.85em; | ||
| 86 | + padding: 5px; | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +#ta_bor td{ | ||
| 90 | + border: 1px solid #333; | ||
| 91 | + background-color: #FFF; | ||
| 92 | + font-size: 0.85em; | ||
| 93 | + padding: 5px; | ||
| 94 | +} | ||
| 95 | + |
error.php
0 → 100644
| 1 | +<?php | ||
| 2 | +//***************************************************************************** | ||
| 3 | +//* プログラムID:srvc1000.php | ||
| 4 | +//* 機能 :め〜るNiポン! ポイント購入画面 | ||
| 5 | +//***************************************************************************** | ||
| 6 | +header( "Content-type: text/html; charset=EUC-JP"); | ||
| 7 | + | ||
| 8 | +?> | ||
| 9 | +エラー画面 |
images/e-gru.jpg
0 → 100644
51.7 KB
images/logo_master.gif
0 → 100644
2.21 KB
images/logo_visa.gif
0 → 100644
1.41 KB
images/mail.jpg
0 → 100644
43.5 KB
inc/dbcon_MLP_ADM.inc
0 → 100644
inc/dbcon_PAY_ADM.inc
0 → 100644
inc/jcode.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/************************************************************************* | ||
| 3 | + ________________________________ | ||
| 4 | + | ||
| 5 | + jcode.phps by TOMO | ||
| 6 | + ________________________________ | ||
| 7 | + | ||
| 8 | + | ||
| 9 | + [Version] : 1.34 (2002/10/10) | ||
| 10 | + [URL] : http://www.spencernetwork.org/ | ||
| 11 | + [E-MAIL] : groove@spencernetwork.org | ||
| 12 | + [Changes] : | ||
| 13 | + v1.30 Changed XXXtoUTF8 and UTF8toXXX with conversion tables. | ||
| 14 | + v1.31 Deleted a useless and harmful line in JIStoUTF8() (^^; | ||
| 15 | + v1.32 Fixed miss type of jsubstr(). | ||
| 16 | + Fixed HANtoZEN_EUC(), HANtoZEN_SJIS() and HANtoZEN_JIS(). | ||
| 17 | + v1.33 Fixed JIStoXXX(), HANtoZEN_JIS() and ZENtoHAN_JIS(). | ||
| 18 | + Added jstr_split() as O-MA-KE No.4. | ||
| 19 | + Added jstrcut() as O-MA-KE No.5. | ||
| 20 | + Changed the logic of AutoDetect() | ||
| 21 | + v1.34 Fixed ZENtoHAN_SJIS() | ||
| 22 | + | ||
| 23 | + * jcode.phps is free but without any warranty. | ||
| 24 | + * use this script at your own risk. | ||
| 25 | + | ||
| 26 | +***************************************************************************/ | ||
| 27 | + | ||
| 28 | +function JcodeConvert(&$str, $from, $to) | ||
| 29 | +{ | ||
| 30 | + //0:AUTO DETECT | ||
| 31 | + //1:EUC-JP | ||
| 32 | + //2:Shift_JIS | ||
| 33 | + //3:ISO-2022-JP(JIS) | ||
| 34 | + //4:UTF-8 | ||
| 35 | + | ||
| 36 | + if ($from == 0) $from = AutoDetect($str); | ||
| 37 | + | ||
| 38 | + if ($from == 1 && $to == 2) return EUCtoSJIS($str); | ||
| 39 | + if ($from == 1 && $to == 3) return EUCtoJIS($str); | ||
| 40 | + if ($from == 1 && $to == 4) return EUCtoUTF8($str); | ||
| 41 | + if ($from == 2 && $to == 1) return SJIStoEUC($str); | ||
| 42 | + if ($from == 2 && $to == 3) return SJIStoJIS($str); | ||
| 43 | + if ($from == 2 && $to == 4) return SJIStoUTF8($str); | ||
| 44 | + if ($from == 3 && $to == 1) return JIStoEUC($str); | ||
| 45 | + if ($from == 3 && $to == 2) return JIStoSJIS($str); | ||
| 46 | + if ($from == 3 && $to == 4) return JIStoUTF8($str); | ||
| 47 | + if ($from == 4 && $to == 1) return UTF8toEUC($str); | ||
| 48 | + if ($from == 4 && $to == 2) return UTF8toSJIS($str); | ||
| 49 | + if ($from == 4 && $to == 3) return UTF8toJIS($str); | ||
| 50 | + | ||
| 51 | + return $str; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +function AutoDetect(&$str) | ||
| 55 | +{ | ||
| 56 | + //0:US-ASCII | ||
| 57 | + //1:EUC-JP | ||
| 58 | + //2:Shift_JIS | ||
| 59 | + //3:ISO-2022-JP(JIS) | ||
| 60 | + //4:UTF-8 | ||
| 61 | + //5:Unknown | ||
| 62 | + | ||
| 63 | + if (!ereg("[\x80-\xFF]", $str)) { | ||
| 64 | + // --- Check ISO-2022-JP --- | ||
| 65 | + if (ereg("\x1B", $str)) return 3; // ISO-2022-JP(JIS) | ||
| 66 | + return 0; //US-ASCII | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + $b = unpack('C*', ereg_replace("^[^\x80-\xFF]+", "", $str)); | ||
| 70 | + $n = count($b); | ||
| 71 | + | ||
| 72 | + // --- Check EUC-JP --- | ||
| 73 | + $euc = TRUE; | ||
| 74 | + for ($i = 1; $i <= $n; ++$i){ | ||
| 75 | + if ($b[$i] < 0x80) { | ||
| 76 | + continue; | ||
| 77 | + } | ||
| 78 | + if ($b[$i] < 0x8E) { | ||
| 79 | + $euc = FALSE; break; | ||
| 80 | + } | ||
| 81 | + if ($b[$i] == 0x8E) { | ||
| 82 | + if (!isset($b[++$i])) { | ||
| 83 | + $euc = FALSE; break; | ||
| 84 | + } | ||
| 85 | + if (($b[$i] < 0xA1) || (0xDF < $b[$i])) { | ||
| 86 | + $euc = FALSE; break; | ||
| 87 | + } | ||
| 88 | + } elseif ((0xA1 <= $b[$i]) && ($b[$i] <= 0xFE)) { | ||
| 89 | + if (!isset($b[++$i])) { | ||
| 90 | + $euc = FALSE; break; | ||
| 91 | + } | ||
| 92 | + if (($b[$i] < 0xA1) || (0xFE < $b[$i])) { | ||
| 93 | + $euc = FALSE; break; | ||
| 94 | + } | ||
| 95 | + } else { | ||
| 96 | + $euc = FALSE; break; | ||
| 97 | + } | ||
| 98 | + } | ||
| 99 | + if ($euc) return 1; // EUC-JP | ||
| 100 | + | ||
| 101 | + // --- Check UTF-8 --- | ||
| 102 | + $utf8 = TRUE; | ||
| 103 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 104 | + if (($b[$i] < 0x80)) { | ||
| 105 | + continue; | ||
| 106 | + } | ||
| 107 | + if ((0xC0 <= $b[$i]) && ($b[$i] <=0xDF)) { | ||
| 108 | + if (!isset($b[++$i])) { | ||
| 109 | + $utf8 = FALSE; break; | ||
| 110 | + } | ||
| 111 | + if (($b[$i] < 0x80) || (0xEF < $b[$i])) { | ||
| 112 | + $utf8 = FALSE; break; | ||
| 113 | + } | ||
| 114 | + } elseif ((0xE0 <= $b[$i]) && ($b[$i] <= 0xEF)) { | ||
| 115 | + if (!isset($b[++$i])) { | ||
| 116 | + $utf8 = FALSE; break; | ||
| 117 | + } | ||
| 118 | + if (($b[$i] < 0x80) || (0xBF < $b[$i])) { | ||
| 119 | + $utf8 = FALSE; break; | ||
| 120 | + } | ||
| 121 | + if (!isset($b[++$i])) { | ||
| 122 | + $utf8 = FALSE; break; | ||
| 123 | + } | ||
| 124 | + if (($b[$i] < 0x80) || (0xBF < $b[$i])) { | ||
| 125 | + $utf8 = FALSE; break; | ||
| 126 | + } | ||
| 127 | + } else { | ||
| 128 | + $utf8 = FALSE; break; | ||
| 129 | + } | ||
| 130 | + } | ||
| 131 | + if ($utf8) return 4; // UTF-8 | ||
| 132 | + | ||
| 133 | + // --- Check Shift_JIS --- | ||
| 134 | + $sjis = TRUE; | ||
| 135 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 136 | + if (($b[$i] <= 0x80) || (0xA1 <= $b[$i] && $b[$i] <= 0xDF)) { | ||
| 137 | + continue; | ||
| 138 | + } | ||
| 139 | + if (($b[$i] == 0xA0) || ($b[$i] > 0xEF)) { | ||
| 140 | + $sjis = FALSE; break; | ||
| 141 | + } | ||
| 142 | + if (!isset($b[++$i])) { | ||
| 143 | + $sjis = FALSE; break; | ||
| 144 | + } | ||
| 145 | + if (($b[$i] < 0x40) || ($b[$i] == 0x7F) || ($b[$i] > 0xFC)){ | ||
| 146 | + $sjis = FALSE; break; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + if ($sjis) return 2; // Shift_JIS | ||
| 150 | + | ||
| 151 | + return 5; // Unknown | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +function HANtoZEN(&$str, $encode) | ||
| 155 | +{ | ||
| 156 | + //0:PASS | ||
| 157 | + //1:EUC-JP | ||
| 158 | + //2:Shift_JIS | ||
| 159 | + //3:ISO-2022-JP(JIS) | ||
| 160 | + //4:UTF-8 | ||
| 161 | + | ||
| 162 | + if ($encode == 0) return $str; | ||
| 163 | + if ($encode == 1) return HANtoZEN_EUC($str); | ||
| 164 | + if ($encode == 2) return HANtoZEN_SJIS($str); | ||
| 165 | + if ($encode == 3) return HANtoZEN_JIS($str); | ||
| 166 | + if ($encode == 4) return HANtoZEN_UTF8($str); | ||
| 167 | + | ||
| 168 | + return $str; | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +function ZENtoHAN(&$str, $encode, $kana=1, $alph=1) | ||
| 172 | +{ | ||
| 173 | + //0:PASS | ||
| 174 | + //1:EUC-JP | ||
| 175 | + //2:Shift_JIS | ||
| 176 | + //3:ISO-2022-JP(JIS) | ||
| 177 | + | ||
| 178 | + if ($encode == 0) return $str; | ||
| 179 | + if ($encode == 1) return ZENtoHAN_EUC($str, $kana, $alph, $kana); | ||
| 180 | + if ($encode == 2) return ZENtoHAN_SJIS($str, $kana, $alph, $kana); | ||
| 181 | + if ($encode == 3) return ZENtoHAN_JIS($str, $kana, $alph, $kana); | ||
| 182 | + | ||
| 183 | + return $str; | ||
| 184 | +} | ||
| 185 | + | ||
| 186 | +function JIStoSJIS(&$str_JIS) | ||
| 187 | +{ | ||
| 188 | + $str_SJIS = ''; | ||
| 189 | + $mode = 0; | ||
| 190 | + $b = unpack('C*', $str_JIS); | ||
| 191 | + $n = count($b); | ||
| 192 | + | ||
| 193 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 194 | + | ||
| 195 | + //Check escape sequence | ||
| 196 | + while ($b[$i] == 0x1B) { | ||
| 197 | + if (($b[$i+1] == 0x24 && $b[$i+2] == 0x42) | ||
| 198 | + || ($b[$i+1] == 0x24 && $b[$i+2] == 0x40)) { | ||
| 199 | + $mode = 1; | ||
| 200 | + } elseif (($b[$i+1] == 0x28 && $b[$i+2] == 0x49)) { | ||
| 201 | + $mode = 2; | ||
| 202 | + } else { | ||
| 203 | + $mode = 0; | ||
| 204 | + } | ||
| 205 | + $i += 3; | ||
| 206 | + if (!isset($b[$i])) break 2; | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + //Do convert | ||
| 210 | + if ($mode == 1) { | ||
| 211 | + $b1 = $b[$i]; | ||
| 212 | + $b2 = $b[++$i]; | ||
| 213 | + if ($b1 & 0x01) { | ||
| 214 | + $b1 >>= 1; | ||
| 215 | + if ($b1 < 0x2F) $b1 += 0x71; else $b1 -= 0x4F; | ||
| 216 | + if ($b2 > 0x5F) $b2 += 0x20; else $b2 += 0x1F; | ||
| 217 | + } else { | ||
| 218 | + $b1 >>= 1; | ||
| 219 | + if ($b1 <= 0x2F) $b1 += 0x70; else $b1 -= 0x50; | ||
| 220 | + $b2 += 0x7E; | ||
| 221 | + } | ||
| 222 | + $str_SJIS .= chr($b1).chr($b2); | ||
| 223 | + } elseif ($mode == 2) { | ||
| 224 | + $str_SJIS .= chr($b[$i] + 0x80); | ||
| 225 | + } else { | ||
| 226 | + $str_SJIS .= chr($b[$i]); | ||
| 227 | + } | ||
| 228 | + } | ||
| 229 | + | ||
| 230 | + return $str_SJIS; | ||
| 231 | +} | ||
| 232 | + | ||
| 233 | +function JIStoEUC(&$str_JIS) | ||
| 234 | +{ | ||
| 235 | + $str_EUC = ''; | ||
| 236 | + $mode = 0; | ||
| 237 | + $b = unpack('C*', $str_JIS); | ||
| 238 | + $n = count($b); | ||
| 239 | + | ||
| 240 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 241 | + | ||
| 242 | + //Check escape sequence | ||
| 243 | + while ($b[$i] == 0x1B) { | ||
| 244 | + if (($b[$i+1] == 0x24 && $b[$i+2] == 0x42) | ||
| 245 | + || ($b[$i+1] == 0x24 && $b[$i+2] == 0x40)) { | ||
| 246 | + $mode = 1; | ||
| 247 | + } elseif (($b[$i+1] == 0x28 && $b[$i+2] == 0x49)) { | ||
| 248 | + $mode = 2; | ||
| 249 | + } else { | ||
| 250 | + $mode = 0; | ||
| 251 | + } | ||
| 252 | + $i += 3; | ||
| 253 | + if (!isset($b[$i])) break 2; | ||
| 254 | + } | ||
| 255 | + | ||
| 256 | + //Do convert | ||
| 257 | + if ($mode == 1) { | ||
| 258 | + $str_EUC .= chr($b[$i] + 0x80).chr($b[++$i] + 0x80); | ||
| 259 | + } elseif ($mode == 2) { | ||
| 260 | + $str_EUC .= chr(0x8E).chr($b[$i] + 0x80); | ||
| 261 | + } else { | ||
| 262 | + $str_EUC .= chr($b[$i]); | ||
| 263 | + } | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + return $str_EUC; | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +function SJIStoJIS(&$str_SJIS) | ||
| 270 | +{ | ||
| 271 | + $str_JIS = ''; | ||
| 272 | + $mode = 0; | ||
| 273 | + $b = unpack('C*', $str_SJIS); | ||
| 274 | + $n = count($b); | ||
| 275 | + | ||
| 276 | + //Escape sequence | ||
| 277 | + $ESC = array(chr(0x1B).chr(0x28).chr(0x42), | ||
| 278 | + chr(0x1B).chr(0x24).chr(0x42), | ||
| 279 | + chr(0x1B).chr(0x28).chr(0x49)); | ||
| 280 | + | ||
| 281 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 282 | + $b1 = $b[$i]; | ||
| 283 | + if (0xA1 <= $b1 && $b1 <= 0xDF) { | ||
| 284 | + if ($mode != 2) { | ||
| 285 | + $mode = 2; | ||
| 286 | + $str_JIS .= $ESC[$mode]; | ||
| 287 | + } | ||
| 288 | + $str_JIS .= chr($b1 - 0x80); | ||
| 289 | + } elseif ($b1 >= 0x80) { | ||
| 290 | + if ($mode != 1) { | ||
| 291 | + $mode = 1; | ||
| 292 | + $str_JIS .= $ESC[$mode]; | ||
| 293 | + } | ||
| 294 | + $b2 = $b[++$i]; | ||
| 295 | + $b1 <<= 1; | ||
| 296 | + if ($b2 < 0x9F) { | ||
| 297 | + if ($b1 < 0x13F) $b1 -= 0xE1; else $b1 -= 0x61; | ||
| 298 | + if ($b2 > 0x7E) $b2 -= 0x20; else $b2 -= 0x1F; | ||
| 299 | + } else { | ||
| 300 | + if ($b1 < 0x13F) $b1 -= 0xE0; else $b1 -= 0x60; | ||
| 301 | + $b2 -= 0x7E; | ||
| 302 | + } | ||
| 303 | + $str_JIS .= chr($b1).chr($b2); | ||
| 304 | + } else { | ||
| 305 | + if ($mode != 0) { | ||
| 306 | + $mode = 0; | ||
| 307 | + $str_JIS .= $ESC[$mode]; | ||
| 308 | + } | ||
| 309 | + $str_JIS .= chr($b1); | ||
| 310 | + } | ||
| 311 | + } | ||
| 312 | + if ($mode != 0) $str_JIS .= $ESC[0]; | ||
| 313 | + | ||
| 314 | + return $str_JIS; | ||
| 315 | +} | ||
| 316 | + | ||
| 317 | +function SJIStoEUC(&$str_SJIS) | ||
| 318 | +{ | ||
| 319 | + $b = unpack('C*', $str_SJIS); | ||
| 320 | + $n = count($b); | ||
| 321 | + $str_EUC = ''; | ||
| 322 | + | ||
| 323 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 324 | + $b1 = $b[$i]; | ||
| 325 | + if (0xA1 <= $b1 && $b1 <= 0xDF) { | ||
| 326 | + $str_EUC .= chr(0x8E).chr($b1); | ||
| 327 | + } elseif ($b1 >= 0x81) { | ||
| 328 | + $b2 = $b[++$i]; | ||
| 329 | + $b1 <<= 1; | ||
| 330 | + if ($b2 < 0x9F) { | ||
| 331 | + if ($b1 < 0x13F) $b1 -= 0x61; else $b1 -= 0xE1; | ||
| 332 | + if ($b2 > 0x7E) $b2 += 0x60; else $b2 += 0x61; | ||
| 333 | + } else { | ||
| 334 | + if ($b1 < 0x13F) $b1 -= 0x60; else $b1 -= 0xE0; | ||
| 335 | + $b2 += 0x02; | ||
| 336 | + } | ||
| 337 | + $str_EUC .= chr($b1).chr($b2); | ||
| 338 | + } else { | ||
| 339 | + $str_EUC .= chr($b1); | ||
| 340 | + } | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + return $str_EUC; | ||
| 344 | +} | ||
| 345 | + | ||
| 346 | +function EUCtoJIS(&$str_EUC) | ||
| 347 | +{ | ||
| 348 | + $str_JIS = ''; | ||
| 349 | + $mode = 0; | ||
| 350 | + $b = unpack('C*', $str_EUC); | ||
| 351 | + $n = count($b); | ||
| 352 | + | ||
| 353 | + //Escape sequence | ||
| 354 | + $ESC = array(chr(0x1B).chr(0x28).chr(0x42), | ||
| 355 | + chr(0x1B).chr(0x24).chr(0x42), | ||
| 356 | + chr(0x1B).chr(0x28).chr(0x49)); | ||
| 357 | + | ||
| 358 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 359 | + $b1 = $b[$i]; | ||
| 360 | + if ($b1 == 0x8E) { | ||
| 361 | + if ($mode != 2) { | ||
| 362 | + $mode = 2; | ||
| 363 | + $str_JIS .= $ESC[$mode]; | ||
| 364 | + } | ||
| 365 | + $str_JIS .= chr($b[++$i] - 0x80); | ||
| 366 | + } elseif ($b1 > 0x8E) { | ||
| 367 | + if ($mode != 1) { | ||
| 368 | + $mode = 1; | ||
| 369 | + $str_JIS .= $ESC[$mode]; | ||
| 370 | + } | ||
| 371 | + $str_JIS .= chr($b1 - 0x80).chr($b[++$i] - 0x80); | ||
| 372 | + } else { | ||
| 373 | + if ($mode != 0) { | ||
| 374 | + $mode = 0; | ||
| 375 | + $str_JIS .= $ESC[$mode]; | ||
| 376 | + } | ||
| 377 | + $str_JIS .= chr($b1); | ||
| 378 | + } | ||
| 379 | + } | ||
| 380 | + if ($mode != 0) $str_JIS .= $ESC[0]; | ||
| 381 | + | ||
| 382 | + return $str_JIS; | ||
| 383 | +} | ||
| 384 | + | ||
| 385 | +function EUCtoSJIS(&$str_EUC) | ||
| 386 | +{ | ||
| 387 | + $str_SJIS = ''; | ||
| 388 | + $b = unpack('C*', $str_EUC); | ||
| 389 | + $n = count($b); | ||
| 390 | + | ||
| 391 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 392 | + $b1 = $b[$i]; | ||
| 393 | + if ($b1 > 0x8E) { | ||
| 394 | + $b2 = $b[++$i]; | ||
| 395 | + if ($b1 & 0x01) { | ||
| 396 | + $b1 >>= 1; | ||
| 397 | + if ($b1 < 0x6F) $b1 += 0x31; else $b1 += 0x71; | ||
| 398 | + if ($b2 > 0xDF) $b2 -= 0x60; else $b2 -= 0x61; | ||
| 399 | + } else { | ||
| 400 | + $b1 >>= 1; | ||
| 401 | + if ($b1 <= 0x6F) $b1 += 0x30; else $b1 += 0x70; | ||
| 402 | + $b2 -= 0x02; | ||
| 403 | + } | ||
| 404 | + $str_SJIS .= chr($b1).chr($b2); | ||
| 405 | + } elseif ($b1 == 0x8E) { | ||
| 406 | + $str_SJIS .= chr($b[++$i]); | ||
| 407 | + } else { | ||
| 408 | + $str_SJIS .= chr($b1); | ||
| 409 | + } | ||
| 410 | + } | ||
| 411 | + | ||
| 412 | + return $str_SJIS; | ||
| 413 | +} | ||
| 414 | + | ||
| 415 | +function SJIStoUTF8(&$str_SJIS) | ||
| 416 | +{ | ||
| 417 | + global $table_jis_utf8; | ||
| 418 | + | ||
| 419 | + $str_UTF8 = ''; | ||
| 420 | + $b = unpack('C*', $str_SJIS); | ||
| 421 | + $n = count($b); | ||
| 422 | + | ||
| 423 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 424 | + if (0xA1 <= $b[$i] && $b[$i] <= 0xDF) { //Hankaku | ||
| 425 | + $b2 = $b[$i] - 0x40; | ||
| 426 | + $u2 = 0xBC | (($b2 >> 6) & 0x03); | ||
| 427 | + $u3 = 0x80 | ($b2 & 0x3F); | ||
| 428 | + $str_UTF8 .= chr(0xEF).chr($u2).chr($u3); | ||
| 429 | + } elseif ($b[$i] >= 0x80) { //Zenkaku | ||
| 430 | + $b1 = $b[$i] << 1; | ||
| 431 | + $b2 = $b[++$i]; | ||
| 432 | + if ($b2 < 0x9F) { | ||
| 433 | + if ($b1 < 0x13F) $b1 -= 0xE1; else $b1 -= 0x61; | ||
| 434 | + if ($b2 > 0x7E) $b2 -= 0x20; else $b2 -= 0x1F; | ||
| 435 | + } else { | ||
| 436 | + if ($b1 < 0x13F) $b1 -= 0xE0; else $b1 -= 0x60; | ||
| 437 | + $b2 -= 0x7E; | ||
| 438 | + } | ||
| 439 | + $b1 &= 0xFF; | ||
| 440 | + $jis = ($b1 << 8) + $b2; | ||
| 441 | + if (isset($table_jis_utf8[$jis])) { | ||
| 442 | + $utf8 = $table_jis_utf8[$jis]; | ||
| 443 | + if ($utf8 < 0xFFFF) { | ||
| 444 | + $str_UTF8 .= chr($utf8 >> 8).chr($utf8); | ||
| 445 | + } else { | ||
| 446 | + $str_UTF8 .= chr($utf8 >> 16).chr($utf8 >> 8).chr($utf8); | ||
| 447 | + } | ||
| 448 | + } else { | ||
| 449 | + $str_UTF8 .= '?'; //Unknown | ||
| 450 | + } | ||
| 451 | + } else { //ASCII | ||
| 452 | + $str_UTF8 .= chr($b[$i]); | ||
| 453 | + } | ||
| 454 | + } | ||
| 455 | + | ||
| 456 | + return $str_UTF8; | ||
| 457 | +} | ||
| 458 | + | ||
| 459 | +function EUCtoUTF8(&$str_EUC) | ||
| 460 | +{ | ||
| 461 | + global $table_jis_utf8; | ||
| 462 | + | ||
| 463 | + $str_UTF8 = ''; | ||
| 464 | + $b = unpack('C*', $str_EUC); | ||
| 465 | + $n = count($b); | ||
| 466 | + | ||
| 467 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 468 | + if ($b[$i] == 0x8E) { //Hankaku | ||
| 469 | + $b2 = $b[++$i] - 0x40; | ||
| 470 | + $u2 = 0xBC | (($b2 >> 6) & 0x03); | ||
| 471 | + $u3 = 0x80 | ($b2 & 0x3F); | ||
| 472 | + $str_UTF8 .= chr(0xEF).chr($u2).chr($u3); | ||
| 473 | + } elseif ($b[$i] >= 0x80) { //Zenkaku | ||
| 474 | + $jis = (($b[$i] - 0x80) << 8) + ($b[++$i] - 0x80); | ||
| 475 | + if (isset($table_jis_utf8[$jis])) { | ||
| 476 | + $utf8 = $table_jis_utf8[$jis]; | ||
| 477 | + if ($utf8 < 0xFFFF) { | ||
| 478 | + $str_UTF8 .= chr($utf8 >> 8).chr($utf8); | ||
| 479 | + } else { | ||
| 480 | + $str_UTF8 .= chr($utf8 >> 16).chr($utf8 >> 8).chr($utf8); | ||
| 481 | + } | ||
| 482 | + } else { //Unknown | ||
| 483 | + $str_UTF8 .= '?'; | ||
| 484 | + } | ||
| 485 | + } else { //ASCII | ||
| 486 | + $str_UTF8 .= chr($b[$i]); | ||
| 487 | + } | ||
| 488 | + } | ||
| 489 | + | ||
| 490 | + return $str_UTF8; | ||
| 491 | +} | ||
| 492 | + | ||
| 493 | +function JIStoUTF8(&$str_JIS) | ||
| 494 | +{ | ||
| 495 | + global $table_jis_utf8; | ||
| 496 | + | ||
| 497 | + $str_UTF8 = ''; | ||
| 498 | + $mode = 0; | ||
| 499 | + $b = unpack('C*', $str_JIS); | ||
| 500 | + $n = count($b); | ||
| 501 | + | ||
| 502 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 503 | + | ||
| 504 | + //Check escape sequence | ||
| 505 | + while ($b[$i] == 0x1B) { | ||
| 506 | + if (($b[$i+1] == 0x24 && $b[$i+2] == 0x42) | ||
| 507 | + || ($b[$i+1] == 0x24 && $b[$i+2] == 0x40)) { | ||
| 508 | + $mode = 1; | ||
| 509 | + } elseif ($b[$i+1] == 0x28 && $b[$i+2] == 0x49) { | ||
| 510 | + $mode = 2; | ||
| 511 | + } else { | ||
| 512 | + $mode = 0; | ||
| 513 | + } | ||
| 514 | + $i += 3; | ||
| 515 | + if (!isset($b[$i])) break 2; | ||
| 516 | + } | ||
| 517 | + | ||
| 518 | + if ($mode == 1) { //Zenkaku | ||
| 519 | + $jis = ($b[$i] << 8) + $b[++$i]; | ||
| 520 | + if (isset($table_jis_utf8[$jis])) { | ||
| 521 | + $utf8 = $table_jis_utf8[$jis]; | ||
| 522 | + if ($utf8 < 0xFFFF) { | ||
| 523 | + $str_UTF8 .= chr($utf8 >> 8).chr($utf8); | ||
| 524 | + } else { | ||
| 525 | + $str_UTF8 .= chr($utf8 >> 16).chr($utf8 >> 8).chr($utf8); | ||
| 526 | + } | ||
| 527 | + } else { //Unknown | ||
| 528 | + $str_UTF8 .= '?'; | ||
| 529 | + } | ||
| 530 | + } elseif ($mode == 2) { //Hankaku | ||
| 531 | + $b2 = $b[$i] + 0x40; | ||
| 532 | + $u2 = 0xBC | (($b2 >> 6) & 0x03); | ||
| 533 | + $u3 = 0x80 | ($b2 & 0x3F); | ||
| 534 | + $str_UTF8 .= chr(0xEF).chr($u2).chr($u3); | ||
| 535 | + } else { //ASCII | ||
| 536 | + $str_UTF8 .= chr($b[$i]); | ||
| 537 | + } | ||
| 538 | + } | ||
| 539 | + | ||
| 540 | + return $str_UTF8; | ||
| 541 | +} | ||
| 542 | + | ||
| 543 | +function UTF8toSJIS(&$str_UTF8) | ||
| 544 | +{ | ||
| 545 | + global $table_utf8_jis; | ||
| 546 | + | ||
| 547 | + $str_SJIS = ''; | ||
| 548 | + $b = unpack('C*', $str_UTF8); | ||
| 549 | + $n = count($b); | ||
| 550 | + | ||
| 551 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 552 | + if ($b[$i] >= 0x80) { //Not ASCII | ||
| 553 | + if ($b[$i] <= 0xDF) { //2 Bytes | ||
| 554 | + $utf8 = ($b[$i] << 8) + $b[++$i]; | ||
| 555 | + } else { //3 Bytes | ||
| 556 | + $utf8 = ($b[$i] << 16) + ($b[++$i] << 8) + $b[++$i]; | ||
| 557 | + } | ||
| 558 | + if (isset($table_utf8_jis[$utf8])) { | ||
| 559 | + $jis = $table_utf8_jis[$utf8]; | ||
| 560 | + if ($jis < 0xFF) { //Hankaku | ||
| 561 | + $str_SJIS .= chr($jis + 0x80); | ||
| 562 | + } else { //Zenkaku | ||
| 563 | + $b1 = $jis >> 8; | ||
| 564 | + $b2 = $jis & 0xFF; | ||
| 565 | + if ($b1 & 0x01) { | ||
| 566 | + $b1 >>= 1; | ||
| 567 | + if ($b1 < 0x2F) $b1 += 0x71; else $b1 -= 0x4F; | ||
| 568 | + if ($b2 > 0x5F) $b2 += 0x20; else $b2 += 0x1F; | ||
| 569 | + } else { | ||
| 570 | + $b1 >>= 1; | ||
| 571 | + if ($b1 <= 0x2F) $b1 += 0x70; else $b1 -= 0x50; | ||
| 572 | + $b2 += 0x7E; | ||
| 573 | + } | ||
| 574 | + $str_SJIS .= chr($b1).chr($b2); | ||
| 575 | + } | ||
| 576 | + } else { //Unknown | ||
| 577 | + $str_SJIS .= '?'; | ||
| 578 | + } | ||
| 579 | + } else { //ASCII | ||
| 580 | + $str_SJIS .= chr($b[$i]); | ||
| 581 | + } | ||
| 582 | + } | ||
| 583 | + | ||
| 584 | + return $str_SJIS; | ||
| 585 | +} | ||
| 586 | + | ||
| 587 | +function UTF8toEUC(&$str_UTF8) | ||
| 588 | +{ | ||
| 589 | + global $table_utf8_jis; | ||
| 590 | + | ||
| 591 | + $str_EUC = ''; | ||
| 592 | + $b = unpack('C*', $str_UTF8); | ||
| 593 | + $n = count($b); | ||
| 594 | + | ||
| 595 | + for ($i = 1; $i <= $n; $i++) { | ||
| 596 | + if ($b[$i] >= 0x80) { //Not ASCII | ||
| 597 | + if ($b[$i] <= 0xDF) { //2 Bytes | ||
| 598 | + $utf8 = ($b[$i++] << 8) + $b[$i]; | ||
| 599 | + } else { //3 Bytes | ||
| 600 | + $utf8 = ($b[$i++] << 16) + ($b[$i++] << 8) + $b[$i]; | ||
| 601 | + } | ||
| 602 | + if (isset($table_utf8_jis[$utf8])) { | ||
| 603 | + $jis = $table_utf8_jis[$utf8]; | ||
| 604 | + if ($jis < 0xFF) { //Hankaku | ||
| 605 | + $str_EUC .= chr(0x8E).chr($jis - 0x80); | ||
| 606 | + } else { //Zenkaku | ||
| 607 | + $str_EUC .= chr(($jis >> 8) - 0x80).chr(($jis & 0xFF) - 0x80); | ||
| 608 | + } | ||
| 609 | + } else { //Unknown | ||
| 610 | + $str_EUC .= '?'; | ||
| 611 | + } | ||
| 612 | + } else { //ASCII | ||
| 613 | + $str_EUC .= chr($b[$i]); | ||
| 614 | + } | ||
| 615 | + } | ||
| 616 | + | ||
| 617 | + return $str_EUC; | ||
| 618 | +} | ||
| 619 | + | ||
| 620 | +function UTF8toJIS(&$str_UTF8) | ||
| 621 | +{ | ||
| 622 | + global $table_utf8_jis; | ||
| 623 | + | ||
| 624 | + $str_JIS = ''; | ||
| 625 | + $mode = 0; | ||
| 626 | + $b = unpack('C*', $str_UTF8); | ||
| 627 | + $n = count($b); | ||
| 628 | + | ||
| 629 | + //Escape sequence | ||
| 630 | + $ESC = array(chr(0x1B).chr(0x28).chr(0x42), | ||
| 631 | + chr(0x1B).chr(0x24).chr(0x42), | ||
| 632 | + chr(0x1B).chr(0x28).chr(0x49)); | ||
| 633 | + | ||
| 634 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 635 | + if ($b[$i] >= 0x80) { //Not ASCII | ||
| 636 | + if ($b[$i] <= 0xDF) { //2 Bytes | ||
| 637 | + $utf8 = ($b[$i] << 8) + $b[++$i]; | ||
| 638 | + } else { //3 Bytes | ||
| 639 | + $utf8 = ($b[$i] << 16) + ($b[++$i] << 8) + $b[++$i]; | ||
| 640 | + } | ||
| 641 | + if (isset($table_utf8_jis[$utf8])) { | ||
| 642 | + $jis = $table_utf8_jis[$utf8]; | ||
| 643 | + if ($jis < 0xFF) { //Hankaku | ||
| 644 | + if ($mode != 2) { | ||
| 645 | + $mode = 2; | ||
| 646 | + $str_JIS .= $ESC[$mode]; | ||
| 647 | + } | ||
| 648 | + $str_JIS .= chr($jis); | ||
| 649 | + } else { //Zenkaku | ||
| 650 | + if ($mode != 1) { | ||
| 651 | + $mode = 1; | ||
| 652 | + $str_JIS .= $ESC[$mode]; | ||
| 653 | + } | ||
| 654 | + $str_JIS .= chr($jis >> 8).chr($jis & 0xFF); | ||
| 655 | + } | ||
| 656 | + } else { //Unknown | ||
| 657 | + if ($mode != 0) { | ||
| 658 | + $mode = 0; | ||
| 659 | + $str_JIS .= $ESC[$mode]; | ||
| 660 | + } | ||
| 661 | + $str_JIS .= '?'; | ||
| 662 | + } | ||
| 663 | + } else { //ASCII | ||
| 664 | + if ($mode != 0) { | ||
| 665 | + $mode = 0; | ||
| 666 | + $str_JIS .= $ESC[$mode]; | ||
| 667 | + } | ||
| 668 | + $str_JIS .= chr($b[$i]); | ||
| 669 | + } | ||
| 670 | + } | ||
| 671 | + if ($mode != 0) $str_JIS .= $ESC[0]; | ||
| 672 | + | ||
| 673 | + return $str_JIS; | ||
| 674 | +} | ||
| 675 | + | ||
| 676 | +function HANtoZEN_EUC(&$str_HAN) | ||
| 677 | +{ | ||
| 678 | + $table_han2zen_euc = array(0xA1A3,0xA1D6,0xA1D7,0xA1A2,0xA1A6,0xA5F2, | ||
| 679 | + 0xA5A1,0xA5A3,0xA5A5,0xA5A7,0xA5A9,0xA5E3,0xA5E5,0xA5E7,0xA5C3,0xA1BC, | ||
| 680 | + 0xA5A2,0xA5A4,0xA5A6,0xA5A8,0xA5AA,0xA5AB,0xA5AD,0xA5AF,0xA5B1,0xA5B3, | ||
| 681 | + 0xA5B5,0xA5B7,0xA5B9,0xA5BB,0xA5BD,0xA5BF,0xA5C1,0xA5C4,0xA5C6,0xA5C8, | ||
| 682 | + 0xA5CA,0xA5CB,0xA5CC,0xA5CD,0xA5CE,0xA5CF,0xA5D2,0xA5D5,0xA5D8,0xA5DB, | ||
| 683 | + 0xA5DE,0xA5DF,0xA5E0,0xA5E1,0xA5E2,0xA5E4,0xA5E6,0xA5E8,0xA5E9,0xA5EA, | ||
| 684 | + 0xA5EB,0xA5EC,0xA5ED,0xA5EF,0xA5F3,0xA1AB,0xA1AC); | ||
| 685 | + | ||
| 686 | + $str_ZEN = ''; | ||
| 687 | + $b = unpack('C*', $str_HAN); | ||
| 688 | + $n = count($b); | ||
| 689 | + | ||
| 690 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 691 | + $b1 = $b[$i]; | ||
| 692 | + if ($b1 == 0x8E) { | ||
| 693 | + $b2 = $b[++$i]; | ||
| 694 | + $ofs = 0; | ||
| 695 | + if ((($b2 == 0xB3) || (0xB6 <= $b2 && $b2 <= 0xC4) || (0xCA <= $b2 && $b2 <= 0xCE)) | ||
| 696 | + && (isset($b[$i+1]) && $b[$i+1] == 0x8E)) { | ||
| 697 | + // Dakuten | ||
| 698 | + if ($b[$i+2] == 0xDE) { | ||
| 699 | + if ($b2 == 0xB3) $ofs = 78; else $ofs = 1; | ||
| 700 | + $i += 2; | ||
| 701 | + // Han-Dakuten | ||
| 702 | + } elseif (($b[$i+2] == 0xDF) && (0xCA <= $b2 && $b2 <= 0xCE)) { | ||
| 703 | + $ofs = 2; | ||
| 704 | + $i += 2; | ||
| 705 | + } | ||
| 706 | + } | ||
| 707 | + $b2 -= 0xA1; | ||
| 708 | + $c1 = (($table_han2zen_euc[$b2]) & 0xFF00) >> 8; | ||
| 709 | + $c2 = (($table_han2zen_euc[$b2]) & 0x00FF) + $ofs; | ||
| 710 | + $str_ZEN .= chr($c1).chr($c2); | ||
| 711 | + } elseif ($b1 >= 0xA1) { | ||
| 712 | + $str_ZEN .= chr($b1).chr($b[++$i]); | ||
| 713 | + } else { | ||
| 714 | + $str_ZEN .= chr($b1); | ||
| 715 | + } | ||
| 716 | + } | ||
| 717 | + | ||
| 718 | + return $str_ZEN; | ||
| 719 | +} | ||
| 720 | + | ||
| 721 | +function HANtoZEN_SJIS(&$str_HAN) | ||
| 722 | +{ | ||
| 723 | + $table_han2zen_sjis = array(0x8142,0x8175,0x8176,0x8141,0x8145,0x8392, | ||
| 724 | + 0x8340,0x8342,0x8344,0x8346,0x8348,0x8383,0x8385,0x8387,0x8362,0x815B, | ||
| 725 | + 0x8341,0x8343,0x8345,0x8347,0x8349,0x834A,0x834C,0x834E,0x8350,0x8352, | ||
| 726 | + 0x8354,0x8356,0x8358,0x835A,0x835C,0x835E,0x8360,0x8363,0x8365,0x8367, | ||
| 727 | + 0x8369,0x836A,0x836B,0x836C,0x836D,0x836E,0x8371,0x8374,0x8377,0x837A, | ||
| 728 | + 0x837D,0x837E,0x8380,0x8381,0x8382,0x8384,0x8386,0x8388,0x8389,0x838A, | ||
| 729 | + 0x838B,0x838C,0x838D,0x838F,0x8393,0x814A,0x814B); | ||
| 730 | + | ||
| 731 | + $str_ZEN = ''; | ||
| 732 | + $b = unpack('C*', $str_HAN); | ||
| 733 | + $n = count($b); | ||
| 734 | + | ||
| 735 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 736 | + $b1 = $b[$i]; | ||
| 737 | + if (0xA1 <= $b1 && $b1 <= 0xDF) { | ||
| 738 | + $ofs = 0; | ||
| 739 | + if ((($b1 == 0xB3) || (0xB6 <= $b1 && $b1 <= 0xC4) || (0xCA <= $b1 && $b1 <= 0xCE)) | ||
| 740 | + && isset($b[$i+1])) { | ||
| 741 | + // Dakuten | ||
| 742 | + if ($b[$i+1] == 0xDE) { | ||
| 743 | + if ($b1 == 0xB3) $ofs = 79; else $ofs = 1; | ||
| 744 | + ++$i; | ||
| 745 | + // Han-Dakuten | ||
| 746 | + } elseif (($b[$i+1] == 0xDF) && (0xCA <= $b1 && $b1 <= 0xCE)) { | ||
| 747 | + $ofs = 2; | ||
| 748 | + ++$i; | ||
| 749 | + } | ||
| 750 | + } | ||
| 751 | + $b1 -= 0xA1; | ||
| 752 | + $c1 = (($table_han2zen_sjis[$b1]) & 0xFF00) >> 8; | ||
| 753 | + $c2 = (($table_han2zen_sjis[$b1]) & 0x00FF) + $ofs; | ||
| 754 | + $str_ZEN .= chr($c1).chr($c2); | ||
| 755 | + } elseif ($b1 >= 0x80) { | ||
| 756 | + $str_ZEN .= chr($b1).chr($b[++$i]); | ||
| 757 | + } else { | ||
| 758 | + $str_ZEN .= chr($b1); | ||
| 759 | + } | ||
| 760 | + } | ||
| 761 | + | ||
| 762 | + return $str_ZEN; | ||
| 763 | +} | ||
| 764 | + | ||
| 765 | +function HANtoZEN_JIS(&$str_HAN) | ||
| 766 | +{ | ||
| 767 | + $table_han2zen_jis = array(0x2123,0x2156,0x2157,0x2122,0x2126,0x2572, | ||
| 768 | + 0x2521,0x2523,0x2525,0x2527,0x2529,0x2563,0x2565,0x2567,0x2543,0x213C, | ||
| 769 | + 0x2522,0x2524,0x2526,0x2528,0x252A,0x252B,0x252D,0x252F,0x2531,0x2533, | ||
| 770 | + 0x2535,0x2537,0x2539,0x253B,0x253D,0x253F,0x2541,0x2544,0x2546,0x2548, | ||
| 771 | + 0x254A,0x254B,0x254C,0x254D,0x254E,0x254F,0x2552,0x2555,0x2558,0x255B, | ||
| 772 | + 0x255E,0x255F,0x2560,0x2561,0x2562,0x2564,0x2566,0x2568,0x2569,0x256A, | ||
| 773 | + 0x256B,0x256C,0x256D,0x256F,0x2573,0x212B,0x212C); | ||
| 774 | + | ||
| 775 | + $str_ZEN = ''; | ||
| 776 | + $b = unpack('C*', $str_HAN); | ||
| 777 | + $n = count($b); | ||
| 778 | + $mode = 0; | ||
| 779 | + $new_mode = 0; | ||
| 780 | + $esc = FALSE; | ||
| 781 | + $ESC = array(chr(0x1B).chr(0x28).chr(0x42), | ||
| 782 | + chr(0x1B).chr(0x24).chr(0x42), | ||
| 783 | + chr(0x1B).chr(0x28).chr(0x49)); | ||
| 784 | + | ||
| 785 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 786 | + | ||
| 787 | + while ($b[$i] == 0x1B) { | ||
| 788 | + if (($b[$i+1] == 0x24 && $b[$i+2] == 0x42) | ||
| 789 | + || ($b[$i+1] == 0x24 && $b[$i+2] == 0x40)) { | ||
| 790 | + $mode = 1; //Zenkaku | ||
| 791 | + } elseif ($b[$i+1] == 0x28 && $b[$i+2] == 0x49) { | ||
| 792 | + $mode = 2; //Hankaku | ||
| 793 | + } else { | ||
| 794 | + $mode = 0; //ASCII | ||
| 795 | + } | ||
| 796 | + $i += 3; | ||
| 797 | + if (!isset($b[$i])) break 2; | ||
| 798 | + } | ||
| 799 | + | ||
| 800 | + if ($mode == 2) { | ||
| 801 | + if ($new_mode != 1) $esc = TRUE; | ||
| 802 | + $new_mode = 1; | ||
| 803 | + $b1 = $b[$i]; | ||
| 804 | + $ofs = 0; | ||
| 805 | + if ((($b1 == 0x33) || (0x36 <= $b1 && $b1 <= 0x44) || (0x4A <= $b1 && $b1 <= 0x4E)) | ||
| 806 | + && isset($b[$i+1])) { | ||
| 807 | + // Dakuten | ||
| 808 | + if ($b[$i+1] == 0x5E) { | ||
| 809 | + if ($b1 == 0x33) $ofs = 78; else $ofs = 1; | ||
| 810 | + ++$i; | ||
| 811 | + // Han-Dakuten | ||
| 812 | + } elseif (($b[$i+1] == 0x5F) && (0x4A <= $b1 && $b1 <= 0x4E) ) { | ||
| 813 | + $ofs = 2; | ||
| 814 | + ++$i; | ||
| 815 | + } | ||
| 816 | + } | ||
| 817 | + $b1 -= 0x21; | ||
| 818 | + $c1 = ($table_han2zen_jis[$b1] & 0xFF00) >> 8; | ||
| 819 | + $c2 = ($table_han2zen_jis[$b1] & 0x00FF) + $ofs; | ||
| 820 | + $str = chr($c1).chr($c2); | ||
| 821 | + } else { | ||
| 822 | + if ($new_mode != $mode) $esc = TRUE; | ||
| 823 | + $new_mode = $mode; | ||
| 824 | + $str = chr($b[$i]); | ||
| 825 | + } | ||
| 826 | + | ||
| 827 | + if ($esc) { //add escape sequence | ||
| 828 | + $str_ZEN .= $ESC[$new_mode]; | ||
| 829 | + $esc = FALSE; | ||
| 830 | + } | ||
| 831 | + $str_ZEN .= $str; | ||
| 832 | + } | ||
| 833 | + | ||
| 834 | + if ($new_mode != 0) $str_ZEN .= $ESC[0]; | ||
| 835 | + | ||
| 836 | + return $str_ZEN; | ||
| 837 | +} | ||
| 838 | + | ||
| 839 | +function HANtoZEN_UTF8(&$str_HAN) | ||
| 840 | +{ | ||
| 841 | + $table_han2zen_utf8_1 = array(0xE38082,0xE3808C,0xE3808D,0xE38081,0xE383BB, | ||
| 842 | + 0xE383B2,0xE382A1,0xE382A3,0xE382A5,0xE382A7,0xE382A9,0xE383A3,0xE383A5, | ||
| 843 | + 0xE383A7,0xE38383,0xE383BC,0xE382A2,0xE382A4,0xE382A6,0xE382A8,0xE382AA, | ||
| 844 | + 0xE382AB,0xE382AD,0xE382AF,0xE382B1,0xE382B3,0xE382B5,0xE382B7,0xE382B9, | ||
| 845 | + 0xE382BB,0xE382BD); | ||
| 846 | + | ||
| 847 | + $table_han2zen_utf8_2 = array(0xE382BF,0xE38381,0xE38384,0xE38386,0xE38388, | ||
| 848 | + 0xE3838A,0xE3838B,0xE3838C,0xE3838D,0xE3838E,0xE3838F,0xE38392,0xE38395, | ||
| 849 | + 0xE38398,0xE3839B,0xE3839E,0xE3839F,0xE383A0,0xE383A1,0xE383A2,0xE383A4, | ||
| 850 | + 0xE383A6,0xE383A8,0xE383A9,0xE383AA,0xE383AB,0xE383AC,0xE383AD,0xE383AF, | ||
| 851 | + 0xE383B3,0xE3829B,0xE3829C); | ||
| 852 | + | ||
| 853 | + $str_ZEN = ''; | ||
| 854 | + $b = unpack('C*', $str_HAN); | ||
| 855 | + $n = count($b); | ||
| 856 | + | ||
| 857 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 858 | + if ($b[$i] >= 0x80) { | ||
| 859 | + if (($b[$i] & 0xE0) == 0xC0) { | ||
| 860 | + $str_ZEN .= chr($b[$i]).chr($b[++$i]); | ||
| 861 | + } elseif (($b[$i] & 0xF0) == 0xE0) { | ||
| 862 | + if ($b[$i+1] == 0xBD && (0xA1 <= $b[$i+2] && $b[$i+2] <= 0xBF)) { | ||
| 863 | + $zen = $table_han2zen_utf8_1[$b[$i+2] - 0xA1]; | ||
| 864 | + $b[$i] = ($zen & 0xFF0000) >> 16; | ||
| 865 | + $b[$i+1] = ($zen & 0x00FF00) >> 8; | ||
| 866 | + $b[$i+2] = $zen & 0x0000FF; | ||
| 867 | + } elseif ($b[$i+1] == 0xBE && (0x80 <= $b[$i+2] && $b[$i+2] <= 0x9F)) { | ||
| 868 | + $zen = $table_han2zen_utf8_2[$b[$i+2] - 0x80]; | ||
| 869 | + $b[$i] = ($zen & 0xFF0000) >> 16; | ||
| 870 | + $b[$i+1] = ($zen & 0x00FF00) >> 8; | ||
| 871 | + $b[$i+2] = $zen & 0x0000FF; | ||
| 872 | + } | ||
| 873 | + $str_ZEN .= chr($b[$i]).chr($b[++$i]).chr($b[++$i]); | ||
| 874 | + } | ||
| 875 | + } else { | ||
| 876 | + $str_ZEN .= chr($b[$i]); | ||
| 877 | + } | ||
| 878 | + } | ||
| 879 | + | ||
| 880 | + return $str_ZEN; | ||
| 881 | +} | ||
| 882 | + | ||
| 883 | +function ZENtoHAN_EUC(&$str_ZEN, $kana = 1, $alph = 1, $sym = 1) | ||
| 884 | +{ | ||
| 885 | + $kana_euc = array( | ||
| 886 | + 0x00A7,0x00B1,0x00A8,0x00B2,0x00A9,0x00B3,0x00AA,0x00B4,0x00AB,0x00B5, | ||
| 887 | + 0x00B6,0xB6DE,0x00B7,0xB7DE,0x00B8,0xB8DE,0x00B9,0xB9DE,0x00BA,0xBADE, | ||
| 888 | + 0x00BB,0xBBDE,0x00BC,0xBCDE,0x00BD,0xBDDE,0x00BE,0xBEDE,0x00BF,0xBFDE, | ||
| 889 | + 0x00C0,0xC0DE,0x00C1,0xC1DE,0x00AF,0x00C2,0xC2DE,0x00C3,0xC3DE,0x00C4, | ||
| 890 | + 0xC4DE,0x00C5,0x00C6,0x00C7,0x00C8,0x00C9,0x00CA,0xCADE,0xCADF,0x00CB, | ||
| 891 | + 0xCBDE,0xCBDF,0x00CC,0xCCDE,0xCCDF,0x00CD,0xCDDE,0xCDDF,0x00CE,0xCEDE, | ||
| 892 | + 0xCEDF,0x00CF,0x00D0,0x00D1,0x00D2,0x00D3,0x00AC,0x00D4,0x00AD,0x00D5, | ||
| 893 | + 0x00AE,0x00D6,0x00D7,0x00D8,0x00D9,0x00DA,0x00DB,0x0000,0x00DC,0x0000, | ||
| 894 | + 0x0000,0x00A6,0x00DD,0xB3DE,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 895 | + 0x0000,0x0000,0x0000,0x0000,0x0000 | ||
| 896 | + ); | ||
| 897 | + | ||
| 898 | + $sym_euc = array( | ||
| 899 | + 0x0020,0x8EA4,0x8EA1,0x0000,0x0000,0x8EA5,0x0000,0x0000,0x0000,0x0000, | ||
| 900 | + 0x8EDE,0x8EDF,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 901 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8EB0,0x0000,0x0000, | ||
| 902 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 903 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 904 | + 0x0000,0x0000,0x0000,0x8EA2,0x8EA3,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 905 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 906 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 907 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 908 | + 0x0000,0x0000,0x0000,0x0000,0x0000 | ||
| 909 | + ); | ||
| 910 | + | ||
| 911 | + $str_HAN = ''; | ||
| 912 | + $b = unpack('C*', $str_ZEN); | ||
| 913 | + $n = count($b); | ||
| 914 | + | ||
| 915 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 916 | + $b1 = $b[$i]; | ||
| 917 | + if ($b1 >= 0x80) { | ||
| 918 | + ++$i; | ||
| 919 | + if ($kana == 1 && $b1 == 0xA5) { // Katakana | ||
| 920 | + $c = $b[$i] - 0xA1; | ||
| 921 | + $c1 = ($kana_euc[$c] & 0xFF00) >> 8; | ||
| 922 | + $c2 = $kana_euc[$c] & 0x00FF; | ||
| 923 | + if ($c1 == 0x00) { | ||
| 924 | + if ($c2 == 0x00) { | ||
| 925 | + $str_HAN .= chr($b1).chr($b[$i]); | ||
| 926 | + } else { | ||
| 927 | + $str_HAN .= chr(0x8E).chr($c2); | ||
| 928 | + } | ||
| 929 | + } else { | ||
| 930 | + $str_HAN .= chr(0x8E).chr($c1).chr(0x8E).chr($c2); | ||
| 931 | + } | ||
| 932 | + } elseif ($sym == 1 && $b1 == 0xA1) { // Symbol | ||
| 933 | + $c = $b[$i] - 0xA1; | ||
| 934 | + $c1 = ($sym_euc[$c] & 0xFF00) >> 8; | ||
| 935 | + $c2 = $sym_euc[$c] & 0x00FF; | ||
| 936 | + if ($c1 == 0x00) { | ||
| 937 | + if ($c2 == 0x00) { | ||
| 938 | + $str_HAN .= chr($b1).chr($b[$i]); | ||
| 939 | + } else { | ||
| 940 | + $str_HAN .= chr($c2); | ||
| 941 | + } | ||
| 942 | + } else { | ||
| 943 | + $str_HAN .= chr($c1).chr($c2); | ||
| 944 | + } | ||
| 945 | + } elseif ( $alph == 1 && $b1 == 0xA3 ) { // Alphabet & Number | ||
| 946 | + $str_HAN .= chr($b[$i] - 0x80); | ||
| 947 | + } else { // Rest of Zenkaku | ||
| 948 | + $str_HAN .= chr($b1).chr($b[$i]); | ||
| 949 | + } | ||
| 950 | + } else { // ASCII | ||
| 951 | + $str_HAN .= chr($b1); | ||
| 952 | + } | ||
| 953 | + } | ||
| 954 | + | ||
| 955 | + return $str_HAN; | ||
| 956 | +} | ||
| 957 | + | ||
| 958 | +function ZENtoHAN_SJIS(&$str_ZEN, $kana = 1, $alph = 1, $sym = 1) | ||
| 959 | +{ | ||
| 960 | + $kana_sjis = array( | ||
| 961 | + 0x00A7,0x00B1,0x00A8,0x00B2,0x00A9,0x00B3,0x00AA,0x00B4,0x00AB,0x00B5, | ||
| 962 | + 0x00B6,0xB6DE,0x00B7,0xB7DE,0x00B8,0xB8DE,0x00B9,0xB9DE,0x00BA,0xBADE, | ||
| 963 | + 0x00BB,0xBBDE,0x00BC,0xBCDE,0x00BD,0xBDDE,0x00BE,0xBEDE,0x00BF,0xBFDE, | ||
| 964 | + 0x00C0,0xC0DE,0x00C1,0xC1DE,0x00AF,0x00C2,0xC2DE,0x00C3,0xC3DE,0x00C4, | ||
| 965 | + 0xC4DE,0x00C5,0x00C6,0x00C7,0x00C8,0x00C9,0x00CA,0xCADE,0xCADF,0x00CB, | ||
| 966 | + 0xCBDE,0xCBDF,0x00CC,0xCCDE,0xCCDF,0x00CD,0xCDDE,0xCDDF,0x00CE,0xCEDE, | ||
| 967 | + 0xCEDF,0x00CF,0x00D0,0x0000,0x00D1,0x00D2,0x00D3,0x00AC,0x00D4,0x00AD, | ||
| 968 | + 0x00D5,0x00AE,0x00D6,0x00D7,0x00D8,0x00D9,0x00DA,0x00DB,0x0000,0x00DC, | ||
| 969 | + 0x0000,0x0000,0x00A6,0x00DD,0xB3DE,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 970 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 | ||
| 971 | + ); | ||
| 972 | + | ||
| 973 | + $sym_sjis = array( | ||
| 974 | + 0x20,0xA4,0xA1,0x00,0x00,0xA5,0x00,0x00,0x00,0x00,0xDE,0xDF,0x00,0x00, | ||
| 975 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB0, | ||
| 976 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
| 977 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA2,0xA3,0x00, | ||
| 978 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
| 979 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | ||
| 980 | + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 | ||
| 981 | + ); | ||
| 982 | + | ||
| 983 | + $str_HAN = ''; | ||
| 984 | + $b = unpack('C*', $str_ZEN); | ||
| 985 | + $n = count($b); | ||
| 986 | + | ||
| 987 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 988 | + $b1 = $b[$i]; | ||
| 989 | + if ($b1 >= 0x80) { | ||
| 990 | + $b2 = $b[++$i]; | ||
| 991 | + if ($kana == 1 && $b1 == 0x83 // Katakana | ||
| 992 | + && (0x3F < $b2 && $b2 < 0x9F)) { | ||
| 993 | + $c = $b2 - 0x40; | ||
| 994 | + $c1 = ($kana_sjis[$c] & 0xFF00) >> 8; | ||
| 995 | + $c2 = $kana_sjis[$c] & 0x00FF; | ||
| 996 | + if ($c1 == 0x00) { | ||
| 997 | + if ($c2 == 0x00) { | ||
| 998 | + $str_HAN .= chr($b1).chr($b2); | ||
| 999 | + } else { | ||
| 1000 | + $str_HAN .= chr($c2); | ||
| 1001 | + } | ||
| 1002 | + } else { | ||
| 1003 | + $str_HAN .= chr($c1).chr($c2); | ||
| 1004 | + } | ||
| 1005 | + } elseif ($sym == 1 && $b1 == 0x81 // Symbol | ||
| 1006 | + && (0x3F < $b2 && $b2 < 0x9F)) { | ||
| 1007 | + $c1 = $sym_sjis[ $b2 - 0x40 ]; | ||
| 1008 | + if ($c1 == 0x00) { | ||
| 1009 | + $str_HAN .= chr($b1).chr($b2); | ||
| 1010 | + } else { | ||
| 1011 | + $str_HAN .= chr($c1); | ||
| 1012 | + } | ||
| 1013 | + } elseif ($alph == 1 && $b1 == 0x82 // Alphabet & Number | ||
| 1014 | + && (0x3F < $b2 && $b2 < 0x9F)) { | ||
| 1015 | + if ($b2 < 0x80) { | ||
| 1016 | + $str_HAN .= chr($b2 - 0x1F); | ||
| 1017 | + } else { | ||
| 1018 | + $str_HAN .= chr($b2 - 0x20); | ||
| 1019 | + } | ||
| 1020 | + } else { // Rest of Zenkaku | ||
| 1021 | + $str_HAN .= chr($b1).chr($b2); | ||
| 1022 | + } | ||
| 1023 | + } else { // ASCII | ||
| 1024 | + $str_HAN .= chr($b1); | ||
| 1025 | + } | ||
| 1026 | + } | ||
| 1027 | + | ||
| 1028 | + return $str_HAN; | ||
| 1029 | +} | ||
| 1030 | + | ||
| 1031 | +function ZENtoHAN_JIS(&$str_ZEN, $kana = 1, $alph = 1, $sym = 1) | ||
| 1032 | +{ | ||
| 1033 | + $kana_jis = array( | ||
| 1034 | + 0x0027,0x0031,0x0028,0x0032,0x0029,0x0033,0x002A,0x0034,0x002B,0x0035, | ||
| 1035 | + 0x0036,0x365E,0x0037,0x375E,0x0038,0x385E,0x0039,0x395E,0x003A,0x3A5E, | ||
| 1036 | + 0x003B,0x3B5E,0x003C,0x3C5E,0x003D,0x3D5E,0x003E,0x3E5E,0x003F,0x3F5E, | ||
| 1037 | + 0x0040,0x405E,0x0041,0x415E,0x002F,0x0042,0x425E,0x0043,0x435E,0x0044, | ||
| 1038 | + 0x445E,0x0045,0x0046,0x0047,0x0048,0x0049,0x004A,0x4A5E,0x4A5F,0x004B, | ||
| 1039 | + 0x4B5E,0x4B5F,0x004C,0x4C5E,0x4C5F,0x004D,0x4D5E,0x4D5F,0x004E,0x4E5E, | ||
| 1040 | + 0x4E5F,0x004F,0x0050,0x0051,0x0052,0x0053,0x002C,0x0054,0x002D,0x0055, | ||
| 1041 | + 0x002E,0x0056,0x0057,0x0058,0x0059,0x005A,0x005B,0x0000,0x005C,0x0000, | ||
| 1042 | + 0x0000,0x0026,0x005D,0x335E,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1043 | + 0x0000,0x0000,0x0000,0x0000,0x0000 | ||
| 1044 | + ); | ||
| 1045 | + | ||
| 1046 | + $sym_jis = array( | ||
| 1047 | + 0x0020,0xFF24,0xFF21,0x0000,0x0000,0xFF25,0x0000,0x0000,0x0000,0x0000, | ||
| 1048 | + 0xFF5E,0xFF5F,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1049 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xFF30,0x0000,0x0000, | ||
| 1050 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1051 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1052 | + 0x0000,0x0000,0x0000,0xFF22,0xFF23,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1053 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1054 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1055 | + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, | ||
| 1056 | + 0x0000,0x0000,0x0000,0x0000,0x0000 | ||
| 1057 | + ); | ||
| 1058 | + | ||
| 1059 | + $str_HAN = ''; | ||
| 1060 | + $b = unpack('C*', $str_ZEN); | ||
| 1061 | + $n = count($b); | ||
| 1062 | + $mode = 0; | ||
| 1063 | + $new_mode = 0; | ||
| 1064 | + $esc = FALSE; | ||
| 1065 | + $ESC = array(chr(0x1B).chr(0x28).chr(0x42), | ||
| 1066 | + chr(0x1B).chr(0x24).chr(0x42), | ||
| 1067 | + chr(0x1B).chr(0x28).chr(0x49)); | ||
| 1068 | + | ||
| 1069 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 1070 | + while ($b[$i] == 0x1B) { | ||
| 1071 | + if (($b[$i+1] == 0x24 && $b[$i+2] == 0x42) | ||
| 1072 | + || ($b[$i+1] == 0x24 && $b[$i+2] == 0x40)) { | ||
| 1073 | + $mode = 1; | ||
| 1074 | + } elseif ($b[$i+1] == 0x28 && $b[$i+2] == 0x49) { | ||
| 1075 | + $mode = 2; | ||
| 1076 | + } else { | ||
| 1077 | + $mode = 0; | ||
| 1078 | + } | ||
| 1079 | + $i += 3; | ||
| 1080 | + if (!isset($b[$i])) break 2; | ||
| 1081 | + } | ||
| 1082 | + | ||
| 1083 | + $b1 = $b[$i]; | ||
| 1084 | + if ($mode == 1) { //Zenkaku | ||
| 1085 | + ++$i; | ||
| 1086 | + if ($alph == 1 && $b1 == 0x23) { //Alphabet & Number | ||
| 1087 | + if ($new_mode != 0) $esc = TRUE; | ||
| 1088 | + $new_mode = 0; | ||
| 1089 | + $str = chr($b[$i]); | ||
| 1090 | + } elseif ($sym == 1 && $b1 == 0x21) { //Symbol | ||
| 1091 | + $c = $b[$i] - 0x21; | ||
| 1092 | + $c1 = ($sym_jis[$c] & 0xFF00) >> 8; | ||
| 1093 | + $c2 = $sym_jis[$c] & 0x00FF; | ||
| 1094 | + if ($c1 == 0x00) { | ||
| 1095 | + if ($c2 == 0x00) { | ||
| 1096 | + if ($new_mode != 1) $esc = TRUE; | ||
| 1097 | + $new_mode = 1; | ||
| 1098 | + $str = chr($b1).chr($b[$i]); | ||
| 1099 | + } else { | ||
| 1100 | + if ($new_mode != 0) $esc = true; | ||
| 1101 | + $new_mode = 0; | ||
| 1102 | + $str = chr($c2); | ||
| 1103 | + } | ||
| 1104 | + } else { | ||
| 1105 | + if ($new_mode != 2) $esc = TRUE; | ||
| 1106 | + $new_mode = 2; | ||
| 1107 | + $str = chr($c2); | ||
| 1108 | + } | ||
| 1109 | + } elseif ($kana == 1 && $b1 == 0x25) { //Katakana | ||
| 1110 | + $c = $b[$i] - 0x21; | ||
| 1111 | + $c1 = ($kana_jis[$c] & 0xFF00) >> 8; | ||
| 1112 | + $c2 = $kana_jis[$c] & 0x00FF; | ||
| 1113 | + if ($c1 == 0x00) { | ||
| 1114 | + if ($c2 == 0x00) { | ||
| 1115 | + if ($new_mode != 1) $esc = TRUE; | ||
| 1116 | + $new_mode = 1; | ||
| 1117 | + $str = chr($b1).chr($b[$i]); | ||
| 1118 | + } else { | ||
| 1119 | + if ($new_mode != 2) $esc = TRUE; | ||
| 1120 | + $new_mode = 2; | ||
| 1121 | + $str = chr($c2); | ||
| 1122 | + } | ||
| 1123 | + } else { | ||
| 1124 | + if ($new_mode != 2) $esc = TRUE; | ||
| 1125 | + $new_mode = 2; | ||
| 1126 | + $str = chr($c1).chr($c2); | ||
| 1127 | + } | ||
| 1128 | + } else { | ||
| 1129 | + if ($new_mode != 1) $esc = TRUE; | ||
| 1130 | + $new_mode = 1; | ||
| 1131 | + $str = chr($b1).chr($b[$i]); | ||
| 1132 | + } | ||
| 1133 | + } elseif ($mode == 2) { | ||
| 1134 | + if ($new_mode != 2) $esc = TRUE; | ||
| 1135 | + $new_mode = 2; | ||
| 1136 | + $str = chr($b1); | ||
| 1137 | + } else { | ||
| 1138 | + if ($new_mode != 0) $esc = TRUE; | ||
| 1139 | + $new_mode = 0; | ||
| 1140 | + $str = chr($b1); | ||
| 1141 | + } | ||
| 1142 | + | ||
| 1143 | + if ($esc) { //add escape sequense | ||
| 1144 | + $str_HAN .= $ESC[$new_mode]; | ||
| 1145 | + $esc = FALSE; | ||
| 1146 | + } | ||
| 1147 | + $str_HAN .= $str; | ||
| 1148 | + } | ||
| 1149 | + | ||
| 1150 | + if ($new_mode != 0) $str_HAN .= $ESC[0]; | ||
| 1151 | + | ||
| 1152 | + return $str_HAN; | ||
| 1153 | +} | ||
| 1154 | + | ||
| 1155 | + | ||
| 1156 | +/* | ||
| 1157 | + O-MA-KE No.1 | ||
| 1158 | + jsubstr() - substr() function for japanese(euc-jp) | ||
| 1159 | + for using shift_jis encoding, remove comment string. | ||
| 1160 | +*/ | ||
| 1161 | +function jsubstr($str, $start = 0, $length = 0) | ||
| 1162 | +{ | ||
| 1163 | + $b = unpack('C*', $str); | ||
| 1164 | + $m = count($b); | ||
| 1165 | + | ||
| 1166 | + for ($i = 1; $i <= $m; ++$i) { | ||
| 1167 | + if ($b[$i] >= 0x80) { //Japanese | ||
| 1168 | +// if ( 0xA0 < $b[$i] && $b[$i] < 0xE0 ) { //SJIS Hankaku | ||
| 1169 | +// $jstr[] = chr($b[$i]); | ||
| 1170 | +// } else { | ||
| 1171 | + $jstr[] = chr($b[$i]).chr($b[++$i]); | ||
| 1172 | +// } | ||
| 1173 | + } else { //ASCII | ||
| 1174 | + $jstr[] = chr($b[$i]); | ||
| 1175 | + } | ||
| 1176 | + } | ||
| 1177 | + if (!isset($jstr)) $jstr[] = ''; | ||
| 1178 | + | ||
| 1179 | + $n = count($jstr); | ||
| 1180 | + if ($start < 0) $start += $n; | ||
| 1181 | + if ($length < 0) $end = $n + $length; else $end = $start + $length; | ||
| 1182 | + if ($end > $n) $end = $n; | ||
| 1183 | + | ||
| 1184 | + $s = ''; | ||
| 1185 | + for ($j = $start; $j < $end; ++$j) $s .= $jstr[$j]; | ||
| 1186 | + | ||
| 1187 | + return $s; | ||
| 1188 | +} | ||
| 1189 | + | ||
| 1190 | +/* | ||
| 1191 | + O-MA-KE No.2 | ||
| 1192 | + jstrlen() - strlen() function for japanese(euc-jp) | ||
| 1193 | + for using shift_jis encoding, remove comment string. | ||
| 1194 | +*/ | ||
| 1195 | +function jstrlen($str) | ||
| 1196 | +{ | ||
| 1197 | + $b = unpack('C*', $str); | ||
| 1198 | + $n = count($b); | ||
| 1199 | + $l = 0; | ||
| 1200 | + | ||
| 1201 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 1202 | + if ($b[$i] >= 0x80 | ||
| 1203 | +// && ($b[$i] <= 0xA0 || $b[$i] >= 0xE0) //exclude SJIS Hankaku | ||
| 1204 | + ) { | ||
| 1205 | + ++$i; | ||
| 1206 | + } | ||
| 1207 | + ++$l; | ||
| 1208 | + } | ||
| 1209 | + | ||
| 1210 | + return $l; | ||
| 1211 | +} | ||
| 1212 | + | ||
| 1213 | +/* | ||
| 1214 | + O-MA-KE No.3 | ||
| 1215 | + jstr_replace() - str_replace() function for japanese(euc-jp) | ||
| 1216 | + for using shift_jis encoding, remove comment string. | ||
| 1217 | +*/ | ||
| 1218 | +function jstr_replace($before, $after, $str) | ||
| 1219 | +{ | ||
| 1220 | + $b = unpack('C*', $str); | ||
| 1221 | + $n = strlen($str); | ||
| 1222 | + $l = strlen($before); | ||
| 1223 | + if ($l == 0) $l = 1; | ||
| 1224 | + $s = ''; | ||
| 1225 | + $i = 1; | ||
| 1226 | + | ||
| 1227 | + while($i <= $n) { | ||
| 1228 | + for ($j = 0; $j < $l; $k = $i + (++$j)) { | ||
| 1229 | + if ($b[$k] >= 0x80) { //Japanese | ||
| 1230 | +// if ( 0xA0 < $b[$k] && $b[$k] < 0xE0 ) { //SJIS Hankaku | ||
| 1231 | +// $c[] = chr($b[$k]); | ||
| 1232 | +// } else { | ||
| 1233 | + $c[] = chr($b[$k]).chr($b[$k+1]); | ||
| 1234 | + $k = $i + (++$j); | ||
| 1235 | +// } | ||
| 1236 | + } else { //ASCII | ||
| 1237 | + $c[] = chr($b[$k]); | ||
| 1238 | + } | ||
| 1239 | + if (!isset($b[$k+1])) break; | ||
| 1240 | + } | ||
| 1241 | + if ($before == implode('', $c)) { | ||
| 1242 | + $s .= $after; //replace | ||
| 1243 | + $i += $l; | ||
| 1244 | + } else { | ||
| 1245 | + $s .= $c[0]; | ||
| 1246 | + $i += strlen($c[0]); | ||
| 1247 | + } | ||
| 1248 | + unset($c); | ||
| 1249 | + } | ||
| 1250 | + | ||
| 1251 | + return $s; | ||
| 1252 | +} | ||
| 1253 | + | ||
| 1254 | +/* | ||
| 1255 | + O-MA-KE No.4 | ||
| 1256 | + jchunk_split() - This function is similar to chunk_split() | ||
| 1257 | + and is designed for euc-jp encoding. | ||
| 1258 | +*/ | ||
| 1259 | +function jchunk_split($str, $width = 76, $end = "\r\n") | ||
| 1260 | +{ | ||
| 1261 | + if ($width < 1) return ''; | ||
| 1262 | + | ||
| 1263 | + $b = unpack('C*', $str); | ||
| 1264 | + $n = count($b); | ||
| 1265 | + $s = ''; | ||
| 1266 | + $l = 0; | ||
| 1267 | + | ||
| 1268 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 1269 | + | ||
| 1270 | + if ($b[$i] >= 0x80) { // 8bit (Japanese) | ||
| 1271 | +// if ( 0xA0 < $b[$i] && $b[$i] < 0xE0 ) { // SJIS Hankaku | ||
| 1272 | +// $c = chr($b[$i]); | ||
| 1273 | +// $w = 1; | ||
| 1274 | +// } else { | ||
| 1275 | + if ($b[$i] == 0x8E) { // EUC-JP Hankaku | ||
| 1276 | + $w = 1; | ||
| 1277 | + } else { // Zenkaku | ||
| 1278 | + $w = 2; | ||
| 1279 | + } | ||
| 1280 | + $c = chr($b[$i]).chr($b[++$i]); | ||
| 1281 | +// } | ||
| 1282 | + } else { // 7bit (ASCII) | ||
| 1283 | + $w = 1; | ||
| 1284 | + $c = chr($b[$i]); | ||
| 1285 | + } | ||
| 1286 | + | ||
| 1287 | + if (($l += $w) > $width) { | ||
| 1288 | + $l = $w; | ||
| 1289 | + $s .= $end; | ||
| 1290 | + } | ||
| 1291 | + | ||
| 1292 | + $s .= $c; | ||
| 1293 | + } | ||
| 1294 | + | ||
| 1295 | + return $s; | ||
| 1296 | +} | ||
| 1297 | + | ||
| 1298 | +/* | ||
| 1299 | + O-MA-KE No.5 | ||
| 1300 | + jstrcut() - This function is similar to mb_strcut() and substr(), | ||
| 1301 | + and is designed for euc-jp encoding. | ||
| 1302 | +*/ | ||
| 1303 | +function jstrcut($str, $start, $len = 0) | ||
| 1304 | +{ | ||
| 1305 | + $b = unpack('C*', $str); | ||
| 1306 | + $n = count($b); | ||
| 1307 | + $s = ''; | ||
| 1308 | + $c = ''; | ||
| 1309 | + $l = 0; | ||
| 1310 | + | ||
| 1311 | + if ($start < 0) $start += $n; | ||
| 1312 | + if ($start < 0) $start = 0; | ||
| 1313 | + | ||
| 1314 | + if ($len == 0) $len = $n; | ||
| 1315 | + if ($len < 0) $len += ($n - $start); | ||
| 1316 | + if ($len > $n) $len = $n; | ||
| 1317 | + if ($len < 1) return ''; | ||
| 1318 | + | ||
| 1319 | + for ($i = 1; $i <= $n; ++$i) { | ||
| 1320 | + | ||
| 1321 | + if ($b[$i] >= 0x80) { // 8bit (Japanese) | ||
| 1322 | +// if ( 0xA0 < $b[$i] && $b[$i] < 0xE0 ) { // SJIS Hankaku | ||
| 1323 | +// $c = chr($b[$i]); | ||
| 1324 | +// $w = 1; | ||
| 1325 | +// } else { | ||
| 1326 | + if ($b[$i] == 0x8E) { // EUC-JP Hankaku | ||
| 1327 | + $w = 1; | ||
| 1328 | + } else { // Zenkaku | ||
| 1329 | + $w = 2; | ||
| 1330 | + } | ||
| 1331 | + $c = chr($b[$i]).chr($b[++$i]); | ||
| 1332 | +// } | ||
| 1333 | + } else { // 7bit (ASCII) | ||
| 1334 | + $w = 1; | ||
| 1335 | + $c = chr($b[$i]); | ||
| 1336 | + } | ||
| 1337 | + | ||
| 1338 | + if ($i > $start) { | ||
| 1339 | + $l += $w; | ||
| 1340 | + if ($l > $len) break; | ||
| 1341 | + $s .= $c; | ||
| 1342 | + } | ||
| 1343 | + | ||
| 1344 | + } | ||
| 1345 | + | ||
| 1346 | + return $s; | ||
| 1347 | +} | ||
| 1348 | + | ||
| 1349 | +?> |
inc/smarty.conf
0 → 100644
lib/http/Net/Socket.php
0 → 100644
| 1 | +<?php | ||
| 2 | +// | ||
| 3 | +// +----------------------------------------------------------------------+ | ||
| 4 | +// | PHP Version 4 | | ||
| 5 | +// +----------------------------------------------------------------------+ | ||
| 6 | +// | Copyright (c) 1997-2003 The PHP Group | | ||
| 7 | +// +----------------------------------------------------------------------+ | ||
| 8 | +// | This source file is subject to version 2.0 of the PHP license, | | ||
| 9 | +// | that is bundled with this package in the file LICENSE, and is | | ||
| 10 | +// | available at through the world-wide-web at | | ||
| 11 | +// | http://www.php.net/license/2_02.txt. | | ||
| 12 | +// | If you did not receive a copy of the PHP license and are unable to | | ||
| 13 | +// | obtain it through the world-wide-web, please send a note to | | ||
| 14 | +// | license@php.net so we can mail you a copy immediately. | | ||
| 15 | +// +----------------------------------------------------------------------+ | ||
| 16 | +// | Authors: Stig Bakken <ssb@php.net> | | ||
| 17 | +// | Chuck Hagenbuch <chuck@horde.org> | | ||
| 18 | +// +----------------------------------------------------------------------+ | ||
| 19 | +// | ||
| 20 | +// $Id: Socket.php,v 1.38 2008/02/15 18:24:17 chagenbu Exp $ | ||
| 21 | + | ||
| 22 | +require_once 'PEAR.php'; | ||
| 23 | + | ||
| 24 | +define('NET_SOCKET_READ', 1); | ||
| 25 | +define('NET_SOCKET_WRITE', 2); | ||
| 26 | +define('NET_SOCKET_ERROR', 4); | ||
| 27 | + | ||
| 28 | +/** | ||
| 29 | + * Generalized Socket class. | ||
| 30 | + * | ||
| 31 | + * @version 1.1 | ||
| 32 | + * @author Stig Bakken <ssb@php.net> | ||
| 33 | + * @author Chuck Hagenbuch <chuck@horde.org> | ||
| 34 | + */ | ||
| 35 | +class Net_Socket extends PEAR { | ||
| 36 | + | ||
| 37 | + /** | ||
| 38 | + * Socket file pointer. | ||
| 39 | + * @var resource $fp | ||
| 40 | + */ | ||
| 41 | + var $fp = null; | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * Whether the socket is blocking. Defaults to true. | ||
| 45 | + * @var boolean $blocking | ||
| 46 | + */ | ||
| 47 | + var $blocking = true; | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Whether the socket is persistent. Defaults to false. | ||
| 51 | + * @var boolean $persistent | ||
| 52 | + */ | ||
| 53 | + var $persistent = false; | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * The IP address to connect to. | ||
| 57 | + * @var string $addr | ||
| 58 | + */ | ||
| 59 | + var $addr = ''; | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * The port number to connect to. | ||
| 63 | + * @var integer $port | ||
| 64 | + */ | ||
| 65 | + var $port = 0; | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Number of seconds to wait on socket connections before assuming | ||
| 69 | + * there's no more data. Defaults to no timeout. | ||
| 70 | + * @var integer $timeout | ||
| 71 | + */ | ||
| 72 | + var $timeout = false; | ||
| 73 | + | ||
| 74 | + /** | ||
| 75 | + * Number of bytes to read at a time in readLine() and | ||
| 76 | + * readAll(). Defaults to 2048. | ||
| 77 | + * @var integer $lineLength | ||
| 78 | + */ | ||
| 79 | + var $lineLength = 2048; | ||
| 80 | + | ||
| 81 | + /** | ||
| 82 | + * Connect to the specified port. If called when the socket is | ||
| 83 | + * already connected, it disconnects and connects again. | ||
| 84 | + * | ||
| 85 | + * @param string $addr IP address or host name. | ||
| 86 | + * @param integer $port TCP port number. | ||
| 87 | + * @param boolean $persistent (optional) Whether the connection is | ||
| 88 | + * persistent (kept open between requests | ||
| 89 | + * by the web server). | ||
| 90 | + * @param integer $timeout (optional) How long to wait for data. | ||
| 91 | + * @param array $options See options for stream_context_create. | ||
| 92 | + * | ||
| 93 | + * @access public | ||
| 94 | + * | ||
| 95 | + * @return boolean | PEAR_Error True on success or a PEAR_Error on failure. | ||
| 96 | + */ | ||
| 97 | + function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null) | ||
| 98 | + { | ||
| 99 | + if (is_resource($this->fp)) { | ||
| 100 | + @fclose($this->fp); | ||
| 101 | + $this->fp = null; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + if (!$addr) { | ||
| 105 | + return $this->raiseError('$addr cannot be empty'); | ||
| 106 | + } elseif (strspn($addr, '.0123456789') == strlen($addr) || | ||
| 107 | + strstr($addr, '/') !== false) { | ||
| 108 | + $this->addr = $addr; | ||
| 109 | + } else { | ||
| 110 | + $this->addr = @gethostbyname($addr); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + $this->port = $port % 65536; | ||
| 114 | + | ||
| 115 | + if ($persistent !== null) { | ||
| 116 | + $this->persistent = $persistent; | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + if ($timeout !== null) { | ||
| 120 | + $this->timeout = $timeout; | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + $openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen'; | ||
| 124 | + $errno = 0; | ||
| 125 | + $errstr = ''; | ||
| 126 | + $old_track_errors = @ini_set('track_errors', 1); | ||
| 127 | + if ($options && function_exists('stream_context_create')) { | ||
| 128 | + if ($this->timeout) { | ||
| 129 | + $timeout = $this->timeout; | ||
| 130 | + } else { | ||
| 131 | + $timeout = 0; | ||
| 132 | + } | ||
| 133 | + $context = stream_context_create($options); | ||
| 134 | + | ||
| 135 | + // Since PHP 5 fsockopen doesn't allow context specification | ||
| 136 | + if (function_exists('stream_socket_client')) { | ||
| 137 | + $flags = $this->persistent ? STREAM_CLIENT_PERSISTENT : STREAM_CLIENT_CONNECT; | ||
| 138 | + $addr = $this->addr . ':' . $this->port; | ||
| 139 | + $fp = stream_socket_client($addr, $errno, $errstr, $timeout, $flags, $context); | ||
| 140 | + } else { | ||
| 141 | + $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); | ||
| 142 | + } | ||
| 143 | + } else { | ||
| 144 | + if ($this->timeout) { | ||
| 145 | + $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout); | ||
| 146 | + } else { | ||
| 147 | + $fp = @$openfunc($this->addr, $this->port, $errno, $errstr); | ||
| 148 | + } | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + if (!$fp) { | ||
| 152 | + if ($errno == 0 && isset($php_errormsg)) { | ||
| 153 | + $errstr = $php_errormsg; | ||
| 154 | + } | ||
| 155 | + @ini_set('track_errors', $old_track_errors); | ||
| 156 | + return $this->raiseError($errstr, $errno); | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + @ini_set('track_errors', $old_track_errors); | ||
| 160 | + $this->fp = $fp; | ||
| 161 | + | ||
| 162 | + return $this->setBlocking($this->blocking); | ||
| 163 | + } | ||
| 164 | + | ||
| 165 | + /** | ||
| 166 | + * Disconnects from the peer, closes the socket. | ||
| 167 | + * | ||
| 168 | + * @access public | ||
| 169 | + * @return mixed true on success or a PEAR_Error instance otherwise | ||
| 170 | + */ | ||
| 171 | + function disconnect() | ||
| 172 | + { | ||
| 173 | + if (!is_resource($this->fp)) { | ||
| 174 | + return $this->raiseError('not connected'); | ||
| 175 | + } | ||
| 176 | + | ||
| 177 | + @fclose($this->fp); | ||
| 178 | + $this->fp = null; | ||
| 179 | + return true; | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + /** | ||
| 183 | + * Find out if the socket is in blocking mode. | ||
| 184 | + * | ||
| 185 | + * @access public | ||
| 186 | + * @return boolean The current blocking mode. | ||
| 187 | + */ | ||
| 188 | + function isBlocking() | ||
| 189 | + { | ||
| 190 | + return $this->blocking; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + /** | ||
| 194 | + * Sets whether the socket connection should be blocking or | ||
| 195 | + * not. A read call to a non-blocking socket will return immediately | ||
| 196 | + * if there is no data available, whereas it will block until there | ||
| 197 | + * is data for blocking sockets. | ||
| 198 | + * | ||
| 199 | + * @param boolean $mode True for blocking sockets, false for nonblocking. | ||
| 200 | + * @access public | ||
| 201 | + * @return mixed true on success or a PEAR_Error instance otherwise | ||
| 202 | + */ | ||
| 203 | + function setBlocking($mode) | ||
| 204 | + { | ||
| 205 | + if (!is_resource($this->fp)) { | ||
| 206 | + return $this->raiseError('not connected'); | ||
| 207 | + } | ||
| 208 | + | ||
| 209 | + $this->blocking = $mode; | ||
| 210 | + socket_set_blocking($this->fp, $this->blocking); | ||
| 211 | + return true; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + /** | ||
| 215 | + * Sets the timeout value on socket descriptor, | ||
| 216 | + * expressed in the sum of seconds and microseconds | ||
| 217 | + * | ||
| 218 | + * @param integer $seconds Seconds. | ||
| 219 | + * @param integer $microseconds Microseconds. | ||
| 220 | + * @access public | ||
| 221 | + * @return mixed true on success or a PEAR_Error instance otherwise | ||
| 222 | + */ | ||
| 223 | + function setTimeout($seconds, $microseconds) | ||
| 224 | + { | ||
| 225 | + if (!is_resource($this->fp)) { | ||
| 226 | + return $this->raiseError('not connected'); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + return socket_set_timeout($this->fp, $seconds, $microseconds); | ||
| 230 | + } | ||
| 231 | + | ||
| 232 | + /** | ||
| 233 | + * Sets the file buffering size on the stream. | ||
| 234 | + * See php's stream_set_write_buffer for more information. | ||
| 235 | + * | ||
| 236 | + * @param integer $size Write buffer size. | ||
| 237 | + * @access public | ||
| 238 | + * @return mixed on success or an PEAR_Error object otherwise | ||
| 239 | + */ | ||
| 240 | + function setWriteBuffer($size) | ||
| 241 | + { | ||
| 242 | + if (!is_resource($this->fp)) { | ||
| 243 | + return $this->raiseError('not connected'); | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + $returned = stream_set_write_buffer($this->fp, $size); | ||
| 247 | + if ($returned == 0) { | ||
| 248 | + return true; | ||
| 249 | + } | ||
| 250 | + return $this->raiseError('Cannot set write buffer.'); | ||
| 251 | + } | ||
| 252 | + | ||
| 253 | + /** | ||
| 254 | + * Returns information about an existing socket resource. | ||
| 255 | + * Currently returns four entries in the result array: | ||
| 256 | + * | ||
| 257 | + * <p> | ||
| 258 | + * timed_out (bool) - The socket timed out waiting for data<br> | ||
| 259 | + * blocked (bool) - The socket was blocked<br> | ||
| 260 | + * eof (bool) - Indicates EOF event<br> | ||
| 261 | + * unread_bytes (int) - Number of bytes left in the socket buffer<br> | ||
| 262 | + * </p> | ||
| 263 | + * | ||
| 264 | + * @access public | ||
| 265 | + * @return mixed Array containing information about existing socket resource or a PEAR_Error instance otherwise | ||
| 266 | + */ | ||
| 267 | + function getStatus() | ||
| 268 | + { | ||
| 269 | + if (!is_resource($this->fp)) { | ||
| 270 | + return $this->raiseError('not connected'); | ||
| 271 | + } | ||
| 272 | + | ||
| 273 | + return socket_get_status($this->fp); | ||
| 274 | + } | ||
| 275 | + | ||
| 276 | + /** | ||
| 277 | + * Get a specified line of data | ||
| 278 | + * | ||
| 279 | + * @access public | ||
| 280 | + * @return $size bytes of data from the socket, or a PEAR_Error if | ||
| 281 | + * not connected. | ||
| 282 | + */ | ||
| 283 | + function gets($size) | ||
| 284 | + { | ||
| 285 | + if (!is_resource($this->fp)) { | ||
| 286 | + return $this->raiseError('not connected'); | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + return @fgets($this->fp, $size); | ||
| 290 | + } | ||
| 291 | + | ||
| 292 | + /** | ||
| 293 | + * Read a specified amount of data. This is guaranteed to return, | ||
| 294 | + * and has the added benefit of getting everything in one fread() | ||
| 295 | + * chunk; if you know the size of the data you're getting | ||
| 296 | + * beforehand, this is definitely the way to go. | ||
| 297 | + * | ||
| 298 | + * @param integer $size The number of bytes to read from the socket. | ||
| 299 | + * @access public | ||
| 300 | + * @return $size bytes of data from the socket, or a PEAR_Error if | ||
| 301 | + * not connected. | ||
| 302 | + */ | ||
| 303 | + function read($size) | ||
| 304 | + { | ||
| 305 | + if (!is_resource($this->fp)) { | ||
| 306 | + return $this->raiseError('not connected'); | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + return @fread($this->fp, $size); | ||
| 310 | + } | ||
| 311 | + | ||
| 312 | + /** | ||
| 313 | + * Write a specified amount of data. | ||
| 314 | + * | ||
| 315 | + * @param string $data Data to write. | ||
| 316 | + * @param integer $blocksize Amount of data to write at once. | ||
| 317 | + * NULL means all at once. | ||
| 318 | + * | ||
| 319 | + * @access public | ||
| 320 | + * @return mixed If the socket is not connected, returns an instance of PEAR_Error | ||
| 321 | + * If the write succeeds, returns the number of bytes written | ||
| 322 | + * If the write fails, returns false. | ||
| 323 | + */ | ||
| 324 | + function write($data, $blocksize = null) | ||
| 325 | + { | ||
| 326 | + if (!is_resource($this->fp)) { | ||
| 327 | + return $this->raiseError('not connected'); | ||
| 328 | + } | ||
| 329 | + | ||
| 330 | + if (is_null($blocksize) && !OS_WINDOWS) { | ||
| 331 | + return @fwrite($this->fp, $data); | ||
| 332 | + } else { | ||
| 333 | + if (is_null($blocksize)) { | ||
| 334 | + $blocksize = 1024; | ||
| 335 | + } | ||
| 336 | + | ||
| 337 | + $pos = 0; | ||
| 338 | + $size = strlen($data); | ||
| 339 | + while ($pos < $size) { | ||
| 340 | + $written = @fwrite($this->fp, substr($data, $pos, $blocksize)); | ||
| 341 | + if ($written === false) { | ||
| 342 | + return false; | ||
| 343 | + } | ||
| 344 | + $pos += $written; | ||
| 345 | + } | ||
| 346 | + | ||
| 347 | + return $pos; | ||
| 348 | + } | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + /** | ||
| 352 | + * Write a line of data to the socket, followed by a trailing "\r\n". | ||
| 353 | + * | ||
| 354 | + * @access public | ||
| 355 | + * @return mixed fputs result, or an error | ||
| 356 | + */ | ||
| 357 | + function writeLine($data) | ||
| 358 | + { | ||
| 359 | + if (!is_resource($this->fp)) { | ||
| 360 | + return $this->raiseError('not connected'); | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + return fwrite($this->fp, $data . "\r\n"); | ||
| 364 | + } | ||
| 365 | + | ||
| 366 | + /** | ||
| 367 | + * Tests for end-of-file on a socket descriptor. | ||
| 368 | + * | ||
| 369 | + * Also returns true if the socket is disconnected. | ||
| 370 | + * | ||
| 371 | + * @access public | ||
| 372 | + * @return bool | ||
| 373 | + */ | ||
| 374 | + function eof() | ||
| 375 | + { | ||
| 376 | + return (!is_resource($this->fp) || feof($this->fp)); | ||
| 377 | + } | ||
| 378 | + | ||
| 379 | + /** | ||
| 380 | + * Reads a byte of data | ||
| 381 | + * | ||
| 382 | + * @access public | ||
| 383 | + * @return 1 byte of data from the socket, or a PEAR_Error if | ||
| 384 | + * not connected. | ||
| 385 | + */ | ||
| 386 | + function readByte() | ||
| 387 | + { | ||
| 388 | + if (!is_resource($this->fp)) { | ||
| 389 | + return $this->raiseError('not connected'); | ||
| 390 | + } | ||
| 391 | + | ||
| 392 | + return ord(@fread($this->fp, 1)); | ||
| 393 | + } | ||
| 394 | + | ||
| 395 | + /** | ||
| 396 | + * Reads a word of data | ||
| 397 | + * | ||
| 398 | + * @access public | ||
| 399 | + * @return 1 word of data from the socket, or a PEAR_Error if | ||
| 400 | + * not connected. | ||
| 401 | + */ | ||
| 402 | + function readWord() | ||
| 403 | + { | ||
| 404 | + if (!is_resource($this->fp)) { | ||
| 405 | + return $this->raiseError('not connected'); | ||
| 406 | + } | ||
| 407 | + | ||
| 408 | + $buf = @fread($this->fp, 2); | ||
| 409 | + return (ord($buf[0]) + (ord($buf[1]) << 8)); | ||
| 410 | + } | ||
| 411 | + | ||
| 412 | + /** | ||
| 413 | + * Reads an int of data | ||
| 414 | + * | ||
| 415 | + * @access public | ||
| 416 | + * @return integer 1 int of data from the socket, or a PEAR_Error if | ||
| 417 | + * not connected. | ||
| 418 | + */ | ||
| 419 | + function readInt() | ||
| 420 | + { | ||
| 421 | + if (!is_resource($this->fp)) { | ||
| 422 | + return $this->raiseError('not connected'); | ||
| 423 | + } | ||
| 424 | + | ||
| 425 | + $buf = @fread($this->fp, 4); | ||
| 426 | + return (ord($buf[0]) + (ord($buf[1]) << 8) + | ||
| 427 | + (ord($buf[2]) << 16) + (ord($buf[3]) << 24)); | ||
| 428 | + } | ||
| 429 | + | ||
| 430 | + /** | ||
| 431 | + * Reads a zero-terminated string of data | ||
| 432 | + * | ||
| 433 | + * @access public | ||
| 434 | + * @return string, or a PEAR_Error if | ||
| 435 | + * not connected. | ||
| 436 | + */ | ||
| 437 | + function readString() | ||
| 438 | + { | ||
| 439 | + if (!is_resource($this->fp)) { | ||
| 440 | + return $this->raiseError('not connected'); | ||
| 441 | + } | ||
| 442 | + | ||
| 443 | + $string = ''; | ||
| 444 | + while (($char = @fread($this->fp, 1)) != "\x00") { | ||
| 445 | + $string .= $char; | ||
| 446 | + } | ||
| 447 | + return $string; | ||
| 448 | + } | ||
| 449 | + | ||
| 450 | + /** | ||
| 451 | + * Reads an IP Address and returns it in a dot formatted string | ||
| 452 | + * | ||
| 453 | + * @access public | ||
| 454 | + * @return Dot formatted string, or a PEAR_Error if | ||
| 455 | + * not connected. | ||
| 456 | + */ | ||
| 457 | + function readIPAddress() | ||
| 458 | + { | ||
| 459 | + if (!is_resource($this->fp)) { | ||
| 460 | + return $this->raiseError('not connected'); | ||
| 461 | + } | ||
| 462 | + | ||
| 463 | + $buf = @fread($this->fp, 4); | ||
| 464 | + return sprintf('%d.%d.%d.%d', ord($buf[0]), ord($buf[1]), | ||
| 465 | + ord($buf[2]), ord($buf[3])); | ||
| 466 | + } | ||
| 467 | + | ||
| 468 | + /** | ||
| 469 | + * Read until either the end of the socket or a newline, whichever | ||
| 470 | + * comes first. Strips the trailing newline from the returned data. | ||
| 471 | + * | ||
| 472 | + * @access public | ||
| 473 | + * @return All available data up to a newline, without that | ||
| 474 | + * newline, or until the end of the socket, or a PEAR_Error if | ||
| 475 | + * not connected. | ||
| 476 | + */ | ||
| 477 | + function readLine() | ||
| 478 | + { | ||
| 479 | + if (!is_resource($this->fp)) { | ||
| 480 | + return $this->raiseError('not connected'); | ||
| 481 | + } | ||
| 482 | + | ||
| 483 | + $line = ''; | ||
| 484 | + $timeout = time() + $this->timeout; | ||
| 485 | + while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { | ||
| 486 | + $line .= @fgets($this->fp, $this->lineLength); | ||
| 487 | + if (substr($line, -1) == "\n") { | ||
| 488 | + return rtrim($line, "\r\n"); | ||
| 489 | + } | ||
| 490 | + } | ||
| 491 | + return $line; | ||
| 492 | + } | ||
| 493 | + | ||
| 494 | + /** | ||
| 495 | + * Read until the socket closes, or until there is no more data in | ||
| 496 | + * the inner PHP buffer. If the inner buffer is empty, in blocking | ||
| 497 | + * mode we wait for at least 1 byte of data. Therefore, in | ||
| 498 | + * blocking mode, if there is no data at all to be read, this | ||
| 499 | + * function will never exit (unless the socket is closed on the | ||
| 500 | + * remote end). | ||
| 501 | + * | ||
| 502 | + * @access public | ||
| 503 | + * | ||
| 504 | + * @return string All data until the socket closes, or a PEAR_Error if | ||
| 505 | + * not connected. | ||
| 506 | + */ | ||
| 507 | + function readAll() | ||
| 508 | + { | ||
| 509 | + if (!is_resource($this->fp)) { | ||
| 510 | + return $this->raiseError('not connected'); | ||
| 511 | + } | ||
| 512 | + | ||
| 513 | + $data = ''; | ||
| 514 | + while (!feof($this->fp)) { | ||
| 515 | + $data .= @fread($this->fp, $this->lineLength); | ||
| 516 | + } | ||
| 517 | + return $data; | ||
| 518 | + } | ||
| 519 | + | ||
| 520 | + /** | ||
| 521 | + * Runs the equivalent of the select() system call on the socket | ||
| 522 | + * with a timeout specified by tv_sec and tv_usec. | ||
| 523 | + * | ||
| 524 | + * @param integer $state Which of read/write/error to check for. | ||
| 525 | + * @param integer $tv_sec Number of seconds for timeout. | ||
| 526 | + * @param integer $tv_usec Number of microseconds for timeout. | ||
| 527 | + * | ||
| 528 | + * @access public | ||
| 529 | + * @return False if select fails, integer describing which of read/write/error | ||
| 530 | + * are ready, or PEAR_Error if not connected. | ||
| 531 | + */ | ||
| 532 | + function select($state, $tv_sec, $tv_usec = 0) | ||
| 533 | + { | ||
| 534 | + if (!is_resource($this->fp)) { | ||
| 535 | + return $this->raiseError('not connected'); | ||
| 536 | + } | ||
| 537 | + | ||
| 538 | + $read = null; | ||
| 539 | + $write = null; | ||
| 540 | + $except = null; | ||
| 541 | + if ($state & NET_SOCKET_READ) { | ||
| 542 | + $read[] = $this->fp; | ||
| 543 | + } | ||
| 544 | + if ($state & NET_SOCKET_WRITE) { | ||
| 545 | + $write[] = $this->fp; | ||
| 546 | + } | ||
| 547 | + if ($state & NET_SOCKET_ERROR) { | ||
| 548 | + $except[] = $this->fp; | ||
| 549 | + } | ||
| 550 | + if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { | ||
| 551 | + return false; | ||
| 552 | + } | ||
| 553 | + | ||
| 554 | + $result = 0; | ||
| 555 | + if (count($read)) { | ||
| 556 | + $result |= NET_SOCKET_READ; | ||
| 557 | + } | ||
| 558 | + if (count($write)) { | ||
| 559 | + $result |= NET_SOCKET_WRITE; | ||
| 560 | + } | ||
| 561 | + if (count($except)) { | ||
| 562 | + $result |= NET_SOCKET_ERROR; | ||
| 563 | + } | ||
| 564 | + return $result; | ||
| 565 | + } | ||
| 566 | + | ||
| 567 | + /** | ||
| 568 | + * Turns encryption on/off on a connected socket. | ||
| 569 | + * | ||
| 570 | + * @param bool $enabled Set this parameter to true to enable encryption | ||
| 571 | + * and false to disable encryption. | ||
| 572 | + * @param integer $type Type of encryption. See | ||
| 573 | + * http://se.php.net/manual/en/function.stream-socket-enable-crypto.php for values. | ||
| 574 | + * | ||
| 575 | + * @access public | ||
| 576 | + * @return false on error, true on success and 0 if there isn't enough data and the | ||
| 577 | + * user should try again (non-blocking sockets only). A PEAR_Error object | ||
| 578 | + * is returned if the socket is not connected | ||
| 579 | + */ | ||
| 580 | + function enableCrypto($enabled, $type) | ||
| 581 | + { | ||
| 582 | + if (version_compare(phpversion(), "5.1.0", ">=")) { | ||
| 583 | + if (!is_resource($this->fp)) { | ||
| 584 | + return $this->raiseError('not connected'); | ||
| 585 | + } | ||
| 586 | + return @stream_socket_enable_crypto($this->fp, $enabled, $type); | ||
| 587 | + } else { | ||
| 588 | + return $this->raiseError('Net_Socket::enableCrypto() requires php version >= 5.1.0'); | ||
| 589 | + } | ||
| 590 | + } | ||
| 591 | + | ||
| 592 | +} |
lib/http/Net/URL.php
0 → 100644
| 1 | +<?php | ||
| 2 | +// +-----------------------------------------------------------------------+ | ||
| 3 | +// | Copyright (c) 2002-2004, Richard Heyes | | ||
| 4 | +// | All rights reserved. | | ||
| 5 | +// | | | ||
| 6 | +// | Redistribution and use in source and binary forms, with or without | | ||
| 7 | +// | modification, are permitted provided that the following conditions | | ||
| 8 | +// | are met: | | ||
| 9 | +// | | | ||
| 10 | +// | o Redistributions of source code must retain the above copyright | | ||
| 11 | +// | notice, this list of conditions and the following disclaimer. | | ||
| 12 | +// | o Redistributions in binary form must reproduce the above copyright | | ||
| 13 | +// | notice, this list of conditions and the following disclaimer in the | | ||
| 14 | +// | documentation and/or other materials provided with the distribution.| | ||
| 15 | +// | o The names of the authors may not be used to endorse or promote | | ||
| 16 | +// | products derived from this software without specific prior written | | ||
| 17 | +// | permission. | | ||
| 18 | +// | | | ||
| 19 | +// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | | ||
| 20 | +// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | | ||
| 21 | +// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | | ||
| 22 | +// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | | ||
| 23 | +// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | | ||
| 24 | +// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | | ||
| 25 | +// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | ||
| 26 | +// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | ||
| 27 | +// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | ||
| 28 | +// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | | ||
| 29 | +// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | ||
| 30 | +// | | | ||
| 31 | +// +-----------------------------------------------------------------------+ | ||
| 32 | +// | Author: Richard Heyes <richard at php net> | | ||
| 33 | +// +-----------------------------------------------------------------------+ | ||
| 34 | +// | ||
| 35 | +// $Id: URL.php,v 1.49 2007/06/28 14:43:07 davidc Exp $ | ||
| 36 | +// | ||
| 37 | +// Net_URL Class | ||
| 38 | + | ||
| 39 | + | ||
| 40 | +class Net_URL | ||
| 41 | +{ | ||
| 42 | + var $options = array('encode_query_keys' => false); | ||
| 43 | + /** | ||
| 44 | + * Full url | ||
| 45 | + * @var string | ||
| 46 | + */ | ||
| 47 | + var $url; | ||
| 48 | + | ||
| 49 | + /** | ||
| 50 | + * Protocol | ||
| 51 | + * @var string | ||
| 52 | + */ | ||
| 53 | + var $protocol; | ||
| 54 | + | ||
| 55 | + /** | ||
| 56 | + * Username | ||
| 57 | + * @var string | ||
| 58 | + */ | ||
| 59 | + var $username; | ||
| 60 | + | ||
| 61 | + /** | ||
| 62 | + * Password | ||
| 63 | + * @var string | ||
| 64 | + */ | ||
| 65 | + var $password; | ||
| 66 | + | ||
| 67 | + /** | ||
| 68 | + * Host | ||
| 69 | + * @var string | ||
| 70 | + */ | ||
| 71 | + var $host; | ||
| 72 | + | ||
| 73 | + /** | ||
| 74 | + * Port | ||
| 75 | + * @var integer | ||
| 76 | + */ | ||
| 77 | + var $port; | ||
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * Path | ||
| 81 | + * @var string | ||
| 82 | + */ | ||
| 83 | + var $path; | ||
| 84 | + | ||
| 85 | + /** | ||
| 86 | + * Query string | ||
| 87 | + * @var array | ||
| 88 | + */ | ||
| 89 | + var $querystring; | ||
| 90 | + | ||
| 91 | + /** | ||
| 92 | + * Anchor | ||
| 93 | + * @var string | ||
| 94 | + */ | ||
| 95 | + var $anchor; | ||
| 96 | + | ||
| 97 | + /** | ||
| 98 | + * Whether to use [] | ||
| 99 | + * @var bool | ||
| 100 | + */ | ||
| 101 | + var $useBrackets; | ||
| 102 | + | ||
| 103 | + /** | ||
| 104 | + * PHP4 Constructor | ||
| 105 | + * | ||
| 106 | + * @see __construct() | ||
| 107 | + */ | ||
| 108 | + function Net_URL($url = null, $useBrackets = true) | ||
| 109 | + { | ||
| 110 | + $this->__construct($url, $useBrackets); | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + /** | ||
| 114 | + * PHP5 Constructor | ||
| 115 | + * | ||
| 116 | + * Parses the given url and stores the various parts | ||
| 117 | + * Defaults are used in certain cases | ||
| 118 | + * | ||
| 119 | + * @param string $url Optional URL | ||
| 120 | + * @param bool $useBrackets Whether to use square brackets when | ||
| 121 | + * multiple querystrings with the same name | ||
| 122 | + * exist | ||
| 123 | + */ | ||
| 124 | + function __construct($url = null, $useBrackets = true) | ||
| 125 | + { | ||
| 126 | + $this->url = $url; | ||
| 127 | + $this->useBrackets = $useBrackets; | ||
| 128 | + | ||
| 129 | + $this->initialize(); | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + function initialize() | ||
| 133 | + { | ||
| 134 | + $HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; | ||
| 135 | + | ||
| 136 | + $this->user = ''; | ||
| 137 | + $this->pass = ''; | ||
| 138 | + $this->host = ''; | ||
| 139 | + $this->port = 80; | ||
| 140 | + $this->path = ''; | ||
| 141 | + $this->querystring = array(); | ||
| 142 | + $this->anchor = ''; | ||
| 143 | + | ||
| 144 | + // Only use defaults if not an absolute URL given | ||
| 145 | + if (!preg_match('/^[a-z0-9]+:\/\//i', $this->url)) { | ||
| 146 | + $this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'); | ||
| 147 | + | ||
| 148 | + /** | ||
| 149 | + * Figure out host/port | ||
| 150 | + */ | ||
| 151 | + if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) && | ||
| 152 | + preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) | ||
| 153 | + { | ||
| 154 | + $host = $matches[1]; | ||
| 155 | + if (!empty($matches[3])) { | ||
| 156 | + $port = $matches[3]; | ||
| 157 | + } else { | ||
| 158 | + $port = $this->getStandardPort($this->protocol); | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + $this->user = ''; | ||
| 163 | + $this->pass = ''; | ||
| 164 | + $this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); | ||
| 165 | + $this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); | ||
| 166 | + $this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/'; | ||
| 167 | + $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; | ||
| 168 | + $this->anchor = ''; | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + // Parse the url and store the various parts | ||
| 172 | + if (!empty($this->url)) { | ||
| 173 | + $urlinfo = parse_url($this->url); | ||
| 174 | + | ||
| 175 | + // Default querystring | ||
| 176 | + $this->querystring = array(); | ||
| 177 | + | ||
| 178 | + foreach ($urlinfo as $key => $value) { | ||
| 179 | + switch ($key) { | ||
| 180 | + case 'scheme': | ||
| 181 | + $this->protocol = $value; | ||
| 182 | + $this->port = $this->getStandardPort($value); | ||
| 183 | + break; | ||
| 184 | + | ||
| 185 | + case 'user': | ||
| 186 | + case 'pass': | ||
| 187 | + case 'host': | ||
| 188 | + case 'port': | ||
| 189 | + $this->$key = $value; | ||
| 190 | + break; | ||
| 191 | + | ||
| 192 | + case 'path': | ||
| 193 | + if ($value{0} == '/') { | ||
| 194 | + $this->path = $value; | ||
| 195 | + } else { | ||
| 196 | + $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); | ||
| 197 | + $this->path = sprintf('%s/%s', $path, $value); | ||
| 198 | + } | ||
| 199 | + break; | ||
| 200 | + | ||
| 201 | + case 'query': | ||
| 202 | + $this->querystring = $this->_parseRawQueryString($value); | ||
| 203 | + break; | ||
| 204 | + | ||
| 205 | + case 'fragment': | ||
| 206 | + $this->anchor = $value; | ||
| 207 | + break; | ||
| 208 | + } | ||
| 209 | + } | ||
| 210 | + } | ||
| 211 | + } | ||
| 212 | + /** | ||
| 213 | + * Returns full url | ||
| 214 | + * | ||
| 215 | + * @return string Full url | ||
| 216 | + * @access public | ||
| 217 | + */ | ||
| 218 | + function getURL() | ||
| 219 | + { | ||
| 220 | + $querystring = $this->getQueryString(); | ||
| 221 | + | ||
| 222 | + $this->url = $this->protocol . '://' | ||
| 223 | + . $this->user . (!empty($this->pass) ? ':' : '') | ||
| 224 | + . $this->pass . (!empty($this->user) ? '@' : '') | ||
| 225 | + . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) | ||
| 226 | + . $this->path | ||
| 227 | + . (!empty($querystring) ? '?' . $querystring : '') | ||
| 228 | + . (!empty($this->anchor) ? '#' . $this->anchor : ''); | ||
| 229 | + | ||
| 230 | + return $this->url; | ||
| 231 | + } | ||
| 232 | + | ||
| 233 | + /** | ||
| 234 | + * Adds or updates a querystring item (URL parameter). | ||
| 235 | + * Automatically encodes parameters with rawurlencode() if $preencoded | ||
| 236 | + * is false. | ||
| 237 | + * You can pass an array to $value, it gets mapped via [] in the URL if | ||
| 238 | + * $this->useBrackets is activated. | ||
| 239 | + * | ||
| 240 | + * @param string $name Name of item | ||
| 241 | + * @param string $value Value of item | ||
| 242 | + * @param bool $preencoded Whether value is urlencoded or not, default = not | ||
| 243 | + * @access public | ||
| 244 | + */ | ||
| 245 | + function addQueryString($name, $value, $preencoded = false) | ||
| 246 | + { | ||
| 247 | + if ($this->getOption('encode_query_keys')) { | ||
| 248 | + $name = rawurlencode($name); | ||
| 249 | + } | ||
| 250 | + | ||
| 251 | + if ($preencoded) { | ||
| 252 | + $this->querystring[$name] = $value; | ||
| 253 | + } else { | ||
| 254 | + $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); | ||
| 255 | + } | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + /** | ||
| 259 | + * Removes a querystring item | ||
| 260 | + * | ||
| 261 | + * @param string $name Name of item | ||
| 262 | + * @access public | ||
| 263 | + */ | ||
| 264 | + function removeQueryString($name) | ||
| 265 | + { | ||
| 266 | + if ($this->getOption('encode_query_keys')) { | ||
| 267 | + $name = rawurlencode($name); | ||
| 268 | + } | ||
| 269 | + | ||
| 270 | + if (isset($this->querystring[$name])) { | ||
| 271 | + unset($this->querystring[$name]); | ||
| 272 | + } | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + /** | ||
| 276 | + * Sets the querystring to literally what you supply | ||
| 277 | + * | ||
| 278 | + * @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc | ||
| 279 | + * @access public | ||
| 280 | + */ | ||
| 281 | + function addRawQueryString($querystring) | ||
| 282 | + { | ||
| 283 | + $this->querystring = $this->_parseRawQueryString($querystring); | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + /** | ||
| 287 | + * Returns flat querystring | ||
| 288 | + * | ||
| 289 | + * @return string Querystring | ||
| 290 | + * @access public | ||
| 291 | + */ | ||
| 292 | + function getQueryString() | ||
| 293 | + { | ||
| 294 | + if (!empty($this->querystring)) { | ||
| 295 | + foreach ($this->querystring as $name => $value) { | ||
| 296 | + // Encode var name | ||
| 297 | + $name = rawurlencode($name); | ||
| 298 | + | ||
| 299 | + if (is_array($value)) { | ||
| 300 | + foreach ($value as $k => $v) { | ||
| 301 | + $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); | ||
| 302 | + } | ||
| 303 | + } elseif (!is_null($value)) { | ||
| 304 | + $querystring[] = $name . '=' . $value; | ||
| 305 | + } else { | ||
| 306 | + $querystring[] = $name; | ||
| 307 | + } | ||
| 308 | + } | ||
| 309 | + $querystring = implode(ini_get('arg_separator.output'), $querystring); | ||
| 310 | + } else { | ||
| 311 | + $querystring = ''; | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + return $querystring; | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + /** | ||
| 318 | + * Parses raw querystring and returns an array of it | ||
| 319 | + * | ||
| 320 | + * @param string $querystring The querystring to parse | ||
| 321 | + * @return array An array of the querystring data | ||
| 322 | + * @access private | ||
| 323 | + */ | ||
| 324 | + function _parseRawQuerystring($querystring) | ||
| 325 | + { | ||
| 326 | + $parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); | ||
| 327 | + $return = array(); | ||
| 328 | + | ||
| 329 | + foreach ($parts as $part) { | ||
| 330 | + if (strpos($part, '=') !== false) { | ||
| 331 | + $value = substr($part, strpos($part, '=') + 1); | ||
| 332 | + $key = substr($part, 0, strpos($part, '=')); | ||
| 333 | + } else { | ||
| 334 | + $value = null; | ||
| 335 | + $key = $part; | ||
| 336 | + } | ||
| 337 | + | ||
| 338 | + if (!$this->getOption('encode_query_keys')) { | ||
| 339 | + $key = rawurldecode($key); | ||
| 340 | + } | ||
| 341 | + | ||
| 342 | + if (preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) { | ||
| 343 | + $key = $matches[1]; | ||
| 344 | + $idx = $matches[2]; | ||
| 345 | + | ||
| 346 | + // Ensure is an array | ||
| 347 | + if (empty($return[$key]) || !is_array($return[$key])) { | ||
| 348 | + $return[$key] = array(); | ||
| 349 | + } | ||
| 350 | + | ||
| 351 | + // Add data | ||
| 352 | + if ($idx === '') { | ||
| 353 | + $return[$key][] = $value; | ||
| 354 | + } else { | ||
| 355 | + $return[$key][$idx] = $value; | ||
| 356 | + } | ||
| 357 | + } elseif (!$this->useBrackets AND !empty($return[$key])) { | ||
| 358 | + $return[$key] = (array)$return[$key]; | ||
| 359 | + $return[$key][] = $value; | ||
| 360 | + } else { | ||
| 361 | + $return[$key] = $value; | ||
| 362 | + } | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + return $return; | ||
| 366 | + } | ||
| 367 | + | ||
| 368 | + /** | ||
| 369 | + * Resolves //, ../ and ./ from a path and returns | ||
| 370 | + * the result. Eg: | ||
| 371 | + * | ||
| 372 | + * /foo/bar/../boo.php => /foo/boo.php | ||
| 373 | + * /foo/bar/../../boo.php => /boo.php | ||
| 374 | + * /foo/bar/.././/boo.php => /foo/boo.php | ||
| 375 | + * | ||
| 376 | + * This method can also be called statically. | ||
| 377 | + * | ||
| 378 | + * @param string $path URL path to resolve | ||
| 379 | + * @return string The result | ||
| 380 | + */ | ||
| 381 | + function resolvePath($path) | ||
| 382 | + { | ||
| 383 | + $path = explode('/', str_replace('//', '/', $path)); | ||
| 384 | + | ||
| 385 | + for ($i=0; $i<count($path); $i++) { | ||
| 386 | + if ($path[$i] == '.') { | ||
| 387 | + unset($path[$i]); | ||
| 388 | + $path = array_values($path); | ||
| 389 | + $i--; | ||
| 390 | + | ||
| 391 | + } elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) { | ||
| 392 | + unset($path[$i]); | ||
| 393 | + unset($path[$i-1]); | ||
| 394 | + $path = array_values($path); | ||
| 395 | + $i -= 2; | ||
| 396 | + | ||
| 397 | + } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { | ||
| 398 | + unset($path[$i]); | ||
| 399 | + $path = array_values($path); | ||
| 400 | + $i--; | ||
| 401 | + | ||
| 402 | + } else { | ||
| 403 | + continue; | ||
| 404 | + } | ||
| 405 | + } | ||
| 406 | + | ||
| 407 | + return implode('/', $path); | ||
| 408 | + } | ||
| 409 | + | ||
| 410 | + /** | ||
| 411 | + * Returns the standard port number for a protocol | ||
| 412 | + * | ||
| 413 | + * @param string $scheme The protocol to lookup | ||
| 414 | + * @return integer Port number or NULL if no scheme matches | ||
| 415 | + * | ||
| 416 | + * @author Philippe Jausions <Philippe.Jausions@11abacus.com> | ||
| 417 | + */ | ||
| 418 | + function getStandardPort($scheme) | ||
| 419 | + { | ||
| 420 | + switch (strtolower($scheme)) { | ||
| 421 | + case 'http': return 80; | ||
| 422 | + case 'https': return 443; | ||
| 423 | + case 'ftp': return 21; | ||
| 424 | + case 'imap': return 143; | ||
| 425 | + case 'imaps': return 993; | ||
| 426 | + case 'pop3': return 110; | ||
| 427 | + case 'pop3s': return 995; | ||
| 428 | + default: return null; | ||
| 429 | + } | ||
| 430 | + } | ||
| 431 | + | ||
| 432 | + /** | ||
| 433 | + * Forces the URL to a particular protocol | ||
| 434 | + * | ||
| 435 | + * @param string $protocol Protocol to force the URL to | ||
| 436 | + * @param integer $port Optional port (standard port is used by default) | ||
| 437 | + */ | ||
| 438 | + function setProtocol($protocol, $port = null) | ||
| 439 | + { | ||
| 440 | + $this->protocol = $protocol; | ||
| 441 | + $this->port = is_null($port) ? $this->getStandardPort($protocol) : $port; | ||
| 442 | + } | ||
| 443 | + | ||
| 444 | + /** | ||
| 445 | + * Set an option | ||
| 446 | + * | ||
| 447 | + * This function set an option | ||
| 448 | + * to be used thorough the script. | ||
| 449 | + * | ||
| 450 | + * @access public | ||
| 451 | + * @param string $optionName The optionname to set | ||
| 452 | + * @param string $value The value of this option. | ||
| 453 | + */ | ||
| 454 | + function setOption($optionName, $value) | ||
| 455 | + { | ||
| 456 | + if (!array_key_exists($optionName, $this->options)) { | ||
| 457 | + return false; | ||
| 458 | + } | ||
| 459 | + | ||
| 460 | + $this->options[$optionName] = $value; | ||
| 461 | + $this->initialize(); | ||
| 462 | + } | ||
| 463 | + | ||
| 464 | + /** | ||
| 465 | + * Get an option | ||
| 466 | + * | ||
| 467 | + * This function gets an option | ||
| 468 | + * from the $this->options array | ||
| 469 | + * and return it's value. | ||
| 470 | + * | ||
| 471 | + * @access public | ||
| 472 | + * @param string $opionName The name of the option to retrieve | ||
| 473 | + * @see $this->options | ||
| 474 | + */ | ||
| 475 | + function getOption($optionName) | ||
| 476 | + { | ||
| 477 | + if (!isset($this->options[$optionName])) { | ||
| 478 | + return false; | ||
| 479 | + } | ||
| 480 | + | ||
| 481 | + return $this->options[$optionName]; | ||
| 482 | + } | ||
| 483 | + | ||
| 484 | +} | ||
| 485 | +?> |
lib/http/Request.php
0 → 100644
| 1 | +<?php | ||
| 2 | +/** | ||
| 3 | + * Class for performing HTTP requests | ||
| 4 | + * | ||
| 5 | + * PHP versions 4 and 5 | ||
| 6 | + * | ||
| 7 | + * LICENSE: | ||
| 8 | + * | ||
| 9 | + * Copyright (c) 2002-2007, Richard Heyes | ||
| 10 | + * All rights reserved. | ||
| 11 | + * | ||
| 12 | + * Redistribution and use in source and binary forms, with or without | ||
| 13 | + * modification, are permitted provided that the following conditions | ||
| 14 | + * are met: | ||
| 15 | + * | ||
| 16 | + * o Redistributions of source code must retain the above copyright | ||
| 17 | + * notice, this list of conditions and the following disclaimer. | ||
| 18 | + * o Redistributions in binary form must reproduce the above copyright | ||
| 19 | + * notice, this list of conditions and the following disclaimer in the | ||
| 20 | + * documentation and/or other materials provided with the distribution. | ||
| 21 | + * o The names of the authors may not be used to endorse or promote | ||
| 22 | + * products derived from this software without specific prior written | ||
| 23 | + * permission. | ||
| 24 | + * | ||
| 25 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 26 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 27 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 28 | + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| 29 | + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| 30 | + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| 31 | + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| 32 | + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| 33 | + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| 34 | + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 35 | + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 36 | + * | ||
| 37 | + * @category HTTP | ||
| 38 | + * @package HTTP_Request | ||
| 39 | + * @author Richard Heyes <richard@phpguru.org> | ||
| 40 | + * @author Alexey Borzov <avb@php.net> | ||
| 41 | + * @copyright 2002-2007 Richard Heyes | ||
| 42 | + * @license http://opensource.org/licenses/bsd-license.php New BSD License | ||
| 43 | + * @version CVS: $Id: Request.php,v 1.63 2008/10/11 11:07:10 avb Exp $ | ||
| 44 | + * @link http://pear.php.net/package/HTTP_Request/ | ||
| 45 | + */ | ||
| 46 | + | ||
| 47 | +/** | ||
| 48 | + * PEAR and PEAR_Error classes (for error handling) | ||
| 49 | + */ | ||
| 50 | +require_once 'PEAR.php'; | ||
| 51 | +/** | ||
| 52 | + * Socket class | ||
| 53 | + */ | ||
| 54 | +require_once 'Net/Socket.php'; | ||
| 55 | +/** | ||
| 56 | + * URL handling class | ||
| 57 | + */ | ||
| 58 | +require_once 'Net/URL.php'; | ||
| 59 | + | ||
| 60 | +/**#@+ | ||
| 61 | + * Constants for HTTP request methods | ||
| 62 | + */ | ||
| 63 | +define('HTTP_REQUEST_METHOD_GET', 'GET', true); | ||
| 64 | +define('HTTP_REQUEST_METHOD_HEAD', 'HEAD', true); | ||
| 65 | +define('HTTP_REQUEST_METHOD_POST', 'POST', true); | ||
| 66 | +define('HTTP_REQUEST_METHOD_PUT', 'PUT', true); | ||
| 67 | +define('HTTP_REQUEST_METHOD_DELETE', 'DELETE', true); | ||
| 68 | +define('HTTP_REQUEST_METHOD_OPTIONS', 'OPTIONS', true); | ||
| 69 | +define('HTTP_REQUEST_METHOD_TRACE', 'TRACE', true); | ||
| 70 | +/**#@-*/ | ||
| 71 | + | ||
| 72 | +/**#@+ | ||
| 73 | + * Constants for HTTP request error codes | ||
| 74 | + */ | ||
| 75 | +define('HTTP_REQUEST_ERROR_FILE', 1); | ||
| 76 | +define('HTTP_REQUEST_ERROR_URL', 2); | ||
| 77 | +define('HTTP_REQUEST_ERROR_PROXY', 4); | ||
| 78 | +define('HTTP_REQUEST_ERROR_REDIRECTS', 8); | ||
| 79 | +define('HTTP_REQUEST_ERROR_RESPONSE', 16); | ||
| 80 | +define('HTTP_REQUEST_ERROR_GZIP_METHOD', 32); | ||
| 81 | +define('HTTP_REQUEST_ERROR_GZIP_READ', 64); | ||
| 82 | +define('HTTP_REQUEST_ERROR_GZIP_DATA', 128); | ||
| 83 | +define('HTTP_REQUEST_ERROR_GZIP_CRC', 256); | ||
| 84 | +/**#@-*/ | ||
| 85 | + | ||
| 86 | +/**#@+ | ||
| 87 | + * Constants for HTTP protocol versions | ||
| 88 | + */ | ||
| 89 | +define('HTTP_REQUEST_HTTP_VER_1_0', '1.0', true); | ||
| 90 | +define('HTTP_REQUEST_HTTP_VER_1_1', '1.1', true); | ||
| 91 | +/**#@-*/ | ||
| 92 | + | ||
| 93 | +if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) { | ||
| 94 | + /** | ||
| 95 | + * Whether string functions are overloaded by their mbstring equivalents | ||
| 96 | + */ | ||
| 97 | + define('HTTP_REQUEST_MBSTRING', true); | ||
| 98 | +} else { | ||
| 99 | + /** | ||
| 100 | + * @ignore | ||
| 101 | + */ | ||
| 102 | + define('HTTP_REQUEST_MBSTRING', false); | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +/** | ||
| 106 | + * Class for performing HTTP requests | ||
| 107 | + * | ||
| 108 | + * Simple example (fetches yahoo.com and displays it): | ||
| 109 | + * <code> | ||
| 110 | + * $a = &new HTTP_Request('http://www.yahoo.com/'); | ||
| 111 | + * $a->sendRequest(); | ||
| 112 | + * echo $a->getResponseBody(); | ||
| 113 | + * </code> | ||
| 114 | + * | ||
| 115 | + * @category HTTP | ||
| 116 | + * @package HTTP_Request | ||
| 117 | + * @author Richard Heyes <richard@phpguru.org> | ||
| 118 | + * @author Alexey Borzov <avb@php.net> | ||
| 119 | + * @version Release: 1.4.4 | ||
| 120 | + */ | ||
| 121 | +class HTTP_Request | ||
| 122 | +{ | ||
| 123 | + /**#@+ | ||
| 124 | + * @access private | ||
| 125 | + */ | ||
| 126 | + /** | ||
| 127 | + * Instance of Net_URL | ||
| 128 | + * @var Net_URL | ||
| 129 | + */ | ||
| 130 | + var $_url; | ||
| 131 | + | ||
| 132 | + /** | ||
| 133 | + * Type of request | ||
| 134 | + * @var string | ||
| 135 | + */ | ||
| 136 | + var $_method; | ||
| 137 | + | ||
| 138 | + /** | ||
| 139 | + * HTTP Version | ||
| 140 | + * @var string | ||
| 141 | + */ | ||
| 142 | + var $_http; | ||
| 143 | + | ||
| 144 | + /** | ||
| 145 | + * Request headers | ||
| 146 | + * @var array | ||
| 147 | + */ | ||
| 148 | + var $_requestHeaders; | ||
| 149 | + | ||
| 150 | + /** | ||
| 151 | + * Basic Auth Username | ||
| 152 | + * @var string | ||
| 153 | + */ | ||
| 154 | + var $_user; | ||
| 155 | + | ||
| 156 | + /** | ||
| 157 | + * Basic Auth Password | ||
| 158 | + * @var string | ||
| 159 | + */ | ||
| 160 | + var $_pass; | ||
| 161 | + | ||
| 162 | + /** | ||
| 163 | + * Socket object | ||
| 164 | + * @var Net_Socket | ||
| 165 | + */ | ||
| 166 | + var $_sock; | ||
| 167 | + | ||
| 168 | + /** | ||
| 169 | + * Proxy server | ||
| 170 | + * @var string | ||
| 171 | + */ | ||
| 172 | + var $_proxy_host; | ||
| 173 | + | ||
| 174 | + /** | ||
| 175 | + * Proxy port | ||
| 176 | + * @var integer | ||
| 177 | + */ | ||
| 178 | + var $_proxy_port; | ||
| 179 | + | ||
| 180 | + /** | ||
| 181 | + * Proxy username | ||
| 182 | + * @var string | ||
| 183 | + */ | ||
| 184 | + var $_proxy_user; | ||
| 185 | + | ||
| 186 | + /** | ||
| 187 | + * Proxy password | ||
| 188 | + * @var string | ||
| 189 | + */ | ||
| 190 | + var $_proxy_pass; | ||
| 191 | + | ||
| 192 | + /** | ||
| 193 | + * Post data | ||
| 194 | + * @var array | ||
| 195 | + */ | ||
| 196 | + var $_postData; | ||
| 197 | + | ||
| 198 | + /** | ||
| 199 | + * Request body | ||
| 200 | + * @var string | ||
| 201 | + */ | ||
| 202 | + var $_body; | ||
| 203 | + | ||
| 204 | + /** | ||
| 205 | + * A list of methods that MUST NOT have a request body, per RFC 2616 | ||
| 206 | + * @var array | ||
| 207 | + */ | ||
| 208 | + var $_bodyDisallowed = array('TRACE'); | ||
| 209 | + | ||
| 210 | + /** | ||
| 211 | + * Methods having defined semantics for request body | ||
| 212 | + * | ||
| 213 | + * Content-Length header (indicating that the body follows, section 4.3 of | ||
| 214 | + * RFC 2616) will be sent for these methods even if no body was added | ||
| 215 | + * | ||
| 216 | + * @var array | ||
| 217 | + */ | ||
| 218 | + var $_bodyRequired = array('POST', 'PUT'); | ||
| 219 | + | ||
| 220 | + /** | ||
| 221 | + * Files to post | ||
| 222 | + * @var array | ||
| 223 | + */ | ||
| 224 | + var $_postFiles = array(); | ||
| 225 | + | ||
| 226 | + /** | ||
| 227 | + * Connection timeout. | ||
| 228 | + * @var float | ||
| 229 | + */ | ||
| 230 | + var $_timeout; | ||
| 231 | + | ||
| 232 | + /** | ||
| 233 | + * HTTP_Response object | ||
| 234 | + * @var HTTP_Response | ||
| 235 | + */ | ||
| 236 | + var $_response; | ||
| 237 | + | ||
| 238 | + /** | ||
| 239 | + * Whether to allow redirects | ||
| 240 | + * @var boolean | ||
| 241 | + */ | ||
| 242 | + var $_allowRedirects; | ||
| 243 | + | ||
| 244 | + /** | ||
| 245 | + * Maximum redirects allowed | ||
| 246 | + * @var integer | ||
| 247 | + */ | ||
| 248 | + var $_maxRedirects; | ||
| 249 | + | ||
| 250 | + /** | ||
| 251 | + * Current number of redirects | ||
| 252 | + * @var integer | ||
| 253 | + */ | ||
| 254 | + var $_redirects; | ||
| 255 | + | ||
| 256 | + /** | ||
| 257 | + * Whether to append brackets [] to array variables | ||
| 258 | + * @var bool | ||
| 259 | + */ | ||
| 260 | + var $_useBrackets = true; | ||
| 261 | + | ||
| 262 | + /** | ||
| 263 | + * Attached listeners | ||
| 264 | + * @var array | ||
| 265 | + */ | ||
| 266 | + var $_listeners = array(); | ||
| 267 | + | ||
| 268 | + /** | ||
| 269 | + * Whether to save response body in response object property | ||
| 270 | + * @var bool | ||
| 271 | + */ | ||
| 272 | + var $_saveBody = true; | ||
| 273 | + | ||
| 274 | + /** | ||
| 275 | + * Timeout for reading from socket (array(seconds, microseconds)) | ||
| 276 | + * @var array | ||
| 277 | + */ | ||
| 278 | + var $_readTimeout = null; | ||
| 279 | + | ||
| 280 | + /** | ||
| 281 | + * Options to pass to Net_Socket::connect. See stream_context_create | ||
| 282 | + * @var array | ||
| 283 | + */ | ||
| 284 | + var $_socketOptions = null; | ||
| 285 | + /**#@-*/ | ||
| 286 | + | ||
| 287 | + /** | ||
| 288 | + * Constructor | ||
| 289 | + * | ||
| 290 | + * Sets up the object | ||
| 291 | + * @param string The url to fetch/access | ||
| 292 | + * @param array Associative array of parameters which can have the following keys: | ||
| 293 | + * <ul> | ||
| 294 | + * <li>method - Method to use, GET, POST etc (string)</li> | ||
| 295 | + * <li>http - HTTP Version to use, 1.0 or 1.1 (string)</li> | ||
| 296 | + * <li>user - Basic Auth username (string)</li> | ||
| 297 | + * <li>pass - Basic Auth password (string)</li> | ||
| 298 | + * <li>proxy_host - Proxy server host (string)</li> | ||
| 299 | + * <li>proxy_port - Proxy server port (integer)</li> | ||
| 300 | + * <li>proxy_user - Proxy auth username (string)</li> | ||
| 301 | + * <li>proxy_pass - Proxy auth password (string)</li> | ||
| 302 | + * <li>timeout - Connection timeout in seconds (float)</li> | ||
| 303 | + * <li>allowRedirects - Whether to follow redirects or not (bool)</li> | ||
| 304 | + * <li>maxRedirects - Max number of redirects to follow (integer)</li> | ||
| 305 | + * <li>useBrackets - Whether to append [] to array variable names (bool)</li> | ||
| 306 | + * <li>saveBody - Whether to save response body in response object property (bool)</li> | ||
| 307 | + * <li>readTimeout - Timeout for reading / writing data over the socket (array (seconds, microseconds))</li> | ||
| 308 | + * <li>socketOptions - Options to pass to Net_Socket object (array)</li> | ||
| 309 | + * </ul> | ||
| 310 | + * @access public | ||
| 311 | + */ | ||
| 312 | + function HTTP_Request($url = '', $params = array()) | ||
| 313 | + { | ||
| 314 | + $this->_method = HTTP_REQUEST_METHOD_GET; | ||
| 315 | + $this->_http = HTTP_REQUEST_HTTP_VER_1_1; | ||
| 316 | + $this->_requestHeaders = array(); | ||
| 317 | + $this->_postData = array(); | ||
| 318 | + $this->_body = null; | ||
| 319 | + | ||
| 320 | + $this->_user = null; | ||
| 321 | + $this->_pass = null; | ||
| 322 | + | ||
| 323 | + $this->_proxy_host = null; | ||
| 324 | + $this->_proxy_port = null; | ||
| 325 | + $this->_proxy_user = null; | ||
| 326 | + $this->_proxy_pass = null; | ||
| 327 | + | ||
| 328 | + $this->_allowRedirects = false; | ||
| 329 | + $this->_maxRedirects = 3; | ||
| 330 | + $this->_redirects = 0; | ||
| 331 | + | ||
| 332 | + $this->_timeout = null; | ||
| 333 | + $this->_response = null; | ||
| 334 | + | ||
| 335 | + foreach ($params as $key => $value) { | ||
| 336 | + $this->{'_' . $key} = $value; | ||
| 337 | + } | ||
| 338 | + | ||
| 339 | + if (!empty($url)) { | ||
| 340 | + $this->setURL($url); | ||
| 341 | + } | ||
| 342 | + | ||
| 343 | + // Default useragent | ||
| 344 | + $this->addHeader('User-Agent', 'PEAR HTTP_Request class ( http://pear.php.net/ )'); | ||
| 345 | + | ||
| 346 | + // We don't do keep-alives by default | ||
| 347 | + $this->addHeader('Connection', 'close'); | ||
| 348 | + | ||
| 349 | + // Basic authentication | ||
| 350 | + if (!empty($this->_user)) { | ||
| 351 | + $this->addHeader('Authorization', 'Basic ' . base64_encode($this->_user . ':' . $this->_pass)); | ||
| 352 | + } | ||
| 353 | + | ||
| 354 | + // Proxy authentication (see bug #5913) | ||
| 355 | + if (!empty($this->_proxy_user)) { | ||
| 356 | + $this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($this->_proxy_user . ':' . $this->_proxy_pass)); | ||
| 357 | + } | ||
| 358 | + | ||
| 359 | + // Use gzip encoding if possible | ||
| 360 | + if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && extension_loaded('zlib')) { | ||
| 361 | + $this->addHeader('Accept-Encoding', 'gzip'); | ||
| 362 | + } | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + /** | ||
| 366 | + * Generates a Host header for HTTP/1.1 requests | ||
| 367 | + * | ||
| 368 | + * @access private | ||
| 369 | + * @return string | ||
| 370 | + */ | ||
| 371 | + function _generateHostHeader() | ||
| 372 | + { | ||
| 373 | + if ($this->_url->port != 80 AND strcasecmp($this->_url->protocol, 'http') == 0) { | ||
| 374 | + $host = $this->_url->host . ':' . $this->_url->port; | ||
| 375 | + | ||
| 376 | + } elseif ($this->_url->port != 443 AND strcasecmp($this->_url->protocol, 'https') == 0) { | ||
| 377 | + $host = $this->_url->host . ':' . $this->_url->port; | ||
| 378 | + | ||
| 379 | + } elseif ($this->_url->port == 443 AND strcasecmp($this->_url->protocol, 'https') == 0 AND strpos($this->_url->url, ':443') !== false) { | ||
| 380 | + $host = $this->_url->host . ':' . $this->_url->port; | ||
| 381 | + | ||
| 382 | + } else { | ||
| 383 | + $host = $this->_url->host; | ||
| 384 | + } | ||
| 385 | + | ||
| 386 | + return $host; | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + /** | ||
| 390 | + * Resets the object to its initial state (DEPRECATED). | ||
| 391 | + * Takes the same parameters as the constructor. | ||
| 392 | + * | ||
| 393 | + * @param string $url The url to be requested | ||
| 394 | + * @param array $params Associative array of parameters | ||
| 395 | + * (see constructor for details) | ||
| 396 | + * @access public | ||
| 397 | + * @deprecated deprecated since 1.2, call the constructor if this is necessary | ||
| 398 | + */ | ||
| 399 | + function reset($url, $params = array()) | ||
| 400 | + { | ||
| 401 | + $this->HTTP_Request($url, $params); | ||
| 402 | + } | ||
| 403 | + | ||
| 404 | + /** | ||
| 405 | + * Sets the URL to be requested | ||
| 406 | + * | ||
| 407 | + * @param string The url to be requested | ||
| 408 | + * @access public | ||
| 409 | + */ | ||
| 410 | + function setURL($url) | ||
| 411 | + { | ||
| 412 | + $this->_url = &new Net_URL($url, $this->_useBrackets); | ||
| 413 | + | ||
| 414 | + if (!empty($this->_url->user) || !empty($this->_url->pass)) { | ||
| 415 | + $this->setBasicAuth($this->_url->user, $this->_url->pass); | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + if (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http) { | ||
| 419 | + $this->addHeader('Host', $this->_generateHostHeader()); | ||
| 420 | + } | ||
| 421 | + | ||
| 422 | + // set '/' instead of empty path rather than check later (see bug #8662) | ||
| 423 | + if (empty($this->_url->path)) { | ||
| 424 | + $this->_url->path = '/'; | ||
| 425 | + } | ||
| 426 | + } | ||
| 427 | + | ||
| 428 | + /** | ||
| 429 | + * Returns the current request URL | ||
| 430 | + * | ||
| 431 | + * @return string Current request URL | ||
| 432 | + * @access public | ||
| 433 | + */ | ||
| 434 | + function getUrl() | ||
| 435 | + { | ||
| 436 | + return empty($this->_url)? '': $this->_url->getUrl(); | ||
| 437 | + } | ||
| 438 | + | ||
| 439 | + /** | ||
| 440 | + * Sets a proxy to be used | ||
| 441 | + * | ||
| 442 | + * @param string Proxy host | ||
| 443 | + * @param int Proxy port | ||
| 444 | + * @param string Proxy username | ||
| 445 | + * @param string Proxy password | ||
| 446 | + * @access public | ||
| 447 | + */ | ||
| 448 | + function setProxy($host, $port = 8080, $user = null, $pass = null) | ||
| 449 | + { | ||
| 450 | + $this->_proxy_host = $host; | ||
| 451 | + $this->_proxy_port = $port; | ||
| 452 | + $this->_proxy_user = $user; | ||
| 453 | + $this->_proxy_pass = $pass; | ||
| 454 | + | ||
| 455 | + if (!empty($user)) { | ||
| 456 | + $this->addHeader('Proxy-Authorization', 'Basic ' . base64_encode($user . ':' . $pass)); | ||
| 457 | + } | ||
| 458 | + } | ||
| 459 | + | ||
| 460 | + /** | ||
| 461 | + * Sets basic authentication parameters | ||
| 462 | + * | ||
| 463 | + * @param string Username | ||
| 464 | + * @param string Password | ||
| 465 | + */ | ||
| 466 | + function setBasicAuth($user, $pass) | ||
| 467 | + { | ||
| 468 | + $this->_user = $user; | ||
| 469 | + $this->_pass = $pass; | ||
| 470 | + | ||
| 471 | + $this->addHeader('Authorization', 'Basic ' . base64_encode($user . ':' . $pass)); | ||
| 472 | + } | ||
| 473 | + | ||
| 474 | + /** | ||
| 475 | + * Sets the method to be used, GET, POST etc. | ||
| 476 | + * | ||
| 477 | + * @param string Method to use. Use the defined constants for this | ||
| 478 | + * @access public | ||
| 479 | + */ | ||
| 480 | + function setMethod($method) | ||
| 481 | + { | ||
| 482 | + $this->_method = $method; | ||
| 483 | + } | ||
| 484 | + | ||
| 485 | + /** | ||
| 486 | + * Sets the HTTP version to use, 1.0 or 1.1 | ||
| 487 | + * | ||
| 488 | + * @param string Version to use. Use the defined constants for this | ||
| 489 | + * @access public | ||
| 490 | + */ | ||
| 491 | + function setHttpVer($http) | ||
| 492 | + { | ||
| 493 | + $this->_http = $http; | ||
| 494 | + } | ||
| 495 | + | ||
| 496 | + /** | ||
| 497 | + * Adds a request header | ||
| 498 | + * | ||
| 499 | + * @param string Header name | ||
| 500 | + * @param string Header value | ||
| 501 | + * @access public | ||
| 502 | + */ | ||
| 503 | + function addHeader($name, $value) | ||
| 504 | + { | ||
| 505 | + $this->_requestHeaders[strtolower($name)] = $value; | ||
| 506 | + } | ||
| 507 | + | ||
| 508 | + /** | ||
| 509 | + * Removes a request header | ||
| 510 | + * | ||
| 511 | + * @param string Header name to remove | ||
| 512 | + * @access public | ||
| 513 | + */ | ||
| 514 | + function removeHeader($name) | ||
| 515 | + { | ||
| 516 | + if (isset($this->_requestHeaders[strtolower($name)])) { | ||
| 517 | + unset($this->_requestHeaders[strtolower($name)]); | ||
| 518 | + } | ||
| 519 | + } | ||
| 520 | + | ||
| 521 | + /** | ||
| 522 | + * Adds a querystring parameter | ||
| 523 | + * | ||
| 524 | + * @param string Querystring parameter name | ||
| 525 | + * @param string Querystring parameter value | ||
| 526 | + * @param bool Whether the value is already urlencoded or not, default = not | ||
| 527 | + * @access public | ||
| 528 | + */ | ||
| 529 | + function addQueryString($name, $value, $preencoded = false) | ||
| 530 | + { | ||
| 531 | + $this->_url->addQueryString($name, $value, $preencoded); | ||
| 532 | + } | ||
| 533 | + | ||
| 534 | + /** | ||
| 535 | + * Sets the querystring to literally what you supply | ||
| 536 | + * | ||
| 537 | + * @param string The querystring data. Should be of the format foo=bar&x=y etc | ||
| 538 | + * @param bool Whether data is already urlencoded or not, default = already encoded | ||
| 539 | + * @access public | ||
| 540 | + */ | ||
| 541 | + function addRawQueryString($querystring, $preencoded = true) | ||
| 542 | + { | ||
| 543 | + $this->_url->addRawQueryString($querystring, $preencoded); | ||
| 544 | + } | ||
| 545 | + | ||
| 546 | + /** | ||
| 547 | + * Adds postdata items | ||
| 548 | + * | ||
| 549 | + * @param string Post data name | ||
| 550 | + * @param string Post data value | ||
| 551 | + * @param bool Whether data is already urlencoded or not, default = not | ||
| 552 | + * @access public | ||
| 553 | + */ | ||
| 554 | + function addPostData($name, $value, $preencoded = false) | ||
| 555 | + { | ||
| 556 | + if ($preencoded) { | ||
| 557 | + $this->_postData[$name] = $value; | ||
| 558 | + } else { | ||
| 559 | + $this->_postData[$name] = $this->_arrayMapRecursive('urlencode', $value); | ||
| 560 | + } | ||
| 561 | + } | ||
| 562 | + | ||
| 563 | + /** | ||
| 564 | + * Recursively applies the callback function to the value | ||
| 565 | + * | ||
| 566 | + * @param mixed Callback function | ||
| 567 | + * @param mixed Value to process | ||
| 568 | + * @access private | ||
| 569 | + * @return mixed Processed value | ||
| 570 | + */ | ||
| 571 | + function _arrayMapRecursive($callback, $value) | ||
| 572 | + { | ||
| 573 | + if (!is_array($value)) { | ||
| 574 | + return call_user_func($callback, $value); | ||
| 575 | + } else { | ||
| 576 | + $map = array(); | ||
| 577 | + foreach ($value as $k => $v) { | ||
| 578 | + $map[$k] = $this->_arrayMapRecursive($callback, $v); | ||
| 579 | + } | ||
| 580 | + return $map; | ||
| 581 | + } | ||
| 582 | + } | ||
| 583 | + | ||
| 584 | + /** | ||
| 585 | + * Adds a file to form-based file upload | ||
| 586 | + * | ||
| 587 | + * Used to emulate file upload via a HTML form. The method also sets | ||
| 588 | + * Content-Type of HTTP request to 'multipart/form-data'. | ||
| 589 | + * | ||
| 590 | + * If you just want to send the contents of a file as the body of HTTP | ||
| 591 | + * request you should use setBody() method. | ||
| 592 | + * | ||
| 593 | + * @access public | ||
| 594 | + * @param string name of file-upload field | ||
| 595 | + * @param mixed file name(s) | ||
| 596 | + * @param mixed content-type(s) of file(s) being uploaded | ||
| 597 | + * @return bool true on success | ||
| 598 | + * @throws PEAR_Error | ||
| 599 | + */ | ||
| 600 | + function addFile($inputName, $fileName, $contentType = 'application/octet-stream') | ||
| 601 | + { | ||
| 602 | + if (!is_array($fileName) && !is_readable($fileName)) { | ||
| 603 | + return PEAR::raiseError("File '{$fileName}' is not readable", HTTP_REQUEST_ERROR_FILE); | ||
| 604 | + } elseif (is_array($fileName)) { | ||
| 605 | + foreach ($fileName as $name) { | ||
| 606 | + if (!is_readable($name)) { | ||
| 607 | + return PEAR::raiseError("File '{$name}' is not readable", HTTP_REQUEST_ERROR_FILE); | ||
| 608 | + } | ||
| 609 | + } | ||
| 610 | + } | ||
| 611 | + $this->addHeader('Content-Type', 'multipart/form-data'); | ||
| 612 | + $this->_postFiles[$inputName] = array( | ||
| 613 | + 'name' => $fileName, | ||
| 614 | + 'type' => $contentType | ||
| 615 | + ); | ||
| 616 | + return true; | ||
| 617 | + } | ||
| 618 | + | ||
| 619 | + /** | ||
| 620 | + * Adds raw postdata (DEPRECATED) | ||
| 621 | + * | ||
| 622 | + * @param string The data | ||
| 623 | + * @param bool Whether data is preencoded or not, default = already encoded | ||
| 624 | + * @access public | ||
| 625 | + * @deprecated deprecated since 1.3.0, method setBody() should be used instead | ||
| 626 | + */ | ||
| 627 | + function addRawPostData($postdata, $preencoded = true) | ||
| 628 | + { | ||
| 629 | + $this->_body = $preencoded ? $postdata : urlencode($postdata); | ||
| 630 | + } | ||
| 631 | + | ||
| 632 | + /** | ||
| 633 | + * Sets the request body (for POST, PUT and similar requests) | ||
| 634 | + * | ||
| 635 | + * @param string Request body | ||
| 636 | + * @access public | ||
| 637 | + */ | ||
| 638 | + function setBody($body) | ||
| 639 | + { | ||
| 640 | + $this->_body = $body; | ||
| 641 | + } | ||
| 642 | + | ||
| 643 | + /** | ||
| 644 | + * Clears any postdata that has been added (DEPRECATED). | ||
| 645 | + * | ||
| 646 | + * Useful for multiple request scenarios. | ||
| 647 | + * | ||
| 648 | + * @access public | ||
| 649 | + * @deprecated deprecated since 1.2 | ||
| 650 | + */ | ||
| 651 | + function clearPostData() | ||
| 652 | + { | ||
| 653 | + $this->_postData = null; | ||
| 654 | + } | ||
| 655 | + | ||
| 656 | + /** | ||
| 657 | + * Appends a cookie to "Cookie:" header | ||
| 658 | + * | ||
| 659 | + * @param string $name cookie name | ||
| 660 | + * @param string $value cookie value | ||
| 661 | + * @access public | ||
| 662 | + */ | ||
| 663 | + function addCookie($name, $value) | ||
| 664 | + { | ||
| 665 | + $cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : ''; | ||
| 666 | + $this->addHeader('Cookie', $cookies . $name . '=' . $value); | ||
| 667 | + } | ||
| 668 | + | ||
| 669 | + /** | ||
| 670 | + * Clears any cookies that have been added (DEPRECATED). | ||
| 671 | + * | ||
| 672 | + * Useful for multiple request scenarios | ||
| 673 | + * | ||
| 674 | + * @access public | ||
| 675 | + * @deprecated deprecated since 1.2 | ||
| 676 | + */ | ||
| 677 | + function clearCookies() | ||
| 678 | + { | ||
| 679 | + $this->removeHeader('Cookie'); | ||
| 680 | + } | ||
| 681 | + | ||
| 682 | + /** | ||
| 683 | + * Sends the request | ||
| 684 | + * | ||
| 685 | + * @access public | ||
| 686 | + * @param bool Whether to store response body in Response object property, | ||
| 687 | + * set this to false if downloading a LARGE file and using a Listener | ||
| 688 | + * @return mixed PEAR error on error, true otherwise | ||
| 689 | + */ | ||
| 690 | + function sendRequest($saveBody = true) | ||
| 691 | + { | ||
| 692 | + if (!is_a($this->_url, 'Net_URL')) { | ||
| 693 | + return PEAR::raiseError('No URL given', HTTP_REQUEST_ERROR_URL); | ||
| 694 | + } | ||
| 695 | + | ||
| 696 | + $host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host; | ||
| 697 | + $port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port; | ||
| 698 | + | ||
| 699 | + if (strcasecmp($this->_url->protocol, 'https') == 0) { | ||
| 700 | + // Bug #14127, don't try connecting to HTTPS sites without OpenSSL | ||
| 701 | + if (version_compare(PHP_VERSION, '4.3.0', '<') || !extension_loaded('openssl')) { | ||
| 702 | + return PEAR::raiseError('Need PHP 4.3.0 or later with OpenSSL support for https:// requests', | ||
| 703 | + HTTP_REQUEST_ERROR_URL); | ||
| 704 | + } elseif (isset($this->_proxy_host)) { | ||
| 705 | + return PEAR::raiseError('HTTPS proxies are not supported', HTTP_REQUEST_ERROR_PROXY); | ||
| 706 | + } | ||
| 707 | + $host = 'ssl://' . $host; | ||
| 708 | + } | ||
| 709 | + | ||
| 710 | + // magic quotes may fuck up file uploads and chunked response processing | ||
| 711 | + $magicQuotes = ini_get('magic_quotes_runtime'); | ||
| 712 | + ini_set('magic_quotes_runtime', false); | ||
| 713 | + | ||
| 714 | + // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive | ||
| 715 | + // connection token to a proxy server... | ||
| 716 | + if (isset($this->_proxy_host) && !empty($this->_requestHeaders['connection']) && | ||
| 717 | + 'Keep-Alive' == $this->_requestHeaders['connection']) | ||
| 718 | + { | ||
| 719 | + $this->removeHeader('connection'); | ||
| 720 | + } | ||
| 721 | + | ||
| 722 | + $keepAlive = (HTTP_REQUEST_HTTP_VER_1_1 == $this->_http && empty($this->_requestHeaders['connection'])) || | ||
| 723 | + (!empty($this->_requestHeaders['connection']) && 'Keep-Alive' == $this->_requestHeaders['connection']); | ||
| 724 | + $sockets = &PEAR::getStaticProperty('HTTP_Request', 'sockets'); | ||
| 725 | + $sockKey = $host . ':' . $port; | ||
| 726 | + unset($this->_sock); | ||
| 727 | + | ||
| 728 | + // There is a connected socket in the "static" property? | ||
| 729 | + if ($keepAlive && !empty($sockets[$sockKey]) && | ||
| 730 | + !empty($sockets[$sockKey]->fp)) | ||
| 731 | + { | ||
| 732 | + $this->_sock =& $sockets[$sockKey]; | ||
| 733 | + $err = null; | ||
| 734 | + } else { | ||
| 735 | + $this->_notify('connect'); | ||
| 736 | + $this->_sock =& new Net_Socket(); | ||
| 737 | + $err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions); | ||
| 738 | + } | ||
| 739 | + PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest()); | ||
| 740 | + | ||
| 741 | + if (!PEAR::isError($err)) { | ||
| 742 | + if (!empty($this->_readTimeout)) { | ||
| 743 | + $this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]); | ||
| 744 | + } | ||
| 745 | + | ||
| 746 | + $this->_notify('sentRequest'); | ||
| 747 | + | ||
| 748 | + // Read the response | ||
| 749 | + $this->_response = &new HTTP_Response($this->_sock, $this->_listeners); | ||
| 750 | + $err = $this->_response->process( | ||
| 751 | + $this->_saveBody && $saveBody, | ||
| 752 | + HTTP_REQUEST_METHOD_HEAD != $this->_method | ||
| 753 | + ); | ||
| 754 | + | ||
| 755 | + if ($keepAlive) { | ||
| 756 | + $keepAlive = (isset($this->_response->_headers['content-length']) | ||
| 757 | + || (isset($this->_response->_headers['transfer-encoding']) | ||
| 758 | + && strtolower($this->_response->_headers['transfer-encoding']) == 'chunked')); | ||
| 759 | + if ($keepAlive) { | ||
| 760 | + if (isset($this->_response->_headers['connection'])) { | ||
| 761 | + $keepAlive = strtolower($this->_response->_headers['connection']) == 'keep-alive'; | ||
| 762 | + } else { | ||
| 763 | + $keepAlive = 'HTTP/'.HTTP_REQUEST_HTTP_VER_1_1 == $this->_response->_protocol; | ||
| 764 | + } | ||
| 765 | + } | ||
| 766 | + } | ||
| 767 | + } | ||
| 768 | + | ||
| 769 | + ini_set('magic_quotes_runtime', $magicQuotes); | ||
| 770 | + | ||
| 771 | + if (PEAR::isError($err)) { | ||
| 772 | + return $err; | ||
| 773 | + } | ||
| 774 | + | ||
| 775 | + if (!$keepAlive) { | ||
| 776 | + $this->disconnect(); | ||
| 777 | + // Store the connected socket in "static" property | ||
| 778 | + } elseif (empty($sockets[$sockKey]) || empty($sockets[$sockKey]->fp)) { | ||
| 779 | + $sockets[$sockKey] =& $this->_sock; | ||
| 780 | + } | ||
| 781 | + | ||
| 782 | + // Check for redirection | ||
| 783 | + if ( $this->_allowRedirects | ||
| 784 | + AND $this->_redirects <= $this->_maxRedirects | ||
| 785 | + AND $this->getResponseCode() > 300 | ||
| 786 | + AND $this->getResponseCode() < 399 | ||
| 787 | + AND !empty($this->_response->_headers['location'])) { | ||
| 788 | + | ||
| 789 | + | ||
| 790 | + $redirect = $this->_response->_headers['location']; | ||
| 791 | + | ||
| 792 | + // Absolute URL | ||
| 793 | + if (preg_match('/^https?:\/\//i', $redirect)) { | ||
| 794 | + $this->_url = &new Net_URL($redirect); | ||
| 795 | + $this->addHeader('Host', $this->_generateHostHeader()); | ||
| 796 | + // Absolute path | ||
| 797 | + } elseif ($redirect{0} == '/') { | ||
| 798 | + $this->_url->path = $redirect; | ||
| 799 | + | ||
| 800 | + // Relative path | ||
| 801 | + } elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') { | ||
| 802 | + if (substr($this->_url->path, -1) == '/') { | ||
| 803 | + $redirect = $this->_url->path . $redirect; | ||
| 804 | + } else { | ||
| 805 | + $redirect = dirname($this->_url->path) . '/' . $redirect; | ||
| 806 | + } | ||
| 807 | + $redirect = Net_URL::resolvePath($redirect); | ||
| 808 | + $this->_url->path = $redirect; | ||
| 809 | + | ||
| 810 | + // Filename, no path | ||
| 811 | + } else { | ||
| 812 | + if (substr($this->_url->path, -1) == '/') { | ||
| 813 | + $redirect = $this->_url->path . $redirect; | ||
| 814 | + } else { | ||
| 815 | + $redirect = dirname($this->_url->path) . '/' . $redirect; | ||
| 816 | + } | ||
| 817 | + $this->_url->path = $redirect; | ||
| 818 | + } | ||
| 819 | + | ||
| 820 | + $this->_redirects++; | ||
| 821 | + return $this->sendRequest($saveBody); | ||
| 822 | + | ||
| 823 | + // Too many redirects | ||
| 824 | + } elseif ($this->_allowRedirects AND $this->_redirects > $this->_maxRedirects) { | ||
| 825 | + return PEAR::raiseError('Too many redirects', HTTP_REQUEST_ERROR_REDIRECTS); | ||
| 826 | + } | ||
| 827 | + | ||
| 828 | + return true; | ||
| 829 | + } | ||
| 830 | + | ||
| 831 | + /** | ||
| 832 | + * Disconnect the socket, if connected. Only useful if using Keep-Alive. | ||
| 833 | + * | ||
| 834 | + * @access public | ||
| 835 | + */ | ||
| 836 | + function disconnect() | ||
| 837 | + { | ||
| 838 | + if (!empty($this->_sock) && !empty($this->_sock->fp)) { | ||
| 839 | + $this->_notify('disconnect'); | ||
| 840 | + $this->_sock->disconnect(); | ||
| 841 | + } | ||
| 842 | + } | ||
| 843 | + | ||
| 844 | + /** | ||
| 845 | + * Returns the response code | ||
| 846 | + * | ||
| 847 | + * @access public | ||
| 848 | + * @return mixed Response code, false if not set | ||
| 849 | + */ | ||
| 850 | + function getResponseCode() | ||
| 851 | + { | ||
| 852 | + return isset($this->_response->_code) ? $this->_response->_code : false; | ||
| 853 | + } | ||
| 854 | + | ||
| 855 | + /** | ||
| 856 | + * Returns the response reason phrase | ||
| 857 | + * | ||
| 858 | + * @access public | ||
| 859 | + * @return mixed Response reason phrase, false if not set | ||
| 860 | + */ | ||
| 861 | + function getResponseReason() | ||
| 862 | + { | ||
| 863 | + return isset($this->_response->_reason) ? $this->_response->_reason : false; | ||
| 864 | + } | ||
| 865 | + | ||
| 866 | + /** | ||
| 867 | + * Returns either the named header or all if no name given | ||
| 868 | + * | ||
| 869 | + * @access public | ||
| 870 | + * @param string The header name to return, do not set to get all headers | ||
| 871 | + * @return mixed either the value of $headername (false if header is not present) | ||
| 872 | + * or an array of all headers | ||
| 873 | + */ | ||
| 874 | + function getResponseHeader($headername = null) | ||
| 875 | + { | ||
| 876 | + if (!isset($headername)) { | ||
| 877 | + return isset($this->_response->_headers)? $this->_response->_headers: array(); | ||
| 878 | + } else { | ||
| 879 | + $headername = strtolower($headername); | ||
| 880 | + return isset($this->_response->_headers[$headername]) ? $this->_response->_headers[$headername] : false; | ||
| 881 | + } | ||
| 882 | + } | ||
| 883 | + | ||
| 884 | + /** | ||
| 885 | + * Returns the body of the response | ||
| 886 | + * | ||
| 887 | + * @access public | ||
| 888 | + * @return mixed response body, false if not set | ||
| 889 | + */ | ||
| 890 | + function getResponseBody() | ||
| 891 | + { | ||
| 892 | + return isset($this->_response->_body) ? $this->_response->_body : false; | ||
| 893 | + } | ||
| 894 | + | ||
| 895 | + /** | ||
| 896 | + * Returns cookies set in response | ||
| 897 | + * | ||
| 898 | + * @access public | ||
| 899 | + * @return mixed array of response cookies, false if none are present | ||
| 900 | + */ | ||
| 901 | + function getResponseCookies() | ||
| 902 | + { | ||
| 903 | + return isset($this->_response->_cookies) ? $this->_response->_cookies : false; | ||
| 904 | + } | ||
| 905 | + | ||
| 906 | + /** | ||
| 907 | + * Builds the request string | ||
| 908 | + * | ||
| 909 | + * @access private | ||
| 910 | + * @return string The request string | ||
| 911 | + */ | ||
| 912 | + function _buildRequest() | ||
| 913 | + { | ||
| 914 | + $separator = ini_get('arg_separator.output'); | ||
| 915 | + ini_set('arg_separator.output', '&'); | ||
| 916 | + $querystring = ($querystring = $this->_url->getQueryString()) ? '?' . $querystring : ''; | ||
| 917 | + ini_set('arg_separator.output', $separator); | ||
| 918 | + | ||
| 919 | + $host = isset($this->_proxy_host) ? $this->_url->protocol . '://' . $this->_url->host : ''; | ||
| 920 | + $port = (isset($this->_proxy_host) AND $this->_url->port != 80) ? ':' . $this->_url->port : ''; | ||
| 921 | + $path = $this->_url->path . $querystring; | ||
| 922 | + $url = $host . $port . $path; | ||
| 923 | + | ||
| 924 | + if (!strlen($url)) { | ||
| 925 | + $url = '/'; | ||
| 926 | + } | ||
| 927 | + | ||
| 928 | + $request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n"; | ||
| 929 | + | ||
| 930 | + if (in_array($this->_method, $this->_bodyDisallowed) || | ||
| 931 | + (0 == strlen($this->_body) && (HTTP_REQUEST_METHOD_POST != $this->_method || | ||
| 932 | + (empty($this->_postData) && empty($this->_postFiles))))) | ||
| 933 | + { | ||
| 934 | + $this->removeHeader('Content-Type'); | ||
| 935 | + } else { | ||
| 936 | + if (empty($this->_requestHeaders['content-type'])) { | ||
| 937 | + // Add default content-type | ||
| 938 | + $this->addHeader('Content-Type', 'application/x-www-form-urlencoded'); | ||
| 939 | + } elseif ('multipart/form-data' == $this->_requestHeaders['content-type']) { | ||
| 940 | + $boundary = 'HTTP_Request_' . md5(uniqid('request') . microtime()); | ||
| 941 | + $this->addHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary); | ||
| 942 | + } | ||
| 943 | + } | ||
| 944 | + | ||
| 945 | + // Request Headers | ||
| 946 | + if (!empty($this->_requestHeaders)) { | ||
| 947 | + foreach ($this->_requestHeaders as $name => $value) { | ||
| 948 | + $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); | ||
| 949 | + $request .= $canonicalName . ': ' . $value . "\r\n"; | ||
| 950 | + } | ||
| 951 | + } | ||
| 952 | + | ||
| 953 | + // Method does not allow a body, simply add a final CRLF | ||
| 954 | + if (in_array($this->_method, $this->_bodyDisallowed)) { | ||
| 955 | + | ||
| 956 | + $request .= "\r\n"; | ||
| 957 | + | ||
| 958 | + // Post data if it's an array | ||
| 959 | + } elseif (HTTP_REQUEST_METHOD_POST == $this->_method && | ||
| 960 | + (!empty($this->_postData) || !empty($this->_postFiles))) { | ||
| 961 | + | ||
| 962 | + // "normal" POST request | ||
| 963 | + if (!isset($boundary)) { | ||
| 964 | + $postdata = implode('&', array_map( | ||
| 965 | + create_function('$a', 'return $a[0] . \'=\' . $a[1];'), | ||
| 966 | + $this->_flattenArray('', $this->_postData) | ||
| 967 | + )); | ||
| 968 | + | ||
| 969 | + // multipart request, probably with file uploads | ||
| 970 | + } else { | ||
| 971 | + $postdata = ''; | ||
| 972 | + if (!empty($this->_postData)) { | ||
| 973 | + $flatData = $this->_flattenArray('', $this->_postData); | ||
| 974 | + foreach ($flatData as $item) { | ||
| 975 | + $postdata .= '--' . $boundary . "\r\n"; | ||
| 976 | + $postdata .= 'Content-Disposition: form-data; name="' . $item[0] . '"'; | ||
| 977 | + $postdata .= "\r\n\r\n" . urldecode($item[1]) . "\r\n"; | ||
| 978 | + } | ||
| 979 | + } | ||
| 980 | + foreach ($this->_postFiles as $name => $value) { | ||
| 981 | + if (is_array($value['name'])) { | ||
| 982 | + $varname = $name . ($this->_useBrackets? '[]': ''); | ||
| 983 | + } else { | ||
| 984 | + $varname = $name; | ||
| 985 | + $value['name'] = array($value['name']); | ||
| 986 | + } | ||
| 987 | + foreach ($value['name'] as $key => $filename) { | ||
| 988 | + $fp = fopen($filename, 'r'); | ||
| 989 | + $basename = basename($filename); | ||
| 990 | + $type = is_array($value['type'])? @$value['type'][$key]: $value['type']; | ||
| 991 | + | ||
| 992 | + $postdata .= '--' . $boundary . "\r\n"; | ||
| 993 | + $postdata .= 'Content-Disposition: form-data; name="' . $varname . '"; filename="' . $basename . '"'; | ||
| 994 | + $postdata .= "\r\nContent-Type: " . $type; | ||
| 995 | + $postdata .= "\r\n\r\n" . fread($fp, filesize($filename)) . "\r\n"; | ||
| 996 | + fclose($fp); | ||
| 997 | + } | ||
| 998 | + } | ||
| 999 | + $postdata .= '--' . $boundary . "--\r\n"; | ||
| 1000 | + } | ||
| 1001 | + $request .= 'Content-Length: ' . | ||
| 1002 | + (HTTP_REQUEST_MBSTRING? mb_strlen($postdata, 'iso-8859-1'): strlen($postdata)) . | ||
| 1003 | + "\r\n\r\n"; | ||
| 1004 | + $request .= $postdata; | ||
| 1005 | + | ||
| 1006 | + // Explicitly set request body | ||
| 1007 | + } elseif (0 < strlen($this->_body)) { | ||
| 1008 | + | ||
| 1009 | + $request .= 'Content-Length: ' . | ||
| 1010 | + (HTTP_REQUEST_MBSTRING? mb_strlen($this->_body, 'iso-8859-1'): strlen($this->_body)) . | ||
| 1011 | + "\r\n\r\n"; | ||
| 1012 | + $request .= $this->_body; | ||
| 1013 | + | ||
| 1014 | + // No body: send a Content-Length header nonetheless (request #12900), | ||
| 1015 | + // but do that only for methods that require a body (bug #14740) | ||
| 1016 | + } else { | ||
| 1017 | + | ||
| 1018 | + if (in_array($this->_method, $this->_bodyRequired)) { | ||
| 1019 | + $request .= "Content-Length: 0\r\n"; | ||
| 1020 | + } | ||
| 1021 | + $request .= "\r\n"; | ||
| 1022 | + } | ||
| 1023 | + | ||
| 1024 | + return $request; | ||
| 1025 | + } | ||
| 1026 | + | ||
| 1027 | + /** | ||
| 1028 | + * Helper function to change the (probably multidimensional) associative array | ||
| 1029 | + * into the simple one. | ||
| 1030 | + * | ||
| 1031 | + * @param string name for item | ||
| 1032 | + * @param mixed item's values | ||
| 1033 | + * @return array array with the following items: array('item name', 'item value'); | ||
| 1034 | + * @access private | ||
| 1035 | + */ | ||
| 1036 | + function _flattenArray($name, $values) | ||
| 1037 | + { | ||
| 1038 | + if (!is_array($values)) { | ||
| 1039 | + return array(array($name, $values)); | ||
| 1040 | + } else { | ||
| 1041 | + $ret = array(); | ||
| 1042 | + foreach ($values as $k => $v) { | ||
| 1043 | + if (empty($name)) { | ||
| 1044 | + $newName = $k; | ||
| 1045 | + } elseif ($this->_useBrackets) { | ||
| 1046 | + $newName = $name . '[' . $k . ']'; | ||
| 1047 | + } else { | ||
| 1048 | + $newName = $name; | ||
| 1049 | + } | ||
| 1050 | + $ret = array_merge($ret, $this->_flattenArray($newName, $v)); | ||
| 1051 | + } | ||
| 1052 | + return $ret; | ||
| 1053 | + } | ||
| 1054 | + } | ||
| 1055 | + | ||
| 1056 | + | ||
| 1057 | + /** | ||
| 1058 | + * Adds a Listener to the list of listeners that are notified of | ||
| 1059 | + * the object's events | ||
| 1060 | + * | ||
| 1061 | + * Events sent by HTTP_Request object | ||
| 1062 | + * - 'connect': on connection to server | ||
| 1063 | + * - 'sentRequest': after the request was sent | ||
| 1064 | + * - 'disconnect': on disconnection from server | ||
| 1065 | + * | ||
| 1066 | + * Events sent by HTTP_Response object | ||
| 1067 | + * - 'gotHeaders': after receiving response headers (headers are passed in $data) | ||
| 1068 | + * - 'tick': on receiving a part of response body (the part is passed in $data) | ||
| 1069 | + * - 'gzTick': on receiving a gzip-encoded part of response body (ditto) | ||
| 1070 | + * - 'gotBody': after receiving the response body (passes the decoded body in $data if it was gzipped) | ||
| 1071 | + * | ||
| 1072 | + * @param HTTP_Request_Listener listener to attach | ||
| 1073 | + * @return boolean whether the listener was successfully attached | ||
| 1074 | + * @access public | ||
| 1075 | + */ | ||
| 1076 | + function attach(&$listener) | ||
| 1077 | + { | ||
| 1078 | + if (!is_a($listener, 'HTTP_Request_Listener')) { | ||
| 1079 | + return false; | ||
| 1080 | + } | ||
| 1081 | + $this->_listeners[$listener->getId()] =& $listener; | ||
| 1082 | + return true; | ||
| 1083 | + } | ||
| 1084 | + | ||
| 1085 | + | ||
| 1086 | + /** | ||
| 1087 | + * Removes a Listener from the list of listeners | ||
| 1088 | + * | ||
| 1089 | + * @param HTTP_Request_Listener listener to detach | ||
| 1090 | + * @return boolean whether the listener was successfully detached | ||
| 1091 | + * @access public | ||
| 1092 | + */ | ||
| 1093 | + function detach(&$listener) | ||
| 1094 | + { | ||
| 1095 | + if (!is_a($listener, 'HTTP_Request_Listener') || | ||
| 1096 | + !isset($this->_listeners[$listener->getId()])) { | ||
| 1097 | + return false; | ||
| 1098 | + } | ||
| 1099 | + unset($this->_listeners[$listener->getId()]); | ||
| 1100 | + return true; | ||
| 1101 | + } | ||
| 1102 | + | ||
| 1103 | + | ||
| 1104 | + /** | ||
| 1105 | + * Notifies all registered listeners of an event. | ||
| 1106 | + * | ||
| 1107 | + * @param string Event name | ||
| 1108 | + * @param mixed Additional data | ||
| 1109 | + * @access private | ||
| 1110 | + * @see HTTP_Request::attach() | ||
| 1111 | + */ | ||
| 1112 | + function _notify($event, $data = null) | ||
| 1113 | + { | ||
| 1114 | + foreach (array_keys($this->_listeners) as $id) { | ||
| 1115 | + $this->_listeners[$id]->update($this, $event, $data); | ||
| 1116 | + } | ||
| 1117 | + } | ||
| 1118 | +} | ||
| 1119 | + | ||
| 1120 | + | ||
| 1121 | +/** | ||
| 1122 | + * Response class to complement the Request class | ||
| 1123 | + * | ||
| 1124 | + * @category HTTP | ||
| 1125 | + * @package HTTP_Request | ||
| 1126 | + * @author Richard Heyes <richard@phpguru.org> | ||
| 1127 | + * @author Alexey Borzov <avb@php.net> | ||
| 1128 | + * @version Release: 1.4.4 | ||
| 1129 | + */ | ||
| 1130 | +class HTTP_Response | ||
| 1131 | +{ | ||
| 1132 | + /** | ||
| 1133 | + * Socket object | ||
| 1134 | + * @var Net_Socket | ||
| 1135 | + */ | ||
| 1136 | + var $_sock; | ||
| 1137 | + | ||
| 1138 | + /** | ||
| 1139 | + * Protocol | ||
| 1140 | + * @var string | ||
| 1141 | + */ | ||
| 1142 | + var $_protocol; | ||
| 1143 | + | ||
| 1144 | + /** | ||
| 1145 | + * Return code | ||
| 1146 | + * @var string | ||
| 1147 | + */ | ||
| 1148 | + var $_code; | ||
| 1149 | + | ||
| 1150 | + /** | ||
| 1151 | + * Response reason phrase | ||
| 1152 | + * @var string | ||
| 1153 | + */ | ||
| 1154 | + var $_reason; | ||
| 1155 | + | ||
| 1156 | + /** | ||
| 1157 | + * Response headers | ||
| 1158 | + * @var array | ||
| 1159 | + */ | ||
| 1160 | + var $_headers; | ||
| 1161 | + | ||
| 1162 | + /** | ||
| 1163 | + * Cookies set in response | ||
| 1164 | + * @var array | ||
| 1165 | + */ | ||
| 1166 | + var $_cookies; | ||
| 1167 | + | ||
| 1168 | + /** | ||
| 1169 | + * Response body | ||
| 1170 | + * @var string | ||
| 1171 | + */ | ||
| 1172 | + var $_body = ''; | ||
| 1173 | + | ||
| 1174 | + /** | ||
| 1175 | + * Used by _readChunked(): remaining length of the current chunk | ||
| 1176 | + * @var string | ||
| 1177 | + */ | ||
| 1178 | + var $_chunkLength = 0; | ||
| 1179 | + | ||
| 1180 | + /** | ||
| 1181 | + * Attached listeners | ||
| 1182 | + * @var array | ||
| 1183 | + */ | ||
| 1184 | + var $_listeners = array(); | ||
| 1185 | + | ||
| 1186 | + /** | ||
| 1187 | + * Bytes left to read from message-body | ||
| 1188 | + * @var null|int | ||
| 1189 | + */ | ||
| 1190 | + var $_toRead; | ||
| 1191 | + | ||
| 1192 | + /** | ||
| 1193 | + * Constructor | ||
| 1194 | + * | ||
| 1195 | + * @param Net_Socket socket to read the response from | ||
| 1196 | + * @param array listeners attached to request | ||
| 1197 | + */ | ||
| 1198 | + function HTTP_Response(&$sock, &$listeners) | ||
| 1199 | + { | ||
| 1200 | + $this->_sock =& $sock; | ||
| 1201 | + $this->_listeners =& $listeners; | ||
| 1202 | + } | ||
| 1203 | + | ||
| 1204 | + | ||
| 1205 | + /** | ||
| 1206 | + * Processes a HTTP response | ||
| 1207 | + * | ||
| 1208 | + * This extracts response code, headers, cookies and decodes body if it | ||
| 1209 | + * was encoded in some way | ||
| 1210 | + * | ||
| 1211 | + * @access public | ||
| 1212 | + * @param bool Whether to store response body in object property, set | ||
| 1213 | + * this to false if downloading a LARGE file and using a Listener. | ||
| 1214 | + * This is assumed to be true if body is gzip-encoded. | ||
| 1215 | + * @param bool Whether the response can actually have a message-body. | ||
| 1216 | + * Will be set to false for HEAD requests. | ||
| 1217 | + * @throws PEAR_Error | ||
| 1218 | + * @return mixed true on success, PEAR_Error in case of malformed response | ||
| 1219 | + */ | ||
| 1220 | + function process($saveBody = true, $canHaveBody = true) | ||
| 1221 | + { | ||
| 1222 | + do { | ||
| 1223 | + $line = $this->_sock->readLine(); | ||
| 1224 | + if (!preg_match('!^(HTTP/\d\.\d) (\d{3})(?: (.+))?!', $line, $s)) { | ||
| 1225 | + return PEAR::raiseError('Malformed response', HTTP_REQUEST_ERROR_RESPONSE); | ||
| 1226 | + } else { | ||
| 1227 | + $this->_protocol = $s[1]; | ||
| 1228 | + $this->_code = intval($s[2]); | ||
| 1229 | + $this->_reason = empty($s[3])? null: $s[3]; | ||
| 1230 | + } | ||
| 1231 | + while ('' !== ($header = $this->_sock->readLine())) { | ||
| 1232 | + $this->_processHeader($header); | ||
| 1233 | + } | ||
| 1234 | + } while (100 == $this->_code); | ||
| 1235 | + | ||
| 1236 | + $this->_notify('gotHeaders', $this->_headers); | ||
| 1237 | + | ||
| 1238 | + // RFC 2616, section 4.4: | ||
| 1239 | + // 1. Any response message which "MUST NOT" include a message-body ... | ||
| 1240 | + // is always terminated by the first empty line after the header fields | ||
| 1241 | + // 3. ... If a message is received with both a | ||
| 1242 | + // Transfer-Encoding header field and a Content-Length header field, | ||
| 1243 | + // the latter MUST be ignored. | ||
| 1244 | + $canHaveBody = $canHaveBody && $this->_code >= 200 && | ||
| 1245 | + $this->_code != 204 && $this->_code != 304; | ||
| 1246 | + | ||
| 1247 | + // If response body is present, read it and decode | ||
| 1248 | + $chunked = isset($this->_headers['transfer-encoding']) && ('chunked' == $this->_headers['transfer-encoding']); | ||
| 1249 | + $gzipped = isset($this->_headers['content-encoding']) && ('gzip' == $this->_headers['content-encoding']); | ||
| 1250 | + $hasBody = false; | ||
| 1251 | + if ($canHaveBody && ($chunked || !isset($this->_headers['content-length']) || | ||
| 1252 | + 0 != $this->_headers['content-length'])) | ||
| 1253 | + { | ||
| 1254 | + if ($chunked || !isset($this->_headers['content-length'])) { | ||
| 1255 | + $this->_toRead = null; | ||
| 1256 | + } else { | ||
| 1257 | + $this->_toRead = $this->_headers['content-length']; | ||
| 1258 | + } | ||
| 1259 | + while (!$this->_sock->eof() && (is_null($this->_toRead) || 0 < $this->_toRead)) { | ||
| 1260 | + if ($chunked) { | ||
| 1261 | + $data = $this->_readChunked(); | ||
| 1262 | + } elseif (is_null($this->_toRead)) { | ||
| 1263 | + $data = $this->_sock->read(4096); | ||
| 1264 | + } else { | ||
| 1265 | + $data = $this->_sock->read(min(4096, $this->_toRead)); | ||
| 1266 | + $this->_toRead -= HTTP_REQUEST_MBSTRING? mb_strlen($data, 'iso-8859-1'): strlen($data); | ||
| 1267 | + } | ||
| 1268 | + if ('' == $data && (!$this->_chunkLength || $this->_sock->eof())) { | ||
| 1269 | + break; | ||
| 1270 | + } else { | ||
| 1271 | + $hasBody = true; | ||
| 1272 | + if ($saveBody || $gzipped) { | ||
| 1273 | + $this->_body .= $data; | ||
| 1274 | + } | ||
| 1275 | + $this->_notify($gzipped? 'gzTick': 'tick', $data); | ||
| 1276 | + } | ||
| 1277 | + } | ||
| 1278 | + } | ||
| 1279 | + | ||
| 1280 | + if ($hasBody) { | ||
| 1281 | + // Uncompress the body if needed | ||
| 1282 | + if ($gzipped) { | ||
| 1283 | + $body = $this->_decodeGzip($this->_body); | ||
| 1284 | + if (PEAR::isError($body)) { | ||
| 1285 | + return $body; | ||
| 1286 | + } | ||
| 1287 | + $this->_body = $body; | ||
| 1288 | + $this->_notify('gotBody', $this->_body); | ||
| 1289 | + } else { | ||
| 1290 | + $this->_notify('gotBody'); | ||
| 1291 | + } | ||
| 1292 | + } | ||
| 1293 | + return true; | ||
| 1294 | + } | ||
| 1295 | + | ||
| 1296 | + | ||
| 1297 | + /** | ||
| 1298 | + * Processes the response header | ||
| 1299 | + * | ||
| 1300 | + * @access private | ||
| 1301 | + * @param string HTTP header | ||
| 1302 | + */ | ||
| 1303 | + function _processHeader($header) | ||
| 1304 | + { | ||
| 1305 | + if (false === strpos($header, ':')) { | ||
| 1306 | + return; | ||
| 1307 | + } | ||
| 1308 | + list($headername, $headervalue) = explode(':', $header, 2); | ||
| 1309 | + $headername = strtolower($headername); | ||
| 1310 | + $headervalue = ltrim($headervalue); | ||
| 1311 | + | ||
| 1312 | + if ('set-cookie' != $headername) { | ||
| 1313 | + if (isset($this->_headers[$headername])) { | ||
| 1314 | + $this->_headers[$headername] .= ',' . $headervalue; | ||
| 1315 | + } else { | ||
| 1316 | + $this->_headers[$headername] = $headervalue; | ||
| 1317 | + } | ||
| 1318 | + } else { | ||
| 1319 | + $this->_parseCookie($headervalue); | ||
| 1320 | + } | ||
| 1321 | + } | ||
| 1322 | + | ||
| 1323 | + | ||
| 1324 | + /** | ||
| 1325 | + * Parse a Set-Cookie header to fill $_cookies array | ||
| 1326 | + * | ||
| 1327 | + * @access private | ||
| 1328 | + * @param string value of Set-Cookie header | ||
| 1329 | + */ | ||
| 1330 | + function _parseCookie($headervalue) | ||
| 1331 | + { | ||
| 1332 | + $cookie = array( | ||
| 1333 | + 'expires' => null, | ||
| 1334 | + 'domain' => null, | ||
| 1335 | + 'path' => null, | ||
| 1336 | + 'secure' => false | ||
| 1337 | + ); | ||
| 1338 | + | ||
| 1339 | + // Only a name=value pair | ||
| 1340 | + if (!strpos($headervalue, ';')) { | ||
| 1341 | + $pos = strpos($headervalue, '='); | ||
| 1342 | + $cookie['name'] = trim(substr($headervalue, 0, $pos)); | ||
| 1343 | + $cookie['value'] = trim(substr($headervalue, $pos + 1)); | ||
| 1344 | + | ||
| 1345 | + // Some optional parameters are supplied | ||
| 1346 | + } else { | ||
| 1347 | + $elements = explode(';', $headervalue); | ||
| 1348 | + $pos = strpos($elements[0], '='); | ||
| 1349 | + $cookie['name'] = trim(substr($elements[0], 0, $pos)); | ||
| 1350 | + $cookie['value'] = trim(substr($elements[0], $pos + 1)); | ||
| 1351 | + | ||
| 1352 | + for ($i = 1; $i < count($elements); $i++) { | ||
| 1353 | + if (false === strpos($elements[$i], '=')) { | ||
| 1354 | + $elName = trim($elements[$i]); | ||
| 1355 | + $elValue = null; | ||
| 1356 | + } else { | ||
| 1357 | + list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); | ||
| 1358 | + } | ||
| 1359 | + $elName = strtolower($elName); | ||
| 1360 | + if ('secure' == $elName) { | ||
| 1361 | + $cookie['secure'] = true; | ||
| 1362 | + } elseif ('expires' == $elName) { | ||
| 1363 | + $cookie['expires'] = str_replace('"', '', $elValue); | ||
| 1364 | + } elseif ('path' == $elName || 'domain' == $elName) { | ||
| 1365 | + $cookie[$elName] = urldecode($elValue); | ||
| 1366 | + } else { | ||
| 1367 | + $cookie[$elName] = $elValue; | ||
| 1368 | + } | ||
| 1369 | + } | ||
| 1370 | + } | ||
| 1371 | + $this->_cookies[] = $cookie; | ||
| 1372 | + } | ||
| 1373 | + | ||
| 1374 | + | ||
| 1375 | + /** | ||
| 1376 | + * Read a part of response body encoded with chunked Transfer-Encoding | ||
| 1377 | + * | ||
| 1378 | + * @access private | ||
| 1379 | + * @return string | ||
| 1380 | + */ | ||
| 1381 | + function _readChunked() | ||
| 1382 | + { | ||
| 1383 | + // at start of the next chunk? | ||
| 1384 | + if (0 == $this->_chunkLength) { | ||
| 1385 | + $line = $this->_sock->readLine(); | ||
| 1386 | + if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) { | ||
| 1387 | + $this->_chunkLength = hexdec($matches[1]); | ||
| 1388 | + // Chunk with zero length indicates the end | ||
| 1389 | + if (0 == $this->_chunkLength) { | ||
| 1390 | + $this->_sock->readLine(); // make this an eof() | ||
| 1391 | + return ''; | ||
| 1392 | + } | ||
| 1393 | + } else { | ||
| 1394 | + return ''; | ||
| 1395 | + } | ||
| 1396 | + } | ||
| 1397 | + $data = $this->_sock->read($this->_chunkLength); | ||
| 1398 | + $this->_chunkLength -= HTTP_REQUEST_MBSTRING? mb_strlen($data, 'iso-8859-1'): strlen($data); | ||
| 1399 | + if (0 == $this->_chunkLength) { | ||
| 1400 | + $this->_sock->readLine(); // Trailing CRLF | ||
| 1401 | + } | ||
| 1402 | + return $data; | ||
| 1403 | + } | ||
| 1404 | + | ||
| 1405 | + | ||
| 1406 | + /** | ||
| 1407 | + * Notifies all registered listeners of an event. | ||
| 1408 | + * | ||
| 1409 | + * @param string Event name | ||
| 1410 | + * @param mixed Additional data | ||
| 1411 | + * @access private | ||
| 1412 | + * @see HTTP_Request::_notify() | ||
| 1413 | + */ | ||
| 1414 | + function _notify($event, $data = null) | ||
| 1415 | + { | ||
| 1416 | + foreach (array_keys($this->_listeners) as $id) { | ||
| 1417 | + $this->_listeners[$id]->update($this, $event, $data); | ||
| 1418 | + } | ||
| 1419 | + } | ||
| 1420 | + | ||
| 1421 | + | ||
| 1422 | + /** | ||
| 1423 | + * Decodes the message-body encoded by gzip | ||
| 1424 | + * | ||
| 1425 | + * The real decoding work is done by gzinflate() built-in function, this | ||
| 1426 | + * method only parses the header and checks data for compliance with | ||
| 1427 | + * RFC 1952 | ||
| 1428 | + * | ||
| 1429 | + * @access private | ||
| 1430 | + * @param string gzip-encoded data | ||
| 1431 | + * @return string decoded data | ||
| 1432 | + */ | ||
| 1433 | + function _decodeGzip($data) | ||
| 1434 | + { | ||
| 1435 | + if (HTTP_REQUEST_MBSTRING) { | ||
| 1436 | + $oldEncoding = mb_internal_encoding(); | ||
| 1437 | + mb_internal_encoding('iso-8859-1'); | ||
| 1438 | + } | ||
| 1439 | + $length = strlen($data); | ||
| 1440 | + // If it doesn't look like gzip-encoded data, don't bother | ||
| 1441 | + if (18 > $length || strcmp(substr($data, 0, 2), "\x1f\x8b")) { | ||
| 1442 | + return $data; | ||
| 1443 | + } | ||
| 1444 | + $method = ord(substr($data, 2, 1)); | ||
| 1445 | + if (8 != $method) { | ||
| 1446 | + return PEAR::raiseError('_decodeGzip(): unknown compression method', HTTP_REQUEST_ERROR_GZIP_METHOD); | ||
| 1447 | + } | ||
| 1448 | + $flags = ord(substr($data, 3, 1)); | ||
| 1449 | + if ($flags & 224) { | ||
| 1450 | + return PEAR::raiseError('_decodeGzip(): reserved bits are set', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1451 | + } | ||
| 1452 | + | ||
| 1453 | + // header is 10 bytes minimum. may be longer, though. | ||
| 1454 | + $headerLength = 10; | ||
| 1455 | + // extra fields, need to skip 'em | ||
| 1456 | + if ($flags & 4) { | ||
| 1457 | + if ($length - $headerLength - 2 < 8) { | ||
| 1458 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1459 | + } | ||
| 1460 | + $extraLength = unpack('v', substr($data, 10, 2)); | ||
| 1461 | + if ($length - $headerLength - 2 - $extraLength[1] < 8) { | ||
| 1462 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1463 | + } | ||
| 1464 | + $headerLength += $extraLength[1] + 2; | ||
| 1465 | + } | ||
| 1466 | + // file name, need to skip that | ||
| 1467 | + if ($flags & 8) { | ||
| 1468 | + if ($length - $headerLength - 1 < 8) { | ||
| 1469 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1470 | + } | ||
| 1471 | + $filenameLength = strpos(substr($data, $headerLength), chr(0)); | ||
| 1472 | + if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) { | ||
| 1473 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1474 | + } | ||
| 1475 | + $headerLength += $filenameLength + 1; | ||
| 1476 | + } | ||
| 1477 | + // comment, need to skip that also | ||
| 1478 | + if ($flags & 16) { | ||
| 1479 | + if ($length - $headerLength - 1 < 8) { | ||
| 1480 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1481 | + } | ||
| 1482 | + $commentLength = strpos(substr($data, $headerLength), chr(0)); | ||
| 1483 | + if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) { | ||
| 1484 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1485 | + } | ||
| 1486 | + $headerLength += $commentLength + 1; | ||
| 1487 | + } | ||
| 1488 | + // have a CRC for header. let's check | ||
| 1489 | + if ($flags & 1) { | ||
| 1490 | + if ($length - $headerLength - 2 < 8) { | ||
| 1491 | + return PEAR::raiseError('_decodeGzip(): data too short', HTTP_REQUEST_ERROR_GZIP_DATA); | ||
| 1492 | + } | ||
| 1493 | + $crcReal = 0xffff & crc32(substr($data, 0, $headerLength)); | ||
| 1494 | + $crcStored = unpack('v', substr($data, $headerLength, 2)); | ||
| 1495 | + if ($crcReal != $crcStored[1]) { | ||
| 1496 | + return PEAR::raiseError('_decodeGzip(): header CRC check failed', HTTP_REQUEST_ERROR_GZIP_CRC); | ||
| 1497 | + } | ||
| 1498 | + $headerLength += 2; | ||
| 1499 | + } | ||
| 1500 | + // unpacked data CRC and size at the end of encoded data | ||
| 1501 | + $tmp = unpack('V2', substr($data, -8)); | ||
| 1502 | + $dataCrc = $tmp[1]; | ||
| 1503 | + $dataSize = $tmp[2]; | ||
| 1504 | + | ||
| 1505 | + // finally, call the gzinflate() function | ||
| 1506 | + // don't pass $dataSize to gzinflate, see bugs #13135, #14370 | ||
| 1507 | + $unpacked = gzinflate(substr($data, $headerLength, -8)); | ||
| 1508 | + if (false === $unpacked) { | ||
| 1509 | + return PEAR::raiseError('_decodeGzip(): gzinflate() call failed', HTTP_REQUEST_ERROR_GZIP_READ); | ||
| 1510 | + } elseif ($dataSize != strlen($unpacked)) { | ||
| 1511 | + return PEAR::raiseError('_decodeGzip(): data size check failed', HTTP_REQUEST_ERROR_GZIP_READ); | ||
| 1512 | + } elseif ((0xffffffff & $dataCrc) != (0xffffffff & crc32($unpacked))) { | ||
| 1513 | + return PEAR::raiseError('_decodeGzip(): data CRC check failed', HTTP_REQUEST_ERROR_GZIP_CRC); | ||
| 1514 | + } | ||
| 1515 | + if (HTTP_REQUEST_MBSTRING) { | ||
| 1516 | + mb_internal_encoding($oldEncoding); | ||
| 1517 | + } | ||
| 1518 | + return $unpacked; | ||
| 1519 | + } | ||
| 1520 | +} // End class HTTP_Response | ||
| 1521 | +?> |
Please
register
or
login
to post a comment