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 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..15d181b 100644 --- a/src/Detector.php +++ b/src/Detector.php @@ -9,11 +9,11 @@ namespace EndorphinStudio\Detector; -use EndorphinStudio\Detector\Data\AbstractData; 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 +23,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 +65,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 +74,159 @@ 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 + { + /** + * If running from vendor directory + */ + if (strpos(dirname(__FILE__, 3), 'endorphin-studio') !== false) { + $vendorDir = dirname(__FILE__, 4); + } else { + $vendorDir = dirname(__FILE__, 2) . '/vendor'; + } + return sprintf('%s/%s', $vendorDir, $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__, 2)); } - 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/cache/.gitignore b/var/cache/.gitignore new file mode 100644 index 0000000..1d085ca --- /dev/null +++ b/var/cache/.gitignore @@ -0,0 +1 @@ +**