source: branches/rel/data/module/Net/UserAgent/Mobile/DoCoMo.php @ 12157

Revision 12157, 15.2 KB checked in by uehara, 17 years ago (diff)
Line 
1<?php
2/* vim: set expandtab tabstop=4 shiftwidth=4: */
3
4/**
5 * PHP versions 4 and 5
6 *
7 * LICENSE: This source file is subject to version 3.0 of the PHP license
8 * that is available through the world-wide-web at the following URI:
9 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
10 * the PHP License and are unable to obtain it through the web, please
11 * send a note to license@php.net so we can mail you a copy immediately.
12 *
13 * @category   Networking
14 * @package    Net_UserAgent_Mobile
15 * @author     KUBO Atsuhiro <iteman@users.sourceforge.net>
16 * @copyright  2003-2007 KUBO Atsuhiro <iteman@users.sourceforge.net>
17 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
18 * @version    CVS: $Id: DoCoMo.php,v 1.35 2007/02/20 18:41:04 kuboa Exp $
19 * @link       http://www.nttdocomo.co.jp/service/imode/make/content/spec/useragent/index.html
20 * @see        Net_UserAgent_Mobile_Common
21 * @since      File available since Release 0.1
22 */
23
24require_once dirname(__FILE__) . '/Common.php';
25require_once dirname(__FILE__) . '/Display.php';
26require_once dirname(__FILE__) . '/DoCoMoDisplayMap.php';
27
28// {{{ Net_UserAgent_Mobile_DoCoMo
29
30/**
31 * NTT DoCoMo implementation
32 *
33 * Net_UserAgent_Mobile_DoCoMo is a subclass of
34 * {@link Net_UserAgent_Mobile_Common}, which implements NTT docomo i-mode
35 * user agents.
36 *
37 * SYNOPSIS:
38 * <code>
39 * require_once 'Net/UserAgent/Mobile.php';
40 *
41 * $_SERVER['HTTP_USER_AGENT'] = 'DoCoMo/1.0/P502i/c10';
42 * $agent = &Net_UserAgent_Mobile::factory();
43 *
44 * printf("Name: %s\n", $agent->getName()); // 'DoCoMo'
45 * printf("Version: %s\n", $agent->getVersion()); // 1.0
46 * printf("HTML version: %s\n", $agent->getHTMLVersion()); // 2.0
47 * printf("Model: %s\n", $agent->getModel()); // 'P502i'
48 * printf("Cache: %dk\n", $agent->getCacheSize()); // 10
49 * if ($agent->isFOMA()) {
50 *     print "FOMA\n";             // false
51 * }
52 * printf("Vendor: %s\n", $agent->getVendor()); // 'P'
53 * printf("Series: %s\n", $agent->getSeries()); // '502i'
54 *
55 * // only available with <form utn>
56 * // e.g.) 'DoCoMo/1.0/P503i/c10/serNMABH200331';
57 * printf("Serial: %s\n", $agent->getSerialNumber()); // 'NMABH200331'
58 *
59 * // e.g.) 'DoCoMo/2.0 N2001(c10;ser0123456789abcde;icc01234567890123456789)';
60 * printf("Serial: %s\n", $agent->getSerialNumber()); // '0123456789abcde'
61 * printf("Card ID: %s\n", $agent->getCardID()); // '01234567890123456789'
62 *
63 * // e.g.) 'DoCoMo/1.0/P502i (Google CHTML Proxy/1.0)'
64 * printf("Comment: %s\n", $agent->getComment()); // 'Google CHTML Proxy/1.0'
65 *
66 * // e.g.) 'DoCoMo/1.0/D505i/c20/TB/W20H10'
67 * printf("Status: %s\n", $agent->getStatus()); // 'TB'
68 *
69 * // only available in eggy/M-stage
70 * // e.g.) 'DoCoMo/1.0/eggy/c300/s32/kPHS-K'
71 * printf("Bandwidth: %dkbps\n", $agent->getBandwidth()); // 32
72 * </code>
73 *
74 * @category   Networking
75 * @package    Net_UserAgent_Mobile
76 * @author     KUBO Atsuhiro <iteman@users.sourceforge.net>
77 * @copyright  2003-2007 KUBO Atsuhiro <iteman@users.sourceforge.net>
78 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
79 * @version    Release: 0.30.0
80 * @link       http://www.nttdocomo.co.jp/service/imode/make/content/spec/useragent/index.html
81 * @see        Net_UserAgent_Mobile_Common
82 * @since      Class available since Release 0.1
83 */
84class Net_UserAgent_Mobile_DoCoMo extends Net_UserAgent_Mobile_Common
85{
86
87    // {{{ properties
88
89    /**#@+
90     * @access public
91     */
92
93    /**#@-*/
94
95    /**#@+
96     * @access private
97     */
98
99    /**
100     * name of the model like 'P502i'
101     * @var string
102     */
103    var $_model = '';
104
105    /**
106     * status of the cache (TC, TB, TD, TJ)
107     * @var string
108     */
109    var $_status = '';
110
111    /**
112     * bandwidth like 32 as kilobytes unit
113     * @var integer
114     */
115    var $_bandwidth = null;
116
117    /**
118     * hardware unique serial number
119     * @var string
120     */
121    var $_serialNumber = null;
122
123    /**
124     * whether it's FOMA or not
125     * @var boolean
126     */
127    var $_isFOMA = false;
128
129    /**
130     * FOMA Card ID (20 digit alphanumeric)
131     * @var string
132     */
133    var $_cardID = null;
134
135    /**
136     * comment on user agent string like 'Google Proxy'
137     * @var string
138     */
139    var $_comment = null;
140
141    /**
142     * cache size as killobytes unit
143     * @var integer
144     */
145    var $_cacheSize;
146
147    /**
148     * width and height of the display
149     * @var string
150     */
151    var $_displayBytes = '';
152
153    /**#@-*/
154
155    /**#@+
156     * @access public
157     */
158
159    // }}}
160    // {{{ isDoCoMo()
161
162    /**
163     * returns true
164     *
165     * @return boolean
166     */
167    function isDoCoMo()
168    {
169        return true;
170    }
171
172    // }}}
173    // {{{ parse()
174
175    /**
176     * parse HTTP_USER_AGENT string
177     *
178     * @return mixed void, or a PEAR error object on error
179     */
180    function parse()
181    {
182        @list($main, $foma_or_comment) =
183            explode(' ', $this->getUserAgent(), 2);
184
185        if ($foma_or_comment
186            && preg_match('/^\((.*)\)$/', $foma_or_comment, $matches)
187            ) {
188
189            // DoCoMo/1.0/P209is (Google CHTML Proxy/1.0)
190            $this->_comment = $matches[1];
191            $result = $this->_parseMain($main);
192        } elseif ($foma_or_comment) {
193
194            // DoCoMo/2.0 N2001(c10;ser0123456789abcde;icc01234567890123456789)
195            $this->_isFOMA = true;
196            list($this->name, $this->version) = explode('/', $main);
197            $result = $this->_parseFOMA($foma_or_comment);
198        } else {
199
200            // DoCoMo/1.0/R692i/c10
201            $result = $this->_parseMain($main);
202        }
203
204        if (Net_UserAgent_Mobile::isError($result)) {
205            return $result;
206        }
207    }
208
209    // }}}
210    // {{{ makeDisplay()
211
212    /**
213     * create a new {@link Net_UserAgent_Mobile_Display} class instance
214     *
215     * @return object a newly created {@link Net_UserAgent_Mobile_Display}
216     *     object
217     * @see Net_UserAgent_Mobile_Display
218     * @see Net_UserAgent_Mobile_DoCoMoDisplayMap::get()
219     */
220    function makeDisplay()
221    {
222        $display = Net_UserAgent_Mobile_DoCoMoDisplayMap::get($this->_model);
223        if ($this->_displayBytes !== '') {
224            list($widthBytes, $heightBytes) =
225                explode('*', $this->_displayBytes);
226            $display['width_bytes']  = $widthBytes;
227            $display['height_bytes'] = $heightBytes;
228        }
229        return new Net_UserAgent_Mobile_Display($display);
230    }
231
232    // }}}
233    // {{{ getHTMLVersion()
234
235    /**
236     * returns supported HTML version like '3.0'. retuns null if unknown.
237     *
238     * @return string
239     */
240    function getHTMLVersion()
241    {
242        static $htmlVersionMap;
243        if (!isset($htmlVersionMap)) {
244            $htmlVersionMap = array(
245                                    '[DFNP]501i' => '1.0',
246                                    '502i|821i|209i|651|691i|(F|N|P|KO)210i|^F671i$' => '2.0',
247                                    '(D210i|SO210i)|503i|211i|SH251i|692i|200[12]|2101V' => '3.0',
248                                    '504i|251i|^F671iS$|212i|2051|2102V|661i|2701|672i|SO213i|850i' => '4.0',
249                                    'eggy|P751v' => '3.2',
250                                    '505i|252i|900i|506i|880i|253i|P213i|901i|700i|851i|701i|881i|^SA800i$|600i|^L601i$|^M702i(S|G)$' => '5.0',
251                                    '902i|702i|851i|882i|^N601i$|^D800iDS$|^P703imyu$' => '6.0',
252                                    '903i|703i' => '7.0'
253                                    );
254        }
255
256        foreach ($htmlVersionMap as $key => $value) {
257            if (preg_match("/$key/", $this->_model)) {
258                return $value;
259            }
260        }
261        return null;
262    }
263
264    // }}}
265    // {{{ getCacheSize()
266
267    /**
268     * returns cache size as kilobytes unit. returns 5 if unknown.
269     *
270     * @return integer
271     */
272    function getCacheSize()
273    {
274        if ($this->_cacheSize) {
275            return $this->_cacheSize;
276        }
277
278        static $defaultCacheSize;
279        if (!isset($defaultCacheSize)) {
280            $defaultCacheSize = 5;
281        }
282        return $defaultCacheSize;
283    }
284
285    // }}}
286    // {{{ getSeries()
287
288    /**
289     * returns series name like '502i'. returns null if unknown.
290     *
291     * @return string
292     */
293    function getSeries()
294    {
295        if ($this->isFOMA() && preg_match('/(\d{4})/', $this->_model)) {
296            return 'FOMA';
297        }
298
299        if (preg_match('/(\d{3}i)/', $this->_model, $matches)) {
300            return $matches[1];
301        }
302
303        if ($this->_model == 'P651ps') {
304            return '651';
305        }
306
307        return null;
308    }
309
310    // }}}
311    // {{{ getVendor()
312
313    /**
314     * returns vender code like 'SO' for Sony. returns null if unknown.
315     *
316     * @return string
317     */
318    function getVendor()
319    {
320        if (preg_match('/([A-Z]+)\d/', $this->_model, $matches)) {
321            return $matches[1];
322        }
323        return null;
324    }
325
326    // }}}
327    // {{{ getModel()
328
329    /**
330     * returns name of the model like 'P502i'
331     *
332     * @return string
333     */
334    function getModel()
335    {
336        return $this->_model;
337    }
338
339    // }}}
340    // {{{ getStatus()
341
342    /**
343     * returns status like "TB", "TC", "TD" or "TJ", which means:
344     *
345     * TB | Browsers
346     * TC | Browsers with image off (only Available in HTML 5.0)
347     * TD | Fetching JAR
348     * TJ | i-Appli
349     *
350     * @return string
351     */
352    function getStatus()
353    {
354        return $this->_status;
355    }
356
357    // }}}
358    // {{{ getBandwidth()
359
360    /**
361     * returns bandwidth like 32 as killobytes unit. Only vailable in eggy,
362     * returns null otherwise.
363     *
364     * @return integer
365     */
366    function getBandwidth()
367    {
368        return $this->_bandwidth;
369    }
370
371    // }}}
372    // {{{ getSerialNumber()
373
374    /**
375     * returns hardware unique serial number (15 digit in FOMA, 11 digit
376     * otherwise alphanumeric). Only available with form utn attribute.
377     * returns null otherwise.
378     *
379     * @return string
380     */
381    function getSerialNumber()
382    {
383        return $this->_serialNumber;
384    }
385
386    // }}}
387    // {{{ isFOMA()
388
389    /**
390     * retuns whether it's FOMA or not
391     *
392     * @return boolean
393     */
394    function isFOMA()
395    {
396        return $this->_isFOMA;
397    }
398
399    // }}}
400    // {{{ getComment()
401
402    /**
403     * returns comment on user agent string like 'Google Proxy'. returns null
404     * otherwise.
405     *
406     * @return string
407     */
408    function getComment()
409    {
410        return $this->_comment;
411    }
412
413    // }}}
414    // {{{ getCardID()
415
416    /**
417     * returns FOMA Card ID (20 digit alphanumeric). Only available in FOMA
418     * with <form utn> attribute. returns null otherwise.
419     *
420     * @return string
421     */
422    function getCardID()
423    {
424        return $this->_cardID;
425    }
426
427    // }}}
428    // {{{ isGPS()
429
430    /**
431     * @return boolean
432     */
433    function isGPS()
434    {
435        static $gpsModels;
436        if (!isset($gpsModels)) {
437            $gpsModels = array('F661i', 'F505iGPS');
438        }
439        return in_array($this->_model, $gpsModels);
440    }
441
442    // }}}
443    // {{{ getCarrierShortName()
444
445    /**
446     * returns the short name of the carrier
447     *
448     * @return string
449     */
450    function getCarrierShortName()
451    {
452        return 'I';
453    }
454
455    // }}}
456    // {{{ getCarrierLongName()
457
458    /**
459     * returns the long name of the carrier
460     *
461     * @return string
462     */
463    function getCarrierLongName()
464    {
465        return 'DoCoMo';
466    }
467
468    /**#@-*/
469
470    /**#@+
471     * @access private
472     */
473
474    // }}}
475    // {{{ _parseMain()
476
477    /**
478     * parse main part of HTTP_USER_AGENT string (not FOMA)
479     *
480     * @param string $main main part of HTTP_USER_AGENT string
481     * @return mixed void, or a PEAR error object on error
482     */
483    function _parseMain($main)
484    {
485        @list($this->name, $this->version, $this->_model, $cache, $rest) =
486            explode('/', $main, 5);
487        if ($this->_model === 'SH505i2') {
488            $this->_model = 'SH505i';
489        }
490
491        if ($cache) {
492            if (!preg_match('/^c(\d+)/', $cache, $matches)) {
493                return $this->noMatch();
494            }
495            $this->_cacheSize = (integer)$matches[1];
496        }
497
498        if ($rest) {
499            $rest = explode('/', $rest);
500            foreach ($rest as $value) {
501                if (preg_match('/^ser(\w{11})$/', $value, $matches)) {
502                    $this->_serialNumber = $matches[1];
503                    continue;
504                }
505                if (preg_match('/^(T[CDBJ])$/', $value, $matches)) {
506                    $this->_status = $matches[1];
507                    continue;
508                }
509                if (preg_match('/^s(\d+)$/', $value, $matches)) {
510                    $this->_bandwidth = (integer)$matches[1];
511                    continue;
512                }
513                if (preg_match('/^W(\d+)H(\d+)$/', $value, $matches)) {
514                    $this->_displayBytes = "{$matches[1]}*{$matches[2]}";
515                    continue;
516                }
517            }
518        }
519    }
520
521    // }}}
522    // {{{ _parseFOMA()
523
524    /**
525     * parse main part of HTTP_USER_AGENT string (FOMA)
526     *
527     * @param string $foma main part of HTTP_USER_AGENT string
528     * @return mixed void, or a PEAR error object on error
529     */
530    function _parseFOMA($foma)
531    {
532        if (!preg_match('/^([^(]+)/', $foma, $matches)) {
533            return $this->noMatch();
534        }
535        $this->_model = $matches[1];
536        if ($matches[1] === 'MST_v_SH2101V') {
537            $this->_model = 'SH2101V';
538        }
539
540        if (preg_match('/^[^(]+\((.*?)\)$/', $foma, $matches)) {
541            $rest = explode(';', $matches[1]);
542            foreach ($rest as $value) {
543                if (preg_match('/^c(\d+)/', $value, $matches)) {
544                    $this->_cacheSize = (integer)$matches[1];
545                    continue;
546                }
547                if (preg_match('/^ser(\w{15})$/', $value, $matches)) {
548                    $this->_serialNumber = $matches[1];
549                    continue;
550                }
551                if (preg_match('/^(T[CDBJ])$/', $value, $matches)) {
552                    $this->_status = $matches[1];
553                    continue;
554                }
555                if (preg_match('/^icc(\w{20})?$/', $value, $matches)) {
556                    if (count($matches) == 2) {
557                        $this->_cardID = $matches[1];
558                    }
559                    continue;
560                }
561                if (preg_match('/^W(\d+)H(\d+)$/', $value, $matches)) {
562                    $this->_displayBytes = "{$matches[1]}*{$matches[2]}";
563                    continue;
564                }
565                return $this->noMatch();
566            }
567        }
568    }
569
570    /**#@-*/
571
572    // }}}
573}
574
575// }}}
576
577/*
578 * Local Variables:
579 * mode: php
580 * coding: iso-8859-1
581 * tab-width: 4
582 * c-basic-offset: 4
583 * c-hanging-comment-ender-p: nil
584 * indent-tabs-mode: nil
585 * End:
586 */
587?>
Note: See TracBrowser for help on using the repository browser.