PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.7
VikBooking Hotel Booking Engine & PMS v1.8.7
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / site / helpers / mobile_detector.php

mobile_detector.php in VikBooking Hotel Booking Engine & PMS 1.8.7, at site/helpers/mobile_detector.php

442 lines 25.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 class MobileDetector {
14 const DETECTION_TYPE_MOBILE = 'mobile';
15 const DETECTION_TYPE_EXTENDED = 'extended';
16 const VER = '([\w._\+]+)';
17 protected $userAgent = null;
18 protected $httpHeaders = array ();
19 protected $detectionType = self::DETECTION_TYPE_MOBILE;
20 protected static $phoneDevices = array (
21 'iPhone' => '\biPhone.*Mobile|\biPod',
22 'BlackBerry' => 'BlackBerry|\bBB10\b|rim[0-9]+',
23 'HTC' => 'HTC|HTC.*(Sensation|Evo|Vision|Explorer|6800|8100|8900|A7272|S510e|C110e|Legend|Desire|T8282)|APX515CKT|Qtek9090|APA9292KT|HD_mini|Sensation.*Z710e|PG86100|Z715e|Desire.*(A8181|HD)|ADR6200|ADR6400L|ADR6425|001HT|Inspire 4G|Android.*\bEVO\b|T-Mobile G1',
24 'Nexus' => 'Nexus One|Nexus S|Galaxy.*Nexus|Android.*Nexus.*Mobile',
25 'Dell' => 'Dell.*Streak|Dell.*Aero|Dell.*Venue|DELL.*Venue Pro|Dell Flash|Dell Smoke|Dell Mini 3iX|XCD28|XCD35|\b001DL\b|\b101DL\b|\bGS01\b',
26 'Motorola' => 'Motorola|\bDroid\b.*Build|DROIDX|Android.*Xoom|HRI39|MOT-|A1260|A1680|A555|A853|A855|A953|A955|A956|Motorola.*ELECTRIFY|Motorola.*i1|i867|i940|MB200|MB300|MB501|MB502|MB508|MB511|MB520|MB525|MB526|MB611|MB612|MB632|MB810|MB855|MB860|MB861|MB865|MB870|ME501|ME502|ME511|ME525|ME600|ME632|ME722|ME811|ME860|ME863|ME865|MT620|MT710|MT716|MT720|MT810|MT870|MT917|Motorola.*TITANIUM|WX435|WX445|XT300|XT301|XT311|XT316|XT317|XT319|XT320|XT390|XT502|XT530|XT531|XT532|XT535|XT603|XT610|XT611|XT615|XT681|XT701|XT702|XT711|XT720|XT800|XT806|XT860|XT862|XT875|XT882|XT883|XT894|XT901|XT907|XT909|XT910|XT912|XT928|XT926|XT915|XT919|XT925',
27 'Samsung' => 'Samsung|SGH-I337|BGT-S5230|GT-B2100|GT-B2700|GT-B2710|GT-B3210|GT-B3310|GT-B3410|GT-B3730|GT-B3740|GT-B5510|GT-B5512|GT-B5722|GT-B6520|GT-B7300|GT-B7320|GT-B7330|GT-B7350|GT-B7510|GT-B7722|GT-B7800|GT-C3010|GT-C3011|GT-C3060|GT-C3200|GT-C3212|GT-C3212I|GT-C3262|GT-C3222|GT-C3300|GT-C3300K|GT-C3303|GT-C3303K|GT-C3310|GT-C3322|GT-C3330|GT-C3350|GT-C3500|GT-C3510|GT-C3530|GT-C3630|GT-C3780|GT-C5010|GT-C5212|GT-C6620|GT-C6625|GT-C6712|GT-E1050|GT-E1070|GT-E1075|GT-E1080|GT-E1081|GT-E1085|GT-E1087|GT-E1100|GT-E1107|GT-E1110|GT-E1120|GT-E1125|GT-E1130|GT-E1160|GT-E1170|GT-E1175|GT-E1180|GT-E1182|GT-E1200|GT-E1210|GT-E1225|GT-E1230|GT-E1390|GT-E2100|GT-E2120|GT-E2121|GT-E2152|GT-E2220|GT-E2222|GT-E2230|GT-E2232|GT-E2250|GT-E2370|GT-E2550|GT-E2652|GT-E3210|GT-E3213|GT-I5500|GT-I5503|GT-I5700|GT-I5800|GT-I5801|GT-I6410|GT-I6420|GT-I7110|GT-I7410|GT-I7500|GT-I8000|GT-I8150|GT-I8160|GT-I8190|GT-I8320|GT-I8330|GT-I8350|GT-I8530|GT-I8700|GT-I8703|GT-I8910|GT-I9000|GT-I9001|GT-I9003|GT-I9010|GT-I9020|GT-I9023|GT-I9070|GT-I9082|GT-I9100|GT-I9103|GT-I9220|GT-I9250|GT-I9300|GT-I9305|GT-I9500|GT-I9505|GT-M3510|GT-M5650|GT-M7500|GT-M7600|GT-M7603|GT-M8800|GT-M8910|GT-N7000|GT-S3110|GT-S3310|GT-S3350|GT-S3353|GT-S3370|GT-S3650|GT-S3653|GT-S3770|GT-S3850|GT-S5210|GT-S5220|GT-S5229|GT-S5230|GT-S5233|GT-S5250|GT-S5253|GT-S5260|GT-S5263|GT-S5270|GT-S5300|GT-S5330|GT-S5350|GT-S5360|GT-S5363|GT-S5369|GT-S5380|GT-S5380D|GT-S5560|GT-S5570|GT-S5600|GT-S5603|GT-S5610|GT-S5620|GT-S5660|GT-S5670|GT-S5690|GT-S5750|GT-S5780|GT-S5830|GT-S5839|GT-S6102|GT-S6500|GT-S7070|GT-S7200|GT-S7220|GT-S7230|GT-S7233|GT-S7250|GT-S7500|GT-S7530|GT-S7550|GT-S7562|GT-S7710|GT-S8000|GT-S8003|GT-S8500|GT-S8530|GT-S8600|SCH-A310|SCH-A530|SCH-A570|SCH-A610|SCH-A630|SCH-A650|SCH-A790|SCH-A795|SCH-A850|SCH-A870|SCH-A890|SCH-A930|SCH-A950|SCH-A970|SCH-A990|SCH-I100|SCH-I110|SCH-I400|SCH-I405|SCH-I500|SCH-I510|SCH-I515|SCH-I600|SCH-I730|SCH-I760|SCH-I770|SCH-I830|SCH-I910|SCH-I920|SCH-I959|SCH-LC11|SCH-N150|SCH-N300|SCH-R100|SCH-R300|SCH-R351|SCH-R400|SCH-R410|SCH-T300|SCH-U310|SCH-U320|SCH-U350|SCH-U360|SCH-U365|SCH-U370|SCH-U380|SCH-U410|SCH-U430|SCH-U450|SCH-U460|SCH-U470|SCH-U490|SCH-U540|SCH-U550|SCH-U620|SCH-U640|SCH-U650|SCH-U660|SCH-U700|SCH-U740|SCH-U750|SCH-U810|SCH-U820|SCH-U900|SCH-U940|SCH-U960|SCS-26UC|SGH-A107|SGH-A117|SGH-A127|SGH-A137|SGH-A157|SGH-A167|SGH-A177|SGH-A187|SGH-A197|SGH-A227|SGH-A237|SGH-A257|SGH-A437|SGH-A517|SGH-A597|SGH-A637|SGH-A657|SGH-A667|SGH-A687|SGH-A697|SGH-A707|SGH-A717|SGH-A727|SGH-A737|SGH-A747|SGH-A767|SGH-A777|SGH-A797|SGH-A817|SGH-A827|SGH-A837|SGH-A847|SGH-A867|SGH-A877|SGH-A887|SGH-A897|SGH-A927|SGH-B100|SGH-B130|SGH-B200|SGH-B220|SGH-C100|SGH-C110|SGH-C120|SGH-C130|SGH-C140|SGH-C160|SGH-C170|SGH-C180|SGH-C200|SGH-C207|SGH-C210|SGH-C225|SGH-C230|SGH-C417|SGH-C450|SGH-D307|SGH-D347|SGH-D357|SGH-D407|SGH-D415|SGH-D780|SGH-D807|SGH-D980|SGH-E105|SGH-E200|SGH-E315|SGH-E316|SGH-E317|SGH-E335|SGH-E590|SGH-E635|SGH-E715|SGH-E890|SGH-F300|SGH-F480|SGH-I200|SGH-I300|SGH-I320|SGH-I550|SGH-I577|SGH-I600|SGH-I607|SGH-I617|SGH-I627|SGH-I637|SGH-I677|SGH-I700|SGH-I717|SGH-I727|SGH-i747M|SGH-I777|SGH-I780|SGH-I827|SGH-I847|SGH-I857|SGH-I896|SGH-I897|SGH-I900|SGH-I907|SGH-I917|SGH-I927|SGH-I937|SGH-I997|SGH-J150|SGH-J200|SGH-L170|SGH-L700|SGH-M110|SGH-M150|SGH-M200|SGH-N105|SGH-N500|SGH-N600|SGH-N620|SGH-N625|SGH-N700|SGH-N710|SGH-P107|SGH-P207|SGH-P300|SGH-P310|SGH-P520|SGH-P735|SGH-P777|SGH-Q105|SGH-R210|SGH-R220|SGH-R225|SGH-S105|SGH-S307|SGH-T109|SGH-T119|SGH-T139|SGH-T209|SGH-T219|SGH-T229|SGH-T239|SGH-T249|SGH-T259|SGH-T309|SGH-T319|SGH-T329|SGH-T339|SGH-T349|SGH-T359|SGH-T369|SGH-T379|SGH-T409|SGH-T429|SGH-T439|SGH-T459|SGH-T469|SGH-T479|SGH-T499|SGH-T509|SGH-T519|SGH-T539|SGH-T559|SGH-T589|SGH-T609|SGH-T619|SGH-T629|SGH-T639|SGH-T659|SGH-T669|SGH-T679|SGH-T709|SGH-T719|SGH-T729|SGH-T739|SGH-T746|SGH-T749|SGH-T759|SGH-T769|SGH-T809|SGH-T819|SGH-T839|SGH-T919|SGH-T929|SGH-T939|SGH-T959|SGH-T989|SGH-U100|SGH-U200|SGH-U800|SGH-V205|SGH-V206|SGH-X100|SGH-X105|SGH-X120|SGH-X140|SGH-X426|SGH-X427|SGH-X475|SGH-X495|SGH-X497|SGH-X507|SGH-X600|SGH-X610|SGH-X620|SGH-X630|SGH-X700|SGH-X820|SGH-X890|SGH-Z130|SGH-Z150|SGH-Z170|SGH-ZX10|SGH-ZX20|SHW-M110|SPH-A120|SPH-A400|SPH-A420|SPH-A460|SPH-A500|SPH-A560|SPH-A600|SPH-A620|SPH-A660|SPH-A700|SPH-A740|SPH-A760|SPH-A790|SPH-A800|SPH-A820|SPH-A840|SPH-A880|SPH-A900|SPH-A940|SPH-A960|SPH-D600|SPH-D700|SPH-D710|SPH-D720|SPH-I300|SPH-I325|SPH-I330|SPH-I350|SPH-I500|SPH-I600|SPH-I700|SPH-L700|SPH-M100|SPH-M220|SPH-M240|SPH-M300|SPH-M305|SPH-M320|SPH-M330|SPH-M350|SPH-M360|SPH-M370|SPH-M380|SPH-M510|SPH-M540|SPH-M550|SPH-M560|SPH-M570|SPH-M580|SPH-M610|SPH-M620|SPH-M630|SPH-M800|SPH-M810|SPH-M850|SPH-M900|SPH-M910|SPH-M920|SPH-M930|SPH-N100|SPH-N200|SPH-N240|SPH-N300|SPH-N400|SPH-Z400|SWC-E100|SCH-i909|GT-N7100|GT-N7105|SCH-I535',
28 'LG' => '\bLG\b;|LG[- ]?(C800|C900|E400|E610|E900|E-900|F160|F180K|F180L|F180S|730|855|L160|LS840|LS970|LU6200|MS690|MS695|MS770|MS840|MS870|MS910|P500|P700|P705|VM696|AS680|AS695|AX840|C729|E970|GS505|272|C395|E739BK|E960|L55C|L75C|LS696|LS860|P769BK|P350|P500|P509|P870|UN272|US730|VS840|VS950|LN272|LN510|LS670|LS855|LW690|MN270|MN510|P509|P769|P930|UN200|UN270|UN510|UN610|US670|US740|US760|UX265|UX840|VN271|VN530|VS660|VS700|VS740|VS750|VS910|VS920|VS930|VX9200|VX11000|AX840A|LW770|P506|P925|P999)',
29 'Sony' => 'SonyST|SonyLT|SonyEricsson|SonyEricssonLT15iv|LT18i|E10i|LT28h|LT26w|SonyEricssonMT27i',
30 'Asus' => 'Asus.*Galaxy|PadFone.*Mobile',
31 'Micromax' => 'Micromax.*\b(A210|A92|A88|A72|A111|A110Q|A115|A116|A110|A90S|A26|A51|A35|A54|A25|A27|A89|A68|A65|A57|A90)\b',
32 'Palm' => 'PalmSource|Palm',
33 'Pantech' => 'PANTECH|IM-A850S|IM-A840S|IM-A830L|IM-A830K|IM-A830S|IM-A820L|IM-A810K|IM-A810S|IM-A800S|IM-T100K|IM-A725L|IM-A780L|IM-A775C|IM-A770K|IM-A760S|IM-A750K|IM-A740S|IM-A730S|IM-A720L|IM-A710K|IM-A690L|IM-A690S|IM-A650S|IM-A630K|IM-A600S|VEGA PTL21|PT003|P8010|ADR910L|P6030|P6020|P9070|P4100|P9060|P5000|CDM8992|TXT8045|ADR8995|IS11PT|P2030|P6010|P8000|PT002|IS06|CDM8999|P9050|PT001|TXT8040|P2020|P9020|P2000|P7040|P7000|C790',
34 'Fly' => 'IQ230|IQ444|IQ450|IQ440|IQ442|IQ441|IQ245|IQ256|IQ236|IQ255|IQ235|IQ245|IQ275|IQ240|IQ285|IQ280|IQ270|IQ260|IQ250',
35 'SimValley' => '\b(SP-80|XT-930|SX-340|XT-930|SX-310|SP-360|SP60|SPT-800|SP-120|SPT-800|SP-140|SPX-5|SPX-8|SP-100|SPX-8|SPX-12)\b',
36 'GenericPhone' => 'Tapatalk|PDA;|SAGEM|\bmmp\b|pocket|\bpsp\b|symbian|Smartphone|smartfon|treo|up.browser|up.link|vodafone|\bwap\b|nokia|Series40|Series60|S60|SonyEricsson|N900|MAUI.*WAP.*Browser'
37 );
38 protected static $tabletDevices = array (
39 'iPad' => 'iPad|iPad.*Mobile',
40 'NexusTablet' => '^.*Android.*Nexus(((?:(?!Mobile))|(?:(\s(7|10).+))).)*$',
41 'SamsungTablet' => 'SAMSUNG.*Tablet|Galaxy.*Tab|SC-01C|GT-P1000|GT-P1003|GT-P1010|GT-P3105|GT-P6210|GT-P6800|GT-P6810|GT-P7100|GT-P7300|GT-P7310|GT-P7500|GT-P7510|SCH-I800|SCH-I815|SCH-I905|SGH-I957|SGH-I987|SGH-T849|SGH-T859|SGH-T869|SPH-P100|GT-P3100|GT-P3108|GT-P3110|GT-P5100|GT-P5110|GT-P6200|GT-P7320|GT-P7511|GT-N8000|GT-P8510|SGH-I497|SPH-P500|SGH-T779|SCH-I705|SCH-I915|GT-N8013|GT-P3113|GT-P5113|GT-P8110|GT-N8010|GT-N8005|GT-N8020|GT-P1013|GT-P6201|GT-P7501|GT-N5100|GT-N5110|SHV-E140K|SHV-E140L|SHV-E140S|SHV-E150S|SHV-E230K|SHV-E230L|SHV-E230S|SHW-M180K|SHW-M180L|SHW-M180S|SHW-M180W|SHW-M300W|SHW-M305W|SHW-M380K|SHW-M380S|SHW-M380W|SHW-M430W|SHW-M480K|SHW-M480S|SHW-M480W|SHW-M485W|SHW-M486W|SHW-M500W|GT-I9228|SCH-P739|SCH-I925|GT-I9200|GT-I9205|GT-P5200|GT-P5210|SM-T311|SM-T310|SM-T210|SM-T211|SM-P900',
42 'Kindle' => 'Kindle|Silk.*Accelerated|Android.*\b(KFTT|KFOTE|WFJWAE)\b',
43 'SurfaceTablet' => 'Windows NT [0-9.]+; ARM;',
44 'HPTablet' => 'HP Slate 7|HP ElitePad 900|hp-tablet|EliteBook.*Touch',
45 'AsusTablet' => '^.*PadFone((?!Mobile).)*$|Transformer|TF101|TF101G|TF300T|TF300TG|TF300TL|TF700T|TF700KL|TF701T|TF810C|ME171|ME301T|ME371MG|ME370T|ME372MG|ME172V|ME173X|ME400C|Slider SL101',
46 'BlackBerryTablet' => 'PlayBook|RIM Tablet',
47 'HTCtablet' => 'HTC Flyer|HTC Jetstream|HTC-P715a|HTC EVO View 4G|PG41200',
48 'MotorolaTablet' => 'xoom|sholest|MZ615|MZ605|MZ505|MZ601|MZ602|MZ603|MZ604|MZ606|MZ607|MZ608|MZ609|MZ615|MZ616|MZ617',
49 'NookTablet' => 'Android.*Nook|NookColor|nook browser|BNRV200|BNRV200A|BNTV250|BNTV250A|BNTV400|BNTV600|LogicPD Zoom2',
50 'AcerTablet' => 'Android.*; \b(A100|A101|A110|A200|A210|A211|A500|A501|A510|A511|A700|A701|W500|W500P|W501|W501P|W510|W511|W700|G100|G100W|B1-A71|B1-710|B1-711|A1-810)\b|W3-810',
51 'ToshibaTablet' => 'Android.*(AT100|AT105|AT200|AT205|AT270|AT275|AT300|AT305|AT1S5|AT500|AT570|AT700|AT830)|TOSHIBA.*FOLIO',
52 'LGTablet' => '\bL-06C|LG-V900|LG-V909\b',
53 'FujitsuTablet' => 'Android.*\b(F-01D|F-05E|F-10D|M532|Q572)\b',
54 'PrestigioTablet' => 'PMP3170B|PMP3270B|PMP3470B|PMP7170B|PMP3370B|PMP3570C|PMP5870C|PMP3670B|PMP5570C|PMP5770D|PMP3970B|PMP3870C|PMP5580C|PMP5880D|PMP5780D|PMP5588C|PMP7280C|PMP7280|PMP7880D|PMP5597D|PMP5597|PMP7100D|PER3464|PER3274|PER3574|PER3884|PER5274|PER5474|PMP5097CPRO|PMP5097|PMP7380D',
55 'LenovoTablet' => 'IdeaTab|S2110|S6000|K3011|A3000|A1000|A2107|A2109|A1107',
56 'YarvikTablet' => 'Android.*(TAB210|TAB211|TAB224|TAB250|TAB260|TAB264|TAB310|TAB360|TAB364|TAB410|TAB411|TAB420|TAB424|TAB450|TAB460|TAB461|TAB464|TAB465|TAB467|TAB468)',
57 'MedionTablet' => 'Android.*\bOYO\b|LIFE.*(P9212|P9514|P9516|S9512)|LIFETAB',
58 'ArnovaTablet' => 'AN10G2|AN7bG3|AN7fG3|AN8G3|AN8cG3|AN7G3|AN9G3|AN7dG3|AN7dG3ST|AN7dG3ChildPad|AN10bG3|AN10bG3DT',
59 'IRUTablet' => 'M702pro',
60 'MegafonTablet' => 'MegaFon V9|ZTE V9',
61 'EbodaTablet' => 'E-Boda (Supreme|Impresspeed|Izzycomm|Essential)',
62 'AllViewTablet' => 'Allview.*(Viva|Alldro|City|Speed|All TV|Frenzy|Quasar|Shine|TX1|AX1|AX2)',
63 'ArchosTablet' => '\b(101G9|80G9|A101IT)\b',
64 'AinolTablet' => 'NOVO7|NOVO8|NOVO10|Novo7Aurora|Novo7Basic|NOVO7PALADIN|novo9-Spark',
65 'SonyTablet' => 'Sony.*Tablet|Xperia Tablet|Sony Tablet S|SO-03E|SGPT12|SGPT121|SGPT122|SGPT123|SGPT111|SGPT112|SGPT113|SGPT211|SGPT213|SGP311|SGP312|SGP321|EBRD1101|EBRD1102|EBRD1201',
66 'CubeTablet' => 'Android.*(K8GT|U9GT|U10GT|U16GT|U17GT|U18GT|U19GT|U20GT|U23GT|U30GT)|CUBE U8GT',
67 'CobyTablet' => 'MID1042|MID1045|MID1125|MID1126|MID7012|MID7014|MID7015|MID7034|MID7035|MID7036|MID7042|MID7048|MID7127|MID8042|MID8048|MID8127|MID9042|MID9740|MID9742|MID7022|MID7010',
68 'MIDTablet' => 'M9701|M9000|M9100|M806|M1052|M806|T703|MID701|MID713|MID710|MID727|MID760|MID830|MID728|MID933|MID125|MID810|MID732|MID120|MID930|MID800|MID731|MID900|MID100|MID820|MID735|MID980|MID130|MID833|MID737|MID960|MID135|MID860|MID736|MID140|MID930|MID835|MID733',
69 'SMiTTablet' => 'Android.*(\bMID\b|MID-560|MTV-T1200|MTV-PND531|MTV-P1101|MTV-PND530)',
70 'RockChipTablet' => 'Android.*(RK2818|RK2808A|RK2918|RK3066)|RK2738|RK2808A',
71 'FlyTablet' => 'IQ310|Fly Vision',
72 'bqTablet' => 'bq.*(Elcano|Curie|Edison|Maxwell|Kepler|Pascal|Tesla|Hypatia|Platon|Newton|Livingstone|Cervantes|Avant)|Maxwell.*Lite|Maxwell.*Plus',
73 'HuaweiTablet' => 'MediaPad|IDEOS S7|S7-201c|S7-202u|S7-101|S7-103|S7-104|S7-105|S7-106|S7-201|S7-Slim',
74 'NecTablet' => '\bN-06D|\bN-08D',
75 'PantechTablet' => 'Pantech.*P4100',
76 'BronchoTablet' => 'Broncho.*(N701|N708|N802|a710)',
77 'VersusTablet' => 'TOUCHPAD.*[78910]|\bTOUCHTAB\b',
78 'ZyncTablet' => 'z1000|Z99 2G|z99|z930|z999|z990|z909|Z919|z900',
79 'PositivoTablet' => 'TB07STA|TB10STA|TB07FTA|TB10FTA',
80 'NabiTablet' => 'Android.*\bNabi',
81 'KoboTablet' => 'Kobo Touch|\bK080\b|\bVox\b Build|\bArc\b Build',
82 'DanewTablet' => 'DSlide.*\b(700|701R|702|703R|704|802|970|971|972|973|974|1010|1012)\b',
83 'TexetTablet' => 'NaviPad|TB-772A|TM-7045|TM-7055|TM-9750|TM-7016|TM-7024|TM-7026|TM-7041|TM-7043|TM-7047|TM-8041|TM-9741|TM-9747|TM-9748|TM-9751|TM-7022|TM-7021|TM-7020|TM-7011|TM-7010|TM-7023|TM-7025|TM-7037W|TM-7038W|TM-7027W|TM-9720|TM-9725|TM-9737W|TM-1020|TM-9738W|TM-9740|TM-9743W|TB-807A|TB-771A|TB-727A|TB-725A|TB-719A|TB-823A|TB-805A|TB-723A|TB-715A|TB-707A|TB-705A|TB-709A|TB-711A|TB-890HD|TB-880HD|TB-790HD|TB-780HD|TB-770HD|TB-721HD|TB-710HD|TB-434HD|TB-860HD|TB-840HD|TB-760HD|TB-750HD|TB-740HD|TB-730HD|TB-722HD|TB-720HD|TB-700HD|TB-500HD|TB-470HD|TB-431HD|TB-430HD|TB-506|TB-504|TB-446|TB-436|TB-416|TB-146SE|TB-126SE',
84 'PlaystationTablet' => 'Playstation.*(Portable|Vita)',
85 'GalapadTablet' => 'Android.*\bG1\b',
86 'MicromaxTablet' => 'Funbook|Micromax.*\b(P250|P560|P360|P362|P600|P300|P350|P500|P275)\b',
87 'KarbonnTablet' => 'Android.*\b(A39|A37|A34|ST8|ST10|ST7|Smart Tab3|Smart Tab2)\b',
88 'AllFineTablet' => 'Fine7 Genius|Fine7 Shine|Fine7 Air|Fine8 Style|Fine9 More|Fine10 Joy|Fine11 Wide',
89 'PROSCANTablet' => '\b(PEM63|PLT1023G|PLT1041|PLT1044|PLT1044G|PLT1091|PLT4311|PLT4311PL|PLT4315|PLT7030|PLT7033|PLT7033D|PLT7035|PLT7035D|PLT7044K|PLT7045K|PLT7045KB|PLT7071KG|PLT7072|PLT7223G|PLT7225G|PLT7777G|PLT7810K|PLT7849G|PLT7851G|PLT7852G|PLT8015|PLT8031|PLT8034|PLT8036|PLT8080K|PLT8082|PLT8088|PLT8223G|PLT8234G|PLT8235G|PLT8816K|PLT9011|PLT9045K|PLT9233G|PLT9735|PLT9760G|PLT9770G)\b',
90 'YONESTablet' => 'BQ1078|BC1003|BC1077|RK9702|BC9730|BC9001|IT9001|BC7008|BC7010|BC708|BC728|BC7012|BC7030|BC7027|BC7026',
91 'ChangJiaTablet' => 'TPC7102|TPC7103|TPC7105|TPC7106|TPC7107|TPC7201|TPC7203|TPC7205|TPC7210|TPC7708|TPC7709|TPC7712|TPC7110|TPC8101|TPC8103|TPC8105|TPC8106|TPC8203|TPC8205|TPC8503|TPC9106|TPC9701|TPC97101|TPC97103|TPC97105|TPC97106|TPC97111|TPC97113|TPC97203|TPC97603|TPC97809|TPC97205|TPC10101|TPC10103|TPC10106|TPC10111|TPC10203|TPC10205|TPC10503',
92 'GUTablet' => 'TX-A1301|TX-M9002|Q702',
93 'PointOfViewTablet' => 'TAB-P506|TAB-navi-7-3G-M|TAB-P517|TAB-P-527|TAB-P701|TAB-P703|TAB-P721|TAB-P731N|TAB-P741|TAB-P825|TAB-P905|TAB-P925|TAB-PR945|TAB-PL1015|TAB-P1025|TAB-PI1045|TAB-P1325|TAB-PROTAB[0-9]+|TAB-PROTAB25|TAB-PROTAB26|TAB-PROTAB27|TAB-PROTAB26XL|TAB-PROTAB2-IPS9|TAB-PROTAB30-IPS9|TAB-PROTAB25XXL|TAB-PROTAB26-IPS10|TAB-PROTAB30-IPS10',
94 'OvermaxTablet' => 'OV-(SteelCore|NewBase|Basecore|Baseone|Exellen|Quattor|EduTab|Solution|ACTION|BasicTab|TeddyTab|MagicTab|Stream|TB-08|TB-09)',
95 'HCLTablet' => 'HCL.*Tablet|Connect-3G-2.0|Connect-2G-2.0|ME Tablet U1|ME Tablet U2|ME Tablet G1|ME Tablet X1|ME Tablet Y2|ME Tablet Sync',
96 'DPSTablet' => 'DPS Dream 9|DPS Dual 7',
97 'TelstraTablet' => 'T-Hub2',
98 'GenericTablet' => 'Android.*\b97D\b|Tablet(?!.*PC)|ViewPad7|BNTV250A|MID-WCDMA|LogicPD Zoom2|\bA7EB\b|CatNova8|A1_07|CT704|CT1002|\bM721\b|rk30sdk|\bEVOTAB\b|SmartTabII10',
99
100 );
101 protected static $operatingSystems = array (
102 'AndroidOS' => 'Android',
103 'BlackBerryOS' => 'blackberry|\bBB10\b|rim tablet os',
104 'PalmOS' => 'PalmOS|avantgo|blazer|elaine|hiptop|palm|plucker|xiino',
105 'SymbianOS' => 'Symbian|SymbOS|Series60|Series40|SYB-[0-9]+|\bS60\b',
106 'WindowsMobileOS' => 'Windows CE.*(PPC|Smartphone|Mobile|[0-9]{3}x[0-9]{3})|Window Mobile|Windows Phone [0-9.]+|WCE;',
107 'WindowsPhoneOS' => 'Windows Phone 8.0|Windows Phone OS|XBLWP7|ZuneWP7',
108 'iOS' => '\biPhone.*Mobile|\biPod|\biPad',
109 'MeeGoOS' => 'MeeGo',
110 'MaemoOS' => 'Maemo',
111 'JavaOS' => 'J2ME/|\bMIDP\b|\bCLDC\b',
112 'webOS' => 'webOS|hpwOS',
113 'badaOS' => '\bBada\b',
114 'BREWOS' => 'BREW',
115
116 );
117 protected static $browsers = array (
118 'Chrome' => '\bCrMo\b|CriOS|Android.*Chrome/[.0-9]* (Mobile)?',
119 'Dolfin' => '\bDolfin\b',
120 'Opera' => 'Opera.*Mini|Opera.*Mobi|Android.*Opera|Mobile.*OPR/[0-9.]+|Coast/[0-9.]+',
121 'Skyfire' => 'Skyfire',
122 'IE' => 'IEMobile|MSIEMobile',
123 'Firefox' => 'fennec|firefox.*maemo|(Mobile|Tablet).*Firefox|Firefox.*Mobile',
124 'Bolt' => 'bolt',
125 'TeaShark' => 'teashark',
126 'Blazer' => 'Blazer',
127 'Safari' => 'Version.*Mobile.*Safari|Safari.*Mobile',
128 'Tizen' => 'Tizen',
129 'UCBrowser' => 'UC.*Browser|UCWEB',
130 'DiigoBrowser' => 'DiigoBrowser',
131 'Puffin' => 'Puffin',
132 'Mercury' => '\bMercury\b',
133 'GenericBrowser' => 'NokiaBrowser|OviBrowser|OneBrowser|TwonkyBeamBrowser|SEMC.*Browser|FlyFlow|Minimo|NetFront|Novarra-Vision|MQQBrowser|MicroMessenger'
134 );
135 protected static $utilities = array (
136 'DesktopMode' => 'WPDesktop',
137 'TV' => 'SonyDTV|HbbTV',
138 'Bot' => 'Googlebot|DoCoMo|YandexBot|bingbot|ia_archiver|AhrefsBot|Ezooms|GSLFbot|WBSearchBot|Twitterbot|TweetmemeBot|Twikle|PaperLiBot|Wotbox|UnwindFetchor|facebookexternalhit',
139 'MobileBot' => 'Googlebot-Mobile|DoCoMo|YahooSeeker/M1A1-R2D2',
140 'Console' => '\b(Nintendo|Nintendo WiiU|PLAYSTATION|Xbox)\b',
141 'Watch' => 'SM-V700',
142
143 );
144 protected static $properties = array (
145
146 // Build
147 'Mobile' => 'Mobile/[VER]',
148 'Build' => 'Build/[VER]',
149 'Version' => 'Version/[VER]',
150 'VendorID' => 'VendorID/[VER]',
151
152 // Devices
153 'iPad' => 'iPad.*CPU[a-z ]+[VER]',
154 'iPhone' => 'iPhone.*CPU[a-z ]+[VER]',
155 'iPod' => 'iPod.*CPU[a-z ]+[VER]',
156 'Kindle' => 'Kindle/[VER]',
157
158 // Browser
159 'Chrome' => array (
160 'Chrome/[VER]',
161 'CriOS/[VER]',
162 'CrMo/[VER]'
163 ),
164 'Coast' => array (
165 'Coast/[VER]'
166 ),
167 'Dolfin' => 'Dolfin/[VER]',
168 'Firefox' => 'Firefox/[VER]',
169 'Fennec' => 'Fennec/[VER]',
170 'IE' => array (
171 'IEMobile/[VER];',
172 'IEMobile [VER]',
173 'MSIE [VER];'
174 ),
175 'NetFront' => 'NetFront/[VER]',
176 'NokiaBrowser' => 'NokiaBrowser/[VER]',
177 'Opera' => array (
178 ' OPR/[VER]',
179 'Opera Mini/[VER]',
180 'Version/[VER]'
181 ),
182 'Opera Mini' => 'Opera Mini/[VER]',
183 'Opera Mobi' => 'Version/[VER]',
184 'UC Browser' => 'UC Browser[VER]',
185 'MQQBrowser' => 'MQQBrowser/[VER]',
186 'MicroMessenger' => 'MicroMessenger/[VER]',
187 'Safari' => array (
188 'Version/[VER]',
189 'Safari/[VER]'
190 ),
191 'Skyfire' => 'Skyfire/[VER]',
192 'Tizen' => 'Tizen/[VER]',
193 'Webkit' => 'webkit[ /][VER]',
194
195 // Engine
196 'Gecko' => 'Gecko/[VER]',
197 'Trident' => 'Trident/[VER]',
198 'Presto' => 'Presto/[VER]',
199
200 // OS
201 'iOS' => ' \bOS\b [VER] ',
202 'Android' => 'Android [VER]',
203 'BlackBerry' => array (
204 'BlackBerry[\w]+/[VER]',
205 'BlackBerry.*Version/[VER]',
206 'Version/[VER]'
207 ),
208 'BREW' => 'BREW [VER]',
209 'Java' => 'Java/[VER]',
210 'Windows Phone OS' => array (
211 'Windows Phone OS [VER]',
212 'Windows Phone [VER]'
213 ),
214 'Windows Phone' => 'Windows Phone [VER]',
215 'Windows CE' => 'Windows CE/[VER]',
216 'Windows NT' => 'Windows NT [VER]',
217 'Symbian' => array (
218 'SymbianOS/[VER]',
219 'Symbian/[VER]'
220 ),
221 'webOS' => array (
222 'webOS/[VER]',
223 'hpwOS/[VER];'
224 ),
225
226 );
227
228 public function __construct(?array $headers = null, $userAgent = null) {
229 $this->setHttpHeaders($headers);
230 $this->setUserAgent($userAgent);
231 }
232
233 public function setHttpHeaders($httpHeaders = null) {
234 if (!is_array($httpHeaders) || !count($httpHeaders)) {
235 $httpHeaders = $_SERVER;
236 }
237 $this->httpHeaders = array ();
238 foreach ($httpHeaders as $key => $value) {
239 if (substr($key, 0, 5) == 'HTTP_') {
240 $this->httpHeaders[$key] = $value;
241 }
242 }
243 }
244
245 public function getHttpHeaders() {
246 return $this->httpHeaders;
247 }
248
249 public function getHttpHeader($header) {
250 if (strpos($header, '_') === false) {
251 $header = str_replace('-', '_', $header);
252 $header = strtoupper($header);
253 }
254 $altHeader = 'HTTP_' . $header;
255 if (isset ($this->httpHeaders[$header])) {
256 return $this->httpHeaders[$header];
257 }
258 elseif (isset ($this->httpHeaders[$altHeader])) {
259 return $this->httpHeaders[$altHeader];
260 }
261 }
262
263 public function setUserAgent($userAgent = null) {
264 if (!empty ($userAgent)) {
265 $this->userAgent = $userAgent;
266 } else {
267 $this->userAgent = $this->getHttpHeader('User-Agent');
268
269 if (empty ($this->userAgent)) {
270 $this->userAgent = $this->getHttpHeader('X-Device-User-Agent');
271 }
272
273 if ($operaMiniUa = $this->getHttpHeader('X-OperaMini-Phone-UA')) {
274 $this->userAgent .= ' ' . $operaMiniUa;
275 }
276 }
277 }
278
279 public function getUserAgent() {
280 return $this->userAgent;
281 }
282
283 public function setDetectionType($type = null) {
284 if ($type === null) {
285 $type = self::DETECTION_TYPE_MOBILE;
286 }
287
288 if ($type != self::DETECTION_TYPE_MOBILE && $type != self::DETECTION_TYPE_EXTENDED) {
289 return;
290 }
291
292 $this->detectionType = $type;
293 }
294
295 public static function getPhoneDevices() {
296 return self::$phoneDevices;
297 }
298
299 public static function getTabletDevices() {
300 return self::$tabletDevices;
301 }
302
303 public static function getUserAgents() {
304 return self::getBrowsers();
305 }
306
307 public static function getBrowsers() {
308 return self::$browsers;
309 }
310
311 public static function getUtilities() {
312 return self::$utilities;
313 }
314
315 public static function getMobileDetectionRules() {
316 static $rules;
317
318 if (!$rules) {
319 $rules = array_merge(self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers);
320 }
321
322 return $rules;
323
324 }
325
326 public function getMobileDetectionRulesExtended() {
327 static $rules;
328
329 if (!$rules) {
330 $rules = array_merge(self::$phoneDevices, self::$tabletDevices, self::$operatingSystems, self::$browsers, self::$utilities);
331 }
332
333 return $rules;
334 }
335
336 public function getRules() {
337 //mod ale e4j
338 //return self::getMobileDetectionRules(); // no utilities (TVs, Consoles etc..)
339 return self::getMobileDetectionRulesExtended(); // any kind including utilities like TVs and Consoles
340 }
341
342 public function checkHttpHeadersForMobile() {
343 return (isset ($this->httpHeaders['HTTP_ACCEPT']) && (strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/x-obml2d') !== false || // Opera Mini
344 strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/vnd.rim.html') !== false || // BlackBerry devices
345 strpos($this->httpHeaders['HTTP_ACCEPT'], 'text/vnd.wap.wml') !== false || strpos($this->httpHeaders['HTTP_ACCEPT'], 'application/vnd.wap.xhtml+xml') !== false) || isset ($this->httpHeaders['HTTP_X_WAP_PROFILE']) || isset ($this->httpHeaders['HTTP_X_WAP_CLIENTID']) || isset ($this->httpHeaders['HTTP_WAP_CONNECTION']) || isset ($this->httpHeaders['HTTP_PROFILE']) || isset ($this->httpHeaders['HTTP_X_OPERAMINI_PHONE_UA']) || // Nokia devices
346 isset ($this->httpHeaders['HTTP_X_NOKIA_IPADDRESS']) || isset ($this->httpHeaders['HTTP_X_NOKIA_GATEWAY_ID']) || isset ($this->httpHeaders['HTTP_X_ORANGE_ID']) || isset ($this->httpHeaders['HTTP_X_VODAFONE_3GPDPCONTEXT']) || isset ($this->httpHeaders['HTTP_X_HUAWEI_USERID']) || isset ($this->httpHeaders['HTTP_UA_OS']) || // Windows Smartphones.
347 isset ($this->httpHeaders['HTTP_X_MOBILE_GATEWAY']) || // Verizon, Vodafone proxy system.
348 isset ($this->httpHeaders['HTTP_X_ATT_DEVICEID']) || // HTC Sensation
349 //HTTP_X_NETWORK_TYPE = WIFI
350 (isset ($this->httpHeaders['HTTP_UA_CPU']) && $this->httpHeaders['HTTP_UA_CPU'] == 'ARM' // HTC.
351 ));
352 }
353
354 private function matchDetectionRulesAgainstUA($userAgent = null) {
355 foreach ($this->getRules() as $_regex) {
356 if (empty ($_regex)) {
357 continue;
358 }
359 if ($this->match($_regex, $userAgent)) {
360 return true;
361 }
362 }
363
364 return false;
365 }
366
367 private function matchUAAgainstKey($key, $userAgent = null) {
368 $key = strtolower($key);
369 $_rules = array_change_key_case($this->getRules());
370
371 if (array_key_exists($key, $_rules)) {
372 if (empty ($_rules[$key])) {
373 return null;
374 }
375
376 return $this->match($_rules[$key], $userAgent);
377 }
378
379 return false;
380 }
381
382 public function isMobile($userAgent = null, $httpHeaders = null) {
383
384 if ($httpHeaders) {
385 $this->setHttpHeaders($httpHeaders);
386 }
387
388 if ($userAgent) {
389 $this->setUserAgent($userAgent);
390 }
391
392 $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
393
394 if ($this->checkHttpHeadersForMobile()) {
395 return true;
396 } else {
397 return $this->matchDetectionRulesAgainstUA();
398 }
399
400 }
401
402 public function isTablet($userAgent = null, $httpHeaders = null) {
403 $this->setDetectionType(self::DETECTION_TYPE_MOBILE);
404
405 foreach (self::$tabletDevices as $_regex) {
406 if ($this->match($_regex, $userAgent)) {
407 return true;
408 }
409 }
410
411 return false;
412 }
413
414 public function is($key, $userAgent = null, $httpHeaders = null) {
415 if ($httpHeaders) {
416 $this->setHttpHeaders($httpHeaders);
417 }
418
419 if ($userAgent) {
420 $this->setUserAgent($userAgent);
421 }
422
423 $this->setDetectionType(self::DETECTION_TYPE_EXTENDED);
424
425 return $this->matchUAAgainstKey($key);
426 }
427
428 public static function getOperatingSystems() {
429 return self::$operatingSystems;
430 }
431
432 public function match($regex, $userAgent = null) {
433 $regex = str_replace('/', '\/', $regex);
434 return (bool) preg_match('/' . $regex . '/is', (!empty ($userAgent) ? $userAgent : $this->userAgent));
435 }
436
437 public static function getProperties() {
438 return self::$properties;
439 }
440
441 }
442