diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..b0d34dc
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+; top-most EditorConfig file
+root = true
+
+; Unix-style newlines
+[*]
+charset = utf-8
+end_of_line = LF
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.{php,html,twig}]
+indent_style = space
+indent_size = 4
+
+[*.md]
+max_line_length = 80
+
+[COMMIT_EDITMSG]
+max_line_length = 0
\ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
new file mode 100644
index 0000000..042050e
--- /dev/null
+++ b/.github/workflows/main.yml
@@ -0,0 +1,101 @@
+name: Symfony Bundle CI
+
+on:
+ push:
+ branches: [ main ]
+ pull_request:
+
+ workflow_dispatch:
+
+jobs:
+ phpunit:
+ name: Test on PHP ${{ matrix.php }} and Symfony ${{ matrix.symfony-require }}
+ runs-on: ubuntu-latest
+ env:
+ SYMFONY_REQUIRE: ${{ matrix.symfony-require }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ php:
+ - 8.2
+ - 8.3
+ dependencies:
+ - highest
+ stability:
+ - stable
+ symfony-require:
+ # Test latest LTS version
+ - 6.4
+ # Test latest stable versions
+ - 7.1
+ - 7.*
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v4
+
+ - name: Install PHP with PCOV
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ coverage: pcov
+ ini-values: zend.assertions=1
+
+ - name: Globally install symfony/flex
+ 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 }}
+
+ - name: Install dependencies with Composer
+ uses: ramsey/composer-install@v3
+ with:
+ dependency-versions: ${{ matrix.dependencies }}
+ composer-options: --prefer-dist
+
+ - 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: Static Analysis via PHPStan
+ run: vendor/bin/phpstan analyse
+
+ - name: Unit and Feature tests via PHPUnit
+ run: php vendor/bin/phpunit
+
+ - name: Upload coverage file
+ uses: actions/upload-artifact@v4
+ with:
+ name: phpunit-${{ matrix.php }}-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}.coverage
+ path: build/coverage.xml
+
+ - 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@v4
+
+ - name: Download coverage files
+ uses: actions/download-artifact@v4
+ with:
+ path: reports
+
+ - name: Upload to Codecov
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ uses: codecov/codecov-action@v4
+ with:
+ directory: reports
diff --git a/.gitignore b/.gitignore
index 3dab634..92f2d5d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,29 +1,5 @@
-# Cache and logs (Symfony2)
-/app/cache/*
-/app/logs/*
-!app/cache/.gitkeep
-!app/logs/.gitkeep
-
-# Email spool folder
-/app/spool/*
-
-# Cache, session files and logs (Symfony3)
-/var/cache/*
-/var/logs/*
-/var/sessions/*
-!var/cache/.gitkeep
-!var/logs/.gitkeep
-!var/sessions/.gitkeep
-
-# Logs (Symfony4)
-/var/log/*
-!var/log/.gitkeep
-
-# Parameters
-/app/config/parameters.yml
-/app/config/parameters.ini
-
# Managed by Composer
+/composer.lock
/app/bootstrap.php.cache
/var/bootstrap.php.cache
/bin/*
@@ -31,22 +7,22 @@
!bin/symfony_requirements
/vendor/
-# Assets and user uploads
-/web/bundles/
-/web/uploads/
+###> phpstan/phpstan ###
+.phpstan
+phpstan.neon
+###< phpstan/phpstan ###
-# PHPUnit
-/app/phpunit.xml
-/phpunit.xml
-
-# Build data
-/build/
+###> friendsofphp/php-cs-fixer ###
+/.php-cs-fixer.php
+/.php-cs-fixer.cache
+###< friendsofphp/php-cs-fixer ###
-# Composer PHAR
-/composer.phar
-
-# Backup entities generated with doctrine:generate:entities command
-**/Entity/*~
+###> phpunit/phpunit ###
+/phpunit.xml
+.phpunit.result.cache
+###< phpunit/phpunit ###
-# Embedded web-server pid file
-/.web-server-pid
+###> squizlabs/php_codesniffer ###
+/.phpcs-cache
+/phpcs.xml
+###< squizlabs/php_codesniffer ###
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
new file mode 100644
index 0000000..2f0b94e
--- /dev/null
+++ b/.php-cs-fixer.dist.php
@@ -0,0 +1,72 @@
+in(__DIR__.'/src')
+ ->in(__DIR__.'/tests')
+;
+
+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,
+ '@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',
+ ],
+ 'no_extra_blank_lines' => [
+ 'tokens' => [
+ 'break',
+ 'continue',
+ 'curly_brace_block',
+ 'extra',
+ 'parenthesis_brace_block',
+ 'return',
+ 'square_brace_block',
+ 'throw',
+ 'use',
+ ],
+ ],
+ 'no_superfluous_phpdoc_tags' => true,
+ 'no_useless_else' => true,
+ 'no_useless_return' => true,
+ 'ordered_class_elements' => true,
+ 'ordered_imports' => [
+ 'imports_order' => [
+ 'class',
+ 'function',
+ 'const',
+ ],
+ 'sort_algorithm' => 'alpha',
+ ],
+ 'php_unit_method_casing' => [
+ 'case' => 'camel_case',
+ ],
+ 'phpdoc_order' => true,
+ 'phpdoc_trim_consecutive_blank_line_separation' => true,
+ 'single_line_comment_style' => true,
+ 'strict_comparison' => true,
+ 'strict_param' => true,
+ 'void_return' => false,
+ ])
+ ->setFinder($finder)
+ ;
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..617443d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+all: test
+
+phpunit:
+ php vendor/bin/phpunit
+
+lint:
+ php vendor/bin/php-cs-fixer fix --diff
+ php vendor/bin/phpcs --report=code
+ php vendor/bin/phpstan analyse
+
+refactor:
+ php vendor/bin/php-cs-fixer fix
+ php vendor/bin/rector
+
+test: lint phpunit
diff --git a/README.md b/README.md
index a27e948..53dc813 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,35 @@
-# MobileDetectSymfonyBundle
-Symfony 6.4, 7.x & PHP 8.2 bundle to detect mobile devices, manage mobile view and redirect to the mobile and tablet version.
+# Mobile Detect Symfony Bundle
+
+Symfony 6.4, 7.x & PHP 8.x bundle to detect mobile devices, manage mobile view and redirect to the mobile and tablet version.
+
+This bundle is inspired by [tattali/MobileDetectBundle](https://github.com/tattali/MobileDetectBundle)
+
+## Introduction
+This Bundle uses [serbanghita/Mobile-Detect](https://github.com/serbanhita/Mobile-Detect) and provides the following features:
+The Versioning of the [serbanhita/Mobile-Detect](https://github.com/serbanhita/Mobile-Detect) is one of the reasons for creating this Bundle.
+Detect the various mobile devices by Name, OS, browser User-Agent
+Manages site views for the various mobile devices (mobile, tablet, full)
+Redirects to mobile and tablet sites
+
+## Documentation
+You find a more detailed documentation in [docs/index.md](docs/index.md).
+
+### Installation
+```sh
+composer require digifa/mobile-detect-symfony-bundle:^4.*
+```
+*Use Major-Version regarding to needed [serbanhita/Mobile-Detect]() Version.*
+### Usage
+
+## Contribute and feedback
+Any feedback and contribution will be very appreciated.
+Read [Contribution](docs/contribution.md) for more informations.
+
+## License and credits
+
+### License
+This bundle is under the MIT license. See the complete [license](LICENSE) in the bundle.
+
+### Credits
+The author [tattali](https://github.com/tattali) for [https://github.com/tattali/MobileDetectBundle]() and [all contributors](https://github.com/suncat2000/MobileDetectBundle/graphs/contributors),
+[suncat2000](https://github.com/suncat2000) for the original [suncat2000/MobileDetectBundle](https://github.com/suncat2000/MobileDetectBundle).
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..7e3b360
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,8 @@
+coverage:
+ status:
+ project:
+ default:
+ target: auto
+ # adjust accordingly based on how flaky your tests are
+ # this allows a 1% drop from the previous base commit coverage
+ threshold: 1%
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..51c27eb
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,69 @@
+{
+ "name": "digifa/mobile-detect-symfony-bundle",
+ "description": "Symfony 6.4, 7.x / PHP >= 8.2 bundle to detect mobile devices, manage mobile view and redirect to the mobile and tablet version.",
+ "minimum-stability": "stable",
+ "keywords": [
+ "mobile detect",
+ "device detect",
+ "device detector",
+ "mobile view managing",
+ "mobiledetect",
+ "mobiledetectbundle",
+ "symfony mobile detect",
+ "symfony mobiledetect",
+ "symfony"
+ ],
+ "homepage": "https://github.com/digifa/MobileDetectSymfonyBundle",
+ "type": "symfony-bundle",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Guido Faust",
+ "email": "gfaust@digifa.de"
+ }
+ ],
+ "require": {
+ "php": ">=8.2",
+ "mobiledetect/mobiledetectlib": "^4.8",
+ "symfony/dependency-injection": "^6.4||^7.0",
+ "symfony/event-dispatcher": "^6.4||^7.0",
+ "symfony/framework-bundle": "^6.4||^7.0",
+ "symfony/yaml": "^6.4||^7.0",
+ "twig/twig": "^2.13 || ^3.0.4"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^3.4 || ^3.8",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^1.0",
+ "phpstan/phpstan-nette": "^1.0",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^9.5",
+ "rector/rector": "^1.2",
+ "squizlabs/php_codesniffer": "^3.6",
+ "symfony/dotenv": "^6.4||^7.0",
+ "symfony/phpunit-bridge": "^6.4||^7.0"
+ },
+ "config": {
+ "sort-packages": true,
+ "allow-plugins": {
+ "phpstan/extension-installer": true,
+ "symfony/flex": true
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "MobileDetectSymfonyBundle\\": "src/"
+ }
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "MobileDetectSymfonyBundle\\Tests\\": "tests/"
+ }
+ },
+ "scripts": {
+ "auto-scripts": {
+ "cache:clear": "symfony-cmd",
+ "assets:install %PUBLIC_DIR%": "symfony-cmd"
+ }
+ }
+}
diff --git a/config/bundles.php b/config/bundles.php
new file mode 100644
index 0000000..6dabfb2
--- /dev/null
+++ b/config/bundles.php
@@ -0,0 +1 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ src/
+ tests/
+
diff --git a/phpstan.neon.dist b/phpstan.neon.dist
new file mode 100644
index 0000000..fde852c
--- /dev/null
+++ b/phpstan.neon.dist
@@ -0,0 +1,7 @@
+parameters:
+ level: 8
+ tmpDir: .phpstan
+ paths:
+ - config/
+ - src/
+ - tests/
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
new file mode 100644
index 0000000..a2bff23
--- /dev/null
+++ b/phpunit.xml.dist
@@ -0,0 +1,32 @@
+
+
+
+
+
+ src
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tests
+
+
+
+
+
+
+
diff --git a/rector.php b/rector.php
new file mode 100644
index 0000000..c7e0a2b
--- /dev/null
+++ b/rector.php
@@ -0,0 +1,22 @@
+withPaths([
+ __DIR__ . '/src',
+ __DIR__ . '/tests',
+ ])
+ ->withPhpSets(php82: true)
+ ->withAttributesSets(symfony: true, doctrine: true)
+ ->withSets([
+ Rector\Symfony\Set\SymfonySetList::SYMFONY_64,
+ Rector\Symfony\Set\SymfonySetList::SYMFONY_70,
+ Rector\Symfony\Set\SymfonySetList::SYMFONY_71,
+ Rector\Symfony\Set\SymfonySetList::SYMFONY_CODE_QUALITY,
+ Rector\Symfony\Set\SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION,
+ ])
+ ->withDeadCodeLevel(10)
+ ->withTypeCoverageLevel(10);
diff --git a/renovate.json b/renovate.json
new file mode 100644
index 0000000..e926ab3
--- /dev/null
+++ b/renovate.json
@@ -0,0 +1,9 @@
+{
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
+ "extends": [
+ "config:recommended",
+ ":disableMajorUpdates",
+ "group:allNonMajor",
+ "schedule:monthly"
+ ]
+}
diff --git a/src/MobileDetectSymfonyBundle.php b/src/MobileDetectSymfonyBundle.php
new file mode 100644
index 0000000..a00f49f
--- /dev/null
+++ b/src/MobileDetectSymfonyBundle.php
@@ -0,0 +1,11 @@
+