protected function parseDevice()
{
$parsers = $this->getDeviceParsers();
foreach ($parsers as $parser) {
$parser->setYamlParser($this->getYamlParser());
$parser->setCache($this->getCache());
$parser->setUserAgent($this->getUserAgent());
if ($parser->parse()) {
$this->device = $parser->getDeviceType();
$this->model = $parser->getModel();
$this->brand = $parser->getBrand();
break;
}
}
/**
* If no brand has been assigned try to match by known vendor fragments
*/
if (empty($this->brand)) {
$vendorParser = new VendorFragment($this->getUserAgent());
$vendorParser->setYamlParser($this->getYamlParser());
$vendorParser->setCache($this->getCache());
$this->brand = $vendorParser->parse();
}
$osShortName = $this->getOs('short_name');
$osFamily = OperatingSystem::getOsFamily($osShortName);
$osVersion = $this->getOs('version');
$clientName = $this->getClient('name');
/**
* Chrome on Android passes the device type based on the keyword 'Mobile'
* If it is present the device should be a smartphone, otherwise it's a tablet
* See https://developer.chrome.com/multidevice/user-agent#chrome_for_android_user_agent
*/
if (is_null($this->device) && $osFamily == 'Android' && in_array($this->getClient('name'), array('Chrome', 'Chrome Mobile'))) {
if ($this->matchUserAgent('Chrome/[\\.0-9]* Mobile')) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE;
} else {
if ($this->matchUserAgent('Chrome/[\\.0-9]* (?!Mobile)')) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET;
}
}
}
/**
* Some user agents simply contain the fragment 'Android; Tablet;' or 'Opera Tablet', so we assume those devices as tablets
*/
if (is_null($this->device) && ($this->hasAndroidTableFragment() || $this->matchUserAgent('Opera Tablet'))) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET;
}
/**
* Some user agents simply contain the fragment 'Android; Mobile;', so we assume those devices as smartphones
*/
if (is_null($this->device) && $this->hasAndroidMobileFragment()) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE;
}
/**
* Android up to 3.0 was designed for smartphones only. But as 3.0, which was tablet only, was published
* too late, there were a bunch of tablets running with 2.x
* With 4.0 the two trees were merged and it is for smartphones and tablets
*
* So were are expecting that all devices running Android < 2 are smartphones
* Devices running Android 3.X are tablets. Device type of Android 2.X and 4.X+ are unknown
*/
if (is_null($this->device) && $osShortName == 'AND' && $osVersion != '') {
if (version_compare($osVersion, '2.0') == -1) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE;
} elseif (version_compare($osVersion, '3.0') >= 0 and version_compare($osVersion, '4.0') == -1) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET;
}
}
/**
* All detected feature phones running android are more likely a smartphone
*/
if ($this->device == DeviceParserAbstract::DEVICE_TYPE_FEATURE_PHONE && $osFamily == 'Android') {
$this->device = DeviceParserAbstract::DEVICE_TYPE_SMARTPHONE;
}
/**
* According to http://msdn.microsoft.com/en-us/library/ie/hh920767(v=vs.85).aspx
* Internet Explorer 10 introduces the "Touch" UA string token. If this token is present at the end of the
* UA string, the computer has touch capability, and is running Windows 8 (or later).
* This UA string will be transmitted on a touch-enabled system running Windows 8 (RT)
*
* As most touch enabled devices are tablets and only a smaller part are desktops/notebooks we assume that
* all Windows 8 touch devices are tablets.
*/
if (is_null($this->device) && ($osShortName == 'WRT' || $osShortName == 'WIN' && version_compare($osVersion, '8.0')) && $this->isTouchEnabled()) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_TABLET;
}
/**
* All devices running Opera TV Store are assumed to be a tv
*/
if ($this->matchUserAgent('Opera TV Store')) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_TV;
}
/**
* Devices running Kylo or Espital TV Browsers are assumed to be a TV
*/
if (is_null($this->device) && in_array($clientName, array('Kylo', 'Espial TV Browser'))) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_TV;
}
// set device type to desktop for all devices running a desktop os that were not detected as an other device type
if (is_null($this->device) && $this->isDesktop()) {
$this->device = DeviceParserAbstract::DEVICE_TYPE_DESKTOP;
}
}