Application.php 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. <?php
  2. namespace WhichBrowser\Analyser\Header\Useragent;
  3. use WhichBrowser\Constants;
  4. use WhichBrowser\Data;
  5. use WhichBrowser\Model\Family;
  6. use WhichBrowser\Model\Using;
  7. use WhichBrowser\Model\Version;
  8. trait Application
  9. {
  10. private function &detectApplication($ua)
  11. {
  12. /* Detect applications */
  13. $this->detectSpecificApplications($ua);
  14. $this->detectRemainingApplications($ua);
  15. return $this;
  16. }
  17. private function detectSpecificApplications($ua)
  18. {
  19. /* Sony Updatecenter */
  20. if (preg_match('/^(.*) Build\/.* (?:com.sonyericsson.updatecenter|UpdateCenter)\/[A-Z0-9\.]+$/iu', $ua, $match)) {
  21. $this->data->browser->name = 'Sony Update Center';
  22. $this->data->browser->version = null;
  23. $this->data->browser->type = Constants\BrowserType::APP;
  24. $this->data->os->reset([
  25. 'name' => 'Android'
  26. ]);
  27. $this->data->device->model = $match[1];
  28. $this->data->device->identified |= Constants\Id::PATTERN;
  29. $this->data->device->type = Constants\DeviceType::MOBILE;
  30. $device = Data\DeviceModels::identify('android', $match[1]);
  31. if ($device->identified) {
  32. $device->identified |= $this->data->device->identified;
  33. $this->data->device = $device;
  34. }
  35. }
  36. /* Sony Select SDK */
  37. if (preg_match('/Android [0-9\.]+; (.*) Sony\/.*SonySelectSDK\/([0-9\.]+)/iu', $ua, $match)) {
  38. $this->data->browser->reset();
  39. $this->data->browser->type = Constants\BrowserType::APP;
  40. $this->data->browser->using = new \WhichBrowser\Model\Using([
  41. 'name' => 'Sony Select SDK',
  42. 'version' => new Version([ 'value' => $match[2], 'details' => 2 ])
  43. ]);
  44. $this->data->device->model = $match[1];
  45. $this->data->device->identified |= Constants\Id::PATTERN;
  46. $this->data->device->type = Constants\DeviceType::MOBILE;
  47. $device = Data\DeviceModels::identify('android', $match[1]);
  48. if ($device->identified) {
  49. $device->identified |= $this->data->device->identified;
  50. $this->data->device = $device;
  51. }
  52. }
  53. /* Samsung Mediahub */
  54. if (preg_match('/^Stamhub [^\/]+\/([^;]+);.*:([0-9\.]+)\/[^\/]+\/[^:]+:user\/release-keys$/iu', $ua, $match)) {
  55. $this->data->browser->name = 'Mediahub';
  56. $this->data->browser->version = null;
  57. $this->data->browser->type = Constants\BrowserType::APP_MEDIAPLAYER;
  58. $this->data->os->reset([
  59. 'name' => 'Android',
  60. 'version' => new Version([ 'value' => $match[2] ])
  61. ]);
  62. $this->data->device->model = $match[1];
  63. $this->data->device->identified |= Constants\Id::PATTERN;
  64. $this->data->device->type = Constants\DeviceType::MOBILE;
  65. $device = Data\DeviceModels::identify('android', $match[1]);
  66. if ($device->identified) {
  67. $device->identified |= $this->data->device->identified;
  68. $this->data->device = $device;
  69. }
  70. }
  71. /* "Android Application" */
  72. if (preg_match('/Android Application/iu', $ua)) {
  73. if (preg_match('/^(.+) Android Application \([0-9]+, .+ v[0-9\.]+\) - [a-z-]+ (.*) [a-z_-]+ - [0-9A-F]{8,8}-[0-9A-F]{4,4}-[0-9A-F]{4,4}-[0-9A-F]{4,4}-[0-9A-F]{12,12}$/iu', $ua, $match)) {
  74. $this->data->browser->name = $match[1];
  75. $this->data->browser->version = null;
  76. $this->data->browser->type = Constants\BrowserType::APP;
  77. $this->data->os->reset([
  78. 'name' => 'Android'
  79. ]);
  80. $this->data->device->model = $match[2];
  81. $this->data->device->identified |= Constants\Id::PATTERN;
  82. $this->data->device->type = Constants\DeviceType::MOBILE;
  83. $device = Data\DeviceModels::identify('android', $match[2]);
  84. if ($device->identified) {
  85. $device->identified |= $this->data->device->identified;
  86. $this->data->device = $device;
  87. }
  88. }
  89. if (preg_match('/^(.+) Android Application - (.*) Build\/(.+) - [0-9A-F]{8,8}-[0-9A-F]{4,4}-[0-9A-F]{4,4}-[0-9A-F]{4,4}-[0-9A-F]{12,12}$/iu', $ua, $match)) {
  90. $this->data->browser->name = $match[1];
  91. $this->data->browser->version = null;
  92. $this->data->browser->type = Constants\BrowserType::APP;
  93. $this->data->os->reset([
  94. 'name' => 'Android'
  95. ]);
  96. $version = Data\BuildIds::identify($match[3]);
  97. if ($version) {
  98. $this->data->os->version = $version;
  99. }
  100. $this->data->device->model = $match[2];
  101. $this->data->device->identified |= Constants\Id::PATTERN;
  102. $this->data->device->type = Constants\DeviceType::MOBILE;
  103. $device = Data\DeviceModels::identify('android', $match[2]);
  104. if ($device->identified) {
  105. $device->identified |= $this->data->device->identified;
  106. $this->data->device = $device;
  107. }
  108. }
  109. if (preg_match('/^(.+) Android Application - [a-z-]+ (.*) [a-z_-]+$/iu', $ua, $match)) {
  110. $this->data->browser->name = $match[1];
  111. $this->data->browser->version = null;
  112. $this->data->browser->type = Constants\BrowserType::APP;
  113. $this->data->os->reset([
  114. 'name' => 'Android'
  115. ]);
  116. $this->data->device->model = $match[2];
  117. $this->data->device->identified |= Constants\Id::PATTERN;
  118. $this->data->device->type = Constants\DeviceType::MOBILE;
  119. $device = Data\DeviceModels::identify('android', $match[2]);
  120. if ($device->identified) {
  121. $device->identified |= $this->data->device->identified;
  122. $this->data->device = $device;
  123. }
  124. }
  125. }
  126. /* AiMeiTuan */
  127. if (preg_match('/^AiMeiTuan \/[^\-]+\-([0-9\.]+)\-(.*)\-[0-9]+x[0-9]+\-/iu', $ua, $match)) {
  128. $this->data->browser->name = 'AiMeiTuan';
  129. $this->data->browser->version = null;
  130. $this->data->browser->type = Constants\BrowserType::APP;
  131. $this->data->os->reset([
  132. 'name' => 'Android',
  133. 'version' => new Version([ 'value' => $match[1] ])
  134. ]);
  135. $this->data->device->model = $match[2];
  136. $this->data->device->identified |= Constants\Id::PATTERN;
  137. $this->data->device->type = Constants\DeviceType::MOBILE;
  138. $device = Data\DeviceModels::identify('android', $match[2]);
  139. if ($device->identified) {
  140. $device->identified |= $this->data->device->identified;
  141. $this->data->device = $device;
  142. }
  143. }
  144. /* Instagram */
  145. if (preg_match('/^Instagram ([0-9\.]+) Android (?:IC )?\([0-9]+\/([0-9\.]+); [0-9]+dpi; [0-9]+x[0-9]+; [^;]+; ([^;]*);/iu', $ua, $match)) {
  146. $this->data->browser->name = 'Instagram';
  147. $this->data->browser->version = new Version([ 'value' => $match[1] ]);
  148. $this->data->browser->type = Constants\BrowserType::APP_SOCIAL;
  149. $this->data->os->reset([
  150. 'name' => 'Android',
  151. 'version' => new Version([ 'value' => $match[2] ])
  152. ]);
  153. $this->data->device->model = $match[3];
  154. $this->data->device->identified |= Constants\Id::PATTERN;
  155. $this->data->device->type = Constants\DeviceType::MOBILE;
  156. $device = Data\DeviceModels::identify('android', $match[3]);
  157. if ($device->identified) {
  158. $device->identified |= $this->data->device->identified;
  159. $this->data->device = $device;
  160. }
  161. }
  162. /* Pinterest */
  163. if (preg_match('/^Pinterest for Android( Tablet)?\/([0-9\.]+) \(([^;]+); ([0-9\.]+)\)/iu', $ua, $match)) {
  164. $this->data->browser->name = 'Pinterest';
  165. $this->data->browser->version = new Version([ 'value' => $match[2] ]);
  166. $this->data->browser->type = Constants\BrowserType::APP_SOCIAL;
  167. $this->data->os->reset([
  168. 'name' => 'Android',
  169. 'version' => new Version([ 'value' => $match[4] ])
  170. ]);
  171. $this->data->device->model = $match[3];
  172. $this->data->device->identified |= Constants\Id::PATTERN;
  173. $this->data->device->type = $match[1] == ' Tablet' ? Constants\DeviceType::TABLET : Constants\DeviceType::MOBILE;
  174. $device = Data\DeviceModels::identify('android', $match[3]);
  175. if ($device->identified) {
  176. $device->identified |= $this->data->device->identified;
  177. $this->data->device = $device;
  178. }
  179. }
  180. /* Dr. Web Anti-Virus */
  181. if (preg_match('/Dr\.Web anti\-virus Light Version: ([0-9\.]+) Device model: (.*) Firmware version: ([0-9\.]+)/u', $ua, $match)) {
  182. $this->data->browser->name = 'Dr. Web Light';
  183. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]);
  184. $this->data->browser->type = Constants\BrowserType::APP_ANTIVIRUS;
  185. $this->data->os->reset([
  186. 'name' => 'Android',
  187. 'version' => new Version([ 'value' => $match[3] ])
  188. ]);
  189. $this->data->device->type = Constants\DeviceType::MOBILE;
  190. $device = Data\DeviceModels::identify('android', $match[2]);
  191. if ($device->identified) {
  192. $device->identified |= $this->data->device->identified;
  193. $this->data->device = $device;
  194. }
  195. }
  196. /* Google Earth */
  197. if (preg_match('/GoogleEarth\/([0-9\.]+)\(Android;Android \((.+)\-[^\-]+\-user-([0-9\.]+)\);/u', $ua, $match)) {
  198. $this->data->browser->name = 'Google Earth';
  199. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]);
  200. $this->data->browser->type = Constants\BrowserType::APP;
  201. $this->data->os->reset([
  202. 'name' => 'Android',
  203. 'version' => new Version([ 'value' => $match[3] ])
  204. ]);
  205. $this->data->device->type = Constants\DeviceType::MOBILE;
  206. $device = Data\DeviceModels::identify('android', $match[2]);
  207. if ($device->identified) {
  208. $device->identified |= $this->data->device->identified;
  209. $this->data->device = $device;
  210. }
  211. }
  212. /* Groupon */
  213. if (preg_match('/Groupon\/([0-9\.]+) \(Android ([0-9\.]+); [^\/]+ \/ [A-Z][a-z]+ ([^;]*);/u', $ua, $match)) {
  214. $this->data->browser->name = 'Groupon';
  215. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]);
  216. $this->data->browser->type = Constants\BrowserType::APP_SHOPPING;
  217. $this->data->os->reset([
  218. 'name' => 'Android',
  219. 'version' => new Version([ 'value' => $match[2] ])
  220. ]);
  221. $this->data->device->type = Constants\DeviceType::MOBILE;
  222. $this->data->device->model = $match[3];
  223. $device = Data\DeviceModels::identify('android', $match[3]);
  224. if ($device->identified) {
  225. $device->identified |= $this->data->device->identified;
  226. $this->data->device = $device;
  227. }
  228. }
  229. /* Whatsapp */
  230. if (preg_match('/WhatsApp\+?\/([0-9\.]+) (Android|S60Version|WP7)\/([0-9\.\_]+) Device\/([^\-]+)\-(.*)(?:-\([0-9]+\.[0-9]+\))?(?:\-H[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)?$/uU', $ua, $match)) {
  231. $this->data->browser->name = 'WhatsApp';
  232. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]);
  233. $this->data->browser->type = Constants\BrowserType::APP_CHAT;
  234. $this->data->device->type = Constants\DeviceType::MOBILE;
  235. $this->data->device->manufacturer = $match[4];
  236. $this->data->device->model = $match[5];
  237. $this->data->device->identified |= Constants\Id::PATTERN;
  238. if ($match[2] == 'Android') {
  239. $this->data->os->reset([
  240. 'name' => 'Android',
  241. 'version' => new Version([ 'value' => str_replace('_', '.', $match[3]) ])
  242. ]);
  243. $device = Data\DeviceModels::identify('android', $match[5]);
  244. if ($device->identified) {
  245. $device->identified |= $this->data->device->identified;
  246. $this->data->device = $device;
  247. }
  248. }
  249. if ($match[2] == 'WP7') {
  250. $this->data->os->reset([
  251. 'name' => 'Windows Phone',
  252. 'version' => new Version([ 'value' => $match[3], 'details' => 2 ])
  253. ]);
  254. $device = Data\DeviceModels::identify('wp', $match[5]);
  255. if ($device->identified) {
  256. $device->identified |= $this->data->device->identified;
  257. $this->data->device = $device;
  258. }
  259. }
  260. if ($match[2] == 'S60Version') {
  261. $this->data->os->reset([
  262. 'name' => 'Series60',
  263. 'version' => new Version([ 'value' => $match[3] ]),
  264. 'family' => new Family([ 'name' => 'Symbian' ])
  265. ]);
  266. $device = Data\DeviceModels::identify('symbian', $match[5]);
  267. if ($device->identified) {
  268. $device->identified |= $this->data->device->identified;
  269. $this->data->device = $device;
  270. }
  271. }
  272. if ($match[2] == 'WP7') {
  273. $this->data->os->reset([
  274. 'name' => 'Windows Phone',
  275. 'version' => new Version([ 'value' => $match[3], 'details' => 2 ])
  276. ]);
  277. $device = Data\DeviceModels::identify('wp', $match[5]);
  278. if ($device->identified) {
  279. $device->identified |= $this->data->device->identified;
  280. $this->data->device = $device;
  281. }
  282. }
  283. }
  284. /* Yahoo */
  285. if (preg_match('/YahooMobile(?:Messenger|Mail|Weather)\/1.0 \(Android (Messenger|Mail|Weather); ([0-9\.]+)\) \([^;]+; ?[^;]+; ?([^;]+); ?([0-9\.]+)\/[^\;\)\/]+\)/u', $ua, $match)) {
  286. $this->data->browser->name = 'Yahoo ' . $match[1];
  287. $this->data->browser->version = new Version([ 'value' => $match[2], 'details' => 3 ]);
  288. switch ($match[1]) {
  289. case 'Messenger':
  290. $this->data->browser->type = Constants\BrowserType::APP_CHAT;
  291. break;
  292. case 'Mail':
  293. $this->data->browser->type = Constants\BrowserType::APP_EMAIL;
  294. break;
  295. case 'Weather':
  296. $this->data->browser->type = Constants\BrowserType::APP_NEWS;
  297. break;
  298. }
  299. $this->data->os->reset([
  300. 'name' => 'Android',
  301. 'version' => new Version([ 'value' => $match[4] ])
  302. ]);
  303. $this->data->device->type = Constants\DeviceType::MOBILE;
  304. $device = Data\DeviceModels::identify('android', $match[3]);
  305. if ($device->identified) {
  306. $device->identified |= $this->data->device->identified;
  307. $this->data->device = $device;
  308. }
  309. }
  310. /* Yahoo Mobile App */
  311. if (preg_match('/YahooJMobileApp\/[0-9\.]+ \(Android [a-z]+; ([0-9\.]+)\) \([^;]+; ?[^;]+; ?[^;]+; ?([^;]+); ?([0-9\.]+)\/[^\;\)\/]+\)/u', $ua, $match)) {
  312. $this->data->browser->name = 'Yahoo Mobile';
  313. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 3 ]);
  314. $this->data->browser->type = Constants\BrowserType::APP_SEARCH;
  315. $this->data->os->reset([
  316. 'name' => 'Android',
  317. 'version' => new Version([ 'value' => $match[3] ])
  318. ]);
  319. $this->data->device->type = Constants\DeviceType::MOBILE;
  320. $device = Data\DeviceModels::identify('android', $match[2]);
  321. if ($device->identified) {
  322. $device->identified |= $this->data->device->identified;
  323. $this->data->device = $device;
  324. }
  325. }
  326. /* ICQ */
  327. if (preg_match('/ICQ_Android\/([0-9\.]+) \(Android; [0-9]+; ([0-9\.]+); [^;]+; ([^;]+);/u', $ua, $match)) {
  328. $this->data->browser->name = 'ICQ';
  329. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 3 ]);
  330. $this->data->browser->type = Constants\BrowserType::APP_CHAT;
  331. $this->data->os->reset([
  332. 'name' => 'Android',
  333. 'version' => new Version([ 'value' => $match[2] ])
  334. ]);
  335. $this->data->device->type = Constants\DeviceType::MOBILE;
  336. $device = Data\DeviceModels::identify('android', $match[3]);
  337. if ($device->identified) {
  338. $device->identified |= $this->data->device->identified;
  339. $this->data->device = $device;
  340. }
  341. }
  342. /* Facebook for Android */
  343. if (preg_match('/^\[FBAN\/(FB4A|PAAA);.*FBDV\/([^;]+);.*FBSV\/([0-9\.]+);/u', $ua, $match)) {
  344. if ($match[1] == 'FB4A') {
  345. $this->data->browser->name = 'Facebook';
  346. $this->data->browser->version = null;
  347. $this->data->browser->type = Constants\BrowserType::APP_SOCIAL;
  348. }
  349. if ($match[1] == 'PAAA') {
  350. $this->data->browser->name = 'Facebook Pages';
  351. $this->data->browser->version = null;
  352. $this->data->browser->type = Constants\BrowserType::APP_SOCIAL;
  353. }
  354. $this->data->os->reset([
  355. 'name' => 'Android',
  356. 'version' => new Version([ 'value' => $match[3] ])
  357. ]);
  358. $this->data->device->type = Constants\DeviceType::MOBILE;
  359. $device = Data\DeviceModels::identify('android', $match[2]);
  360. if ($device->identified) {
  361. $device->identified |= $this->data->device->identified;
  362. $this->data->device = $device;
  363. }
  364. }
  365. /* VK */
  366. if (preg_match('/^VKAndroidApp\/([0-9\.]+)-[0-9]+ \(Android ([^;]+); SDK [^;]+; [^;]+; [a-z]+ ([^;]+);/iu', $ua, $match)) {
  367. $this->data->browser->name = 'VK';
  368. $this->data->browser->version = new Version([ 'value' => $match[1], 'details' => 2 ]);
  369. $this->data->browser->type = Constants\BrowserType::APP_SOCIAL;
  370. $this->data->os->reset([
  371. 'name' => 'Android',
  372. 'version' => new Version([ 'value' => $match[2] ])
  373. ]);
  374. $this->data->device->model = $match[3];
  375. $this->data->device->identified |= Constants\Id::PATTERN;
  376. $this->data->device->type = Constants\DeviceType::MOBILE;
  377. $device = Data\DeviceModels::identify('android', $match[3]);
  378. if ($device->identified) {
  379. $device->identified |= $this->data->device->identified;
  380. $this->data->device = $device;
  381. }
  382. }
  383. }
  384. private function detectRemainingApplications($ua)
  385. {
  386. if ($data = Data\Applications::identifyOther($ua)) {
  387. $this->data->browser->set($data['browser']);
  388. if (!empty($data['device'])) {
  389. $this->data->device->set($data['device']);
  390. }
  391. }
  392. }
  393. }