source: branches/version-2_5-dev/data/module/Net/UserAgent/Mobile.php @ 19661

Revision 19661, 13.3 KB checked in by nanasess, 13 years ago (diff)

source:branches/camp/camp-2_5-E のマージ

  • スマートフォン対応(#787)
  • プラグイン機能(#494)
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-httpd-php; charset=UTF-8
Line 
1<?php
2/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
4/**
5 * PHP versions 4 and 5
6 *
7 * Copyright (c) 2003-2009 KUBO Atsuhiro <kubo@iteman.jp>,
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 *     * Redistributions of source code must retain the above copyright
14 *       notice, this list of conditions and the following disclaimer.
15 *     * Redistributions in binary form must reproduce the above copyright
16 *       notice, this list of conditions and the following disclaimer in the
17 *       documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * @category   Networking
32 * @package    Net_UserAgent_Mobile
33 * @author     KUBO Atsuhiro <kubo@iteman.jp>
34 * @copyright  2003-2009 KUBO Atsuhiro <kubo@iteman.jp>
35 * @license    http://www.opensource.org/licenses/bsd-license.php  New BSD License
36 * @version    CVS: $Id$
37 * @since      File available since Release 0.1
38 */
39
40require_once dirname(__FILE__) . '/../../PEAR.php';
41require_once dirname(__FILE__) . '/Mobile/Error.php';
42
43// {{{ GLOBALS
44
45/**
46 * globals for fallback on no match
47 *
48 * @global boolean $GLOBALS['NET_USERAGENT_MOBILE_FallbackOnNomatch']
49 */
50$GLOBALS['NET_USERAGENT_MOBILE_FallbackOnNomatch'] = false;
51
52// }}}
53// {{{ Net_UserAgent_Mobile
54
55/**
56 * HTTP mobile user agent string parser
57 *
58 * Net_UserAgent_Mobile parses HTTP_USER_AGENT strings of (mainly Japanese) mobile
59 * HTTP user agents. It'll be useful in page dispatching by user agents.
60 * This package was ported from Perl's HTTP::MobileAgent.
61 * See {@link http://search.cpan.org/search?mode=module&query=HTTP-MobileAgent}
62 *
63 * SYNOPSIS:
64 * <code>
65 * require_once 'Net/UserAgent/Mobile.php';
66 *
67 * $agent = &Net_UserAgent_Mobile::factory($agent_string);
68 * // or $agent = &Net_UserAgent_Mobile::factory(); // to get from $_SERVER
69 *
70 * if ($agent->isDoCoMo()) {
71 *     // or if ($agent->getName() == 'DoCoMo')
72 *     // or if (strtolower(get_class($agent)) == 'http_mobileagent_docomo')
73 *     // it's NTT DoCoMo i-mode
74 *     // see what's available in Net_UserAgent_Mobile_DoCoMo
75 * } elseif ($agent->isSoftBank()) {
76 *     // it's SoftBank
77 *     // see what's available in Net_UserAgent_Mobile_SoftBank
78 * } elseif ($agent->isEZweb()) {
79 *     // it's KDDI/EZWeb
80 *     // see what's available in Net_UserAgent_Mobile_EZweb
81 * } else {
82 *     // may be PC
83 *     // $agent is Net_UserAgent_Mobile_NonMobile
84 * }
85 *
86 * $display = $agent->getDisplay();    // Net_UserAgent_Mobile_Display
87 * if ($display->isColor()) {
88 *    ...
89 * }
90 * </code>
91 *
92 * @category   Networking
93 * @package    Net_UserAgent_Mobile
94 * @author     KUBO Atsuhiro <kubo@iteman.jp>
95 * @copyright  2003-2009 KUBO Atsuhiro <kubo@iteman.jp>
96 * @license    http://www.opensource.org/licenses/bsd-license.php  New BSD License
97 * @version    Release: 1.0.0
98 * @since      Class available since Release 0.1
99 */
100class Net_UserAgent_Mobile
101{
102
103    // {{{ properties
104
105    /**#@+
106     * @access public
107     */
108
109    /**#@-*/
110
111    /**#@+
112     * @access private
113     */
114
115    /**#@-*/
116
117    /**#@+
118     * @access public
119     * @static
120     */
121
122    // }}}
123    // {{{ factory()
124
125    /**
126     * create a new {@link Net_UserAgent_Mobile_Common} subclass instance
127     *
128     * parses HTTP headers and constructs {@link Net_UserAgent_Mobile_Common}
129     * subclass instance.
130     * If no argument is supplied, $_SERVER{'HTTP_*'} is used.
131     *
132     * @param string $userAgent User-Agent string
133     * @return Net_UserAgent_Mobile_Common a newly created or an existing
134     *     Net_UserAgent_Mobile_Common object
135     * @throws Net_UserAgent_Mobile_Error
136     */
137    function &factory($userAgent = null)
138    {
139        if (is_null($userAgent)) {
140            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
141        }
142
143        // parse User-Agent string
144        if (Net_UserAgent_Mobile::isDoCoMo($userAgent)) {
145            $driver = 'DoCoMo';
146        } elseif (Net_UserAgent_Mobile::isEZweb($userAgent)) {
147            $driver = 'EZweb';
148        } elseif (Net_UserAgent_Mobile::isSoftBank($userAgent)) {
149            $driver = 'SoftBank';
150        } elseif (Net_UserAgent_Mobile::isWillcom($userAgent)) {
151            $driver = 'Willcom';
152        } else {
153            $driver = 'NonMobile';
154        }
155
156        $class = "Net_UserAgent_Mobile_$driver";
157
158        if (!class_exists($class)) {
159            $file = dirname(__FILE__) . "/Mobile/{$driver}.php";
160            if (!include_once $file) {
161                return PEAR::raiseError(null,
162                                        NET_USERAGENT_MOBILE_ERROR_NOT_FOUND,
163                                        null, null,
164                                        "Unable to include the $file file",
165                                        'Net_UserAgent_Mobile_Error', true
166                                        );
167            }
168        }
169
170        PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN);
171        $instance = new $class($userAgent);
172        PEAR::staticPopErrorHandling();
173        $error = &$instance->getError();
174        if (Net_UserAgent_Mobile::isError($error)) {
175            if ($GLOBALS['NET_USERAGENT_MOBILE_FallbackOnNomatch']
176                && $error->getCode() == NET_USERAGENT_MOBILE_ERROR_NOMATCH
177                ) {
178                $instance = &Net_UserAgent_Mobile::factory('Net_UserAgent_Mobile_Fallback_On_NoMatch');
179                return $instance;
180            }
181
182            return PEAR::raiseError($error);
183        }
184
185        return $instance;
186    }
187
188    // }}}
189    // {{{ singleton()
190
191    /**
192     * creates a new {@link Net_UserAgent_Mobile_Common} subclass instance or returns
193     * a instance from existent ones
194     *
195     * @param string $userAgent User-Agent string
196     * @return Net_UserAgent_Mobile_Common a newly created or an existing
197     *     Net_UserAgent_Mobile_Common object
198     * @throws Net_UserAgent_Mobile_Error
199     */
200    function &singleton($userAgent = null)
201    {
202        static $instances;
203
204        if (!isset($instances)) {
205            $instances = array();
206        }
207
208        if (is_null($userAgent)) {
209            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
210        }
211
212        if (!array_key_exists($userAgent, $instances)) {
213            $instances[$userAgent] = Net_UserAgent_Mobile::factory($userAgent);
214        }
215
216        return $instances[$userAgent];
217    }
218
219    // }}}
220    // {{{ isError()
221
222    /**
223     * tell whether a result code from a Net_UserAgent_Mobile method is an error
224     *
225     * @param integer $value result code
226     * @return boolean whether $value is an {@link Net_UserAgent_Mobile_Error}
227     */
228    function isError($value)
229    {
230        return is_object($value)
231            && (strtolower(get_class($value)) == strtolower('Net_UserAgent_Mobile_Error')
232                || is_subclass_of($value, 'Net_UserAgent_Mobile_Error'));
233    }
234
235    // }}}
236    // {{{ errorMessage()
237
238    /**
239     * return a textual error message for a Net_UserAgent_Mobile error code
240     *
241     * @param integer $value error code
242     * @return string error message, or null if the error code was not recognized
243     */
244    function errorMessage($value)
245    {
246        static $errorMessages;
247        if (!isset($errorMessages)) {
248            $errorMessages = array(
249                                   NET_USERAGENT_MOBILE_ERROR           => 'unknown error',
250                                   NET_USERAGENT_MOBILE_ERROR_NOMATCH   => 'no match',
251                                   NET_USERAGENT_MOBILE_ERROR_NOT_FOUND => 'not found',
252                                   NET_USERAGENT_MOBILE_OK              => 'no error'
253                                   );
254        }
255
256        if (Net_UserAgent_Mobile::isError($value)) {
257            $value = $value->getCode();
258        }
259
260        return isset($errorMessages[$value]) ?
261            $errorMessages[$value] :
262            $errorMessages[NET_USERAGENT_MOBILE_ERROR];
263    }
264
265    // }}}
266    // {{{ isMobile()
267
268    /**
269     * Checks whether or not the user agent is mobile by a given user agent string.
270     *
271     * @param string $userAgent
272     * @return boolean
273     * @since Method available since Release 0.31.0
274     */
275    function isMobile($userAgent = null)
276    {
277        if (Net_UserAgent_Mobile::isDoCoMo($userAgent)) {
278            return true;
279        } elseif (Net_UserAgent_Mobile::isEZweb($userAgent)) {
280            return true;
281        } elseif (Net_UserAgent_Mobile::isSoftBank($userAgent)) {
282            return true;
283        } elseif (Net_UserAgent_Mobile::isWillcom($userAgent)) {
284            return true;
285        }
286
287        return false;
288    }
289
290    // }}}
291    // {{{ isDoCoMo()
292
293    /**
294     * Checks whether or not the user agent is DoCoMo by a given user agent string.
295     *
296     * @param string $userAgent
297     * @return boolean
298     * @since Method available since Release 0.31.0
299     */
300    function isDoCoMo($userAgent = null)
301    {
302        if (is_null($userAgent)) {
303            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
304        }
305
306        if (preg_match('!^DoCoMo!', $userAgent)) {
307            return true;
308        }
309
310        return false;
311    }
312
313    // }}}
314    // {{{ isEZweb()
315
316    /**
317     * Checks whether or not the user agent is EZweb by a given user agent string.
318     *
319     * @param string $userAgent
320     * @return boolean
321     * @since Method available since Release 0.31.0
322     */
323    function isEZweb($userAgent = null)
324    {
325        if (is_null($userAgent)) {
326            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
327        }
328
329        if (preg_match('!^KDDI-!', $userAgent)) {
330            return true;
331        } elseif (preg_match('!^UP\.Browser!', $userAgent)) {
332            return true;
333        }
334
335        return false;
336    }
337
338    // }}}
339    // {{{ isSoftBank()
340
341    /**
342     * Checks whether or not the user agent is SoftBank by a given user agent string.
343     *
344     * @param string $userAgent
345     * @return boolean
346     * @since Method available since Release 0.31.0
347     */
348    function isSoftBank($userAgent = null)
349    {
350        if (is_null($userAgent)) {
351            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
352        }
353
354        if (preg_match('!^SoftBank!', $userAgent)) {
355            return true;
356        } elseif (preg_match('!^Semulator!', $userAgent)) {
357            return true;
358        } elseif (preg_match('!^Vodafone!', $userAgent)) {
359            return true;
360        } elseif (preg_match('!^Vemulator!', $userAgent)) {
361            return true;
362        } elseif (preg_match('!^MOT-!', $userAgent)) {
363            return true;
364        } elseif (preg_match('!^MOTEMULATOR!', $userAgent)) {
365            return true;
366        } elseif (preg_match('!^J-PHONE!', $userAgent)) {
367            return true;
368        } elseif (preg_match('!^J-EMULATOR!', $userAgent)) {
369            return true;
370        }
371
372        return false;
373    }
374
375    // }}}
376    // {{{ isWillcom()
377
378    /**
379     * Checks whether or not the user agent is Willcom by a given user agent string.
380     *
381     * @param string $userAgent
382     * @return boolean
383     * @since Method available since Release 0.31.0
384     */
385    function isWillcom($userAgent = null)
386    {
387        if (is_null($userAgent)) {
388            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
389        }
390
391        if (preg_match('!^Mozilla/3\.0\((?:DDIPOCKET|WILLCOM);!', $userAgent)) {
392            return true;
393        }
394
395        return false;
396    }
397
398    // }}}
399    // {{{ isSmartphone()
400
401    /**
402     * Checks whether or not the user agent is Smartphone by a given user agent string.
403     *
404     * @param string $userAgent
405     * @return boolean
406     * @since Method available since Release 0.31.0
407     */
408    function isSmartphone($userAgent = null)
409    {
410        if (is_null($userAgent)) {
411            $userAgent = @$_SERVER['HTTP_USER_AGENT'];
412        }
413
414        $useragents = array(
415            'iPhone',         // Apple iPhone
416            'iPod',           // Apple iPod touch
417            'Android',        // 1.5+ Android
418            'dream',          // Pre 1.5 Android
419            'CUPCAKE',        // 1.5+ Android
420            'blackberry9500', // Storm
421            'blackberry9530', // Storm
422            'blackberry9520', // Storm v2
423            'blackberry9550', // Storm v2
424            'blackberry9800', // Torch
425            'webOS',          // Palm Pre Experimental
426            'incognito',      // Other iPhone browser
427            'webmate'         // Other iPhone browser
428        );
429
430        $pattern = implode("|", $useragents);
431        return preg_match('/'.$pattern.'/', $userAgent);
432    }
433
434    /**#@-*/
435
436    /**#@+
437     * @access private
438     */
439
440    /**#@-*/
441
442    // }}}
443}
444
445// }}}
446
447/*
448 * Local Variables:
449 * mode: php
450 * coding: iso-8859-1
451 * tab-width: 4
452 * c-basic-offset: 4
453 * c-hanging-comment-ender-p: nil
454 * indent-tabs-mode: nil
455 * End:
456 */
Note: See TracBrowser for help on using the repository browser.