From 5f0979884c68b824399798f646acc865afdc9050 Mon Sep 17 00:00:00 2001 From: Kieran Brahney Date: Thu, 11 Nov 2021 20:59:03 +0000 Subject: [PATCH 1/5] Integrate PHPStan --- .gitattributes | 8 +++++--- .travis.yml | 1 + composer.json | 3 ++- phpstan.neon.dist | 6 ++++++ src/Css/Processor.php | 11 ++++++----- src/Css/Property/Processor.php | 4 ++-- src/Css/Property/Property.php | 4 ++-- src/Css/Rule/Processor.php | 10 +++++----- src/CssToInlineStyles.php | 15 +++++++++++---- stubs/CssSelector.stub | 34 ++++++++++++++++++++++++++++++++++ 10 files changed, 74 insertions(+), 22 deletions(-) create mode 100644 phpstan.neon.dist create mode 100644 stubs/CssSelector.stub diff --git a/.gitattributes b/.gitattributes index 55fdd3c..5f3072b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,11 +1,13 @@ * text=auto -/example export-ignore -/tests export-ignore /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore /.travis.yml export-ignore -/phpunit.xml.dist export-ignore /CHANGELOG.md export-ignore +/example export-ignore +/phpstan.neon.dist export-ignore +/phpunit.xml.dist export-ignore /README.md export-ignore +/stubs export-ignore +/tests export-ignore diff --git a/.travis.yml b/.travis.yml index d7e62ef..6b99928 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,7 @@ install: - if [[ "$TRAVIS_PHP_VERSION" = "nightly" ]]; then travis_retry composer install --prefer-dist --no-interaction --ignore-platform-reqs; fi script: + - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then vendor/bin/phpstan; fi - vendor/bin/phpunit --verbose --coverage-clover=coverage.clover after_success: diff --git a/composer.json b/composer.json index 066129c..3c06c3d 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5", + "phpstan/phpstan": "^1.1" }, "autoload": { "psr-4": { diff --git a/phpstan.neon.dist b/phpstan.neon.dist new file mode 100644 index 0000000..4fa9155 --- /dev/null +++ b/phpstan.neon.dist @@ -0,0 +1,6 @@ +parameters: + level: max + paths: + - src/ + scanFiles: + - stubs/CssSelector.stub diff --git a/src/Css/Processor.php b/src/Css/Processor.php index 0c5ceb1..67a6c68 100644 --- a/src/Css/Processor.php +++ b/src/Css/Processor.php @@ -35,7 +35,7 @@ public function getCssFromStyleTags($html) { $css = ''; $matches = array(); - $htmlNoComments = preg_replace('||s', '', $html); + $htmlNoComments = preg_replace('||s', '', $html) ?: $html; preg_match_all('|(.*)|isU', $htmlNoComments, $matches); if (!empty($matches[1])) { @@ -55,15 +55,16 @@ public function getCssFromStyleTags($html) private function doCleanup($css) { // remove charset - $css = preg_replace('/@charset "[^"]++";/', '', $css); + $css = preg_replace('/@charset "[^"]++";/', '', $css) ?: $css; // remove media queries - $css = preg_replace('/@media [^{]*+{([^{}]++|{[^{}]*+})*+}/', '', $css); + $css = preg_replace('/@media [^{]*+{([^{}]++|{[^{}]*+})*+}/', '', $css) ?: $css; $css = str_replace(array("\r", "\n"), '', $css); $css = str_replace(array("\t"), ' ', $css); $css = str_replace('"', '\'', $css); - $css = preg_replace('|/\*.*?\*/|', '', $css); - $css = preg_replace('/\s\s++/', ' ', $css); + $css = preg_replace('|/\*.*?\*/|', '', $css) ?: $css; + $css = preg_replace('/\s\s++/', ' ', $css) ?: $css; + $css = trim($css); return $css; diff --git a/src/Css/Property/Processor.php b/src/Css/Property/Processor.php index 3b01861..d4d328f 100644 --- a/src/Css/Property/Processor.php +++ b/src/Css/Property/Processor.php @@ -50,8 +50,8 @@ private function cleanup($string) $string = str_replace(array("\r", "\n"), '', $string); $string = str_replace(array("\t"), ' ', $string); $string = str_replace('"', '\'', $string); - $string = preg_replace('|/\*.*?\*/|', '', $string); - $string = preg_replace('/\s\s+/', ' ', $string); + $string = preg_replace('|/\*.*?\*/|', '', $string) ?: $string; + $string = preg_replace('/\s\s+/', ' ', $string) ?: $string; $string = trim($string); $string = rtrim($string, ';'); diff --git a/src/Css/Property/Property.php b/src/Css/Property/Property.php index c8970cf..396b7c8 100644 --- a/src/Css/Property/Property.php +++ b/src/Css/Property/Property.php @@ -17,7 +17,7 @@ final class Property private $value; /** - * @var Specificity + * @var Specificity|null */ private $originalSpecificity; @@ -57,7 +57,7 @@ public function getValue() /** * Get originalSpecificity * - * @return Specificity + * @return Specificity|null */ public function getOriginalSpecificity() { diff --git a/src/Css/Rule/Processor.php b/src/Css/Rule/Processor.php index d183262..ac88644 100644 --- a/src/Css/Rule/Processor.php +++ b/src/Css/Rule/Processor.php @@ -31,8 +31,8 @@ private function cleanup($string) $string = str_replace(array("\r", "\n"), '', $string); $string = str_replace(array("\t"), ' ', $string); $string = str_replace('"', '\'', $string); - $string = preg_replace('|/\*.*?\*/|', '', $string); - $string = preg_replace('/\s\s+/', ' ', $string); + $string = preg_replace('|/\*.*?\*/|', '', $string) ?: $string; + $string = preg_replace('/\s\s+/', ' ', $string) ?: $string; $string = trim($string); $string = rtrim($string, '}'); @@ -116,9 +116,9 @@ public function calculateSpecificityBasedOnASelector($selector) )"; return new Specificity( - preg_match_all("/{$idSelectorsPattern}/ix", $selector, $matches), - preg_match_all("/{$classAttributesPseudoClassesSelectorsPattern}/ix", $selector, $matches), - preg_match_all("/{$typePseudoElementsSelectorPattern}/ix", $selector, $matches) + preg_match_all("/{$idSelectorsPattern}/ix", $selector, $matches) ?: 0, + preg_match_all("/{$classAttributesPseudoClassesSelectorsPattern}/ix", $selector, $matches) ?: 0, + preg_match_all("/{$typePseudoElementsSelectorPattern}/ix", $selector, $matches) ?: 0 ); } diff --git a/src/CssToInlineStyles.php b/src/CssToInlineStyles.php index 3268c5f..8bf2d93 100644 --- a/src/CssToInlineStyles.php +++ b/src/CssToInlineStyles.php @@ -11,6 +11,7 @@ class CssToInlineStyles { + /** @var CssSelectorConverter */ private $cssConverter; public function __construct() @@ -130,12 +131,15 @@ protected function getHtmlFromDocument(\DOMDocument $document) // retrieve the document element // we do it this way to preserve the utf-8 encoding $htmlElement = $document->documentElement; - $html = $document->saveHTML($htmlElement); + $html = $document->saveHTML($htmlElement) ?: ''; $html = trim($html); + if ($htmlElement === null) { + return $html; + } // retrieve the doctype $document->removeChild($htmlElement); - $doctype = $document->saveHTML(); + $doctype = $document->saveHTML() ?: ''; $doctype = trim($doctype); // if it is the html5 doctype convert it to lowercase @@ -158,6 +162,7 @@ protected function inline(\DOMDocument $document, array $rules) return $document; } + /** @var \SplObjectStorage<\DOMElement, Css\Property\Property[]> $propertyStorage */ $propertyStorage = new \SplObjectStorage(); $xPath = new \DOMXPath($document); @@ -222,8 +227,10 @@ private function calculatePropertiesToBeApplied(array $properties, array $cssPro //overrule if current property is important and existing is not, else check specificity $overrule = !$existingProperty->isImportant() && $property->isImportant(); - if (!$overrule) { - $overrule = $existingProperty->getOriginalSpecificity()->compareTo($property->getOriginalSpecificity()) <= 0; + $originalSpecificity = $existingProperty->getOriginalSpecificity(); + $specificity = $property->getOriginalSpecificity(); + if (!$overrule && $originalSpecificity !== null && $specificity !== null) { + $overrule = $originalSpecificity->compareTo($specificity) <= 0; } if ($overrule) { diff --git a/stubs/CssSelector.stub b/stubs/CssSelector.stub new file mode 100644 index 0000000..fbd31fc --- /dev/null +++ b/stubs/CssSelector.stub @@ -0,0 +1,34 @@ +toXPath($cssExpr, $prefix); + } + + /** @return void */ + public static function enableHtmlExtension() + { + self::$html = true; + } + + /** @return void */ + public static function disableHtmlExtension() + { + self::$html = false; + } +} From 2767e93646280f5739b39ad8fc3414741890af2e Mon Sep 17 00:00:00 2001 From: Kieran Brahney Date: Thu, 11 Nov 2021 21:09:32 +0000 Subject: [PATCH 2/5] only install phpstan on php 7.4 --- .travis.yml | 3 ++- composer.json | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6b99928..4b41651 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,9 +37,10 @@ install: - if [[ $setup = 'basic' && "$TRAVIS_PHP_VERSION" != "nightly" ]]; then travis_retry composer install --prefer-dist --no-interaction; fi - if [[ $setup = 'lowest' && "$TRAVIS_PHP_VERSION" != "nightly" ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable; fi - if [[ "$TRAVIS_PHP_VERSION" = "nightly" ]]; then travis_retry composer install --prefer-dist --no-interaction --ignore-platform-reqs; fi + - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then travis_retry composer requrie --dev phpstan/phpstan:1.1.2; fi script: - - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then vendor/bin/phpstan; fi + - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then composer require vendor/bin/phpstan; fi - vendor/bin/phpunit --verbose --coverage-clover=coverage.clover after_success: diff --git a/composer.json b/composer.json index 3c06c3d..066129c 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,7 @@ "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5", - "phpstan/phpstan": "^1.1" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5" }, "autoload": { "psr-4": { From ca2febfa90e6c6b40833633c0b9e34090ceca76e Mon Sep 17 00:00:00 2001 From: Kieran Brahney Date: Thu, 11 Nov 2021 21:31:23 +0000 Subject: [PATCH 3/5] fix preg_replace return value --- src/Css/Processor.php | 8 ++++---- src/Css/Property/Processor.php | 4 ++-- src/Css/Rule/Processor.php | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Css/Processor.php b/src/Css/Processor.php index 67a6c68..ed34689 100644 --- a/src/Css/Processor.php +++ b/src/Css/Processor.php @@ -55,15 +55,15 @@ public function getCssFromStyleTags($html) private function doCleanup($css) { // remove charset - $css = preg_replace('/@charset "[^"]++";/', '', $css) ?: $css; + $css = (string) preg_replace('/@charset "[^"]++";/', '', $css); // remove media queries - $css = preg_replace('/@media [^{]*+{([^{}]++|{[^{}]*+})*+}/', '', $css) ?: $css; + $css = (string) preg_replace('/@media [^{]*+{([^{}]++|{[^{}]*+})*+}/', '', $css); $css = str_replace(array("\r", "\n"), '', $css); $css = str_replace(array("\t"), ' ', $css); $css = str_replace('"', '\'', $css); - $css = preg_replace('|/\*.*?\*/|', '', $css) ?: $css; - $css = preg_replace('/\s\s++/', ' ', $css) ?: $css; + $css = (string) preg_replace('|/\*.*?\*/|', '', $css); + $css = (string) preg_replace('/\s\s++/', ' ', $css); $css = trim($css); diff --git a/src/Css/Property/Processor.php b/src/Css/Property/Processor.php index d4d328f..d5d4251 100644 --- a/src/Css/Property/Processor.php +++ b/src/Css/Property/Processor.php @@ -50,8 +50,8 @@ private function cleanup($string) $string = str_replace(array("\r", "\n"), '', $string); $string = str_replace(array("\t"), ' ', $string); $string = str_replace('"', '\'', $string); - $string = preg_replace('|/\*.*?\*/|', '', $string) ?: $string; - $string = preg_replace('/\s\s+/', ' ', $string) ?: $string; + $string = (string) preg_replace('|/\*.*?\*/|', '', $string); + $string = (string) preg_replace('/\s\s+/', ' ', $string); $string = trim($string); $string = rtrim($string, ';'); diff --git a/src/Css/Rule/Processor.php b/src/Css/Rule/Processor.php index ac88644..4bd5328 100644 --- a/src/Css/Rule/Processor.php +++ b/src/Css/Rule/Processor.php @@ -31,8 +31,8 @@ private function cleanup($string) $string = str_replace(array("\r", "\n"), '', $string); $string = str_replace(array("\t"), ' ', $string); $string = str_replace('"', '\'', $string); - $string = preg_replace('|/\*.*?\*/|', '', $string) ?: $string; - $string = preg_replace('/\s\s+/', ' ', $string) ?: $string; + $string = (string) preg_replace('|/\*.*?\*/|', '', $string); + $string = (string) preg_replace('/\s\s+/', ' ', $string); $string = trim($string); $string = rtrim($string, '}'); From 8480769a624c7bcd2f5ad8217988a166170c1a04 Mon Sep 17 00:00:00 2001 From: Kieran Brahney Date: Thu, 11 Nov 2021 21:33:57 +0000 Subject: [PATCH 4/5] fix preg_replace return value --- src/Css/Processor.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Css/Processor.php b/src/Css/Processor.php index ed34689..9568e29 100644 --- a/src/Css/Processor.php +++ b/src/Css/Processor.php @@ -35,7 +35,7 @@ public function getCssFromStyleTags($html) { $css = ''; $matches = array(); - $htmlNoComments = preg_replace('||s', '', $html) ?: $html; + $htmlNoComments = (string) preg_replace('||s', '', $html); preg_match_all('|(.*)|isU', $htmlNoComments, $matches); if (!empty($matches[1])) { From 9f076e68e9aa5663a7aa07f5728ade655760204b Mon Sep 17 00:00:00 2001 From: Kieran Date: Fri, 12 Nov 2021 10:47:23 +0000 Subject: [PATCH 5/5] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4b41651..83b9edb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,7 +40,7 @@ install: - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then travis_retry composer requrie --dev phpstan/phpstan:1.1.2; fi script: - - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then composer require vendor/bin/phpstan; fi + - if [[ "$TRAVIS_PHP_VERSION" = "7.4" ]]; then vendor/bin/phpstan analyse; fi - vendor/bin/phpunit --verbose --coverage-clover=coverage.clover after_success: