source: branches/feature-module-update/data/include/mobile.inc @ 15078

Revision 15078, 13.1 KB checked in by nanasess, 17 years ago (diff)

r15064 から svn cp
とりあえず暫定コミット.

  • UTF-8 に変更
  • slib.php, glib.php のクラス化
  • LC_Page の抽象化(一部)
RevLine 
[12157]1<?php
2/**
[15078]3 * モバイルサイト共有関数ファイル
[12157]4 */
5
6require_once DATA_PATH . 'module/Net/URL.php';
7require_once DATA_PATH . 'class/SC_DbConn.php';
8require_once DATA_PATH . 'class/SC_Query.php';
9
10/**
[15078]11 * EC-CUBE がサポートする携帯端末かどうかをチェックする。
12 * 非対応端末の場合は unsupported/index.php へリダイレクトする。
[12157]13 *
14 * @return void
15 */
16function lfMobileCheckCompatibility() {
17    if (!GC_MobileUserAgent::isSupported()) {
18        header('Location: ' . URL_DIR . 'unsupported/index.php');
19        exit;
20    }
21}
22
23/**
[15078]24 * 入力データを内部エンコーディングに変換し、絵文字を除去する。
[12157]25 *
[15078]26 * @param string &$value 入力データへの参照
[12157]27 * @return void
28 */
29function lfMobileConvertInputValue(&$value) {
[15078]30    // Shift JIS から内部エンコーディングに変換する。
31    // SoftBank 以外の絵文字は外字領域に含まれるため、この段階で除去される。
[12157]32    $value = mb_convert_encoding($value, CHAR_CODE, 'SJIS');
33
[15078]34    // SoftBank の絵文字を除去する。
[12157]35    $value = preg_replace('/\\x1b\\$[^\\x0f]*\\x0f/', '', $value);
36}
37
38/**
[15078]39 * モバイルサイト用の入力の初期処理を行う。
[12157]40 *
41 * @return void
42 */
43function lfMobileInitInput() {
44    array_walk($_GET, 'lfMobileConvertInputValue');
45    array_walk($_POST, 'lfMobileConvertInputValue');
46    array_walk($_REQUEST, 'lfMobileConvertInputValue');
47}
48
49/**
[15078]50 * dtb_mobile_ext_session_id テーブルを検索してセッションIDを取得する。
[12157]51 *
[15078]52 * @return string|null 取得したセッションIDを返す。
53 *                     取得できなかった場合は null を返す。
[12157]54 */
55function lfMobileGetExtSessionId() {
56    if (!preg_match('|^' . URL_DIR . '(.*)$|', $_SERVER['SCRIPT_NAME'], $matches)) {
57        return null;
58    }
59
60    $url = $matches[1];
61    $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
62    $objQuery = new SC_Query;
63
64    foreach ($_REQUEST as $key => $value) {
65        $session_id = $objQuery->get('dtb_mobile_ext_session_id', 'session_id',
66                                     'param_key = ? AND param_value = ? AND url = ? AND create_date >= ?',
67                                     array($key, $value, $url, $time));
68        if (isset($session_id)) {
69            return $session_id;
70        }
71    }
72
73    return null;
74}
75
76/**
[15078]77 * パラメーターから有効なセッションIDを取得する。
[12157]78 *
[15078]79 * @return string|false 取得した有効なセッションIDを返す。
80 *                      取得できなかった場合は false を返す。
[12157]81 */
82function lfMobileGetSessionId() {
[15078]83    // パラメーターからセッションIDを取得する。
[12157]84    $sessionId = @$_POST[session_name()];
85    if (!isset($sessionId)) {
86        $sessionId = @$_GET[session_name()];
87    }
88    if (!isset($sessionId)) {
89        $sessionId = lfMobileGetExtSessionId();
90    }
91    if (!isset($sessionId)) {
92        return false;
93    }
94
[15078]95    // セッションIDのフォーマットをチェックする。
[12157]96    if (preg_match('/^[0-9a-zA-Z,-]{32,}$/', $sessionId) < 1) {
97        gfPrintLog("Invalid session id : sid=$sessionId");
98        return false;
99    }
100
[15078]101    // セッションIDの存在をチェックする。
[12157]102    if (sfSessRead($sessionId) === null) {
103        gfPrintLog("Non-existent session id : sid=$sessionId");
104        return false;
105    }
106
107    return session_id($sessionId);
108}
109
110/**
[15078]111 * セッションデータが有効かどうかをチェックする。
[12157]112 *
[15078]113 * @return boolean セッションデータが有効な場合は true、無効な場合は false を返す。
[12157]114 */
115function lfMobileValidateSession() {
[15078]116    // 配列 mobile が登録されているかどうかをチェックする。
[12157]117    if (!is_array(@$_SESSION['mobile'])) {
118        return false;
119    }
120
[15078]121    // 有効期限を過ぎていないかどうかをチェックする。
[12157]122    if (intval(@$_SESSION['mobile']['expires']) < time()) {
123        gfPrintLog("Session expired at " .
124                   date('Y/m/d H:i:s', @$_SESSION['mobile']['expires']) .
125                   ' : sid=' . session_id());
126
127        return false;
128    }
129
[15078]130    // 携帯端末の機種が一致するかどうかをチェックする。
[12157]131    $model = GC_MobileUserAgent::getModel();
132    if (@$_SESSION['mobile']['model'] != $model) {
133        gfPrintLog("User agent model mismatch : " .
134                   "\"$model\" != \"" . @$_SESSION['mobile']['model'] .
135                   '" (expected), sid=' . session_id());
136        return false;
137    }
138
139    return true;
140}
141
142/**
[15078]143 * モバイルサイト用のセッション関連の初期処理を行う。
[12157]144 *
145 * @return void
146 */
147function lfMobileInitSession() {
[15078]148    // セッションIDの受け渡しにクッキーを使用しない。
[12157]149    ini_set('session.use_cookies', '0');
150
[15078]151    // パラメーターから有効なセッションIDを取得する。
[12157]152    $sessionId = lfMobileGetSessionId();
153
154    session_start();
155
[15078]156    // セッションIDまたはセッションデータが無効な場合は、セッションIDを再生成
157    // し、セッションデータを初期化する。
[12157]158    if ($sessionId === false || !lfMobileValidateSession()) {
159        session_regenerate_id();
160        $_SESSION = array('mobile' => array('model'    => GC_MobileUserAgent::getModel(),
161                                            'phone_id' => GC_MobileUserAgent::getId(),
162                                            'expires'  => time() + MOBILE_SESSION_LIFETIME));
163
[15078]164        // 新しいセッションIDを付加してリダイレクトする。
[12157]165        if ($_SERVER['REQUEST_METHOD'] == 'GET') {
[15078]166            // GET の場合は同じページにリダイレクトする。
[12157]167            header('Location: ' . gfAddSessionId());
168        } else {
[15078]169            // GET 以外の場合はトップページへリダイレクトする。
[12157]170            header('Location: ' . URL_SITE_TOP . '?' . SID);
171        }
172        exit;
173    }
174
[15078]175    // 携帯端末IDを取得できた場合はセッションデータに保存する。
[12157]176    $phoneId = GC_MobileUserAgent::getId();
177    if ($phoneId !== false) {
178        $_SESSION['mobile']['phone_id'] = $phoneId;
179    }
180
[15078]181    // セッションの有効期限を更新する。
[12157]182    $_SESSION['mobile']['expires'] = time() + MOBILE_SESSION_LIFETIME;
183}
184
185/**
[15078]186 * モバイルサイト用の出力の初期処理を行う。
[12157]187 *
[15078]188 * 出力の流れ
[12157]189 * 1. Smarty
[15078]190 * 2. 内部エンコーディングから Shift JIS に変換する。
191 * 3. 全角カタカナを半角カタカナに変換する。
192 * 4. 画像用のタグを調整する。
193 * 5. 絵文字タグを絵文字コードに変換する。
194 * 6. 出力
[12157]195 *
196 * @return void
197 */
198function lfMobileInitOutput() {
[15078]199    // Smarty 用のディレクトリーを作成する。
[12157]200    @mkdir(COMPILE_DIR);
201
[15078]202    // 出力用のエンコーディングを Shift JIS に固定する。
[12157]203    mb_http_output('SJIS-win');
204
[15078]205    // 絵文字タグを絵文字コードに変換する。
[12157]206    ob_start(array('GC_MobileEmoji', 'handler'));
207
[15078]208    // 端末に合わせて画像サイズを変換する。
[12157]209    ob_start(array('GC_MobileImage', 'handler'));
210
[15078]211    // 全角カタカナを半角カタカナに変換する。
[12157]212    ob_start(create_function('$buffer', 'return mb_convert_kana($buffer, "k", "SJIS-win");'));
213
[15078]214    // 内部エンコーディングから Shift JIS に変換する。
[12157]215    ob_start('mb_output_handler');
216}
217
218/**
[15078]219 * モバイルサイト用の初期処理を行う。
[12157]220 *
221 * @return void
222 */
223function sfMobileInit() {
224    lfMobileInitInput();
225
226    if (basename(dirname($_SERVER['SCRIPT_NAME'])) != 'unsupported') {
227        lfMobileCheckCompatibility();
228        lfMobileInitSession();
229    }
230
231    lfMobileInitOutput();
232}
233
234/**
[15078]235 * Location等でセッションIDを付加する必要があるURLにセッションIDを付加する。
[12157]236 *
237 * @return String
238 */
239function gfAddSessionId($url = null) {
240    $objURL = new Net_URL($url);
241    $objURL->addQueryString(session_name(), session_id());
242    return $objURL->getURL();
243}
244
245/**
[15078]246 * 空メール用のトークンを生成する。
[12157]247 *
[15078]248 * @return string 生成したトークンを返す。
[12157]249 */
250function lfGenerateKaraMailToken() {
251    $token_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
252    $token_chars_length = strlen($token_chars);
253    $token_length = 10;
254    $token = '';
255
256    while ($token_length > 0) {
257        $token .= $token_chars{mt_rand(0, $token_chars_length - 1)};
258        --$token_length;
259    }
260
261    return $token;
262}
263
264/**
[15078]265 * 空メール管理テーブルに新規エントリーを登録し、トークンを返す。
[12157]266 *
[15078]267 * @param string $next_url 空メール受け付け後に遷移させるページ (モバイルサイトトップからの相対URL)
268 * @param string $session_id セッションID (省略した場合は現在のセッションID)
269 * @return string|false トークンを返す。エラーが発生した場合はfalseを返す。
[12157]270 */
271function gfPrepareKaraMail($next_url, $session_id = null) {
272    if (!isset($session_id)) {
273        $session_id = session_id();
274    }
275
276    $objQuery = new SC_Query;
277
278    // GC
279    $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
280    $objQuery->delete('dtb_mobile_kara_mail', 'email IS NULL AND create_date < ?', array($time));
281
282    $objQuery->delete('dtb_mobile_kara_mail', 'session_id = ?', array($session_id));
283
284    $arrValues = array('session_id' => $session_id,
285                       'next_url'   => $next_url);
286
287    $try = 10;
288
289    while ($try > 0) {
290        $arrValues['token'] = $token = lfGenerateKaraMailToken();
291
292        $objQuery->insert('dtb_mobile_kara_mail', $arrValues);
293        $count = $objQuery->count('dtb_mobile_kara_mail', 'token = ?', array($token));
294
295        if ($count == 1) {
296            break;
297        }
298
299        $objQuery->delete('dtb_mobile_kara_mail', 'session_id = ?', array($session_id));
300        $token = false;
301        --$try;
302    }
303
304    return $token;
305}
306
307/**
[15078]308 * 空メールから取得したメールアドレスを空メール管理テーブルに登録する。
[12157]309 *
[15078]310 * @param string $token トークン
311 * @param string $email メールアドレス
312 * @return boolean 成功した場合はtrue、失敗した場合はfalseを返す。
[12157]313 */
314function gfRegisterKaraMail($token, $email) {
315    $objQuery = new SC_Query;
316
317    // GC
318    $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
319    $objQuery->delete('dtb_mobile_kara_mail',
320                      '(email IS NULL AND create_date < ?) OR (email IS NOT NULL AND receive_date < ?)',
321                      array($time, $time));
322
323    $kara_mail_id = $objQuery->get('dtb_mobile_kara_mail', 'kara_mail_id', 'token = ?', array($token));
324    if (!isset($kara_mail_id)) {
325        return false;
326    }
327
328    $arrValues = array('email' => $email);
329    $arrRawValues = array('receive_date' => 'now()');
330    $objQuery->update('dtb_mobile_kara_mail', $arrValues, 'kara_mail_id = ?', array($kara_mail_id), $arrRawValues);
331
332    return true;
333}
334
335/**
[15078]336 * 空メール管理テーブルからトークンが一致する行を削除し、
337 * 次に遷移させるページのURLを返す。 
[12157]338 *
[15078]339 * メールアドレスは $_SESSION['mobile']['kara_mail_from'] に登録される。
[12157]340 *
[15078]341 * @param string $token トークン
342 * @return string|false URLを返す。エラーが発生した場合はfalseを返す。
[12157]343 */
344function gfFinishKaraMail($token) {
345    $objQuery = new SC_Query;
346
347    $arrRow = $objQuery->getrow('dtb_mobile_kara_mail', 'session_id, next_url, email',
348                                'token = ? AND email IS NOT NULL AND receive_date >= ?',
349                                array($token, date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME)));
350    if (!isset($arrRow)) {
351        return false;
352    }
353
354    $objQuery->delete('dtb_mobile_kara_mail', 'token = ?', array($token));
355
356    list($session_id, $next_url, $email) = $arrRow;
357    $objURL = new Net_URL(MOBILE_SITE_URL . $next_url);
358    $objURL->addQueryString(session_name(), $session_id);
359    $url = $objURL->getURL();
360
361    session_id($session_id);
362    session_start();
363    $_SESSION['mobile']['kara_mail_from'] = $email;
364    session_write_close();
365
366    return $url;
367}
368
369/**
[15078]370 * 外部サイト連携用にセッションIDとパラメーターの組み合わせを保存する。
[12157]371 *
[15078]372 * @param string $param_key パラメーター名
373 * @param string $param_value パラメーター値
[12157]374 * @param string $url URL
375 * @return void
376 */
377function sfMobileSetExtSessionId($param_key, $param_value, $url) {
378    $objQuery = new SC_Query;
379
380    // GC
381    $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
382    $objQuery->delete('dtb_mobile_ext_session_id', 'create_date < ?', array($time));
383
384    $arrValues = array('session_id'  => session_id(),
385                       'param_key'   => $param_key,
386                       'param_value' => $param_value,
387                       'url'         => $url);
388
389    $objQuery->insert('dtb_mobile_ext_session_id', $arrValues);
390}
391
392/**
[15078]393 * メールアドレスが携帯のものかどうかを判別する。
[12157]394 *
[15078]395 * @param string $address メールアドレス
396 * @return boolean 携帯のメールアドレスの場合はtrue、それ以外の場合はfalseを返す。
[12157]397 */
398function gfIsMobileMailAddress($address) {
[15078]399    // pdx.ne.jp(ウィルコム)追加
[13356]400    $arrMobileMailDomains = array('docomo.ne.jp', 'ezweb.ne.jp', 'softbank.ne.jp', 'vodafone.ne.jp', 'pdx.ne.jp');
[12157]401
402    if (defined('MOBILE_ADDITIONAL_MAIL_DOMAINS')) {
403        $arrMobileMailDomains = array_merge($arrMobileMailDomains, split('[ ,]+', MOBILE_ADDITIONAL_MAIL_DOMAINS));
404    }
405
406    foreach ($arrMobileMailDomains as $domain) {
407        $domain = str_replace('.', '\\.', $domain);
408        if (preg_match("/@([^@]+\\.)?$domain\$/", $address)) {
409            return true;
410        }
411    }
412
413    return false;
414}
415?>
Note: See TracBrowser for help on using the repository browser.