diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index f7d6396..6c61cb4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,90 +14,76 @@ on: workflow_dispatch: jobs: - phpunit: - name: Test on PHP ${{ matrix.php }} and Symfony ${{ matrix.symfony-require }} + tests: + environment: main runs-on: ubuntu-latest - env: - SYMFONY_REQUIRE: ${{ matrix.symfony-require }} - strategy: fail-fast: false matrix: - php: - - 8.2 - dependencies: - - highest - stability: - - stable - symfony-require: - # Test latest stable version - - 7.* + php: ['8.2'] + stability: [prefer-stable] + minimum-stability: [stable] + symfony-version: [7.2.*] + is-current: [true] + include: + - php: '8.3' + symfony-version: 7.2.* + stability: prefer-stable + - php: '8.4' + symfony-version: 7.2.* + stability: prefer-stable + + name: PHP ${{ matrix.php }} and Symfony ${{ matrix.symfony-require }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.composer/cache/files + key: composer-packages-${{ hashFiles('composer.lock') }} - - name: Install PHP with PCOV + - name: Install PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} - coverage: pcov - ini-values: zend.assertions=1 + coverage: xdebug - - name: Globally install symfony/flex + - name: Install dependencies + env: + SYMFONY_REQUIRE: ${{ matrix.symfony-version }} run: | - composer global config --no-plugins allow-plugins.symfony/flex true - composer global require --no-progress --no-scripts --no-plugins symfony/flex - - - name: Configure minimum stability of dependencies - run: composer config minimum-stability ${{ matrix.stability }} + composer global config --no-plugins allow-plugins.symfony/flex true + composer global require --no-progress --no-scripts --no-plugins symfony/flex + composer config minimum-stability ${{ matrix.minimum-stability }} + composer update --no-interaction --prefer-dist - - name: Install dependencies with Composer - uses: ramsey/composer-install@v2 - with: - dependency-versions: ${{ matrix.dependencies }} - composer-options: --prefer-dist + - name: PHP-CS-Fixer + continue-on-error: ${{ !matrix.is-current }} + run: vendor/bin/php-cs-fixer fix --dry-run --ansi -vvv - - name: Lint via PHP Coding Standards Fixer and PHP_CodeSniffer - run: | - vendor/bin/php-cs-fixer fix --dry-run --diff --ansi -vvv - vendor/bin/phpcs --report=code + - name: PHP_CodeSniffer + continue-on-error: ${{ !matrix.is-current }} + run: vendor/bin/phpcs --report=code - - name: Static Analysis via PHPStan - run: vendor/bin/phpstan analyse + - name: PHPStan + continue-on-error: ${{ !matrix.is-current }} + run: vendor/bin/phpstan analyse src tests --level 7 - name: Unit and Feature tests via PHPUnit - run: php vendor/bin/phpunit + env: + SYMFONY_DEPRECATIONS_HELPER: weak + run: vendor/bin/phpunit - - name: Upload coverage file - uses: actions/upload-artifact@v3 - with: - name: phpunit-${{ matrix.php }}-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}.coverage - path: build/coverage.xml + - name: SonarCloud Scan + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + uses: sonarsource/sonarcloud-github-action@v2 - name: Setup tmate session if: ${{ failure() }} uses: mxschmitt/action-tmate@v3 with: limit-access-to-actor: true - - upload_coverage: - name: Upload coverage to Codecov - runs-on: ubuntu-latest - needs: - - phpunit - - steps: - - name: Checkout code - uses: actions/checkout@v3 - - - name: Download coverage files - uses: actions/download-artifact@v3 - with: - path: reports - - - name: Upload to Codecov - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - uses: codecov/codecov-action@v2 - with: - directory: reports diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.php similarity index 60% rename from .php-cs-fixer.dist.php rename to .php-cs-fixer.php index e8b1e39..72a8f90 100755 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.php @@ -10,31 +10,13 @@ return (new PhpCsFixer\Config()) ->setRiskyAllowed(true) ->setRules([ - '@DoctrineAnnotation' => true, - '@PhpCsFixer:risky' => true, - '@PhpCsFixer' => true, - '@PHPUnit84Migration:risky' => true, - '@PSR1' => true, - '@PSR12:risky' => true, - '@PSR12' => true, - '@PSR2' => true, - '@Symfony:risky' => true, + '@PER-CS:risky' => true, + '@PER-CS' => true, + '@PHP82Migration:risky' => true, + '@PHP84Migration' => true, + '@PHPUnit100Migration:risky' => true, '@Symfony' => true, - 'array_indentation' => true, - 'array_syntax' => [ - 'syntax' => 'short', - ], - 'doctrine_annotation_array_assignment' => [ - 'operator' => '=', - ], - 'doctrine_annotation_spaces' => [ - 'after_array_assignments_equals' => false, - 'before_array_assignments_equals' => false, - ], - 'linebreak_after_opening_tag' => true, - 'list_syntax' => [ - 'syntax' => 'short', - ], + '@Symfony:risky' => true, 'no_extra_blank_lines' => [ 'tokens' => [ 'break', @@ -48,7 +30,6 @@ 'use', ], ], - 'no_superfluous_phpdoc_tags' => true, 'no_useless_else' => true, 'no_useless_return' => true, 'ordered_class_elements' => true, @@ -68,7 +49,7 @@ 'single_line_comment_style' => true, 'strict_comparison' => true, 'strict_param' => true, - 'void_return' => false, + 'php_unit_test_class_requires_covers' => false, ]) ->setFinder($finder) ; diff --git a/src/Resources/meta/LICENSE b/LICENSE similarity index 100% rename from src/Resources/meta/LICENSE rename to LICENSE diff --git a/Makefile b/Makefile index 4ea0654..3eb4d4e 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ all: test phpunit: - php vendor/bin/phpunit + XDEBUG_MODE=coverage | php vendor/bin/phpunit --display-phpunit-deprecations lint: php vendor/bin/php-cs-fixer fix --diff php vendor/bin/phpcs --report=code - php vendor/bin/phpstan analyse + php vendor/bin/phpstan analyse src tests --level 7 --memory-limit=-1 test: lint phpunit diff --git a/README.md b/README.md index fca082a..db25de9 100644 --- a/README.md +++ b/README.md @@ -3,22 +3,24 @@ MobileDetectBundle ================== -Symfony 3.4.x-6.0.x bundle to detect mobile devices, manage mobile view and redirect to the mobile and tablet version. +Symfony 5.4.x-7.0 bundle to detect mobile devices, manage mobile view and redirect to the mobile and tablet version. [![Github Actions Status](https://github.com/tattali/MobileDetectBundle/actions/workflows/main.yml/badge.svg?branch=main -)](https://github.com/tattali/MobileDetectBundle/actions/workflows/main.yml?query=branch%3Amain) [![Latest Stable Version](http://poser.pugx.org/tattali/mobile-detect-bundle/v)](https://packagist.org/packages/tattali/mobile-detect-bundle) [![Total Downloads](http://poser.pugx.org/tattali/mobile-detect-bundle/downloads)](https://packagist.org/packages/tattali/mobile-detect-bundle) [![codecov](https://codecov.io/gh/tattali/MobileDetectBundle/branch/main/graph/badge.svg?token=HWV1OYRSD9)](https://codecov.io/gh/tattali/MobileDetectBundle) [![License](http://poser.pugx.org/tattali/mobile-detect-bundle/license)](https://packagist.org/packages/tattali/mobile-detect-bundle) [![PHP Version Require](http://poser.pugx.org/tattali/mobile-detect-bundle/require/php)](https://packagist.org/packages/tattali/mobile-detect-bundle) +)](https://github.com/tattali/MobileDetectBundle/actions/workflows/main.yml?query=branch%3Amain) [![Latest Stable Version](https://poser.pugx.org/tattali/mobile-detect-bundle/v)](https://packagist.org/packages/tattali/mobile-detect-bundle) [![Total Downloads](https://poser.pugx.org/tattali/mobile-detect-bundle/downloads)](https://packagist.org/packages/tattali/mobile-detect-bundle) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=tattali_MobileDetectBundle&metric=coverage)](https://sonarcloud.io/summary/new_code?id=tattali_MobileDetectBundle) [![License](https://poser.pugx.org/tattali/mobile-detect-bundle/license)](https://packagist.org/packages/tattali/mobile-detect-bundle) [![PHP Version Require](https://poser.pugx.org/tattali/mobile-detect-bundle/require/php)](https://packagist.org/packages/tattali/mobile-detect-bundle) *This bundle is a fork of [suncat2000/MobileDetectBundle](https://github.com/suncat2000/MobileDetectBundle). As this project doesn't look maintained anymore, we decided to create & maintain a fork. For more information read our [manifest](https://github.com/tattali/MobileDetectBundle/issues/8).* Introduction ------------ -This Bundle use [Mobile_Detect](https://github.com/serbanghita/Mobile-Detect) class and provides the following features: +This Bundle use [MobileDetect](https://github.com/serbanghita/Mobile-Detect) class and provides the following features: * Detect the various mobile devices by Name, OS, browser User-Agent -* Manages site views for the various mobile devices (`mobile`, `tablet`, `full`) +* Manages site views for the various mobile devices (`mobile`, `tablet`, `desktop`) * Redirects to mobile and tablet sites +* **[Migrate to 7x](src/Resources/doc/migration-7x.md)** + Documentation ------------- @@ -32,9 +34,9 @@ composer require tattali/mobile-detect-bundle #### Checking device ```php -use MobileDetectBundle\DeviceDetector\MobileDetectorInterface; +use Detection\MobileDetect; -public function someaction(MobileDetectorInterface $mobileDetector) +public function someaction(MobileDetect $mobileDetector) { $mobileDetector->isMobile(); $mobileDetector->isTablet(); @@ -55,11 +57,11 @@ Available User-Agents (uaMatch) with the php `is()` and twig `is_device()` [here For switch device view, use `device_view` GET parameter: ```url -http://localhost:8000?device_view={full/mobile/tablet} +https://localhost:8000?device_view={desktop/mobile/tablet} ``` Or using the Symfony toolbar -![mbd-bundle-sf-toolbar](https://user-images.githubusercontent.com/10502887/161488224-aaedde1c-d3c3-4636-8761-a207fbd5d4ff.png) +![mbd-bundle-sf-toolbar](src/Resources/doc/sf-toolbar.png) #### Going further @@ -75,6 +77,6 @@ Any feedback and contribution will be very appreciated. License and credits ------- -This bundle is under the MIT license. See the complete [license](src/Resources/meta/LICENSE) in the bundle +This bundle is under the MIT license. See the complete [license](LICENSE) in the bundle Original authors: [suncat2000](https://github.com/suncat2000), [HenriVesala](https://github.com/HenriVesala), [netmikey](https://github.com/netmikey) and [all contributors](https://github.com/suncat2000/MobileDetectBundle/graphs/contributors) diff --git a/codecov.yml b/codecov.yml deleted file mode 100644 index 1bc4f5d..0000000 --- a/codecov.yml +++ /dev/null @@ -1,8 +0,0 @@ -coverage: - status: - project: - default: - target: auto - # adjust accordingly based on how flaky your tests are - # this allows a 10% drop from the previous base commit coverage - threshold: 10% diff --git a/composer.json b/composer.json index 8180cfb..ede2eb6 100644 --- a/composer.json +++ b/composer.json @@ -35,23 +35,25 @@ ], "require": { "php": ">=8.2", - "mobiledetect/mobiledetectlib": "^2.8.15", - "symfony/dependency-injection": "^7.0", - "symfony/event-dispatcher": "^7.0", - "symfony/framework-bundle": "^7.0", - "symfony/yaml": "^7.0", - "twig/twig": "^2.0 || ^3.0" + "mobiledetect/mobiledetectlib": "^4.8", + "symfony/config": "^7.2", + "symfony/dependency-injection": "^7.2", + "symfony/event-dispatcher": "^7.2", + "symfony/http-kernel": "^7.2", + "symfony/routing": "^7.2", + "symfony/yaml": "^7.2", + "twig/twig": "^3.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.8", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan-nette": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "phpstan/phpstan": "^1.0", - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "^3.6", - "symfony/dotenv": "^7.0", - "symfony/phpunit-bridge": "^7.0" + "friendsofphp/php-cs-fixer": "^3.65", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-symfony": "^2.0", + "phpunit/phpunit": "^11.5", + "squizlabs/php_codesniffer": "^3.11", + "symfony/dotenv": "^7.2", + "symfony/phpunit-bridge": "^7.2" }, "config": { "sort-packages": true, diff --git a/phpstan.neon.dist b/phpstan.neon.dist deleted file mode 100755 index 0ecb26b..0000000 --- a/phpstan.neon.dist +++ /dev/null @@ -1,6 +0,0 @@ -parameters: - level: 1 - tmpDir: .phpstan - paths: - - src - - tests diff --git a/phpunit.xml.dist b/phpunit.xml.dist index a2bff23..910b0ce 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,32 +1,34 @@ - + - - - src - - - - - - - - - - - - - - - tests - - - - - - + colors="true" + bootstrap="vendor/autoload.php" + failOnRisky="true" + failOnWarning="true"> + + + + + + + + ./tests/ + + + + + + ./src/ + + + + + + + + + + diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..a2bc61e --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,15 @@ +sonar.projectKey=tattali_MobileDetectBundle +sonar.organization=tattali + +sonar.php.coverage.reportPaths=build/coverage.xml + +# This is the name and version displayed in the SonarCloud UI. +#sonar.projectName=CalendarBundle +#sonar.projectVersion=1.0 + + +# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. +sonar.sources=./src + +# Encoding of the source code. Default is default system encoding +#sonar.sourceEncoding=UTF-8 diff --git a/src/DataCollector/DeviceDataCollector.php b/src/DataCollector/DeviceDataCollector.php index 071b28d..0320f44 100644 --- a/src/DataCollector/DeviceDataCollector.php +++ b/src/DataCollector/DeviceDataCollector.php @@ -18,6 +18,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\DataCollector\DataCollector; +use Symfony\Component\VarDumper\Cloner\Data; /** * @author Jonas HAOUZI @@ -25,18 +26,12 @@ class DeviceDataCollector extends DataCollector { /** - * @var DeviceView + * @param array $redirectConfig */ - protected $deviceView; - - /** - * @var array - */ - protected $redirectConfig; - - public function __construct(DeviceView $deviceView) - { - $this->deviceView = $deviceView; + public function __construct( + protected readonly DeviceView $deviceView, + protected readonly array $redirectConfig = [], + ) { } /** @@ -45,26 +40,26 @@ public function __construct(DeviceView $deviceView) public function collect( Request $request, Response $response, - \Throwable $exception = null + ?\Throwable $exception = null, ): void { $this->data['currentView'] = $this->deviceView->getViewType(); $this->data['views'] = [ [ - 'type' => DeviceView::VIEW_FULL, - 'label' => 'Full', + 'type' => DeviceView::VIEW_DESKTOP, + 'label' => 'Desktop', 'link' => $this->generateSwitchLink( $request, - DeviceView::VIEW_FULL + DeviceView::VIEW_DESKTOP, ), - 'isCurrent' => $this->deviceView->isFullView(), - 'enabled' => $this->canUseView(DeviceView::VIEW_FULL, $request->getSchemeAndHttpHost()), + 'isCurrent' => $this->deviceView->isDesktopView(), + 'enabled' => $this->canUseView(DeviceView::VIEW_DESKTOP, $request->getSchemeAndHttpHost()), ], [ 'type' => DeviceView::VIEW_TABLET, 'label' => 'Tablet', 'link' => $this->generateSwitchLink( $request, - DeviceView::VIEW_TABLET + DeviceView::VIEW_TABLET, ), 'isCurrent' => $this->deviceView->isTabletView(), 'enabled' => $this->canUseView(DeviceView::VIEW_TABLET, $request->getSchemeAndHttpHost()), @@ -74,7 +69,7 @@ public function collect( 'label' => 'Mobile', 'link' => $this->generateSwitchLink( $request, - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), 'isCurrent' => $this->deviceView->isMobileView(), 'enabled' => $this->canUseView(DeviceView::VIEW_MOBILE, $request->getSchemeAndHttpHost()), @@ -87,22 +82,23 @@ public function getCurrentView(): string return $this->data['currentView']; } + /** + * @return array + */ public function getViews(): array { return $this->data['views']; } - public function setRedirectConfig(array $redirectConfig): void - { - $this->redirectConfig = $redirectConfig; - } - public function getName(): string { return 'device.collector'; } - public function getData(): array + /** + * @return array + */ + public function getData(): array|Data { return $this->data; } @@ -114,8 +110,7 @@ public function reset(): void protected function canUseView(string $view, ?string $host): bool { - if (!\is_array($this->redirectConfig) - || !isset($this->redirectConfig[$view]) + if (!isset($this->redirectConfig[$view]) || !isset($this->redirectConfig[$view]['is_enabled']) || false === $this->redirectConfig[$view]['is_enabled'] ) { @@ -128,7 +123,7 @@ protected function canUseView(string $view, ?string $host): bool && \in_array($this->redirectConfig[$view]['action'], [RequestResponseListener::REDIRECT, RequestResponseListener::REDIRECT_WITHOUT_PATH], true) ) { $parseHost = parse_url($this->redirectConfig[$view]['host']); - $redirectHost = $parseHost['scheme'].'://'.$parseHost['host']; + $redirectHost = ($parseHost['scheme'] ?? '').'://'.($parseHost['host'] ?? ''); if (!empty($parseHost['port'])) { $redirectHost .= ':'.$parseHost['port']; } @@ -143,15 +138,15 @@ protected function canUseView(string $view, ?string $host): bool private function generateSwitchLink( Request $request, - string $view - ): ?string { + string $view, + ): string { $requestSwitchView = $request->duplicate(); $requestSwitchView->query->set($this->deviceView->getSwitchParam(), $view); $requestSwitchView->server->set( 'QUERY_STRING', Request::normalizeQueryString( - http_build_query($requestSwitchView->query->all()) - ) + http_build_query($requestSwitchView->query->all()), + ), ); return $requestSwitchView->getUri(); diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index fa8ac27..85c2c19 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -21,7 +21,7 @@ /** * @author suncat2000 - * @author HenriVesala + * @author HenriVesala */ class Configuration implements ConfigurationInterface { @@ -56,7 +56,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('action')->defaultValue(RequestResponseListener::REDIRECT)->cannotBeEmpty()->end() ->end() ->end() - ->arrayNode('full') + ->arrayNode('desktop') ->addDefaultsIfNotSet() ->children() ->booleanNode('is_enabled')->defaultFalse()->end() diff --git a/src/DependencyInjection/MobileDetectExtension.php b/src/DependencyInjection/MobileDetectExtension.php index 016565b..ad5b687 100644 --- a/src/DependencyInjection/MobileDetectExtension.php +++ b/src/DependencyInjection/MobileDetectExtension.php @@ -15,14 +15,11 @@ use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Extension\Extension; use Symfony\Component\DependencyInjection\Loader; -use Symfony\Component\HttpKernel\DependencyInjection\Extension; class MobileDetectExtension extends Extension { - /** - * {@inheritDoc} - */ public function load(array $configs, ContainerBuilder $container): void { $configuration = new Configuration(); @@ -41,9 +38,9 @@ public function load(array $configs, ContainerBuilder $container): void $config['redirect']['tablet']['is_enabled'] = false; } - // valid full host - if ($config['redirect']['full']['is_enabled'] && !$this->validHost($config['redirect']['full']['host'])) { - $config['redirect']['full']['is_enabled'] = false; + // valid desktop host + if ($config['redirect']['desktop']['is_enabled'] && !$this->validHost($config['redirect']['desktop']['host'])) { + $config['redirect']['desktop']['is_enabled'] = false; } $container->setParameter('mobile_detect.redirect', $config['redirect']); diff --git a/src/DeviceDetector/MobileDetector.php b/src/DeviceDetector/MobileDetector.php deleted file mode 100644 index 4634b08..0000000 --- a/src/DeviceDetector/MobileDetector.php +++ /dev/null @@ -1,21 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MobileDetectBundle\DeviceDetector; - -/** - * @author suncat2000 - */ -class MobileDetector extends \Mobile_Detect implements MobileDetectorInterface -{ -} diff --git a/src/DeviceDetector/MobileDetectorInterface.php b/src/DeviceDetector/MobileDetectorInterface.php deleted file mode 100644 index 24241e0..0000000 --- a/src/DeviceDetector/MobileDetectorInterface.php +++ /dev/null @@ -1,427 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace MobileDetectBundle\DeviceDetector; - -/** - * @method bool isiPhone() - * @method bool isBlackBerry() - * @method bool isPixel() - * @method bool isHTC() - * @method bool isNexus() - * @method bool isDell() - * @method bool isMotorola() - * @method bool isSamsung() - * @method bool isLG() - * @method bool isSony() - * @method bool isAsus() - * @method bool isXiaomi() - * @method bool isNokiaLumia() - * @method bool isMicromax() - * @method bool isPalm() - * @method bool isVertu() - * @method bool isPantech() - * @method bool isFly() - * @method bool isWiko() - * @method bool isiMobile() - * @method bool isSimValley() - * @method bool isWolfgang() - * @method bool isAlcatel() - * @method bool isNintendo() - * @method bool isAmoi() - * @method bool isINQ() - * @method bool isOnePlus() - * @method bool isGenericPhone() - * @method bool isiPad() - * @method bool isNexusTablet() - * @method bool isGoogleTablet() - * @method bool isSamsungTablet() - * @method bool isKindle() - * @method bool isSurfaceTablet() - * @method bool isHPTablet() - * @method bool isAsusTablet() - * @method bool isBlackBerryTablet() - * @method bool isHTCtablet() - * @method bool isMotorolaTablet() - * @method bool isNookTablet() - * @method bool isAcerTablet() - * @method bool isToshibaTablet() - * @method bool isLGTablet() - * @method bool isFujitsuTablet() - * @method bool isPrestigioTablet() - * @method bool isLenovoTablet() - * @method bool isDellTablet() - * @method bool isYarvikTablet() - * @method bool isMedionTablet() - * @method bool isArnovaTablet() - * @method bool isIntensoTablet() - * @method bool isIRUTablet() - * @method bool isMegafonTablet() - * @method bool isEbodaTablet() - * @method bool isAllViewTablet() - * @method bool isArchosTablet() - * @method bool isAinolTablet() - * @method bool isNokiaLumiaTablet() - * @method bool isSonyTablet() - * @method bool isPhilipsTablet() - * @method bool isCubeTablet() - * @method bool isCobyTablet() - * @method bool isMIDTablet() - * @method bool isMSITablet() - * @method bool isSMiTTablet() - * @method bool isRockChipTablet() - * @method bool isFlyTablet() - * @method bool isbqTablet() - * @method bool isHuaweiTablet() - * @method bool isNecTablet() - * @method bool isPantechTablet() - * @method bool isBronchoTablet() - * @method bool isVersusTablet() - * @method bool isZyncTablet() - * @method bool isPositivoTablet() - * @method bool isNabiTablet() - * @method bool isKoboTablet() - * @method bool isDanewTablet() - * @method bool isTexetTablet() - * @method bool isPlaystationTablet() - * @method bool isTrekstorTablet() - * @method bool isPyleAudioTablet() - * @method bool isAdvanTablet() - * @method bool isDanyTechTablet() - * @method bool isGalapadTablet() - * @method bool isMicromaxTablet() - * @method bool isKarbonnTablet() - * @method bool isAllFineTablet() - * @method bool isPROSCANTablet() - * @method bool isYONESTablet() - * @method bool isChangJiaTablet() - * @method bool isGUTablet() - * @method bool isPointOfViewTablet() - * @method bool isOvermaxTablet() - * @method bool isHCLTablet() - * @method bool isDPSTablet() - * @method bool isVistureTablet() - * @method bool isCrestaTablet() - * @method bool isMediatekTablet() - * @method bool isConcordeTablet() - * @method bool isGoCleverTablet() - * @method bool isModecomTablet() - * @method bool isVoninoTablet() - * @method bool isECSTablet() - * @method bool isStorexTablet() - * @method bool isVodafoneTablet() - * @method bool isEssentielBTablet() - * @method bool isRossMoorTablet() - * @method bool isiMobileTablet() - * @method bool isTolinoTablet() - * @method bool isAudioSonicTablet() - * @method bool isAMPETablet() - * @method bool isSkkTablet() - * @method bool isTecnoTablet() - * @method bool isJXDTablet() - * @method bool isiJoyTablet() - * @method bool isFX2Tablet() - * @method bool isXoroTablet() - * @method bool isViewsonicTablet() - * @method bool isVerizonTablet() - * @method bool isOdysTablet() - * @method bool isCaptivaTablet() - * @method bool isIconbitTablet() - * @method bool isTeclastTablet() - * @method bool isOndaTablet() - * @method bool isJaytechTablet() - * @method bool isBlaupunktTablet() - * @method bool isDigmaTablet() - * @method bool isEvolioTablet() - * @method bool isLavaTablet() - * @method bool isAocTablet() - * @method bool isMpmanTablet() - * @method bool isCelkonTablet() - * @method bool isWolderTablet() - * @method bool isMediacomTablet() - * @method bool isMiTablet() - * @method bool isNibiruTablet() - * @method bool isNexoTablet() - * @method bool isLeaderTablet() - * @method bool isUbislateTablet() - * @method bool isPocketBookTablet() - * @method bool isKocasoTablet() - * @method bool isHisenseTablet() - * @method bool isHudl() - * @method bool isTelstraTablet() - * @method bool isGenericTablet() - * @method bool isAndroidOS() - * @method bool isBlackBerryOS() - * @method bool isPalmOS() - * @method bool isSymbianOS() - * @method bool isWindowsMobileOS() - * @method bool isWindowsPhoneOS() - * @method bool isiOS() - * @method bool isiPadOS() - * @method bool isSailfishOS() - * @method bool isMeeGoOS() - * @method bool isMaemoOS() - * @method bool isJavaOS() - * @method bool iswebOS() - * @method bool isbadaOS() - * @method bool isBREWOS() - * @method bool isChrome() - * @method bool isDolfin() - * @method bool isOpera() - * @method bool isSkyfire() - * @method bool isEdge() - * @method bool isIE() - * @method bool isFirefox() - * @method bool isBolt() - * @method bool isTeaShark() - * @method bool isBlazer() - * @method bool isSafari() - * @method bool isWeChat() - * @method bool isUCBrowser() - * @method bool isbaiduboxapp() - * @method bool isbaidubrowser() - * @method bool isDiigoBrowser() - * @method bool isMercury() - * @method bool isObigoBrowser() - * @method bool isNetFront() - * @method bool isGenericBrowser() - * @method bool isPaleMoon() - * @method bool isBot() - * @method bool isMobileBot() - * @method bool isDesktopMode() - * @method bool isTV() - * @method bool isWebKit() - * @method bool isConsole() - * @method bool isWatch() - */ -interface MobileDetectorInterface -{ - /** - * Magic overloading method. - * - * @method bool is[...]() - * - * @param string $name - * @param array $arguments - * - * @throws \BadMethodCallException when the method doesn't exist and doesn't start with 'is' - */ - public function __call($name, $arguments); - - /** - * Retrieve the list of known browsers. Specifically, the user agents. - * - * @return array list of browsers / user agents - */ - public static function getBrowsers(); - - /** - * Retrieve the list of mobile operating systems. - * - * @return array the list of mobile operating systems - */ - public static function getOperatingSystems(); - - /** - * Retrieve the list of known phone devices. - * - * @return array list of phone devices - */ - public static function getPhoneDevices(); - - /** - * Get the properties array. - * - * @return array - */ - public static function getProperties(); - - /** - * Get the current script version. - * This is useful for the demo.php file, - * so people can check on what version they are testing - * for mobile devices. - * - * @return string the version number in semantic version format - */ - public static function getScriptVersion(); - - /** - * Retrieve the list of known tablet devices. - * - * @return array list of tablet devices - */ - public static function getTabletDevices(); - - /** - * Alias for getBrowsers() method. - * - * @return array list of user agents - */ - public static function getUserAgents(); - - /** - * Retrieve the list of known utilities. - * - * @return array list of utilities - */ - public static function getUtilities(); - - /** - * Check the HTTP headers for signs of mobile. - * This is the fastest mobile check possible; it's used - * inside isMobile() method. - * - * @return bool - */ - public function checkHttpHeadersForMobile(); - - /** - * Retrieves the cloudfront headers. - * - * @return array - */ - public function getCfHeaders(); - - /** - * Set CloudFront headers - * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/header-caching.html#header-caching-web-device. - * - * @param array $cfHeaders List of HTTP headers - * - * @return bool If there were CloudFront headers to be set - */ - public function setCfHeaders($cfHeaders = null); - - /** - * Retrieves a particular header. If it doesn't exist, no exception/error is caused. - * Simply null is returned. - * - * @param string $header The name of the header to retrieve. Can be HTTP compliant such as - * "User-Agent" or "X-Device-User-Agent" or can be php-esque with the - * all-caps, HTTP_ prefixed, underscore seperated awesomeness. - * - * @return string|null the value of the header - */ - public function getHttpHeader($header); - - /** - * Retrieves the HTTP headers. - * - * @return array - */ - public function getHttpHeaders(); - - /** - * Set the HTTP Headers. Must be PHP-flavored. This method will reset existing headers. - * - * @param array $httpHeaders The headers to set. If null, then using PHP's _SERVER to extract - * the headers. The default null is left for backwards compatibility. - */ - public function setHttpHeaders($httpHeaders = null); - - public function getMatchesArray(); - - public function getMatchingRegex(); - - public function getMobileHeaders(); - - /** - * Get all possible HTTP headers that - * can contain the User-Agent string. - * - * @return array list of HTTP headers - */ - public function getUaHttpHeaders(); - - /** - * Retrieve the User-Agent. - * - * @return string|null the user agent if it's set - */ - public function getUserAgent(); - - /** - * Set the User-Agent to be used. - * - * @param string $userAgent the user agent string to set - * - * @return string|null - */ - public function setUserAgent($userAgent = null); - - /** - * This method checks for a certain property in the - * userAgent. - * - * @param string $key - * - * @return bool|int|null - */ - public function is($key); - - /** - * Check if the device is mobile. - * Returns true if any type of mobile device detected, including special ones. - * - * @return bool - */ - public function isMobile(); - - /** - * Check if the device is a tablet. - * Return true if any type of tablet device is detected. - * - * @return bool - */ - public function isTablet(); - - /** - * Some detection rules are relative (not standard), - * because of the diversity of devices, vendors and - * their conventions in representing the User-Agent or - * the HTTP headers. - * - * This method will be used to check custom regexes against - * the User-Agent string. - * - * @param string $userAgent - * - * @return bool - */ - public function match($regex, $userAgent = null); - - /** - * Prepare the version number. - * - * @param string $ver The string version, like "2.6.21.2152"; - * - * @return float - */ - public function prepareVersionNo($ver); - - /** - * Check the version of the given property in the User-Agent. - * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31). - * - * @param string $propertyName The name of the property. See self::getProperties() array - * keys for all possible properties. - * @param string $type Either self::VERSION_TYPE_STRING to get a string value or - * self::VERSION_TYPE_FLOAT indicating a float value. This parameter - * is optional and defaults to self::VERSION_TYPE_STRING. Passing an - * invalid parameter will default to the this type as well. - * - * @return string|float the version of the property we are trying to extract - */ - public function version($propertyName, $type = MobileDetector::VERSION_TYPE_STRING); -} diff --git a/src/EventListener/RequestResponseListener.php b/src/EventListener/RequestResponseListener.php index 47ccf0e..08a711f 100644 --- a/src/EventListener/RequestResponseListener.php +++ b/src/EventListener/RequestResponseListener.php @@ -13,7 +13,7 @@ namespace MobileDetectBundle\EventListener; -use MobileDetectBundle\DeviceDetector\MobileDetectorInterface; +use Detection\MobileDetect; use MobileDetectBundle\Helper\DeviceView; use MobileDetectBundle\Helper\RedirectResponseWithCookie; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -35,69 +35,34 @@ class RequestResponseListener public const MOBILE = 'mobile'; public const TABLET = 'tablet'; - public const FULL = 'full'; + public const DESKTOP = 'desktop'; - /** - * @var RouterInterface - */ - protected $router; - - /** - * @var MobileDetectorInterface - */ - protected $mobileDetector; - - /** - * @var DeviceView - */ - protected $deviceView; - - /** - * @var array - */ - protected $redirectConf; + protected bool $needModifyResponse = false; - /** - * @var bool - */ - protected $isFullPath; + protected ?\Closure $modifyResponseClosure; /** - * @var bool + * @param array $redirectConf */ - protected $needModifyResponse = false; - - /** - * @var \Closure - */ - protected $modifyResponseClosure; - public function __construct( - MobileDetectorInterface $mobileDetector, - DeviceView $deviceView, - RouterInterface $router, - array $redirectConf, - bool $fullPath = true + protected readonly MobileDetect $mobileDetect, + protected readonly DeviceView $deviceView, + protected readonly RouterInterface $router, + protected readonly array $redirectConf, + protected readonly bool $isDesktopPath = true, ) { - $this->mobileDetector = $mobileDetector; - $this->deviceView = $deviceView; - $this->router = $router; - - // Configs mobile & tablet - $this->redirectConf = $redirectConf; - $this->isFullPath = $fullPath; } public function handleRequest(RequestEvent $event): void { - // only handle master request, do not handle sub request like esi includes + // Only handle main request, do not handle sub request like esi includes // If the device view is "not the mobile view" (e.g. we're not in the request context) - if ((\defined('Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST') ? \constant('Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST') : \constant('Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST')) !== $event->getRequestType() || $this->deviceView->isNotMobileView()) { + if (!$event->isMainRequest() || $this->deviceView->isNotMobileView()) { return; } $request = $event->getRequest(); - $this->mobileDetector->setUserAgent($request->headers->get('user-agent')); + $this->mobileDetect->setUserAgent($request->headers->get('user-agent', '')); // Sets the flag for the response handled by the GET switch param and the type of the view. if ($this->deviceView->hasSwitchParam()) { @@ -109,12 +74,12 @@ public function handleRequest(RequestEvent $event): void // If neither the SwitchParam nor the cookie are set, detect the view... $cookieIsSet = null !== $this->deviceView->getRequestedViewType(); if (!$cookieIsSet) { - if (false === $this->redirectConf['detect_tablet_as_mobile'] && $this->mobileDetector->isTablet()) { + if (false === $this->redirectConf['detect_tablet_as_mobile'] && $this->mobileDetect->isTablet()) { $this->deviceView->setTabletView(); - } elseif ($this->mobileDetector->isMobile()) { + } elseif ($this->mobileDetect->isMobile()) { $this->deviceView->setMobileView(); } else { - $this->deviceView->setFullView(); + $this->deviceView->setDesktopView(); } } @@ -167,7 +132,7 @@ protected function getRedirectResponseBySwitchParam(Request $request): RedirectR // do it in one response while setting the cookie. $redirectUrl = $this->getRedirectUrl($request, $this->deviceView->getViewType()); } else { - if (true === $this->isFullPath) { + if (true === $this->isDesktopPath) { $redirectUrl = $request->getUriForPath($request->getPathInfo()); // $redirectUrl = ($request->getPathInfo()) ? $request->getUriForPath($request->getPathInfo()) : $this->getCurrentHost($request); $queryParams = $request->query->all(); @@ -258,7 +223,7 @@ protected function getRedirectResponse(Request $request, string $view): ?Redirec return $this->deviceView->getRedirectResponse( $view, $host, - $this->redirectConf[$view]['status_code'] + $this->redirectConf[$view]['status_code'], ); } @@ -272,8 +237,6 @@ protected function getRedirectResponse(Request $request, string $view): ?Redirec */ protected function prepareResponseModification(string $view): void { - $this->modifyResponseClosure = static function (DeviceView $deviceView, ResponseEvent $event) use ($view) { - return $deviceView->modifyResponse($view, $event->getResponse()); - }; + $this->modifyResponseClosure = static fn (DeviceView $deviceView, ResponseEvent $event) => $deviceView->modifyResponse($view, $event->getResponse()); } } diff --git a/src/Helper/DeviceView.php b/src/Helper/DeviceView.php index 198dffe..89d3235 100644 --- a/src/Helper/DeviceView.php +++ b/src/Helper/DeviceView.php @@ -25,7 +25,7 @@ class DeviceView { public const VIEW_MOBILE = 'mobile'; public const VIEW_TABLET = 'tablet'; - public const VIEW_FULL = 'full'; + public const VIEW_DESKTOP = 'desktop'; public const VIEW_NOT_MOBILE = 'not_mobile'; public const COOKIE_KEY_DEFAULT = 'device_view'; @@ -38,73 +38,37 @@ class DeviceView public const COOKIE_EXPIRE_DATETIME_MODIFIER_DEFAULT = '1 month'; public const SWITCH_PARAM_DEFAULT = 'device_view'; - /** - * @var Request - */ - protected $request; + protected ?Request $request = null; - /** - * @var string - */ - protected $requestedViewType; + protected ?string $requestedViewType = null; - /** - * @var string - */ - protected $viewType; + protected ?string $viewType = null; - /** - * @var string - */ - protected $cookieKey = self::COOKIE_KEY_DEFAULT; + protected string $cookieKey = self::COOKIE_KEY_DEFAULT; - /** - * @var string - */ - protected $cookiePath = self::COOKIE_PATH_DEFAULT; + protected string $cookiePath = self::COOKIE_PATH_DEFAULT; - /** - * @var string - */ - protected $cookieDomain = self::COOKIE_DOMAIN_DEFAULT; + protected string $cookieDomain = self::COOKIE_DOMAIN_DEFAULT; - /** - * @var bool - */ - protected $cookieSecure = self::COOKIE_SECURE_DEFAULT; + protected bool $cookieSecure = self::COOKIE_SECURE_DEFAULT; - /** - * @var bool - */ - protected $cookieHttpOnly = self::COOKIE_HTTP_ONLY_DEFAULT; + protected bool $cookieHttpOnly = self::COOKIE_HTTP_ONLY_DEFAULT; - /** - * @var bool - */ - protected $cookieRaw = self::COOKIE_RAW_DEFAULT; + protected bool $cookieRaw = self::COOKIE_RAW_DEFAULT; - /** - * @var string|null - */ - protected $cookieSameSite = self::COOKIE_SAMESITE_DEFAULT; + protected ?string $cookieSameSite = self::COOKIE_SAMESITE_DEFAULT; - /** - * @var string - */ - protected $cookieExpireDatetimeModifier = self::COOKIE_EXPIRE_DATETIME_MODIFIER_DEFAULT; + protected string $cookieExpireDatetimeModifier = self::COOKIE_EXPIRE_DATETIME_MODIFIER_DEFAULT; - /** - * @var string - */ - protected $switchParam = self::SWITCH_PARAM_DEFAULT; + protected string $switchParam = self::SWITCH_PARAM_DEFAULT; /** - * @var array + * @param array $redirectConfig */ - protected $redirectConfig = []; - - public function __construct(RequestStack $requestStack = null) - { + public function __construct( + ?RequestStack $requestStack = null, + protected array $redirectConfig = [], + ) { if (!$requestStack || !$this->request = $requestStack->getMainRequest()) { $this->viewType = self::VIEW_NOT_MOBILE; @@ -139,11 +103,11 @@ public function getRequestedViewType(): ?string } /** - * Is the device in full view. + * Is the device in desktop view. */ - public function isFullView(): bool + public function isDesktopView(): bool { - return self::VIEW_FULL === $this->viewType; + return self::VIEW_DESKTOP === $this->viewType; } public function isTabletView(): bool @@ -178,11 +142,11 @@ public function setView(string $view): void } /** - * Sets the full (desktop) view type. + * Sets the desktop (desktop) view type. */ - public function setFullView(): void + public function setDesktopView(): void { - $this->viewType = self::VIEW_FULL; + $this->viewType = self::VIEW_DESKTOP; } public function setTabletView(): void @@ -200,16 +164,14 @@ public function setNotMobileView(): void $this->viewType = self::VIEW_NOT_MOBILE; } + /** + * @return array + */ public function getRedirectConfig(): array { return $this->redirectConfig; } - public function setRedirectConfig(array $redirectConfig): void - { - $this->redirectConfig = $redirectConfig; - } - public function getRedirectResponseBySwitchParam(string $redirectUrl): RedirectResponseWithCookie { switch ($this->getSwitchParamValue()) { @@ -224,13 +186,13 @@ public function getRedirectResponseBySwitchParam(string $redirectUrl): RedirectR } break; default: - $viewType = self::VIEW_FULL; + $viewType = self::VIEW_DESKTOP; } return new RedirectResponseWithCookie( $redirectUrl, $this->getStatusCode($viewType), - $this->createCookie($viewType) + $this->createCookie($viewType), ); } @@ -243,7 +205,7 @@ public function getSwitchParamValue(): ?string return null; } - return $this->request->query->get($this->switchParam, self::VIEW_FULL); + return $this->request->query->get($this->switchParam, self::VIEW_DESKTOP); } public function getCookieExpireDatetimeModifier(): string @@ -389,7 +351,8 @@ protected function createCookie(string $value): Cookie $this->isCookieSecure(), $this->isCookieHttpOnly(), $this->isCookieRaw(), - $this->getCookieSameSite() + // @phpstan-ignore-next-line + $this->getCookieSameSite(), ); } } diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml index 8b1efd8..99041d0 100644 --- a/src/Resources/config/services.yaml +++ b/src/Resources/config/services.yaml @@ -15,16 +15,14 @@ services: alias: MobileDetectBundle\EventListener\RequestResponseListener MobileDetectBundle\DataCollector\DeviceDataCollector: - arguments: [ '@mobile_detect.device_view' ] - calls: - - [ setRedirectConfig, [ '%mobile_detect.redirect%' ] ] + arguments: [ '@mobile_detect.device_view', [ '%mobile_detect.redirect%' ] ] tags: - { name: data_collector, template: '@MobileDetect/Collector/device.html.twig', id: device.collector } mobile_detect_bundle.device.collector: alias: MobileDetectBundle\DataCollector\DeviceDataCollector MobileDetectBundle\Helper\DeviceView: - arguments: [ '@request_stack' ] + arguments: [ '@request_stack', [ '%mobile_detect.redirect%' ] ] calls: - [ setCookieDomain, [ '%mobile_detect.cookie_domain%' ] ] - [ setCookieExpireDatetimeModifier, [ '%mobile_detect.cookie_expire_datetime_modifier%' ] ] @@ -32,7 +30,6 @@ services: - [ setCookieKey, [ '%mobile_detect.cookie_key%' ] ] - [ setCookiePath, [ '%mobile_detect.cookie_path%' ] ] - [ setCookieSecure, [ '%mobile_detect.cookie_secure%' ] ] - - [ setRedirectConfig, [ '%mobile_detect.redirect%' ] ] - [ setSwitchParam, [ '%mobile_detect.switch_param%' ] ] mobile_detect.device_view: alias: MobileDetectBundle\Helper\DeviceView @@ -44,8 +41,7 @@ services: mobile_detect.twig.extension: alias: MobileDetectBundle\Twig\Extension\MobileDetectExtension - MobileDetectBundle\DeviceDetector\MobileDetector: - MobileDetectBundle\DeviceDetector\MobileDetectorInterface: - alias: MobileDetectBundle\DeviceDetector\MobileDetector + + Detection\MobileDetect: mobile_detect.mobile_detector.default: - alias: MobileDetectBundle\DeviceDetector\MobileDetectorInterface + alias: Detection\MobileDetect diff --git a/src/Resources/doc/migration-7x.md b/src/Resources/doc/migration-7x.md new file mode 100644 index 0000000..acc3b2d --- /dev/null +++ b/src/Resources/doc/migration-7x.md @@ -0,0 +1,13 @@ +Migrate to 7x +============= + +Changes from version `^2` to `^7` + +- All references of `full` have been changed by `desktop` +- To enjoy auto completion `MobileDetectBundle\DeviceDetector\MobileDetectorInterface` has be deprecated in favor of `Detection\MobileDetect` + +#### Going further + +- [Symfony legacy versions](src/Resources/doc/legacy-versions.md) +- [Redirection](src/Resources/doc/redirection.md) +- [Full reference](src/Resources/doc/reference.md) diff --git a/src/Resources/doc/redirection.md b/src/Resources/doc/redirection.md index a60d316..5c2dd61 100644 --- a/src/Resources/doc/redirection.md +++ b/src/Resources/doc/redirection.md @@ -5,7 +5,7 @@ Set up automated mobile/desktop/tablet redirection In this example, we will make sure to activate the automatic redirection to a mobile site http://m.example.com when the user uses a mobile device and desktop http://example.com when the user uses a computer or desktop browser. -If the user reaches the mobile site http://m.example.com, on his desktop browser he should be redirected to the full version at http://example.com. +If the user reaches the mobile site http://m.example.com, on his desktop browser he should be redirected to the desktop version at http://example.com. If the user reaches the desktop site http://example.com, with his mobile he should be redirected to the mobile version at http://m.example.com. @@ -24,7 +24,7 @@ parameters: # config/packages/mobile_detect.yaml mobile_detect: redirect: - full: + desktop: action: redirect # redirect, no_redirect, redirect_without_path host: '%env(REDIRECT_DESKTOP)%' # with scheme (http|https), default null, url validate is_enabled: true # default false diff --git a/src/Resources/doc/reference.md b/src/Resources/doc/reference.md index 08eda27..d449ae5 100644 --- a/src/Resources/doc/reference.md +++ b/src/Resources/doc/reference.md @@ -11,7 +11,7 @@ You can change default behaviour of your redirects with action parameter: # config/packages/mobile_detect.yaml mobile_detect: redirect: - full: + desktop: action: redirect # redirect, no_redirect, redirect_without_path host: http://site.com # with scheme (http|https), default null, url validate is_enabled: true # default false diff --git a/src/Resources/doc/sf-toolbar.png b/src/Resources/doc/sf-toolbar.png index e9d501a..e250ca5 100644 Binary files a/src/Resources/doc/sf-toolbar.png and b/src/Resources/doc/sf-toolbar.png differ diff --git a/src/Twig/Extension/MobileDetectExtension.php b/src/Twig/Extension/MobileDetectExtension.php index ac24731..0e36d69 100644 --- a/src/Twig/Extension/MobileDetectExtension.php +++ b/src/Twig/Extension/MobileDetectExtension.php @@ -13,8 +13,7 @@ namespace MobileDetectBundle\Twig\Extension; -use MobileDetectBundle\DeviceDetector\MobileDetector; -use MobileDetectBundle\DeviceDetector\MobileDetectorInterface; +use Detection\MobileDetect; use MobileDetectBundle\Helper\DeviceView; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; @@ -26,36 +25,24 @@ */ class MobileDetectExtension extends AbstractExtension { - /** - * @var MobileDetectorInterface - */ - private $mobileDetector; - - /** - * @var DeviceView - */ - private $deviceView; + private ?Request $request; /** - * @var array + * @param array $redirectConf */ - private $redirectConf; - - /** - * @var Request - */ - private $request; - - public function __construct(RequestStack $requestStack, MobileDetectorInterface $mobileDetector, DeviceView $deviceView, array $redirectConf) - { + public function __construct( + RequestStack $requestStack, + private readonly MobileDetect $mobileDetect, + private readonly DeviceView $deviceView, + private readonly array $redirectConf, + ) { $this->request = $requestStack->getMainRequest(); - $this->mobileDetector = $mobileDetector; - $this->deviceView = $deviceView; - $this->redirectConf = $redirectConf; } /** * Get extension twig function. + * + * @return TwigFunction[] */ public function getFunctions(): array { @@ -63,78 +50,53 @@ public function getFunctions(): array new TwigFunction('is_mobile', [$this, 'isMobile']), new TwigFunction('is_tablet', [$this, 'isTablet']), new TwigFunction('is_device', [$this, 'isDevice']), - new TwigFunction('is_full_view', [$this, 'isFullView']), + new TwigFunction('is_desktop_view', [$this, 'isDesktopView']), new TwigFunction('is_mobile_view', [$this, 'isMobileView']), new TwigFunction('is_tablet_view', [$this, 'isTabletView']), new TwigFunction('is_not_mobile_view', [$this, 'isNotMobileView']), - new TwigFunction('is_ios', [$this, 'isIOS']), + new TwigFunction('is_ios', [$this, 'isiOS']), new TwigFunction('is_android_os', [$this, 'isAndroidOS']), new TwigFunction('is_windows_os', [$this, 'isWindowsOS']), - new TwigFunction('full_view_url', [$this, 'fullViewUrl'], ['is_safe' => ['html']]), + new TwigFunction('desktop_view_url', [$this, 'desktopViewUrl'], ['is_safe' => ['html']]), new TwigFunction('device_version', [$this, 'deviceVersion']), new TwigFunction('rules_list', [$this, 'getRules']), ]; } + /** + * @return array + */ public function getRules(): array { - return array_merge( - $this->mobileDetector->getPhoneDevices(), - $this->mobileDetector->getTabletDevices(), - $this->mobileDetector->getOperatingSystems(), - $this->mobileDetector->getBrowsers(), - $this->mobileDetector->getUtilities() - ); + return $this->mobileDetect->getRules(); } - /** - * Check the version of the given property in the User-Agent. - * Will return a float number. (eg. 2_0 will return 2.0, 4.3.1 will return 4.31). - * - * @param string $propertyName The name of the property. See self::getProperties() array - * keys for all possible properties. - * @param string $type Either self::VERSION_TYPE_STRING to get a string value or - * self::VERSION_TYPE_FLOAT indicating a float value. This parameter - * is optional and defaults to self::VERSION_TYPE_STRING. Passing an - * invalid parameter will default to the this type as well. - * - * @return string|float|null the version of the property we are trying to extract - */ - public function deviceVersion(string $propertyName, string $type = MobileDetector::VERSION_TYPE_STRING) + public function deviceVersion(string $propertyName, string $type = ''): float|bool|string|null { - return $this->mobileDetector->version($propertyName, $type) ?: null; + return $this->mobileDetect->version($propertyName, $type) ?: null; } /** * Regardless of the current view, returns the URL that leads to the equivalent page - * in the full/desktop view. This is useful for generating tags + * in the desktop/desktop view. This is useful for generating tags * on mobile pages for Search Engine Optimization. * See: http://searchengineland.com/the-definitive-guide-to-mobile-technical-seo-166066. */ - public function fullViewUrl(bool $addCurrentPathAndQuery = true): ?string + public function desktopViewUrl(bool $addCurrentPathAndQuery = true): ?string { - if (!isset($this->redirectConf[DeviceView::VIEW_FULL]['host'])) { - // The host property has not been configured for the full view - return null; - } - - $fullHost = $this->redirectConf[DeviceView::VIEW_FULL]['host']; + $desktopHost = $this->redirectConf[DeviceView::VIEW_DESKTOP]['host']; - if (empty($fullHost)) { + if (empty($desktopHost)) { return null; } - // If not in request scope, we can only return the base URL to the full view - if (!$this->request) { - return $fullHost; - } - - if (false === $addCurrentPathAndQuery) { - return $fullHost; + // If not in request scope, we can only return the base URL to the desktop view + if (!$this->request || !$addCurrentPathAndQuery) { + return $desktopHost; } - // if fullHost ends with /, skip it since getPathInfo() also starts with / - $result = rtrim($fullHost, '/').$this->request->getPathInfo(); + // if desktopHost ends with /, skip it since getPathInfo() also starts with / + $result = rtrim($desktopHost, '/').$this->request->getPathInfo(); $query = Request::normalizeQueryString(http_build_query($this->request->query->all(), '', '&')); if ($query) { @@ -146,12 +108,12 @@ public function fullViewUrl(bool $addCurrentPathAndQuery = true): ?string public function isMobile(): bool { - return $this->mobileDetector->isMobile(); + return $this->mobileDetect->isMobile(); } public function isTablet(): bool { - return $this->mobileDetector->isTablet(); + return $this->mobileDetect->isTablet(); } /** @@ -161,12 +123,12 @@ public function isDevice(string $deviceName): bool { $magicMethodName = 'is'.strtolower((string) $deviceName); - return $this->mobileDetector->{$magicMethodName}(); + return $this->mobileDetect->{$magicMethodName}(); } - public function isFullView(): bool + public function isDesktopView(): bool { - return $this->deviceView->isFullView(); + return $this->deviceView->isDesktopView(); } public function isMobileView(): bool @@ -184,18 +146,18 @@ public function isNotMobileView(): bool return $this->deviceView->isNotMobileView(); } - public function isIOS(): bool + public function isiOS(): bool { - return $this->mobileDetector->isIOS(); + return $this->mobileDetect->isiOS(); } public function isAndroidOS(): bool { - return $this->mobileDetector->isAndroidOS(); + return $this->mobileDetect->isAndroidOS(); } public function isWindowsOS(): bool { - return $this->mobileDetector->isWindowsMobileOS() || $this->mobileDetector->isWindowsPhoneOS(); + return $this->mobileDetect->isWindowsMobileOS() || $this->mobileDetect->isWindowsPhoneOS(); } } diff --git a/symfony.lock b/symfony.lock deleted file mode 100644 index 0cc13c1..0000000 --- a/symfony.lock +++ /dev/null @@ -1,17 +0,0 @@ -{ - "php": { - "version": "7.2" - }, - "symfony/flex": { - "version": "1.0", - "recipe": { - "repo": "github.com/symfony/recipes", - "branch": "master", - "version": "1.0", - "ref": "c0eeb50665f0f77226616b6038a9b06c03752d8e" - }, - "files": [ - ".env" - ] - } -} diff --git a/tests/DataCollector/DeviceDataCollectorTest.php b/tests/DataCollector/DeviceDataCollectorTest.php index d2d841c..7754912 100644 --- a/tests/DataCollector/DeviceDataCollectorTest.php +++ b/tests/DataCollector/DeviceDataCollectorTest.php @@ -1,7 +1,5 @@ - * - * @internal - * - * @coversDefaultClass */ final class DeviceDataCollectorTest extends TestCase { - /** - * @var MockObject|RequestStack - */ - private $requestStack; + private MockObject&RequestStack $requestStack; - /** - * @var MockObject|Request - */ - private $request; + private MockObject&Request $request; - /** - * @var MockObject|Response - */ - private $response; + private MockObject&Response $response; protected function setUp(): void { @@ -77,8 +64,7 @@ public function testCollectCurrentViewMobileIsCurrent(): void ]; $this->request->cookies = new InputBag([DeviceView::COOKIE_KEY_DEFAULT => DeviceView::VIEW_MOBILE]); $deviceView = new DeviceView($this->requestStack); - $deviceDataCollector = new DeviceDataCollector($deviceView); - $deviceDataCollector->setRedirectConfig($redirectConfig); + $deviceDataCollector = new DeviceDataCollector($deviceView, $redirectConfig); $deviceDataCollector->collect($this->request, $this->response); $currentView = $deviceDataCollector->getCurrentView(); @@ -128,8 +114,7 @@ public function testCollectCurrentViewMobileCanUseTablet(): void }); $this->request->cookies = new InputBag([DeviceView::COOKIE_KEY_DEFAULT => DeviceView::VIEW_MOBILE]); $deviceView = new DeviceView($this->requestStack); - $deviceDataCollector = new DeviceDataCollector($deviceView); - $deviceDataCollector->setRedirectConfig($redirectConfig); + $deviceDataCollector = new DeviceDataCollector($deviceView, $redirectConfig); $deviceDataCollector->collect($this->request, $this->response); $currentView = $deviceDataCollector->getCurrentView(); @@ -153,18 +138,18 @@ public function testCollectCurrentViewMobileCanUseTablet(): void self::assertFalse($view['isCurrent']); self::assertTrue($view['enabled']); self::assertSame( - sprintf( + \sprintf( 'http://t.testsite.com/base-url/path-info?%s=%s¶m1=value1', $deviceView->getSwitchParam(), - DeviceView::VIEW_TABLET + DeviceView::VIEW_TABLET, ), - $view['link'] + $view['link'], ); } } } - public function testCollectCurrentViewFullCanUseMobile(): void + public function testCollectCurrentViewDesktopCanUseMobile(): void { $redirectConfig['tablet'] = [ 'is_enabled' => true, @@ -189,17 +174,16 @@ public function testCollectCurrentViewFullCanUseMobile(): void return $test->request->getSchemeAndHttpHost().$test->request->getBaseUrl().$test->request->getPathInfo().$qs; }); - $this->request->cookies = new InputBag([DeviceView::COOKIE_KEY_DEFAULT => DeviceView::VIEW_FULL]); + $this->request->cookies = new InputBag([DeviceView::COOKIE_KEY_DEFAULT => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - $deviceDataCollector = new DeviceDataCollector($deviceView); - $deviceDataCollector->setRedirectConfig($redirectConfig); + $deviceDataCollector = new DeviceDataCollector($deviceView, $redirectConfig); $deviceDataCollector->collect($this->request, $this->response); $currentView = $deviceDataCollector->getCurrentView(); $views = $deviceDataCollector->getViews(); self::assertSame($deviceView->getViewType(), $currentView); - self::assertSame(DeviceView::VIEW_FULL, $currentView); + self::assertSame(DeviceView::VIEW_DESKTOP, $currentView); self::assertCount(3, $views); foreach ($views as $view) { @@ -209,25 +193,25 @@ public function testCollectCurrentViewFullCanUseMobile(): void self::assertArrayHasKey('link', $view); self::assertArrayHasKey('isCurrent', $view); self::assertArrayHasKey('enabled', $view); - if (DeviceView::VIEW_FULL === $view['type']) { + if (DeviceView::VIEW_DESKTOP === $view['type']) { self::assertTrue($view['isCurrent']); } if (DeviceView::VIEW_MOBILE === $view['type']) { self::assertFalse($view['isCurrent']); self::assertTrue($view['enabled']); self::assertSame( - sprintf( + \sprintf( 'http://t.testsite.com/base-url/path-info?%s=%s¶m1=value1', $deviceView->getSwitchParam(), - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), - $view['link'] + $view['link'], ); } } } - public function testCollectCurrentViewFullCantUseMobile(): void + public function testCollectCurrentViewDesktopCantUseMobile(): void { $redirectConfig['mobile'] = [ 'is_enabled' => true, @@ -252,17 +236,16 @@ public function testCollectCurrentViewFullCantUseMobile(): void return $test->request->getSchemeAndHttpHost().$test->request->getBaseUrl().$test->request->getPathInfo().$qs; }); - $this->request->cookies = new InputBag([DeviceView::COOKIE_KEY_DEFAULT => DeviceView::VIEW_FULL]); + $this->request->cookies = new InputBag([DeviceView::COOKIE_KEY_DEFAULT => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - $deviceDataCollector = new DeviceDataCollector($deviceView); - $deviceDataCollector->setRedirectConfig($redirectConfig); + $deviceDataCollector = new DeviceDataCollector($deviceView, $redirectConfig); $deviceDataCollector->collect($this->request, $this->response); $currentView = $deviceDataCollector->getCurrentView(); $views = $deviceDataCollector->getViews(); self::assertSame($deviceView->getViewType(), $currentView); - self::assertSame(DeviceView::VIEW_FULL, $currentView); + self::assertSame(DeviceView::VIEW_DESKTOP, $currentView); self::assertCount(3, $views); foreach ($views as $view) { @@ -272,19 +255,19 @@ public function testCollectCurrentViewFullCantUseMobile(): void self::assertArrayHasKey('link', $view); self::assertArrayHasKey('isCurrent', $view); self::assertArrayHasKey('enabled', $view); - if (DeviceView::VIEW_FULL === $view['type']) { + if (DeviceView::VIEW_DESKTOP === $view['type']) { self::assertTrue($view['isCurrent']); } if (DeviceView::VIEW_MOBILE === $view['type']) { self::assertFalse($view['isCurrent']); self::assertFalse($view['enabled']); self::assertSame( - sprintf( + \sprintf( 'http://testsite.com/base-url/path-info?%s=%s¶m1=value1', $deviceView->getSwitchParam(), - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), - $view['link'] + $view['link'], ); } } diff --git a/tests/DependencyInjection/MobileDetectExtensionTest.php b/tests/DependencyInjection/MobileDetectExtensionTest.php index 0d4f4a9..0990d0f 100644 --- a/tests/DependencyInjection/MobileDetectExtensionTest.php +++ b/tests/DependencyInjection/MobileDetectExtensionTest.php @@ -1,4 +1,5 @@ - * - * @internal - * - * @coversDefaultClass */ final class MobileDetectExtensionTest extends TestCase { - /** - * @var ContainerBuilder - */ - private $container; + private ContainerBuilder $container; - /** - * @var MobileDetectExtension - */ - private $extension; + private MobileDetectExtension $extension; protected function setUp(): void { @@ -55,24 +45,23 @@ public function testLoadDefaultConfig(): void [ 'mobile' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], - $this->container->getParameter('mobile_detect.redirect') + $this->container->getParameter('mobile_detect.redirect'), ); self::assertTrue($this->container->getParameter('mobile_detect.switch_device_view.save_referer_path')); self::assertSame(DeviceView::COOKIE_KEY_DEFAULT, $this->container->getParameter('mobile_detect.cookie_key')); self::assertSame( DeviceView::COOKIE_EXPIRE_DATETIME_MODIFIER_DEFAULT, - $this->container->getParameter('mobile_detect.cookie_expire_datetime_modifier') + $this->container->getParameter('mobile_detect.cookie_expire_datetime_modifier'), ); self::assertSame( DeviceView::SWITCH_PARAM_DEFAULT, - $this->container->getParameter('mobile_detect.switch_param') + $this->container->getParameter('mobile_detect.switch_param'), ); - self::assertTrue($this->container->hasDefinition(MobileDetector::class)); - self::assertTrue($this->container->hasAlias(MobileDetectorInterface::class)); + self::assertTrue($this->container->hasDefinition(MobileDetect::class)); } public function testCustomRedirectConfigMobileHost(): void @@ -82,7 +71,7 @@ public function testCustomRedirectConfigMobileHost(): void 'redirect' => [ 'mobile' => ['is_enabled' => true, 'host' => 'http://m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], ], @@ -91,7 +80,7 @@ public function testCustomRedirectConfigMobileHost(): void self::assertSame([ 'mobile' => ['is_enabled' => true, 'host' => 'http://m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], $this->container->getParameter('mobile_detect.redirect')); } @@ -103,7 +92,7 @@ public function testCustomRedirectConfigWithMobileNotValidHost(): void 'redirect' => [ 'mobile' => ['is_enabled' => true, 'host' => 'http:///m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], ], @@ -112,7 +101,7 @@ public function testCustomRedirectConfigWithMobileNotValidHost(): void self::assertSame([ 'mobile' => ['is_enabled' => false, 'host' => 'http:///m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], $this->container->getParameter('mobile_detect.redirect')); } @@ -124,7 +113,7 @@ public function testCustomRedirectConfigWithTabletNotValidHost(): void 'redirect' => [ 'mobile' => ['is_enabled' => true, 'host' => 'http://m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => true, 'host' => 'http:///t.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], ], @@ -133,19 +122,19 @@ public function testCustomRedirectConfigWithTabletNotValidHost(): void self::assertSame([ 'mobile' => ['is_enabled' => true, 'host' => 'http://m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => false, 'host' => 'http:///t.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], $this->container->getParameter('mobile_detect.redirect')); } - public function testCustomRedirectConfigWithFullNotValidHost(): void + public function testCustomRedirectConfigWithDesktopNotValidHost(): void { $config = [ 'mobile_detect' => [ 'redirect' => [ 'mobile' => ['is_enabled' => true, 'host' => 'http://m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => true, 'host' => 'http://t.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => 'http://testsite', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => 'http://testsite', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], ], @@ -154,7 +143,7 @@ public function testCustomRedirectConfigWithFullNotValidHost(): void self::assertSame([ 'mobile' => ['is_enabled' => true, 'host' => 'http://m.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'tablet' => ['is_enabled' => true, 'host' => 'http://t.testsite.com', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], - 'full' => ['is_enabled' => false, 'host' => 'http://testsite', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => 'http://testsite', 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ], $this->container->getParameter('mobile_detect.redirect')); } diff --git a/tests/EventListener/RequestResponseListenerTest.php b/tests/EventListener/RequestResponseListenerTest.php index b6d9ed6..1b28fe7 100644 --- a/tests/EventListener/RequestResponseListenerTest.php +++ b/tests/EventListener/RequestResponseListenerTest.php @@ -4,13 +4,12 @@ namespace MobileDetectBundle\Tests\EventListener; -use MobileDetectBundle\DeviceDetector\MobileDetectorInterface; +use Detection\MobileDetect; use MobileDetectBundle\EventListener\RequestResponseListener; use MobileDetectBundle\Helper\DeviceView; use MobileDetectBundle\Helper\RedirectResponseWithCookie; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\Request; @@ -23,48 +22,28 @@ use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouterInterface; -/** - * @internal - * - * @coversDefaultClass - */ final class RequestResponseListenerTest extends TestCase { - /** - * @var MockObject|MobileDetectorInterface - */ - private $mobileDetector; + private MockObject&MobileDetect $mobileDetect; - /** - * @var MockObject|RequestStack - */ - private $requestStack; + private MockObject&RequestStack $requestStack; - /** - * @var MockObject|Request - */ - private $request; + private MockObject&Request $request; - /** - * @var MockObject|RouterInterface - */ - private $router; + private MockObject&RouterInterface $router; /** - * @var array + * @var array */ - private $config; + private array $config; - /** - * @var string - */ - private $switchParam = DeviceView::SWITCH_PARAM_DEFAULT; + private string $switchParam = DeviceView::SWITCH_PARAM_DEFAULT; protected function setUp(): void { parent::setUp(); - $this->mobileDetector = $this->createMock(MobileDetectorInterface::class); + $this->mobileDetect = $this->createMock(MobileDetect::class); $this->router = $this->createMock(RouterInterface::class); $this->request = $this->getMockBuilder(Request::class)->getMock(); @@ -91,21 +70,20 @@ public function testHandleRequestHasSwitchParam(): void { $this->request->query = new InputBag(['myparam' => 'myvalue', $this->switchParam => DeviceView::VIEW_MOBILE]); $this->request->expects(self::any())->method('getPathInfo')->willReturn('/'); - $deviceView = new DeviceView($this->requestStack); - $deviceView->setRedirectConfig([DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_FOUND]]); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, []); + $deviceView = new DeviceView($this->requestStack, [DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_FOUND]]); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, []); $event = $this->createGetResponseEvent('some content'); $listener->handleRequest($event); self::assertFalse($listener->needsResponseModification()); + /** @var ?RedirectResponseWithCookie */ $response = $event->getResponse(); self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -116,9 +94,8 @@ public function testHandleRequestBis(): void { $this->request->query = new InputBag(['myparam' => 'myvalue', $this->switchParam => DeviceView::VIEW_MOBILE]); $this->request->expects(self::any())->method('getPathInfo')->willReturn('/'); - $deviceView = new DeviceView($this->requestStack); - $deviceView->setRedirectConfig([DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_FOUND]]); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, [], false); + $deviceView = new DeviceView($this->requestStack, [DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_FOUND]]); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, [], false); $event = $this->createGetResponseEvent('some content'); $listener->handleRequest($event); @@ -130,7 +107,6 @@ public function testHandleRequestBis(): void $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -145,66 +121,63 @@ public function testHandleRequestHasSwitchParamAndQuery(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/'); $this->request->expects(self::any())->method('get')->willReturn('value'); $this->router->expects(self::exactly(2))->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2), ); - $deviceView = new DeviceView($this->requestStack); - $deviceView->setRedirectConfig([DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_FOUND]]); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $deviceView = new DeviceView($this->requestStack, [DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_FOUND]]); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $event = $this->createGetResponseEvent('some content'); $listener->handleRequest($event); self::assertFalse($listener->needsResponseModification()); + /** @var ?RedirectResponseWithCookie */ $response = $event->getResponse(); self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://mobilehost.com/?%s=%s&myparam=myvalue', $this->switchParam, - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } } } - public function testHandleRequestIsFullView(): void + public function testHandleRequestIsDesktopView(): void { $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); self::assertFalse($deviceView->hasSwitchParam()); self::assertNull($deviceView->getRequestedViewType()); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); self::assertTrue($listener->needsResponseModification()); - self::assertSame(DeviceView::VIEW_FULL, $deviceView->getViewType()); + self::assertSame(DeviceView::VIEW_DESKTOP, $deviceView->getViewType()); $requestEventResponse = $getResponseEvent->getResponse(); self::assertNull($requestEventResponse); - $responseEventResponse = new Response('Full view', Response::HTTP_OK); + $responseEventResponse = new Response('Desktop view', Response::HTTP_OK); $responseEvent = $this->createResponseEvent($responseEventResponse); $listener->handleResponse($responseEvent); $modifiedResponse = $responseEvent->getResponse(); - self::assertInstanceOf(Response::class, $modifiedResponse); self::assertSame(Response::HTTP_OK, $modifiedResponse->getStatusCode()); - self::assertSame('Full view', $modifiedResponse->getContent()); + self::assertSame('Desktop view', $modifiedResponse->getContent()); $cookies = $modifiedResponse->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { - self::assertSame(DeviceView::VIEW_FULL, $cookie->getValue()); + self::assertSame(DeviceView::VIEW_DESKTOP, $cookie->getValue()); } } } @@ -212,7 +185,7 @@ public function testHandleRequestIsFullView(): void public function testHandleRequestIsNotMobileView(): void { $deviceView = new DeviceView(); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); self::assertFalse($deviceView->hasSwitchParam()); self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_NOT_MOBILE, $deviceView->getViewType()); @@ -229,7 +202,6 @@ public function testHandleRequestIsNotMobileView(): void $listener->handleResponse($responseEvent); $modifiedResponse = $responseEvent->getResponse(); - self::assertInstanceOf(Response::class, $modifiedResponse); self::assertSame(Response::HTTP_OK, $modifiedResponse->getStatusCode()); self::assertSame('Not mobile view', $modifiedResponse->getContent()); @@ -245,12 +217,12 @@ public function testHandleRequestHasTabletRedirect(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->request->expects(self::any())->method('get')->willReturn('value'); $this->router->expects(self::exactly(2))->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); @@ -259,19 +231,19 @@ public function testHandleRequestHasTabletRedirect(): void self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_TABLET, $deviceView->getViewType()); + /** @var ?RedirectResponseWithCookie */ $response = $getResponseEvent->getResponse(); self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://t.testsite.com/some/parameters?%s=%s&some=param', $this->switchParam, - DeviceView::VIEW_TABLET + DeviceView::VIEW_TABLET, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_TABLET, $cookie->getValue()); } @@ -287,13 +259,13 @@ public function testHandleRequestWithDifferentSwitchParamRedirect(): void $this->request->query = new InputBag(['some' => 'param']); $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::exactly(2))->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(true); $deviceView = new DeviceView($this->requestStack); $deviceView->setSwitchParam($switchParam); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); @@ -302,19 +274,19 @@ public function testHandleRequestWithDifferentSwitchParamRedirect(): void self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_TABLET, $deviceView->getViewType()); + /** @var ?RedirectResponseWithCookie */ $response = $getResponseEvent->getResponse(); self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://testsite.com/some/parameters?%s=%s&some=param', $switchParam, - DeviceView::VIEW_TABLET + DeviceView::VIEW_TABLET, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_TABLET, $cookie->getValue()); } @@ -325,10 +297,10 @@ public function testHandleDeviceIsTabletAndTabletRedirectIsDisabledAndDetectTabl { $this->config['mobile'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -345,14 +317,12 @@ public function testHandleDeviceIsTabletAndTabletRedirectIsDisabledAndDetectTabl $listener->handleResponse($responseEvent); $modifiedResponse = $responseEvent->getResponse(); - self::assertInstanceOf(Response::class, $modifiedResponse); self::assertSame(Response::HTTP_OK, $modifiedResponse->getStatusCode()); self::assertSame('Tablet view', $modifiedResponse->getContent()); $cookies = $modifiedResponse->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_TABLET, $cookie->getValue()); } @@ -366,12 +336,12 @@ public function testHandleDeviceIsTabletAsMobileAndTabletRedirectIsDisabledAndDe $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::atLeastOnce())->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2), ); - $this->mobileDetector->expects(self::atLeastOnce())->method('isMobile')->willReturn(true); + $this->mobileDetect->expects(self::atLeastOnce())->method('isMobile')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -380,20 +350,19 @@ public function testHandleDeviceIsTabletAsMobileAndTabletRedirectIsDisabledAndDe self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_MOBILE, $deviceView->getViewType()); + /** @var ?RedirectResponseWithCookie */ $response = $getResponseEvent->getResponse(); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://mobilehost.com/some/parameters?%s=%s', $this->switchParam, - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -406,12 +375,12 @@ public function testHandleRequestHasTabletRedirectWithoutPath(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::atLeastOnce())->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT_WITHOUT_PATH, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT_WITHOUT_PATH, 2), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -420,21 +389,20 @@ public function testHandleRequestHasTabletRedirectWithoutPath(): void self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_TABLET, $deviceView->getViewType()); + /** @var ?RedirectResponseWithCookie */ $response = $getResponseEvent->getResponse(); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); self::assertSame('http://testsite.com?device_view=tablet', $response->getTargetUrl()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://testsite.com?%s=%s', $this->switchParam, - DeviceView::VIEW_TABLET + DeviceView::VIEW_TABLET, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_TABLET, $cookie->getValue()); } @@ -447,12 +415,12 @@ public function testHandleRequestHasTabletNoRedirect(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::atLeastOnce())->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::NO_REDIRECT, 1) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::NO_REDIRECT, 1), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -469,14 +437,12 @@ public function testHandleRequestHasTabletNoRedirect(): void $listener->handleResponse($responseEvent); $modifiedResponse = $responseEvent->getResponse(); - self::assertInstanceOf(Response::class, $modifiedResponse); self::assertSame(Response::HTTP_OK, $modifiedResponse->getStatusCode()); self::assertSame('Tablet view no redirect', $modifiedResponse->getContent()); $cookies = $modifiedResponse->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_TABLET, $cookie->getValue()); } @@ -489,13 +455,13 @@ public function testHandleRequestHasMobileRedirect(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::atLeastOnce())->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT, 2), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(false); - $this->mobileDetector->expects(self::once())->method('isMobile')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(false); + $this->mobileDetect->expects(self::once())->method('isMobile')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -504,20 +470,19 @@ public function testHandleRequestHasMobileRedirect(): void self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_MOBILE, $deviceView->getViewType()); + /** @var ?RedirectResponseWithCookie */ $response = $getResponseEvent->getResponse(); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://testsite.com/some/parameters?%s=%s', $this->switchParam, - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -530,13 +495,13 @@ public function testHandleRequestHasMobileRedirectWithoutPath(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::atLeastOnce())->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT_WITHOUT_PATH, 2) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::REDIRECT_WITHOUT_PATH, 2), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(false); - $this->mobileDetector->expects(self::once())->method('isMobile')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(false); + $this->mobileDetect->expects(self::once())->method('isMobile')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -545,20 +510,19 @@ public function testHandleRequestHasMobileRedirectWithoutPath(): void self::assertNull($deviceView->getRequestedViewType()); self::assertSame(DeviceView::VIEW_MOBILE, $deviceView->getViewType()); + /** @var ?RedirectResponseWithCookie */ $response = $getResponseEvent->getResponse(); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); - self::assertSame(sprintf( + self::assertSame(\sprintf( 'http://testsite.com?%s=%s', $this->switchParam, - DeviceView::VIEW_MOBILE + DeviceView::VIEW_MOBILE, ), $response->getTargetUrl()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -571,13 +535,13 @@ public function testHandleRequestHasMobileNoRedirect(): void $this->request->expects(self::any())->method('getPathInfo')->willReturn('/some/parameters'); $this->router->expects(self::atLeastOnce())->method('getRouteCollection')->willReturn( - $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::NO_REDIRECT, 1) + $this->createRouteCollectionWithRouteAndRoutingOption(RequestResponseListener::NO_REDIRECT, 1), ); - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(false); - $this->mobileDetector->expects(self::once())->method('isMobile')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(false); + $this->mobileDetect->expects(self::once())->method('isMobile')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $getResponseEvent = $this->createGetResponseEvent('some content'); $listener->handleRequest($getResponseEvent); @@ -594,51 +558,52 @@ public function testHandleRequestHasMobileNoRedirect(): void $listener->handleResponse($responseEvent); $modifiedResponse = $responseEvent->getResponse(); - self::assertInstanceOf(Response::class, $modifiedResponse); self::assertSame(Response::HTTP_OK, $modifiedResponse->getStatusCode()); self::assertSame('Mobile view no redirect', $modifiedResponse->getContent()); $cookies = $modifiedResponse->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } } } - public function testHandleRequestUpdatedMobileDetectorUserAgent(): void + public function testHandleRequestUpdatedMobileDetectUserAgent(): void { - $this->mobileDetector->expects(self::once())->method('setUserAgent')->with(self::equalTo('agent')); + $this->mobileDetect->expects(self::once())->method('setUserAgent')->with(self::equalTo('agent')); $event = $this->createGetResponseEvent('some content'); $event->getRequest()->headers->set('user-agent', 'agent'); $deviceView = new DeviceView($this->requestStack); - $listener = new RequestResponseListener($this->mobileDetector, $deviceView, $this->router, $this->config); + $listener = new RequestResponseListener($this->mobileDetect, $deviceView, $this->router, $this->config); $listener->handleRequest($event); } + /** + * @param array> $headers + */ private function createGetResponseEvent(string $content, array $headers = []): ViewEvent { $event = new ViewEvent( $this->createMock(HttpKernelInterface::class), $this->request, - \defined('Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST') ? \constant('Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST') : \constant('Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST'), - $content + HttpKernelInterface::MAIN_REQUEST, + $content, ); $event->getRequest()->headers = new HeaderBag($headers); return $event; } - private function createRouteCollectionWithRouteAndRoutingOption(string $returnValue, int $times): RouteCollection + private function createRouteCollectionWithRouteAndRoutingOption(string $returnValue, int $times): MockObject&RouteCollection { $route = $this->getMockBuilder(Route::class)->disableOriginalConstructor()->getMock(); $route->expects(self::exactly($times))->method('getOption')->willReturn($returnValue); /** - * @var MockObject|RouteCollection + * @var MockObject&RouteCollection */ $routeCollection = $this->createMock(RouteCollection::class); $routeCollection->expects(self::exactly($times))->method('get')->willReturn($route); @@ -646,13 +611,16 @@ private function createRouteCollectionWithRouteAndRoutingOption(string $returnVa return $routeCollection; } + /** + * @param array> $headers + */ private function createResponseEvent(Response $response, array $headers = []): ResponseEvent { $event = new ResponseEvent( $this->createMock(HttpKernelInterface::class), $this->request, - \defined('Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST') ? \constant('Symfony\Component\HttpKernel\HttpKernelInterface::MAIN_REQUEST') : \constant('Symfony\Component\HttpKernel\HttpKernelInterface::MASTER_REQUEST'), - $response + HttpKernelInterface::MAIN_REQUEST, + $response, ); $event->getRequest()->headers = new HeaderBag($headers); diff --git a/tests/Helper/DeviceViewTest.php b/tests/Helper/DeviceViewTest.php index f03c28b..58477c8 100644 --- a/tests/Helper/DeviceViewTest.php +++ b/tests/Helper/DeviceViewTest.php @@ -5,33 +5,22 @@ namespace MobileDetectBundle\Tests\Helper; use MobileDetectBundle\Helper\DeviceView; -use MobileDetectBundle\Helper\RedirectResponseWithCookie; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; -use Symfony\Component\HttpFoundation\Cookie; use Symfony\Component\HttpFoundation\InputBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; -/** - * @internal - * - * @coversDefaultClass - */ final class DeviceViewTest extends TestCase { - /** - * @var MockObject|RequestStack - */ - private $requestStack; + private MockObject&RequestStack $requestStack; - /** - * @var MockObject|Request - */ - private $request; + private MockObject&Request $request; - private $cookieKey = DeviceView::COOKIE_KEY_DEFAULT; - private $switchParam = DeviceView::SWITCH_PARAM_DEFAULT; + private string $cookieKey = DeviceView::COOKIE_KEY_DEFAULT; + + private string $switchParam = DeviceView::SWITCH_PARAM_DEFAULT; protected function setUp(): void { @@ -67,12 +56,12 @@ public function testGetViewTypeTablet(): void self::assertSame(DeviceView::VIEW_TABLET, $deviceView->getRequestedViewType()); } - public function testGetViewTypeFull(): void + public function testGetViewTypeDesktop(): void { - $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_FULL]); + $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - self::assertSame(DeviceView::VIEW_FULL, $deviceView->getViewType()); - self::assertSame(DeviceView::VIEW_FULL, $deviceView->getRequestedViewType()); + self::assertSame(DeviceView::VIEW_DESKTOP, $deviceView->getViewType()); + self::assertSame(DeviceView::VIEW_DESKTOP, $deviceView->getRequestedViewType()); } public function testGetViewTypeNotMobile(): void @@ -91,18 +80,18 @@ public function testGetViewTypeMobileFromCookie(): void self::assertSame(DeviceView::VIEW_MOBILE, $deviceView->getRequestedViewType()); } - public function testIsFullViewTrue(): void + public function testIsDesktopViewTrue(): void { - $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_FULL]); + $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - self::assertTrue($deviceView->isFullView()); + self::assertTrue($deviceView->isDesktopView()); } - public function testIsFullViewFalse(): void + public function testIsDesktopViewFalse(): void { $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_MOBILE]); $deviceView = new DeviceView($this->requestStack); - self::assertFalse($deviceView->isFullView()); + self::assertFalse($deviceView->isDesktopView()); } public function testIsTabletViewTrue(): void @@ -175,18 +164,18 @@ public function testSetViewMobile(): void self::assertTrue($deviceView->isMobileView()); } - public function testSetViewFull(): void + public function testSetViewDesktop(): void { $deviceView = new DeviceView(); - $deviceView->setView(DeviceView::VIEW_FULL); - self::assertTrue($deviceView->isFullView()); + $deviceView->setView(DeviceView::VIEW_DESKTOP); + self::assertTrue($deviceView->isDesktopView()); } - public function testSetFullViewAndCheckIsFullView(): void + public function testSetDesktopViewAndCheckIsDesktopView(): void { $deviceView = new DeviceView(); - $deviceView->setFullView(); - self::assertTrue($deviceView->isFullView()); + $deviceView->setDesktopView(); + self::assertTrue($deviceView->isDesktopView()); } public function testSetTabletViewAndCheckIsTabletView(): void @@ -217,18 +206,18 @@ public function testGetSwitchParamValueNull(): void self::assertNull($deviceView->getSwitchParamValue()); } - public function testGetSwitchParamValueFullDefault(): void + public function testGetSwitchParamValueDesktopDefault(): void { $this->request->query = new InputBag(); $deviceView = new DeviceView($this->requestStack); - self::assertSame(DeviceView::VIEW_FULL, $deviceView->getSwitchParamValue()); + self::assertSame(DeviceView::VIEW_DESKTOP, $deviceView->getSwitchParamValue()); } - public function testGetSwitchParamValueFull(): void + public function testGetSwitchParamValueDesktop(): void { - $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_FULL]); + $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - self::assertSame(DeviceView::VIEW_FULL, $deviceView->getSwitchParamValue()); + self::assertSame(DeviceView::VIEW_DESKTOP, $deviceView->getSwitchParamValue()); } public function testGetSwitchParamValueMobile(): void @@ -248,29 +237,24 @@ public function testGetSwitchParamValueTablet(): void public function testGetRedirectResponseBySwitchParamWithCookieViewMobile(): void { $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_MOBILE]); - $deviceView = new DeviceView($this->requestStack); - $deviceView->setRedirectConfig([DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_MOVED_PERMANENTLY]]); + $deviceView = new DeviceView($this->requestStack, [DeviceView::VIEW_MOBILE => ['status_code' => Response::HTTP_MOVED_PERMANENTLY]]); $response = $deviceView->getRedirectResponseBySwitchParam('/redirect-url'); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_MOVED_PERMANENTLY, $response->getStatusCode()); } public function testGetRedirectResponseBySwitchParamWithCookieViewTablet(): void { $this->request->query = new InputBag([$this->switchParam => DeviceView::VIEW_TABLET]); - $deviceView = new DeviceView($this->requestStack); - $deviceView->setRedirectConfig([DeviceView::VIEW_TABLET => ['status_code' => Response::HTTP_MOVED_PERMANENTLY]]); + $deviceView = new DeviceView($this->requestStack, [DeviceView::VIEW_TABLET => ['status_code' => Response::HTTP_MOVED_PERMANENTLY]]); $response = $deviceView->getRedirectResponseBySwitchParam('/redirect-url'); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_MOVED_PERMANENTLY, $response->getStatusCode()); } - public function testGetRedirectResponseBySwitchParamWithCookieViewFullDefault(): void + public function testGetRedirectResponseBySwitchParamWithCookieViewDesktopDefault(): void { $this->request->query = new InputBag(); $deviceView = new DeviceView($this->requestStack); $response = $deviceView->getRedirectResponseBySwitchParam('/redirect-url'); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); } @@ -280,12 +264,11 @@ public function testModifyResponseToMobileAndCheckResponse(): void $deviceView = new DeviceView($this->requestStack); $response = new Response(); self::assertCount(0, $response->headers->getCookies()); - $deviceView->modifyResponse(DeviceView::VIEW_MOBILE, $response); + $response = $deviceView->modifyResponse(DeviceView::VIEW_MOBILE, $response); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -297,12 +280,10 @@ public function testGetRedirectResponseWithCookieViewMobile(): void $this->request->query = new InputBag(); $deviceView = new DeviceView($this->requestStack); $response = $deviceView->getRedirectResponse(DeviceView::VIEW_MOBILE, 'http://mobilesite.com', Response::HTTP_FOUND); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); $cookies = $response->headers->getCookies(); self::assertGreaterThan(0, \count($cookies)); foreach ($cookies as $cookie) { - self::assertInstanceOf(Cookie::class, $cookie); if ($cookie->getName() === $deviceView->getCookieKey()) { self::assertSame(DeviceView::VIEW_MOBILE, $cookie->getValue()); } @@ -319,7 +300,6 @@ public function testGetRedirectResponseAndCheckCookieSettings(): void $deviceView->setCookieHttpOnly(false); $response = $deviceView->getRedirectResponse(DeviceView::VIEW_MOBILE, 'http://mobilesite.com', Response::HTTP_FOUND); - self::assertInstanceOf(RedirectResponseWithCookie::class, $response); self::assertSame(Response::HTTP_FOUND, $response->getStatusCode()); $cookies = $response->headers->getCookies(); diff --git a/tests/Twig/Extension/MobileDetectExtensionTest.php b/tests/Twig/Extension/MobileDetectExtensionTest.php index 41cdbb0..6396c65 100644 --- a/tests/Twig/Extension/MobileDetectExtensionTest.php +++ b/tests/Twig/Extension/MobileDetectExtensionTest.php @@ -4,7 +4,7 @@ namespace MobileDetectBundle\Tests\Twig\Extension; -use MobileDetectBundle\DeviceDetector\MobileDetector; +use Detection\MobileDetect; use MobileDetectBundle\Helper\DeviceView; use MobileDetectBundle\Twig\Extension\MobileDetectExtension; use PHPUnit\Framework\MockObject\MockObject; @@ -13,42 +13,27 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; -use Twig\TwigFunction; -/** - * @internal - * - * @coversDefaultClass - */ final class MobileDetectExtensionTest extends TestCase { - /** - * @var MockObject|MobileDetector - */ - private $mobileDetector; + private MockObject&MobileDetect $mobileDetect; - /** - * @var MockObject|RequestStack - */ - private $requestStack; + private MockObject&RequestStack $requestStack; - /** - * @var MockObject|Request - */ - private $request; + private MockObject&Request $request; /** - * @var array + * @var array */ - private $config; + private array $config; - private $switchParam = DeviceView::SWITCH_PARAM_DEFAULT; + private string $switchParam = DeviceView::SWITCH_PARAM_DEFAULT; protected function setUp(): void { parent::setUp(); - $this->mobileDetector = $this->createMock(MobileDetector::class); + $this->mobileDetect = $this->createMock(MobileDetect::class); $this->requestStack = $this->getMockBuilder(RequestStack::class)->disableOriginalConstructor()->getMock(); $this->request = $this->getMockBuilder(Request::class)->getMock(); @@ -63,7 +48,7 @@ protected function setUp(): void ; $this->config = [ - 'full' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], + 'desktop' => ['is_enabled' => false, 'host' => null, 'status_code' => Response::HTTP_FOUND, 'action' => 'redirect'], 'detect_tablet_as_mobile' => false, ]; } @@ -71,7 +56,7 @@ protected function setUp(): void public function testGetFunctionsArray(): void { $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); $functions = $extension->getFunctions(); self::assertCount(13, $functions); @@ -79,19 +64,18 @@ public function testGetFunctionsArray(): void 'is_mobile' => 'isMobile', 'is_tablet' => 'isTablet', 'is_device' => 'isDevice', - 'is_full_view' => 'isFullView', + 'is_desktop_view' => 'isDesktopView', 'is_mobile_view' => 'isMobileView', 'is_tablet_view' => 'isTabletView', 'is_not_mobile_view' => 'isNotMobileView', - 'is_ios' => 'isIOS', + 'is_ios' => 'isiOS', 'is_android_os' => 'isAndroidOS', 'is_windows_os' => 'isWindowsOS', - 'full_view_url' => 'fullViewUrl', + 'desktop_view_url' => 'desktopViewUrl', 'device_version' => 'deviceVersion', 'rules_list' => 'getRules', ]; foreach ($functions as $function) { - self::assertInstanceOf(TwigFunction::class, $function); $name = $function->getName(); $callable = $function->getCallable(); self::assertArrayHasKey($name, $names); @@ -103,151 +87,170 @@ public function testGetFunctionsArray(): void public function testRulesList(): void { $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, new MobileDetector(), $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, new MobileDetect(), $deviceView, $this->config); self::assertEqualsWithDelta(173, \count($extension->getRules()), 190); } public function testDeviceVersion(): void { - $this->mobileDetector->expects(self::exactly(3)) + $reflection = new \ReflectionClass(MobileDetect::class); + $versionTypeString = $reflection->getConstant('VERSION_TYPE_STRING'); + $versionTypeFloat = $reflection->getConstant('VERSION_TYPE_FLOAT'); + + $matcher = self::exactly(3); + $this->mobileDetect->expects($matcher) ->method('version') - ->withConsecutive( - [self::equalTo('Version'), self::equalTo(MobileDetector::VERSION_TYPE_STRING)], - [self::equalTo('Firefox'), self::equalTo(MobileDetector::VERSION_TYPE_STRING)], - [self::equalTo('Firefox'), self::equalTo(MobileDetector::VERSION_TYPE_FLOAT)] - ) - ->willReturn(false, '98.0', 98.0) + ->willReturnCallback(static function ($parameters) use ($matcher) { + if (1 === $matcher->numberOfInvocations()) { + self::assertSame('Version', $parameters); + + return false; + } + + if (2 === $matcher->numberOfInvocations()) { + self::assertSame('Firefox', $parameters); + + return '98.0'; + } + + if (3 === $matcher->numberOfInvocations()) { + self::assertSame('Firefox', $parameters); + + return 98.0; + } + }) ; + $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertNull($extension->deviceVersion('Version', MobileDetector::VERSION_TYPE_STRING)); - self::assertSame('98.0', $extension->deviceVersion('Firefox', MobileDetector::VERSION_TYPE_STRING)); - self::assertSame(98.0, $extension->deviceVersion('Firefox', MobileDetector::VERSION_TYPE_FLOAT)); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertNull($extension->deviceVersion('Version', $versionTypeString)); + self::assertSame('98.0', $extension->deviceVersion('Firefox', $versionTypeString)); + self::assertSame(98.0, $extension->deviceVersion('Firefox', $versionTypeFloat)); } - public function testFullViewUrlHostNull(): void + public function testDesktopViewUrlHostNull(): void { - $this->config['full'] = ['is_enabled' => true, 'host' => null]; + $this->config['desktop'] = ['is_enabled' => true, 'host' => null]; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertNull($extension->fullViewUrl()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertNull($extension->desktopViewUrl()); } - public function testFullViewUrlHostEmpty(): void + public function testDesktopViewUrlHostEmpty(): void { - $this->config['full'] = ['is_enabled' => true, 'host' => '']; + $this->config['desktop'] = ['is_enabled' => true, 'host' => '']; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertNull($extension->fullViewUrl()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertNull($extension->desktopViewUrl()); } - public function testFullViewUrlNotSetRequest(): void + public function testDesktopViewUrlNotSetRequest(): void { - $this->config['full'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; + $this->config['desktop'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertSame('http://mobilehost.com', $extension->fullViewUrl()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertSame('http://mobilehost.com', $extension->desktopViewUrl()); } - public function testFullViewUrlWithRequestQuery(): void + public function testDesktopViewUrlWithRequestQuery(): void { - $this->config['full'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; + $this->config['desktop'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; $this->request->query = new InputBag(['myparam' => 'myvalue']); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertSame('http://mobilehost.com?myparam=myvalue', $extension->fullViewUrl()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertSame('http://mobilehost.com?myparam=myvalue', $extension->desktopViewUrl()); } - public function testFullViewUrlWithRequestOnlyHost(): void + public function testDesktopViewUrlWithRequestOnlyHost(): void { - $this->config['full'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; + $this->config['desktop'] = ['is_enabled' => true, 'host' => 'http://mobilehost.com']; $this->request->query = new InputBag(['myparam' => 'myvalue']); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertSame('http://mobilehost.com', $extension->fullViewUrl(false)); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertSame('http://mobilehost.com', $extension->desktopViewUrl(false)); } public function testIsMobileTrue(): void { - $this->mobileDetector->expects(self::once())->method('isMobile')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isMobile')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isMobile()); } public function testIsMobileFalse(): void { - $this->mobileDetector->expects(self::once())->method('isMobile')->willReturn(false); + $this->mobileDetect->expects(self::once())->method('isMobile')->willReturn(false); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isMobile()); } public function testIsTabletTrue(): void { - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(true); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(true); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isTablet()); } public function testIsTabletFalse(): void { - $this->mobileDetector->expects(self::once())->method('isTablet')->willReturn(false); + $this->mobileDetect->expects(self::once())->method('isTablet')->willReturn(false); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isTablet()); } public function testIsDeviceIPhone(): void { - $this->mobileDetector->expects(self::once()) + $this->mobileDetect->expects(self::once()) ->method('__call') ->with(self::equalTo('isiphone')) ->willReturn(true) ; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isDevice('iphone')); } public function testIsDeviceAndroid(): void { - $this->mobileDetector->expects(self::once()) + $this->mobileDetect->expects(self::once()) ->method('__call') ->with(self::equalTo('isandroid')) ->willReturn(true) ; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isDevice('android')); } - public function testIsFullViewTrue(): void + public function testIsDesktopViewTrue(): void { - $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_FULL]); + $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertTrue($extension->isFullView()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertTrue($extension->isDesktopView()); } - public function testIsFullViewFalse(): void + public function testIsDesktopViewFalse(): void { $deviceView = new DeviceView(); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertFalse($extension->isFullView()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertFalse($extension->isDesktopView()); } public function testIsMobileViewTrue(): void { $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_MOBILE]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isMobileView()); } @@ -255,7 +258,7 @@ public function testIsMobileViewFalse(): void { $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_TABLET]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isMobileView()); } @@ -263,7 +266,7 @@ public function testIsTabletViewTrue(): void { $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_TABLET]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isTabletView()); } @@ -271,7 +274,7 @@ public function testIsTabletViewFalse(): void { $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_MOBILE]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isTabletView()); } @@ -279,93 +282,113 @@ public function testIsNotMobileViewTrue(): void { $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_NOT_MOBILE]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isNotMobileView()); } public function testIsNotMobileViewFalse(): void { - $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_FULL]); + $this->request->cookies = new InputBag([$this->switchParam => DeviceView::VIEW_DESKTOP]); $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isNotMobileView()); } - public function testIsIOSTrue(): void + public function testIsiOSTrue(): void { - $this->mobileDetector->expects(self::once()) + $this->mobileDetect->expects(self::once()) ->method('__call') - ->with(self::equalTo('isIOS')) + ->with(self::equalTo('isiOS')) ->willReturn(true) ; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertTrue($extension->isIOS()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertTrue($extension->isiOS()); } - public function testIsIOSFalse(): void + public function testIsiOSFalse(): void { - $this->mobileDetector->expects(self::once()) + $this->mobileDetect->expects(self::once()) ->method('__call') - ->with(self::equalTo('isIOS')) + ->with(self::equalTo('isiOS')) ->willReturn(false) ; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); - self::assertFalse($extension->isIOS()); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); + self::assertFalse($extension->isiOS()); } public function testIsAndroidOSTrue(): void { - $this->mobileDetector->expects(self::once()) + $this->mobileDetect->expects(self::once()) ->method('__call') ->with(self::equalTo('isAndroidOS')) ->willReturn(true) ; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isAndroidOS()); } public function testIsAndroidOSFalse(): void { - $this->mobileDetector->expects(self::once()) + $this->mobileDetect->expects(self::once()) ->method('__call') ->with(self::equalTo('isAndroidOS')) ->willReturn(false) ; $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isAndroidOS()); } public function testIsWindowsOSTrue(): void { - $this->mobileDetector->expects(self::exactly(1)) + $matcher = self::exactly(1); + $this->mobileDetect->expects($matcher) ->method('__call') - ->withConsecutive( - [self::equalTo('isWindowsMobileOS')], - [self::equalTo('isWindowsPhoneOS')] - ) - ->willReturnOnConsecutiveCalls(true) + ->willReturnCallback(static function ($parameters) use ($matcher) { + if (1 === $matcher->numberOfInvocations()) { + self::assertSame('isWindowsMobileOS', $parameters); + + return true; + } + + // if (1 === $matcher->numberOfInvocations()) { + // self::assertSame('isWindowsPhoneOS', $parameters); + + // return true; + // } + }) ; + $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertTrue($extension->isWindowsOS()); } public function testIsWindowsOSFalse(): void { - $this->mobileDetector->expects(self::exactly(2)) + $matcher = self::exactly(2); + $this->mobileDetect->expects($matcher) ->method('__call') - ->withConsecutive( - [self::equalTo('isWindowsMobileOS')], - [self::equalTo('isWindowsPhoneOS')] - ) - ->willReturn(false) + ->willReturnCallback(static function ($parameters) use ($matcher) { + if (1 === $matcher->numberOfInvocations()) { + self::assertSame('isWindowsMobileOS', $parameters); + + return false; + } + + // if (1 === $matcher->numberOfInvocations()) { + // self::assertSame('isWindowsPhoneOS', $parameters); + + // return false; + // } + }) ; + $deviceView = new DeviceView($this->requestStack); - $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetector, $deviceView, $this->config); + $extension = new MobileDetectExtension($this->requestStack, $this->mobileDetect, $deviceView, $this->config); self::assertFalse($extension->isWindowsOS()); } }