Skip to content

Commit

Permalink
Merge pull request #3 from fchastanet/fix/CK-664
Browse files Browse the repository at this point in the history
use matomo device-detector instead of piwik
  • Loading branch information
mwebberck authored Feb 4, 2021
2 parents 6362ac9 + 6b61f56 commit 0a3c76a
Show file tree
Hide file tree
Showing 14 changed files with 2,922 additions and 725 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/vendor/
logs/
.idea/
23 changes: 7 additions & 16 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
language: php

php:
- 5.5
- 5.6
- hhvm
- 7.2
- 7.3
- 7.4
- 8.0

matrix:
fast_finish: true
include:
- php: 5.6
env: SYMFONY_VERSION=2.6.*
- php: 5.6
env: SYMFONY_VERSION=2.7.*
- php: 5.6
env: SYMFONY_VERSION=2.8.*
allow_failures:
- php: hhvm
- php: 8.0

sudo: false

Expand All @@ -25,16 +19,13 @@ cache:

before_install:
- composer selfupdate
- if [ "$SYMFONY_VERSION" != "" ]; then composer require "symfony/symfony:${SYMFONY_VERSION}" --no-update; fi;

install: composer update --prefer-dist --no-interaction $COMPOSER_FLAGS
install: composer install --prefer-dist --no-interaction $COMPOSER_FLAGS

script:
- phpunit --coverage-text --coverage-clover=coverage.clover
- ./vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover

after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover

notifications:
email: cyril.quintin@gmail.com
16 changes: 11 additions & 5 deletions DependencyInjection/CrossKnowledgeDeviceDetectExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace CrossKnowledge\DeviceDetectBundle\DependencyInjection;

use Exception;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Reference;
Expand All @@ -10,21 +11,26 @@

