source: branches/version-2_12-dev/data/class/helper/SC_Helper_Mobile.php @ 22567

Revision 22567, 16.7 KB checked in by shutta, 11 years ago (diff)

#2043 (typo修正・ソース整形・ソースコメントの改善 for 2.12.4)
Zend Framework PHP 標準コーディング規約のコーディングスタイルへ準拠。
classおよびfunctionの開始波括弧「{」のスタイルを修正。

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2013 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24/**
25 * モバイルのヘルパークラス.
26 *
27 * @package Helper
28 * @author LOCKON CO.,LTD.
29 * @version $Id$
30 */
31class SC_Helper_Mobile
32{
33
34    /** 基本MimeType */
35    var $defaultMimeType = 'application/force-download';
36
37    /** 拡張MimeType配列
38     * Application/octet-streamで対応出来ないファイルタイプのみ拡張子をキーに記述する
39     * 拡張子が本配列に存在しない場合は application/force-download を利用する */
40    var $arrMimetypes = array(
41            'html'=> 'text/html',
42            'css' => 'text/css',
43            'hdml'=> 'text/x-hdml',
44            'mmf' => 'application/x-smaf',
45            'jpeg'=> 'image/jpeg',
46            'jpg' => 'image/jpeg',
47            'gif' => 'image/gif',
48            'png' => 'image/png',
49            'bmp' => 'image/x-ms-bmp',
50            'amc' => 'application/x-mpeg',
51            '3g2' => 'video/3gpp2',
52            '3gp' => 'video/3gpp',
53            'jam' => 'application/x-jam',
54            'kjx' => 'application/x-kjx',
55            'jar' => 'application/java-archive',
56            'jad' => 'text/vnd.sun.j2me.app-descriptor',
57            'swf' => 'application/x-shockwave-flash',
58            'dmt' => 'application/x-decomail-template',
59            'khm' => 'application/x-kddi-htmlmail',
60            'hmt' => 'application/x-htmlmail-template',
61            'ucm' => 'application/x-ucf-package',
62            'ucp' => 'application/x-ucf-package',
63            'pdf' => 'application/pdf',
64            'wma' => 'audio/x-ms-wma',
65            'asf' => 'video/x-ms-asf',
66            'wax' => 'audio/x-ms-wax',
67            'wvx' => 'video/x-ms-wvx',
68            'wmv' => 'video/x-ms-wmv',
69            'asx' => 'video/asx',
70            'txt' => 'text/plain',
71            'exe' => 'application/octet-stream',
72            'zip' => 'application/zip',
73            'doc' => 'application/msword',
74            'xls' => 'application/vnd.ms-excel',
75            'ppt' => 'application/vnd.ms-powerpoint'
76        );
77
78    /**
79     * EC-CUBE がサポートする携帯端末かどうかをチェックする。
80     * 非対応端末の場合は /unsupported/ へリダイレクトする。
81     *
82     * @return void
83     */
84    function lfMobileCheckCompatibility()
85    {
86        if (!SC_MobileUserAgent_Ex::isSupported()) {
87            header('Location: ' . ROOT_URLPATH . 'unsupported/' . DIR_INDEX_PATH);
88            exit;
89        }
90    }
91
92    /**
93     * 入力データを内部エンコーディングに変換し、絵文字を除去する。
94     *
95     * @param string &$value 入力データへの参照
96     * @return void
97     */
98    function lfMobileConvertInputValue(&$value)
99    {
100        if (is_array($value)) {
101            foreach ($value as $key => $val) {
102                $this->lfMobileConvertInputValue($value[$key]);
103            }
104        } else {
105            // Shift JIS から内部エンコーディングに変換する。
106            $value = mb_convert_encoding($value, CHAR_CODE, 'SJIS');
107            // SoftBank? 以外の絵文字は外字領域に含まれるため、この段階で除去される。
108            // SoftBank? の絵文字を除去する。
109            $value = preg_replace('/\\x1b\\$[^\\x0f]*\\x0f/', '', $value);
110        }
111    }
112
113    /**
114     * モバイルサイト用の入力の初期処理を行う。
115     *
116     * @return void
117     */
118    function lfMobileInitInput()
119    {
120        array_walk($_GET, array($this, 'lfMobileConvertInputValue'));
121        array_walk($_POST, array($this, 'lfMobileConvertInputValue'));
122        array_walk($_REQUEST, array($this, 'lfMobileConvertInputValue'));
123    }
124
125    /**
126     * dtb_mobile_ext_session_id テーブルを検索してセッションIDを取得する。
127     *
128     * @return string|null 取得したセッションIDを返す。
129     *                     取得できなかった場合は null を返す。
130     */
131    function lfMobileGetExtSessionId()
132    {
133        if (!preg_match('|^' . ROOT_URLPATH . '(.*)$|', $_SERVER['SCRIPT_NAME'], $matches = array())) {
134            return null;
135        }
136
137        $url = $matches[1];
138        $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
139        $objQuery =& SC_Query_Ex::getSingletonInstance();
140
141        foreach ($_REQUEST as $key => $value) {
142            $session_id = $objQuery->get('session_id', 'dtb_mobile_ext_session_id',
143                                         'param_key = ? AND param_value = ? AND url = ? AND create_date >= ?',
144                                         array($key, $value, $url, $time));
145            if (isset($session_id)) {
146                return $session_id;
147            }
148        }
149
150        return null;
151    }
152
153    /**
154     * パラメーターから有効なセッションIDを取得する。
155     *
156     * @return string|false 取得した有効なセッションIDを返す。
157     *                      取得できなかった場合は false を返す。
158     */
159    function lfMobileGetSessionId()
160    {
161        // パラメーターからセッションIDを取得する。
162        $sessionId = @$_POST[session_name()];
163        if (!isset($sessionId)) {
164            $sessionId = @$_GET[session_name()];
165        }
166        if (!isset($sessionId)) {
167            $sessionId = $this->lfMobileGetExtSessionId();
168        }
169        if (!isset($sessionId)) {
170            return false;
171        }
172
173        // セッションIDの存在をチェックする。
174        $objSession = new SC_Helper_Session_Ex();
175        if ($objSession->sfSessRead($sessionId) === null) {
176            GC_Utils_Ex::gfPrintLog("Non-existent session id : sid=$sessionId");
177            return false;
178        }
179        return session_id($sessionId);
180    }
181
182    /**
183     * セッションデータが有効かどうかをチェックする。
184     *
185     * FIXME '@' でエラーを抑制するのは良くない
186     *
187     * @return boolean セッションデータが有効な場合は true、無効な場合は false を返す。
188     */
189    function lfMobileValidateSession()
190    {
191        // 配列 mobile が登録されているかどうかをチェックする。
192        if (!is_array(@$_SESSION['mobile'])) {
193            return false;
194        }
195
196        // 有効期限を過ぎていないかどうかをチェックする。
197        if (intval(@$_SESSION['mobile']['expires']) < time()) {
198            $msg = 'Session expired at ' . date('Y/m/d H:i:s', @$_SESSION['mobile']['expires'])
199                 . ' : sid=' . session_id();
200            GC_Utils_Ex::gfPrintLog($msg);
201
202            return false;
203        }
204
205        // 携帯端末の機種が一致するかどうかをチェックする。
206        $model = SC_MobileUserAgent_Ex::getModel();
207        if (@$_SESSION['mobile']['model'] != $model) {
208            $msg = 'User agent model mismatch : '
209                 . '"$model" != "' . @$_SESSION['mobile']['model']
210                 . '" (expected), sid=' . session_id();
211            GC_Utils_Ex::gfPrintLog($msg);
212            return false;
213        }
214
215        return true;
216    }
217
218    /**
219     * モバイルサイト用の出力の初期処理を行う。
220     *
221     * 出力の流れ
222     * 1. ページクラスでの出力
223     * 2. 全角カタカナを半角カタカナに変換する。
224     * 3. 内部エンコーディングから Shift JIS に変換する。
225     * 4. 画像を調整する。
226     * 5. 絵文字タグを絵文字コードに変換する。(require.php で設定)
227     *
228     * @return void
229     */
230    function lfMobileInitOutput()
231    {
232        // 出力用のエンコーディングを Shift JIS に固定する。
233        mb_http_output('SJIS-win');
234
235        // 端末に合わせて画像サイズを変換する。
236        ob_start(array('SC_MobileImage_Ex', 'handler'));
237
238        // 内部エンコーディングから Shift JIS に変換する。
239        ob_start('mb_output_handler');
240
241        //download.phpに対してカタカナ変換をするとファイルが壊れてしまうため回避する
242        if ($_SERVER['SCRIPT_FILENAME'] != HTML_REALDIR . 'mypage/download.php') {
243            // 全角カタカナを半角カタカナに変換する。
244            ob_start(create_function('$buffer', 'return mb_convert_kana($buffer, "k");'));
245        }
246    }
247
248    /**
249     * モバイルサイト用の初期処理を行う。
250     *
251     * @return void
252     */
253    function sfMobileInit()
254    {
255        $this->lfMobileInitInput();
256
257        if (basename(dirname($_SERVER['SCRIPT_NAME'])) != 'unsupported') {
258            $this->lfMobileCheckCompatibility();
259        }
260
261        $this->lfMobileInitOutput();
262    }
263
264    /**
265     * Location等でセッションIDを付加する必要があるURLにセッションIDを付加する。
266     *
267     * @return String
268     */
269    function gfAddSessionId($url = null)
270    {
271        $objURL = new Net_URL($url);
272        $objURL->addQueryString(session_name(), session_id());
273        return $objURL->getURL();
274    }
275
276    /**
277     * セッション ID を付加した配列を返す.
278     *
279     * @param array $array 元となる配列
280     * @param array セッション ID を追加した配列
281     */
282    function sessionIdArray($array = array())
283    {
284        return array_merge($array, array(session_name() => session_id()));
285    }
286
287    /**
288     * 空メール用のトークンを生成する。
289     *
290     * @return string 生成したトークンを返す。
291     */
292    function lfGenerateKaraMailToken()
293    {
294        $token_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
295        $token_chars_length = strlen($token_chars);
296        $token_length = 10;
297        $token = '';
298
299        while ($token_length > 0) {
300            $token .= $token_chars{mt_rand(0, $token_chars_length - 1)};
301            --$token_length;
302        }
303
304        return $token;
305    }
306
307    /**
308     * 空メール管理テーブルに新規エントリーを登録し、トークンを返す。
309     *
310     * @param string $next_url 空メール受け付け後に遷移させるページ (モバイルサイトトップからの相対URL)
311     * @param string $session_id セッションID (省略した場合は現在のセッションID)
312     * @return string|false トークンを返す。エラーが発生した場合はfalseを返す。
313     */
314    function gfPrepareKaraMail($next_url, $session_id = null)
315    {
316        if (!isset($session_id)) {
317            $session_id = session_id();
318        }
319
320        $objQuery =& SC_Query_Ex::getSingletonInstance();
321
322        // GC
323        $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
324        $objQuery->delete('dtb_mobile_kara_mail', 'email IS NULL AND create_date < ?', array($time));
325
326        $objQuery->delete('dtb_mobile_kara_mail', 'session_id = ?', array($session_id));
327
328        $arrValues = array(
329            'session_id' => $session_id,
330            'next_url'   => $next_url,
331        );
332
333        $try = 10;
334
335        while ($try > 0) {
336            $arrValues['token'] = $token = $this->lfGenerateKaraMailToken();
337
338            $arrValues['kara_mail_id'] = $objQuery->nextVal('dtb_mobile_kara_mail_kara_mail_id');
339            $objQuery->insert('dtb_mobile_kara_mail', $arrValues);
340            $exists = $objQuery->exists('dtb_mobile_kara_mail', 'token = ?', array($token));
341
342            if ($exists) {
343                break;
344            }
345
346            $objQuery->delete('dtb_mobile_kara_mail', 'session_id = ?', array($session_id));
347            $token = false;
348            --$try;
349        }
350
351        return $token;
352    }
353
354    /**
355     * 空メールから取得したメールアドレスを空メール管理テーブルに登録する。
356     *
357     * @param string $token トークン
358     * @param string $email メールアドレス
359     * @return boolean 成功した場合はtrue、失敗した場合はfalseを返す。
360     */
361    function gfRegisterKaraMail($token, $email)
362    {
363        $objQuery =& SC_Query_Ex::getSingletonInstance();
364
365        // GC
366        $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
367        $objQuery->delete('dtb_mobile_kara_mail',
368                          '(email IS NULL AND create_date < ?) OR (email IS NOT NULL AND receive_date < ?)',
369                          array($time, $time));
370
371        $kara_mail_id = $objQuery->get('kara_mail_id', 'dtb_mobile_kara_mail', 'token = ?', array($token));
372        if (!isset($kara_mail_id)) {
373            return false;
374        }
375
376        $arrValues = array('email' => $email);
377        $arrRawValues = array('receive_date' => 'CURRENT_TIMESTAMP');
378        $objQuery->update('dtb_mobile_kara_mail', $arrValues, 'kara_mail_id = ?', array($kara_mail_id), $arrRawValues);
379
380        return true;
381    }
382
383    /**
384     * 空メール管理テーブルからトークンが一致する行を削除し、
385     * 次に遷移させるページのURLを返す。 
386     *
387     * メールアドレスは $_SESSION['mobile']['kara_mail_from'] に登録される。
388     *
389     * @param string $token トークン
390     * @return string|false URLを返す。エラーが発生した場合はfalseを返す。
391     */
392    function gfFinishKaraMail($token)
393    {
394        $objQuery =& SC_Query_Ex::getSingletonInstance();
395
396        $arrRow = $objQuery->getRow(
397             'session_id, next_url, email'
398            ,'dtb_mobile_kara_mail'
399            ,'token = ? AND email IS NOT NULL AND receive_date >= ?'
400            ,array($token, date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME))
401            ,DB_FETCHMODE_ORDERED
402        );
403
404        if (!isset($arrRow)) {
405            return false;
406        }
407
408        $objQuery->delete('dtb_mobile_kara_mail', 'token = ?', array($token));
409
410        list($session_id, $next_url, $email) = $arrRow;
411        $objURL = new Net_URL(HTTP_URL . $next_url);
412        $objURL->addQueryString(session_name(), $session_id);
413        $url = $objURL->getURL();
414
415        session_id($session_id);
416        session_start();
417        $_SESSION['mobile']['kara_mail_from'] = $email;
418        session_write_close();
419
420        return $url;
421    }
422
423    /**
424     * 外部サイト連携用にセッションIDとパラメーターの組み合わせを保存する。
425     *
426     * @param string $param_key パラメーター名
427     * @param string $param_value パラメーター値
428     * @param string $url URL
429     * @return void
430     */
431    function sfMobileSetExtSessionId($param_key, $param_value, $url)
432    {
433        $objQuery =& SC_Query_Ex::getSingletonInstance();
434
435        // GC
436        $time = date('Y-m-d H:i:s', time() - MOBILE_SESSION_LIFETIME);
437        $objQuery->delete('dtb_mobile_ext_session_id', 'create_date < ?', array($time));
438
439        $arrValues = array(
440            'session_id'  => session_id(),
441            'param_key'   => $param_key,
442            'param_value' => $param_value,
443            'url'         => $url,
444        );
445
446        $objQuery->insert('dtb_mobile_ext_session_id', $arrValues);
447    }
448
449    /**
450     * メールアドレスが携帯のものかどうかを判別する。
451     *
452     * @param string $address メールアドレス
453     * @return boolean 携帯のメールアドレスの場合はtrue、それ以外の場合はfalseを返す。
454     */
455    function gfIsMobileMailAddress($address)
456    {
457        $masterData = new SC_DB_MasterData_Ex();
458        $arrMobileMailDomains = $masterData->getMasterData('mtb_mobile_domain');
459
460        foreach ($arrMobileMailDomains as $domain) {
461            $domain = preg_quote($domain, '/');
462            if (preg_match("/@([^@]+\\.)?$domain\$/", $address)) {
463                return true;
464            }
465        }
466
467        return false;
468    }
469
470    /**
471     * ファイルのMIMEタイプを判別する
472     *
473     * @param string $filename ファイル名
474     * @return string MIMEタイプ
475     */
476    function getMimeType($filename)
477    {
478        //ファイルの拡張子からコンテンツタイプを決定する
479        $file_extension = strtolower(substr(strrchr($filename,'.'),1));
480        $mime_type = $this->defaultMimeType;
481        if (array_key_exists($file_extension, $this->arrMimetypes)) {
482            $mime_type = $this->arrMimetypes[$file_extension];
483        }
484        return $mime_type;
485    }
486}
Note: See TracBrowser for help on using the repository browser.