diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..891e8ea --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.php] +indent_size = 4 + +[*.js] +indent_size = 4 + +[{*.vue,*.json,*.html5,*.xlf,*.twig}] +indent_size = 2 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..124aeab --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +.composer-require-checker.json export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitlab-ci.yml export-ignore +.gitignore export-ignore +.phpcq.lock export-ignore +.phpcq.yaml.dist export-ignore +phpcs.xml.dist export-ignore +psalm.xml export-ignore diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..de900e1 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,23 @@ +# https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 + +updates: + - commit-message: + include: "scope" + prefix: "composer" + directory: "/" + open-pull-requests-limit: 0 + package-ecosystem: "composer" + schedule: + interval: "weekly" + versioning-strategy: "increase" + + - commit-message: + include: "scope" + prefix: "github-actions" + directory: "/" + open-pull-requests-limit: 10 + package-ecosystem: "github-actions" + schedule: + interval: "weekly" diff --git a/.github/workflows/diagnostics.yml b/.github/workflows/diagnostics.yml new file mode 100644 index 0000000..7816f2b --- /dev/null +++ b/.github/workflows/diagnostics.yml @@ -0,0 +1,77 @@ +name: Code Quality Diagnostics + +on: + pull_request: + push: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + name: PHP ${{ matrix.php }} + + strategy: + fail-fast: false + matrix: + include: + - php: 8.1 + output: '-o default' + phpcq_install: 'update' + - php: 8.2 + output: '-o default' + phpcq_install: 'update' + + steps: + - name: Pull source + uses: actions/checkout@v3 + + - name: Setup PHP with PECL extension + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + + - name: Cache composer cache directory + uses: actions/cache@v3 + env: + cache-name: composer-cache-dir + with: + path: ~/.cache/composer + key: ${{ runner.os }}-${{ matrix.php }}-build-${{ env.cache-name }} + + - name: Install composer dependencies + run: composer install + + - name: Cache vendor directory + uses: actions/cache@v3 + env: + cache-name: vendor + with: + path: vendor + key: ${{ runner.os }}-${{ matrix.php }}-build-${{ env.cache-name }}-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-${{ matrix.php }}-build-${{ env.cache-name }}- + + - name: Install phpcq toolchain + run: ./vendor/bin/phpcq ${{ matrix.phpcq_install }} -v + + - name: Cache phpcq directory + uses: actions/cache@v3 + env: + cache-name: phpcq + with: + path: .phpcq + key: ${{ runner.os }}-${{ matrix.php }}-build-${{ env.cache-name }}-${{ hashFiles('**/.phpcq.lock') }} + restore-keys: | + ${{ runner.os }}-${{ matrix.php }}-build-${{ env.cache-name }}- + + - name: Run tests + run: ./vendor/bin/phpcq run -v ${{ matrix.output }} + + - name: Upload build directory to artifact + uses: actions/upload-artifact@v3 + if: ${{ success() }} || ${{ failure() }} + with: + name: phpcq-builds-php-${{ matrix.php }} + path: .phpcq/build/ diff --git a/.gitignore b/.gitignore index 4e3a67a..786b39c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,16 +1,9 @@ -# OS -.DS_Store -Thumbs.db - -# IDEs -.buildpath -.project -.settings/ -.build/ -.idea/ -nbproject/ - # Composer -/vendor/ -composer.phar -composer.lock \ No newline at end of file +/vendor +composer.lock + +# PHPCQ and related tools +/.phpcq +.phpcq.yaml +.phpcs-cache +.phpunit.result.cache diff --git a/.phpcq.lock b/.phpcq.lock new file mode 100644 index 0000000..c531d20 --- /dev/null +++ b/.phpcq.lock @@ -0,0 +1 @@ +{"plugins":{"psalm":{"api-version":"1.0.0","version":"1.2.0.0","type":"php-file","url":"https://phpcq.github.io/repository/psalm-1.2.0.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0","ext-dom":"*"},"tool":{"psalm":"^3.0 || ^4.0 || ^5.0"}},"checksum":{"type":"sha-512","value":"4a550c9226d7bca582d7c10bd87cce01190c96398936b1613421640c83df62ed1c6e0d44c1b39635414ea8cf4a892a6458d27590793238add24e7cb5547e6ffd"},"tools":{"psalm":{"version":"5.12.0","url":"https://github.com/vimeo/psalm/releases/download/5.12.0/psalm.phar","requirements":{"php":{"php":"^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0","ext-SimpleXML":"*","ext-ctype":"*","ext-dom":"*","ext-json":"*","ext-libxml":"*","ext-mbstring":"*","ext-tokenizer":"*"}},"checksum":null,"signature":"https://github.com/vimeo/psalm/releases/download/5.12.0/psalm.phar.asc"}},"composerLock":null},"composer-require-checker":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-require-checker-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.4 || ^8.0"},"tool":{"composer-require-checker":"^3.8 || ^4.0"}},"checksum":{"type":"sha-512","value":"d5415bddfe024c5749d894034583882aee4e5c3e1087815d9fdd81cb5e71630f631a0e35de0ff84b97fbbf738c16ece5f83bd8c00695913eb846aa6f04577dc2"},"tools":{"composer-require-checker":{"version":"4.6.0","url":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.6.0/composer-require-checker.phar","requirements":{"php":{"php":"~8.1.0 || ~8.2.0","ext-phar":"*"}},"checksum":null,"signature":"https://github.com/maglnet/ComposerRequireChecker/releases/download/4.6.0/composer-require-checker.phar.asc"}},"composerLock":null},"phpmd":{"api-version":"1.0.0","version":"1.0.2.0","type":"php-file","url":"https://phpcq.github.io/repository/phpmd-1.0.2.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpmd":"^2.6.1"}},"checksum":{"type":"sha-512","value":"f22280a6dec8dbdd2ec1d83b294f23237fe32c34f4a298e52038e0a7a0074d541635b2b488b1a6098a42d8418a6cd8eb804406ea82b91e362be2b5d11a0915b0"},"tools":{"phpmd":{"version":"2.13.0","url":"https://github.com/phpmd/phpmd/releases/download/2.13.0/phpmd.phar","requirements":{"php":{"php":">=5.3.9","ext-xml":"*"}},"checksum":null,"signature":"https://github.com/phpmd/phpmd/releases/download/2.13.0/phpmd.phar.asc"}},"composerLock":null},"phpcpd":{"api-version":"1.0.0","version":"1.1.1.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcpd-1.1.1.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcpd":"^6.0"}},"checksum":{"type":"sha-512","value":"1189ce0bf3fade4cb4241f1d96f915ef8fc7651f4450dc79fdf464ee3d6be3009316f0d423ce2d4af9d76ad50807b7fdf4d77bfa6d9ee2c91d6eda32ea214433"},"tools":{"phpcpd":{"version":"6.0.3","url":"https://phar.phpunit.de/phpcpd-6.0.3.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*"}},"checksum":{"type":"sha-256","value":"2cbaea7cfda1bb4299d863eb075e977c3f49055dd16d88529fae5150d48a84cb"},"signature":"https://phar.phpunit.de/phpcpd-6.0.3.phar.asc"}},"composerLock":null},"phploc":{"api-version":"1.0.0","version":"1.0.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phploc-1.0.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*","ext-json":"*"},"tool":{"phploc":"^3.0 || ^4.0 || ^5.0 || ^6.0 || ^7.0"}},"checksum":{"type":"sha-512","value":"f67b02d494796adf553cb3dd13ec06c1cb8e53c799954061749424251379541637538199afb3afa3c7a01cabd1cb6f1c53eb621f015dff9644c6c7cbf10c56d1"},"tools":{"phploc":{"version":"7.0.2","url":"https://phar.phpunit.de/phploc-7.0.2.phar","requirements":{"php":{"php":">=7.3","ext-dom":"*","ext-json":"*"}},"checksum":{"type":"sha-256","value":"3d59778ec86faf25fd00e3a329b2f9ad4a3c751ca91601ea7dab70f887b0bf46"},"signature":"https://phar.phpunit.de/phploc-7.0.2.phar.asc"}},"composerLock":null},"phpcs":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/phpcs-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-dom":"*"},"tool":{"phpcs":"^3.0 || ^2.0","phpcbf":"^3.0 || ^2.0"}},"checksum":{"type":"sha-512","value":"2737022369da1318cc4e0ea194e8a81019f7b079080d869aab878b7486052fdbe68fee3f28131f35573226def1aabd4bd005e038ee7b767c137b1107c1492a83"},"tools":{"phpcs":{"version":"3.7.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.7.2/phpcs.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.7.2/phpcs.phar.asc"},"phpcbf":{"version":"3.7.2","url":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.7.2/phpcbf.phar","requirements":{"php":{"php":">=5.4.0","ext-tokenizer":"*","ext-xmlwriter":"*","ext-simplexml":"*"}},"checksum":null,"signature":"https://github.com/squizlabs/PHP_CodeSniffer/releases/download/3.7.2/phpcbf.phar.asc"}},"composerLock":null},"composer-normalize":{"api-version":"1.0.0","version":"1.1.0.0","type":"php-file","url":"https://phpcq.github.io/repository/composer-normalize-1.1.0.0.php","signature":null,"requirements":{"php":{"php":"^7.3 || ^8.0","ext-json":"*"},"tool":{"composer-normalize":"^2.1"}},"checksum":{"type":"sha-512","value":"d59d3557cb20630734878a9115df5dd32d5aff815e5b15be36f6fb5d6e9d83dd36efd84215ab6529edcc924f600946f739a0d9e67723deff95c88346ab502498"},"tools":{"composer-normalize":{"version":"2.31.0","url":"https://github.com/ergebnis/composer-normalize/releases/download/2.31.0/composer-normalize.phar","requirements":{"php":{"php":"~8.0.0 || ~8.1.0 || ~8.2.0","ext-json":"*"}},"checksum":null,"signature":"https://github.com/ergebnis/composer-normalize/releases/download/2.31.0/composer-normalize.phar.asc"}},"composerLock":null}},"tools":[]} \ No newline at end of file diff --git a/.phpcq.yaml.dist b/.phpcq.yaml.dist new file mode 100644 index 0000000..a45bb5d --- /dev/null +++ b/.phpcq.yaml.dist @@ -0,0 +1,100 @@ +phpcq: + repositories: + - https://phpcq.github.io/repository/repository.json + directories: + - src + artifact: .phpcq/build + + plugins: + psalm: + version: ^1.0 + signed: false + composer-require-checker: + version: ^1.0 + signed: false + phpmd: + version: ^1.0 + signed: false + requirements: + phpmd: + signed: false + phpcpd: + version: ^1.1 + signed: false + phploc: + version: ^1.0 + signed: false + phpcs: + version: ^1.0 + signed: false + composer-normalize: + version: ^1.0 + signed: false + + trusted-keys: + # composer-require-checker + - 033E5F8D801A2F8D + # sb@sebastian-bergmann.de + - 4AA394086372C20A + # psalm + - 8A03EA3B385DBAA1 + - 12CE0F1D262429A5 + # magl@magll.net + - D2CCAC42F6295E7D + # PHP_CodeSniffer + - 31C7E470E2138192 + # Composer normalize + - C00543248C87FB13 + # phpmd + - A4E55EA12C7C085C + +tasks: + fix: + - composer-normalize-fix + - phpcbf + + verify: + - composer-require-checker + - composer-normalize + + analyze: + - phploc + - phpcpd + - phpmd + - phpcs + - psalm + + default: + - verify + - analyze + + phpmd: + config: + ruleset: + - codesize + - controversial + - design + - naming + - unusedcode + + composer-require-checker: + config: + config_file: '.composer-require-checker.json' + + phpcs: + config: &phpcs-config + standard: ~ + standard_paths: + - ./vendor/slevomat/coding-standard + - ./vendor/doctrine/coding-standard/lib + + phpcbf: + plugin: phpcs + config: + <<: *phpcs-config + fix: true + + composer-normalize-fix: + plugin: composer-normalize + config: + dry_run: false diff --git a/composer.json b/composer.json index edb3dbd..a62de7f 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,8 @@ { "name": "hofff/contao-facebook-pixel", "description": "Integrate Facebook Tracking Pixel in Contao", + "license": "LGPL-3.0-or-later", + "type": "contao-bundle", "keywords": [ "contao", "plugin", @@ -9,14 +11,11 @@ "analytics", "tracking" ], - "type": "contao-bundle", - "license": "LGPL-3.0-or-later", - "homepage": "https://www.hofff.com", "authors": [ { "name": "Nicky Hoff", - "homepage": "https://www.hofff.com", "email": "nick@hofff.com", + "homepage": "https://www.hofff.com", "role": "Manager" }, { @@ -26,29 +25,40 @@ "role": "Developer" } ], + "homepage": "https://www.hofff.com", "require": { - "php": "^7.1", + "php": "^8.1", "ext-pdo": "*", - "contao/core-bundle": "^4.4", + "contao/core-bundle": "^4.9", + "doctrine/dbal": "^2.13 || ^3.4", "hofff/contao-consent-bridge": "^1.1", - "symfony/http-kernel": "^3.3 || ^4.0", - "symfony/config": "^3.3 || ^4.0", - "symfony/dependency-injection": "^3.3 || ^4.0", - "doctrine/dbal": "^2.5" + "symfony/config": "^4.4 || ^5.4", + "symfony/dependency-injection": "^4.4 || ^5.4", + "symfony/http-kernel": "^4.4 || ^5.4" }, "require-dev": { - "contao/manager-plugin": "^2.0" + "contao/manager-plugin": "^2.0", + "doctrine/coding-standard": "^12.0", + "phpcq/runner-bootstrap": "^1.0@dev" }, "autoload": { "psr-4": { "Hofff\\Contao\\FacebookPixel\\": "src/" } }, + "config": { + "allow-plugins": { + "contao-components/installer": true, + "php-http/discovery": true, + "contao/manager-plugin": true, + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, "extra": { - "contao-manager-plugin": "Hofff\\Contao\\FacebookPixel\\ContaoManager\\Plugin", "branch-alias": { - "dev-master": "2.1.x-dev", - "dev-develop": "2.2.x-dev" - } + "dev-develop": "2.2.x-dev", + "dev-master": "2.1.x-dev" + }, + "contao-manager-plugin": "Hofff\\Contao\\FacebookPixel\\ContaoManager\\Plugin" } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 0000000..8acdf1f --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,32 @@ + + + + + + + + + + vendor/autoload.php + + + + + + src + + + + + + + + + + + + + + languages/* + + diff --git a/psalm.xml b/psalm.xml new file mode 100644 index 0000000..190ee92 --- /dev/null +++ b/psalm.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + diff --git a/src/Contao/FacebookPixelElement.php b/src/Contao/FacebookPixelElement.php index 8e0c263..4da3a2e 100644 --- a/src/Contao/FacebookPixelElement.php +++ b/src/Contao/FacebookPixelElement.php @@ -7,13 +7,9 @@ use Contao\ContentElement; /** - * Class ContentRecursiveDownloadFolder - * - * Front end content element "hofff_facebook-pixel". - * - * @copyright Hofff.com 2017 - * @author Mathias Arzberger - * @package Hofff_facebook-pixel + * @property string $fb_pixel_opt_out_active_text + * @property string $fb_pixel_opt_out_inactive_text + * @psalm-suppress PropertyNotSetInConstructor */ class FacebookPixelElement extends ContentElement { @@ -24,5 +20,6 @@ class FacebookPixelElement extends ContentElement * * @var string */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint protected $strTemplate = 'ce_hofff_facebook_pixel_optout'; } diff --git a/src/Contao/FacebookPixelModule.php b/src/Contao/FacebookPixelModule.php index 5805329..e8331c3 100644 --- a/src/Contao/FacebookPixelModule.php +++ b/src/Contao/FacebookPixelModule.php @@ -7,13 +7,9 @@ use Contao\Module; /** - * Class ContentRecursiveDownloadFolder - * - * Front end content element "hofff_facebook-pixel". - * - * @copyright Hofff.com 2017 - * @author Mathias Arzberger - * @package Hofff_facebook-pixel + * @property string $fb_pixel_opt_out_active_text + * @property string $fb_pixel_opt_out_inactive_text + * @psalm-suppress PropertyNotSetInConstructor */ class FacebookPixelModule extends Module { @@ -24,5 +20,6 @@ class FacebookPixelModule extends Module * * @var string */ + // phpcs:ignore SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint protected $strTemplate = 'mod_hofff_facebook_pixel_optout'; } diff --git a/src/Contao/FacebookPixelTrait.php b/src/Contao/FacebookPixelTrait.php index 72402ca..758dd75 100644 --- a/src/Contao/FacebookPixelTrait.php +++ b/src/Contao/FacebookPixelTrait.php @@ -8,42 +8,46 @@ use Contao\Database; use Contao\Input; +use function defined; + trait FacebookPixelTrait { + protected string $fb_pixel_id = ''; + /** - * Return if there are no files - * - * @return string + * @psalm-suppress MixedPropertyFetch + * @SuppressWarnings(PHPMD.Superglobals) */ public function generate(): string { - if (TL_MODE === 'BE') { + if (defined('TL_MODE') && TL_MODE === 'BE') { $objTemplate = new BackendTemplate('be_wildcard'); $objTemplate->wildcard = '### Facebook Pixel OptOut ###'; $objTemplate->title = $this->headline; $objTemplate->id = $this->id; - $objTemplate->link = $this->name; - $objTemplate->href = 'contao/main.php?do=themes&table=tl_module&act=edit&id=' . $this->id; + $objTemplate->link = $this->name ?? null; return $objTemplate->parse(); } - $this->fb_pixel_id = Database::getInstance() - ->prepare("SELECT * FROM tl_page WHERE id=?") + $this->fb_pixel_id = (string) Database::getInstance() + ->prepare('SELECT fb_pixel_id FROM tl_page WHERE id=?') ->limit(1) ->execute($GLOBALS['objPage']->rootId) ->fb_pixel_id; // Return if there is no page id - if (!$this->fb_pixel_id) { - return '
' . $GLOBALS['TL_LANG']['MSC']['fbPixelNoIdIsSet'] . '
'; + if (! $this->fb_pixel_id) { + /** @psalm-suppress MixedArrayAccess */ + return '
' . (string) $GLOBALS['TL_LANG']['MSC']['fbPixelNoIdIsSet'] . '
'; } return parent::generate(); } /** - * Compile the content element + * @psalm-suppress MixedArrayAccess + * @SuppressWarnings(PHPMD.Superglobals) */ protected function compile(): void { diff --git a/src/ContaoManager/Plugin.php b/src/ContaoManager/Plugin.php index 334f301..bb819f4 100644 --- a/src/ContaoManager/Plugin.php +++ b/src/ContaoManager/Plugin.php @@ -12,12 +12,17 @@ final class Plugin implements BundlePluginInterface { + /** + * {@inheritDoc} + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ public function getBundles(ParserInterface $parser): array { return [ BundleConfig::create(HofffContaoFacebookPixelBundle::class) ->setLoadAfter([ContaoCoreBundle::class]) - ->setReplace(['hofff_facebook-pixel']) + ->setReplace(['hofff_facebook-pixel']), ]; } } diff --git a/src/DependencyInjection/HofffContaoFacebookPixelExtension.php b/src/DependencyInjection/HofffContaoFacebookPixelExtension.php index 449360d..60b7895 100644 --- a/src/DependencyInjection/HofffContaoFacebookPixelExtension.php +++ b/src/DependencyInjection/HofffContaoFacebookPixelExtension.php @@ -11,12 +11,14 @@ final class HofffContaoFacebookPixelExtension extends Extension { - public function load(array $configs, ContainerBuilder $container) + /** + * {@inheritDoc} + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function load(array $configs, ContainerBuilder $container): void { - $loader = new XmlFileLoader( - $container, - new FileLocator(__DIR__ . '/../Resources/config') - ); + $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); $loader->load('services.xml'); } diff --git a/src/EventListener/HookSubscriber.php b/src/EventListener/HookSubscriber.php index d03e82f..7ce0750 100644 --- a/src/EventListener/HookSubscriber.php +++ b/src/EventListener/HookSubscriber.php @@ -11,63 +11,21 @@ use Hofff\Contao\Consent\Bridge\ConsentToolManager; use Hofff\Contao\Consent\Bridge\Exception\InvalidArgumentException as InvalidConsentIdException; -/** - * Class FacebookPixel - * - * Front end content element "hofff_facebook-pixel". - * - * @copyright Hofff.com 2017 - * @author Mathias Arzberger - * @package Hofff_facebook-pixel - */ +use function explode; + final class HookSubscriber { - /** - * Database connection. - * - * @var Connection - */ - private $connection; - - /** - * Consent tool manager. - * - * @var ConsentToolManager - */ - private $consentToolManager; - - /** - * Consent Id parser. - * - * @var ConsentIdParser - */ - private $consentIdParser; - - /** - * HookSubscriber constructor. - * - * @param Connection $connection Database connection. - * @param ConsentToolManager $consentToolManager Consent tool manager. - * @param ConsentIdParser $consentIdParser Consent Id parser. - */ public function __construct( - Connection $connection, - ConsentToolManager $consentToolManager, - ConsentIdParser $consentIdParser - ){ - $this->connection = $connection; - $this->consentToolManager = $consentToolManager; - $this->consentIdParser = $consentIdParser; + private readonly Connection $connection, + private readonly ConsentToolManager $consentToolManager, + private readonly ConsentIdParser $consentIdParser, + ) { } /** * Add the facebook pixel when parsing a frontend template. * - * @param string $content - * - * @return string - * - * @throws \Doctrine\DBAL\DBALException + * @SuppressWarnings(PHPMD.Superglobals) */ public function onParseFrontendTemplate(string $content): string { @@ -87,12 +45,14 @@ public function onParseFrontendTemplate(string $content): string } // parse template file - $objTemplate = new FrontendTemplate('hofff_facebook_pixel'); + $objTemplate = new FrontendTemplate('hofff_facebook_pixel'); + /** @psalm-suppress InvalidPropertyAssignmentValue */ $objTemplate->id = $pixelConfig['fb_pixel_id']; $parsed = $objTemplate->parse(); $parsed = $this->applyConsentTool($parsed, $pixelConfig['fb_pixel_consentId']); + /** @psalm-suppress MixedArrayAssignment */ $GLOBALS['TL_HEAD'][] = $parsed; } @@ -102,11 +62,10 @@ public function onParseFrontendTemplate(string $content): string /** * function to add facebook pixel privacy link with an insert tag using switch to add other functions later. * - * @param string $tag - * - * @return bool|string + * @psalm-suppress MixedArrayAccess + * @SuppressWarnings(PHPMD.Superglobals) */ - public function onReplaceInsertTag(string $tag) + public function onReplaceInsertTag(string $tag): string|false { $parts = explode('::', $tag); @@ -119,8 +78,8 @@ public function onReplaceInsertTag(string $tag) [ 'optOutActiveText' => $parts[2] ?: $GLOBALS['TL_LANG']['MSC']['fbPixelOptOutActiveText'], 'optOutInActiveText' => $parts[3] ?: $GLOBALS['TL_LANG']['MSC']['fbPixelOptOutInActiveText'], - 'optOutStatus' => (bool) Input::cookie('FB_PIXEL_OPTOUT') - ] + 'optOutStatus' => (bool) Input::cookie('FB_PIXEL_OPTOUT'), + ], ); return $template->parse(); @@ -129,42 +88,48 @@ public function onReplaceInsertTag(string $tag) /** * Get the pixel config from the root page. * - * @return array + * @return array * - * @throws \Doctrine\DBAL\DBALException + * @psalm-suppress MixedReturnTypeCoercion + * @psalm-suppress InvalidFalsableReturnType + * @psalm-suppress FalsableReturnStatement + * @SuppressWarnings(PHPMD.Superglobals) */ private function getPixelConfig(): array { $query = 'SELECT fb_pixel_id, fb_pixel_status, fb_pixel_consentId FROM tl_page WHERE id=:pageId'; $statement = $this->connection->prepare($query); - $statement->bindValue('pageId', $GLOBALS['objPage']->rootId); - if (!$statement->execute() || $statement->rowCount() === 0) { + /** @psalm-suppress MixedPropertyFetch */ + $result = $statement->executeQuery(['pageId' => $GLOBALS['objPage']->rootId]); + if ($result->rowCount() === 0) { return [ - 'fb_pixel_id' => null, - 'fb_pixel_status' => null, - 'fb_pixel_consentId' => null + 'fb_pixel_id' => null, + 'fb_pixel_status' => null, + 'fb_pixel_consentId' => null, ]; } - return $statement->fetch(\PDO::FETCH_ASSOC); + return $result->fetchAssociative(); } - private function applyConsentTool(string $buffer, ?string $rawConsentId): string + private function applyConsentTool(string $buffer, string|null $rawConsentId): string { - if (null === $rawConsentId) { + if ($rawConsentId === null) { return $buffer; } $consentTool = $this->consentToolManager->activeConsentTool(); - if (null === $consentTool) { + if ($consentTool === null) { return $buffer; } try { $consentId = $this->consentIdParser->parse($rawConsentId); $buffer = $consentTool->renderRaw($buffer, $consentId); - } catch (InvalidConsentIdException $exception) {} + } catch (InvalidConsentIdException) { + // Invalid consent id given, ignore it + } return $buffer; } diff --git a/src/Resources/contao/config/config.php b/src/Resources/contao/config/config.php index 90300eb..fadf081 100644 --- a/src/Resources/contao/config/config.php +++ b/src/Resources/contao/config/config.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use Hofff\Contao\FacebookPixel\EventListener\HookSubscriber; use Hofff\Contao\FacebookPixel\Contao\FacebookPixelElement; +use Hofff\Contao\FacebookPixel\EventListener\HookSubscriber; /** * Content elements @@ -20,7 +20,7 @@ 'miscellaneous' => [ 'hofff_facebook_pixel_optout' => FacebookPixelElement::class, ], - ] + ], ); /* diff --git a/src/Resources/contao/dca/tl_page.php b/src/Resources/contao/dca/tl_page.php index 2136383..e1c777a 100644 --- a/src/Resources/contao/dca/tl_page.php +++ b/src/Resources/contao/dca/tl_page.php @@ -2,21 +2,26 @@ declare(strict_types=1); +use Contao\CoreBundle\DataContainer\PaletteManipulator; +use Contao\CoreBundle\DataContainer\PaletteNotFoundException; use Hofff\Contao\Consent\Bridge\EventListener\Dca\ConsentIdOptions; -$GLOBALS['TL_DCA']['tl_page']['palettes']['root'] = str_replace( - '{publish_legend}', - '{facebook_pixel_legend},fb_pixel_id,fb_pixel_status,fb_pixel_consentId;{publish_legend}', - $GLOBALS['TL_DCA']['tl_page']['palettes']['root'] -); +(static function (): void { + $manipulator = PaletteManipulator::create() + ->addLegend('facebook_pixel_legend', 'publish_legend', PaletteManipulator::POSITION_BEFORE) + ->addFields( + ['fb_pixel_id', 'fb_pixel_status', 'fb_pixel_consentId'], + 'facebook_pixel_legend', + PaletteManipulator::POSITION_APPEND, + ); -if (isset($GLOBALS['TL_DCA']['tl_page']['palettes']['rootfallback'])) { - $GLOBALS['TL_DCA']['tl_page']['palettes']['rootfallback'] = str_replace( - '{publish_legend}', - '{facebook_pixel_legend},fb_pixel_id,fb_pixel_status,fb_pixel_consentId;{publish_legend}', - $GLOBALS['TL_DCA']['tl_page']['palettes']['rootfallback'] - ); -} + foreach (['root', 'rootfallback'] as $palette) { + try { + $manipulator->applyToPalette($palette, 'tl_page'); + } catch (PaletteNotFoundException) { + } + } +})(); $GLOBALS['TL_DCA']['tl_page']['fields']['fb_pixel_id'] = [ 'label' => &$GLOBALS['TL_LANG']['tl_page']['fb_pixel_id'], diff --git a/src/Resources/contao/languages/de/default.php b/src/Resources/contao/languages/de/default.php index cfddda3..760dcb9 100644 --- a/src/Resources/contao/languages/de/default.php +++ b/src/Resources/contao/languages/de/default.php @@ -1,23 +1,12 @@