class CrossKnowledgeDeviceDetectExtension extends Extension
{
/**
* @param array $configs
* @param ContainerBuilder $container
* @throws Exception
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$configs = $this->processConfiguration($configuration, $configs);

$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
$loader->load('services.yml');

$definition = $container->findDefinition('crossknowledge.device_detect');
if (!empty($config['cache_manager'])) {
$definition->replaceArgument(1, new Reference($config['cache_manager']));
if (!empty($configs['cache_manager'])) {
$definition->replaceArgument(1, new Reference($configs['cache_manager']));
}

if (!empty($config['device_detector_options'])) {
$definition->addArgument($config['device_detector_options']);
if (!empty($configs['device_detector_options'])) {
$definition->addArgument($configs['device_detector_options']);
} else {
$definition->addArgument(null);
}
Expand Down
14 changes: 12 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
CrossKnowledge DeviceDetect Bundle
==================================

The CrossKnowledge/DeviceDetectBundle wraps piwik/device-detector with semantic D.I configuration and twig helpers.
The CrossKnowledge/DeviceDetectBundle wraps matomo/device-detector with semantic D.I. configuration and twig helpers.

Features:

Expand All @@ -26,6 +26,16 @@ Installation

All the installation instructions are located in the documentation.

Release Notes
-------------

## V2.0 (2020-01-06)
Change underlying library from piwik/device-detector to matomo/device-detector
DeviceDetector lazy loading
Minimum php version is 7.2
Upgraded phpunit version to 8
hhvm no more supported

License
-------

Expand All @@ -38,7 +48,7 @@ About

CrossKnowledgeDeviceDetectBundle is a [CrossKnowledge](https://crossknowledge.com) initiative.
See also the list of [contributors](https://github.com/CrossKnowledge/DeviceDetectBundle/contributors).
A couple of "distribution" (travis,readme.md, etc..) files are inspired from FriendsOfSymfony/FOSUserBundle's.
A couple of "distribution" (travis,readme.md, etc.) files are inspired from FriendsOfSymfony/FOSUserBundle's.

Contributions
-------------
Expand Down
8 changes: 6 additions & 2 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
services:
crossknowledge.default_cache_manager:
class: Doctrine\Common\Cache\PhpFileCache
arguments: [%kernel.cache_dir%/devicedetect]
arguments: ["%kernel.cache_dir%/devicedetect"]

crossknowledge.default_cache_manager_bridge:
class: DeviceDetector\Cache\DoctrineBridge
arguments: ["@crossknowledge.default_cache_manager"]

crossknowledge.device_detect.twig.device_detect:
class: CrossKnowledge\DeviceDetectBundle\Twig\DeviceDetectExtension
Expand All @@ -12,4 +16,4 @@ services:

crossknowledge.device_detect:
class: CrossKnowledge\DeviceDetectBundle\Services\DeviceDetect
arguments: ["@request_stack", "@crossknowledge.default_cache_manager"]
arguments: ["@request_stack", "@crossknowledge.default_cache_manager_bridge"]
104 changes: 71 additions & 33 deletions Services/DeviceDetect.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,80 +2,118 @@

namespace CrossKnowledge\DeviceDetectBundle\Services;

use DeviceDetector\DeviceDetector;
use Symfony\Component\HttpFoundation\RequestStack;
use \Doctrine\Common\Cache\CacheProvider;
use DeviceDetector\Cache\CacheInterface;

class DeviceDetect
{
/** @var RequestStack */
protected $requestStack;

/** @var \DeviceDetector\DeviceDetector */
/** @var DeviceDetector */
protected $deviceDetector;

/** @var Cache */
/** @var CacheInterface */
protected $cacheManager;

/** @var [] */
/** @var []|null */
protected $deviceDetectorOptions;

public function __construct(RequestStack $stack, CacheProvider $cache, $deviceDetectorOptions)
/** @var string we save here user agent as $_SERVER['HTTP_USER_AGENT'] could be lost when using symfony events */
protected $userAgent;

/**
* user agent deduced from requestStack or $_SERVER['HTTP_USER_AGENT'] if not available
* '' if no user agent found
*/
public function __construct(RequestStack $stack, CacheInterface $cache, $deviceDetectorOptions)
{
$this->cacheManager = $cache;
$this->requestStack = $stack;
$this->setOptions($deviceDetectorOptions);

if (null !== $this->requestStack && $this->requestStack->getCurrentRequest()) {
$userAgent = $this->requestStack->getCurrentRequest()->headers->get('User-Agent');
} else {
$userAgent = '';
}

$this->deviceDetector = new \DeviceDetector\DeviceDetector($userAgent);
$this->deviceDetector->setCache($this->getCacheManager());

if (!empty($this->deviceDetectorOptions['discard_bot_information'])) {
$this->deviceDetector->discardBotInformation();
$this->userAgent = $this->requestStack->getCurrentRequest()->headers->get('User-Agent') ?? '';
}

if (!empty($this->deviceDetectorOptions['skip_bot_detection'])) {
$this->deviceDetector->skipBotDetection();
// Symfony Bug, in case of symfony event, request stack is lost
if (empty($this->userAgent)) {
$this->userAgent = @$_SERVER['HTTP_USER_AGENT'] ?? '';
}

$this->deviceDetector->parse();
$this->setOptions($deviceDetectorOptions);
}

public function isTablet()
/**
* @return bool
*/
public function isTablet(): bool
{
return $this->deviceDetector->isTablet();
return $this->getDeviceDetector()->isTablet();
}

public function isMobile()
/**
* @return bool
*/
public function isMobile(): bool
{
if ($this->deviceDetector->isTablet()) {
if ($this->getDeviceDetector()->isTablet()) {
return false;
}

return $this->deviceDetector->isMobile();
return $this->getDeviceDetector()->isMobile();
}

public function isDesktop()
/**
* @return bool
*/
public function isDesktop(): bool
{
return $this->deviceDetector->isDesktop();
return $this->getDeviceDetector()->isDesktop();
}

public function getCacheManager()
/**
* @return CacheInterface
*/
public function getCacheManager(): CacheInterface
{
return $this->cacheManager;
}

public function setOptions($deviceDetectorOptions)
/**
* @param array|null $deviceDetectorOptions
*/
public function setOptions(?array $deviceDetectorOptions): void
{
$this->deviceDetectorOptions = $deviceDetectorOptions;
}

public function getDeviceDetector()
{
/**
* @return string user agent deduced from requestStack or $_SERVER['HTTP_USER_AGENT'] if not available
* '' if no user agent found
*/
protected function getUserAgent(): string {
return $this->userAgent;
}

/**
* Lazy loading of DeviceDetector
* @return DeviceDetector
*/
public function getDeviceDetector(): DeviceDetector {
if (null !== $this->deviceDetector) {
return $this->deviceDetector;
}
$this->deviceDetector = new DeviceDetector($this->getUserAgent());
$this->deviceDetector->setCache($this->getCacheManager());

if (!empty($this->deviceDetectorOptions['discard_bot_information'])) {
$this->deviceDetector->discardBotInformation();
}

if (!empty($this->deviceDetectorOptions['skip_bot_detection'])) {
$this->deviceDetector->skipBotDetection();
}

$this->deviceDetector->parse();

return $this->deviceDetector;
}
}
32 changes: 23 additions & 9 deletions Tests/Services/DeviceDetectTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,21 @@
namespace CrossKnowledge\DeviceDetectBundle\Tests\Services;

use CrossKnowledge\DeviceDetectBundle\DependencyInjection\CrossKnowledgeDeviceDetectExtension;
use Exception;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

class DeviceDetectTest extends \PHPUnit_Framework_TestCase
class DeviceDetectTest extends TestCase
{
protected function createContainer($loadAppFile)
/**
* @param $loadAppFile
* @return ContainerBuilder
* @throws Exception
*/
protected function createContainer($loadAppFile): ContainerBuilder
{
$extension = new CrossKnowledgeDeviceDetectExtension();
$container = new ContainerBuilder(new ParameterBag(['kernel.cache_dir' => __DIR__.'/fixtures']));
Expand All @@ -29,27 +36,34 @@ protected function createContainer($loadAppFile)
return $container;
}

public function toggleWithAndWithoutAppConfig()
/**
* @return array[]
*/
public function toggleWithAndWithoutAppConfig(): array
{
return [
[true, 'crossknowledge.example_cache_override'],
[false, 'crossknowledge.default_cache_manager'],
[false, 'crossknowledge.default_cache_manager_bridge'],
];
}

/**
* @dataProvider toggleWithAndWithoutAppConfig
* @param bool $configLoaded
* @param string $expectedServiceName
* @throws Exception
*/
public function testCacheManagerDefaultIsOverridable($configLoaded, $expectedServicename)
public function testCacheManagerDefaultIsOverridable(bool $configLoaded, string $expectedServiceName): void
{
$container = $this->createContainer($configLoaded);
$definition = $container->getDefinition('crossknowledge.device_detect');
$arguments = $definition->getArguments();

$this->assertEquals(
$expectedServicename,
self::assertEquals(
$expectedServiceName,
(string)$arguments[1],
'Once the option cache_manager is '.($configLoaded ? 'set' : 'not set').', the service must be overriden'
'Once the option cache_manager is '.($configLoaded ? 'set' : 'not set').', the service must be overridden'
);
}

}
}
2 changes: 1 addition & 1 deletion Tests/Services/fixtures/config.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
cross_knowledge_device_detect:
cache_manager: crossknowledge.example_cache_override
cache_manager: crossknowledge.example_cache_override
Loading

0 comments on commit 0a3c76a

Please sign in to comment.