From e6c96551427460eb86e2ffa124abe20b32e1ff49 Mon Sep 17 00:00:00 2001 From: Serhii Nekhaienko Date: Tue, 1 Jun 2021 21:05:30 +0300 Subject: [PATCH 1/6] v6.0.1 - added link to laravel package - changed README.md - fixed version in Detector.php --- README.md | 27 ++++++++++++++++----------- composer.json | 2 +- src/Detector.php | 4 ++-- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1ed5232..1c86964 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ Detect user Browser, OS and Device through USER AGENT -[Live demo](http://detector.serhii.work/) ## Code Status [![Latest Stable Version](https://poser.pugx.org/endorphin-studio/browser-detector/v/stable)](https://packagist.org/packages/endorphin-studio/browser-detector) @@ -11,9 +10,13 @@ Detect user Browser, OS and Device through USER AGENT ## About Author: Serhii Nekhaienko Email: sergey.nekhaenko@gmail.com - Stable Version: 6.0.0 + Stable Version: 6.0.1 License: MIT +## Packages + +[Laravel Package](https://github.com/endorphin-studio/browser-detector-laravel) + ## Requirements PHP >=7.0 <7.3 endorphin-studio/browser-detector-detection >=1.0.1 @@ -23,16 +26,17 @@ Detect user Browser, OS and Device through USER AGENT ## Install via Composer composer require endorphin-studio/browser-detector ## Basic Usage +```php +use EndorphinStudio\Detector\Detector; - use EndorphinStudio\Detector\Detector; - - $detector = new Detector(); - $result = $detector->analyse(); - - echo json_encode($result); +$detector = new Detector(); +$result = $detector->analyse(); - // Result - { +echo json_encode($result); +``` +Result: +```json +{ "userAgent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36", "os": { "family": "unix", @@ -53,7 +57,8 @@ Detect user Browser, OS and Device through USER AGENT "isTouch": false, "isMobile": false, "isTablet": false - } +} +``` #### Browser Detection Support diff --git a/composer.json b/composer.json index b36ec53..ea0aa64 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "description": "Detect user Browser, OS and Device through Browser USER AGENT", "minimum-stability": "stable", "type": "library", - "license": "GPL-3.0+", + "license": "MIT", "keywords": ["browser-detector","user-agent-string","user-agent","device-detector"], "authors": [ { diff --git a/src/Detector.php b/src/Detector.php index ce5b148..49f5e56 100644 --- a/src/Detector.php +++ b/src/Detector.php @@ -23,7 +23,7 @@ */ class Detector { - private $version = '5.0.0'; + private $version = '6.0.1'; public function getVersion(): string { @@ -202,4 +202,4 @@ private function findCacheDirectory(): string } throw new StorageException(sprintf(StorageException::DIRECTORY_NOT_FOUND, $cacheDirectory)); } -} \ No newline at end of file +} From cc0216cb9afc2b875a05413e3c845aa01b1e0ef6 Mon Sep 17 00:00:00 2001 From: Serhii Nekhaienko Date: Wed, 1 Sep 2021 19:14:48 +0300 Subject: [PATCH 2/6] v6.0.2 - moved yaml to own package - code optimization --- .codacy.yml | 3 + composer.json | 5 +- src/Detector.php | 216 ++++++++++++++++++++++++++--------------------- var/.gitignore | 1 + 4 files changed, 125 insertions(+), 100 deletions(-) create mode 100644 .codacy.yml create mode 100644 var/.gitignore diff --git a/.codacy.yml b/.codacy.yml new file mode 100644 index 0000000..2856aa9 --- /dev/null +++ b/.codacy.yml @@ -0,0 +1,3 @@ +exclude_paths: + - "demo.php" + - "*.md" diff --git a/composer.json b/composer.json index ea0aa64..064efba 100644 --- a/composer.json +++ b/composer.json @@ -12,10 +12,11 @@ } ], "require": { - "php": ">=7.0", + "php": ">=7.1", "endorphin-studio/browser-detector-detection": "^2.1", "endorphin-studio/browser-detector-tools": "^1.2", - "endorphin-studio/browser-detector-data": "^1.2" + "endorphin-studio/browser-detector-data": "^1.2", + "endorphin-studio/browser-detector-data-yaml": "^1.0" }, "require-dev": { diff --git a/src/Detector.php b/src/Detector.php index 49f5e56..a06ce0f 100644 --- a/src/Detector.php +++ b/src/Detector.php @@ -9,11 +9,12 @@ namespace EndorphinStudio\Detector; -use EndorphinStudio\Detector\Data\AbstractData; +use Composer\Composer; use EndorphinStudio\Detector\Data\Result; use EndorphinStudio\Detector\Exception\StorageException; -use EndorphinStudio\Detector\Storage\AbstractStorage; use EndorphinStudio\Detector\Storage\StorageInterface; +use EndorphinStudio\Detector\Storage\YamlStorage; +use RuntimeException; use Symfony\Component\HttpFoundation\Request; /** @@ -23,68 +24,33 @@ */ class Detector { - private $version = '6.0.1'; - - public function getVersion(): string - { - return $this->version; - } + private const DATA_PACKAGE = 'endorphin-studio/browser-detector-data-yaml'; /** * @var array Array of options */ protected $options = [ - 'dataProvider' => '\\EndorphinStudio\\Detector\\Storage\\YamlStorage', + 'dataProvider' => YamlStorage::class, 'dataDirectory' => 'auto', 'cacheDirectory' => 'auto', 'format' => 'yaml' ]; + private $version = '6.0.3'; + /** * @var StorageInterface */ private $dataProvider; - /** - * Get storage provider - * @return StorageInterface - */ - public function getDataProvider(): StorageInterface - { - return $this->dataProvider; - } - - /** - * Get result object - * @return Result Result object - */ - public function getResultObject(): Result - { - return $this->resultObject; - } - /** * @var Result Result object */ private $resultObject; /** - * Set data provider - * @param StorageInterface $dataProvider - */ - public function setDataProvider(StorageInterface $dataProvider) - { - $this->dataProvider = $dataProvider; - } - - /** - * @return mixed + * @var string $ua User Agent */ - public function getUserAgent() - { - return $this->ua; - } - private $ua; /** @@ -100,8 +66,8 @@ public function getUserAgent() * 'cacheDirectory' => 'auto', * 'format' => 'yaml' * @param array $options Array of options - * @throws \ReflectionException * @throws StorageException + * @SuppressWarnings(PHPMD.StaticAccess) */ public function __construct(array $options = []) { @@ -109,97 +75,151 @@ public function __construct(array $options = []) $this->init(); $this->detectors = []; - $check = ['os','device', 'browser', 'robot']; Tools::setWindowsConfig($this->dataProvider->getConfig()['windows']); - foreach ($check as $detectionType) { - $className = sprintf('\\EndorphinStudio\\Detector\\Detection\\%s', ucfirst(sprintf('%sDetector', $detectionType))); - if(class_exists($className)) { - $this->detectors[$detectionType] = new $className(); - $this->detectors[$detectionType]->init($this); - } + foreach (['os', 'device', 'browser'] as $detectionType) { + $this->initDetector($detectionType); } } - /** - * Analyse User Agent String - * @param string $ua - * @return Result - */ - public function analyse(string $ua = 'ua'): Result - { - $request = Request::createFromGlobals(); - $this->ua = $ua === 'ua' ? $request->server->get('HTTP_USER_AGENT') : $ua; - $this->resultObject = new Result($this->ua, $this); - foreach ($this->detectors as $detectionType => $detector) { - $detector->detect(); - } - return $this->resultObject; - } - - /** - * Get list of patterns from config - * @param $list - * @param $type - * @return array - */ - public function getPatternList($list, $type) - { - return array_key_exists($type, $list) ? $list[$type] : []; - } - /** * Initialisation method - * @throws \ReflectionException * @throws StorageException + * @throws RuntimeException */ - protected function init() + protected function init(): void { - $dataProvider = new $this->options['dataProvider'](); - - /** @var StorageInterface $dataProvider */ - $this->setDataProvider($dataProvider); + $this->setDataProvider($this->createDataProvider()); $this->dataProvider->setDataDirectory($this->findDataDirectory()); - if(method_exists($this->dataProvider,'setCacheDirectory')) { - $this->dataProvider->setCacheDirectory($this->findCacheDirectory()); - } - if(method_exists($this->dataProvider,'setCacheEnabled')) { - $this->dataProvider->setCacheEnabled(true); + $this->callMethod($this->dataProvider, 'setCacheDirectory', $this->findCacheDirectory()); + $this->callMethod($this->dataProvider, 'setCacheEnabled', true); + } + + private function createDataProvider() + { + if (class_exists($this->options['dataProvider'])) { + return new $this->options['dataProvider'](); } + throw new RuntimeException('Data Provider class isn\'t exist'); } /** * @return string * @throws StorageException - * @throws \ReflectionException */ private function findDataDirectory(): string { $dataDirectory = $this->options['dataDirectory']; - if($this->options['dataDirectory'] === 'auto') { - $reflection = new \ReflectionClass(AbstractData::class); - $dataDirectory = sprintf('%s/var/%s', dirname($reflection->getFileName(),3), $this->options['format']); + if ($this->options['dataDirectory'] === 'auto') { + $dataDirectory = sprintf('%s/data', $this->getPackagePath(self::DATA_PACKAGE)); } - if(is_dir($dataDirectory)){ + if (is_dir($dataDirectory)) { return $dataDirectory; } throw new StorageException(sprintf(StorageException::DIRECTORY_NOT_FOUND, $dataDirectory)); } + private function getPackagePath(string $package): string + { + return (new Composer())->getInstallationManager()->getInstallPath($package); + } + + protected function callMethod($object, string $methodName, ...$arguments): void + { + if (method_exists($object, $methodName)) { + $object->$methodName($arguments); + } + } + /** * @return string * @throws StorageException - * @throws \ReflectionException */ private function findCacheDirectory(): string { $cacheDirectory = $this->options['cacheDirectory']; - if($this->options['cacheDirectory'] === 'auto') { - $reflection = new \ReflectionClass(AbstractData::class); - $cacheDirectory = sprintf('%s/var/cache', dirname($reflection->getFileName(),3)); + if ($this->options['cacheDirectory'] === 'auto') { + $cacheDirectory = sprintf('%s/var/cache', dirname(__FILE__, 1)); } - if(is_dir($cacheDirectory)){ + if (is_dir($cacheDirectory)) { return $cacheDirectory; } throw new StorageException(sprintf(StorageException::DIRECTORY_NOT_FOUND, $cacheDirectory)); } + + private function initDetector(string $type): void + { + $className = sprintf('\\EndorphinStudio\\Detector\\Detection\\%s', ucfirst(sprintf('%sDetector', $type))); + if (class_exists($className)) { + $this->detectors[$type] = new $className(); + $this->detectors[$type]->init($this); + } + } + + public function getVersion(): string + { + return $this->version; + } + + /** + * Get storage provider + * @return StorageInterface + */ + public function getDataProvider(): StorageInterface + { + return $this->dataProvider; + } + + /** + * Set data provider + * @param StorageInterface $dataProvider + */ + public function setDataProvider(StorageInterface $dataProvider): void + { + $this->dataProvider = $dataProvider; + } + + /** + * Get result object + * @return Result Result object + */ + public function getResultObject(): Result + { + return $this->resultObject; + } + + /** + * @return string + */ + public function getUserAgent(): string + { + return $this->ua; + } + + /** + * Analyse User Agent String + * @param string $ua + * @return Result + * @SuppressWarnings(PHPMD.StaticAccess) + */ + public function analyse(string $ua = 'ua'): Result + { + $request = Request::createFromGlobals(); + $this->ua = $ua === 'ua' ? $request->server->get('HTTP_USER_AGENT') : $ua; + $this->resultObject = new Result($this->ua, $this); + foreach ($this->detectors as $detectionType => $detector) { + $detector->detect(); + } + return $this->resultObject; + } + + /** + * Get list of patterns from config + * @param $list + * @param $type + * @return array + */ + public function getPatternList($list, $type): array + { + return array_key_exists($type, $list) ? $list[$type] : []; + } } diff --git a/var/.gitignore b/var/.gitignore new file mode 100644 index 0000000..1d085ca --- /dev/null +++ b/var/.gitignore @@ -0,0 +1 @@ +** From bc36c8271e7f4812d23e73ef54d1015bd5f739f7 Mon Sep 17 00:00:00 2001 From: Serhii Nekhaienko Date: Wed, 1 Sep 2021 19:17:35 +0300 Subject: [PATCH 3/6] v6.0.3 - fixed circle.ci config.yml --- .circleci/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 47a6fa2..4378bc1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,7 +2,7 @@ version: 2 jobs: test: docker: - - image: circleci/php:7.0-apache-node-browsers + - image: circleci/php:7.1-apache-node-browsers steps: - checkout - run: sudo composer self-update @@ -12,4 +12,4 @@ workflows: version: 2 test: jobs: - - test \ No newline at end of file + - test From cd5c0a4a13cb9b78a273eaf8a857b2bcb8fe15d8 Mon Sep 17 00:00:00 2001 From: Serhii Nekhaienko Date: Wed, 1 Sep 2021 19:25:07 +0300 Subject: [PATCH 4/6] v6.0.3 - fix get data function --- src/Detector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Detector.php b/src/Detector.php index a06ce0f..6ca306e 100644 --- a/src/Detector.php +++ b/src/Detector.php @@ -9,7 +9,6 @@ namespace EndorphinStudio\Detector; -use Composer\Composer; use EndorphinStudio\Detector\Data\Result; use EndorphinStudio\Detector\Exception\StorageException; use EndorphinStudio\Detector\Storage\StorageInterface; @@ -120,7 +119,8 @@ private function findDataDirectory(): string private function getPackagePath(string $package): string { - return (new Composer())->getInstallationManager()->getInstallPath($package); + $vendorDir = dirname(__FILE__, 3); + return sprintf('%s/%s', $vendorDir, $package); } protected function callMethod($object, string $methodName, ...$arguments): void From 490d514f04ccc52bd6c020542c493889692141e9 Mon Sep 17 00:00:00 2001 From: Serhii Nekhaienko Date: Wed, 1 Sep 2021 19:28:14 +0300 Subject: [PATCH 5/6] v6.0.3 - fix get data function --- src/Detector.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Detector.php b/src/Detector.php index 6ca306e..8b27a5d 100644 --- a/src/Detector.php +++ b/src/Detector.php @@ -119,7 +119,11 @@ private function findDataDirectory(): string private function getPackagePath(string $package): string { - $vendorDir = dirname(__FILE__, 3); + if(dirname(__FILE__, 2) === 'endorphin-studio') { + $vendorDir = dirname(__FILE__, 3); + } else { + $vendorDir = dirname(__FILE__, 1).'/vendor'; + } return sprintf('%s/%s', $vendorDir, $package); } From 23d943468465d90256416dfd2a9bbcb4250f3b35 Mon Sep 17 00:00:00 2001 From: Serhii Nekhaienko Date: Wed, 1 Sep 2021 19:35:06 +0300 Subject: [PATCH 6/6] v6.0.3 - fix get data function --- src/Detector.php | 11 +++++++---- var/{ => cache}/.gitignore | 0 2 files changed, 7 insertions(+), 4 deletions(-) rename var/{ => cache}/.gitignore (100%) diff --git a/src/Detector.php b/src/Detector.php index 8b27a5d..15d181b 100644 --- a/src/Detector.php +++ b/src/Detector.php @@ -119,10 +119,13 @@ private function findDataDirectory(): string private function getPackagePath(string $package): string { - if(dirname(__FILE__, 2) === 'endorphin-studio') { - $vendorDir = dirname(__FILE__, 3); + /** + * If running from vendor directory + */ + if (strpos(dirname(__FILE__, 3), 'endorphin-studio') !== false) { + $vendorDir = dirname(__FILE__, 4); } else { - $vendorDir = dirname(__FILE__, 1).'/vendor'; + $vendorDir = dirname(__FILE__, 2) . '/vendor'; } return sprintf('%s/%s', $vendorDir, $package); } @@ -142,7 +145,7 @@ private function findCacheDirectory(): string { $cacheDirectory = $this->options['cacheDirectory']; if ($this->options['cacheDirectory'] === 'auto') { - $cacheDirectory = sprintf('%s/var/cache', dirname(__FILE__, 1)); + $cacheDirectory = sprintf('%s/var/cache', dirname(__FILE__, 2)); } if (is_dir($cacheDirectory)) { return $cacheDirectory; diff --git a/var/.gitignore b/var/cache/.gitignore similarity index 100% rename from var/.gitignore rename to var/cache/.gitignore