diff --git a/src/Id.php b/src/Id.php index a578876..aedc1f4 100644 --- a/src/Id.php +++ b/src/Id.php @@ -9,6 +9,8 @@ */ namespace Templado\Engine; +use function implode; +use function preg_match; use InvalidArgumentException; final readonly class Id { diff --git a/src/StaticNodeList.php b/src/StaticNodeList.php index 176faa0..b1fb564 100644 --- a/src/StaticNodeList.php +++ b/src/StaticNodeList.php @@ -9,6 +9,8 @@ */ namespace Templado\Engine; +use function array_values; +use function count; use function iterator_to_array; use ArrayIterator; use Countable; diff --git a/src/csrfprotection/CSRFProtection.php b/src/csrfprotection/CSRFProtection.php index 801990e..f4aa358 100644 --- a/src/csrfprotection/CSRFProtection.php +++ b/src/csrfprotection/CSRFProtection.php @@ -9,14 +9,11 @@ */ namespace Templado\Engine; -class CSRFProtection { - private readonly string $fieldName; - - private readonly string $tokenValue; - - public function __construct(string $fieldName, string $tokenValue) { - $this->fieldName = $fieldName; - $this->tokenValue = $tokenValue; +final readonly class CSRFProtection { + public function __construct( + private string $fieldName, + private string $tokenValue + ) { } public function fieldName(): string { diff --git a/src/csrfprotection/CSRFProtectionRenderer.php b/src/csrfprotection/CSRFProtectionRenderer.php index 63b9fff..6a38b12 100644 --- a/src/csrfprotection/CSRFProtectionRenderer.php +++ b/src/csrfprotection/CSRFProtectionRenderer.php @@ -9,6 +9,7 @@ */ namespace Templado\Engine; +use function assert; use function sprintf; use DOMDocument; use DOMElement; @@ -19,7 +20,8 @@ final class CSRFProtectionRenderer { private CSRFProtection $protection; private DOMDocument $dom; - private DOMXPath$xp; + + private DOMXPath $xp; public function render(DOMElement $context, CSRFProtection $protection): void { $this->protection = $protection; diff --git a/src/document/DocumentCollection.php b/src/document/DocumentCollection.php index 951e565..a25078a 100644 --- a/src/document/DocumentCollection.php +++ b/src/document/DocumentCollection.php @@ -9,6 +9,8 @@ */ namespace Templado\Engine; +use function array_push; +use function count; use ArrayIterator; use Countable; use IteratorAggregate; diff --git a/src/formdata/FormData.php b/src/formdata/FormData.php index 3f2de7e..cd463f4 100644 --- a/src/formdata/FormData.php +++ b/src/formdata/FormData.php @@ -17,7 +17,6 @@ class FormData { private readonly string $identifier; - private readonly array $values; /** diff --git a/src/merger/MergeList.php b/src/merger/MergeList.php index 09b2564..d56b34a 100644 --- a/src/merger/MergeList.php +++ b/src/merger/MergeList.php @@ -9,6 +9,8 @@ */ namespace Templado\Engine; +use function count; +use function sprintf; use ArrayIterator; use DOMDocument; diff --git a/src/merger/Merger.php b/src/merger/Merger.php index 9e07a55..0700cad 100644 --- a/src/merger/Merger.php +++ b/src/merger/Merger.php @@ -9,6 +9,8 @@ */ namespace Templado\Engine; +use function assert; +use function sprintf; use DOMDocument; use DOMElement; use DOMXPath; @@ -90,7 +92,7 @@ private function isConnected(DOMElement $context, DOMElement $contextChild): boo return false; } - private function mergeIn(DOMElement $contextChild, DOMElement $import): DOMElement { + private function mergeIn(DOMElement $contextChild, DOMElement $import): void { $workContext = [$import]; if ($import->namespaceURI === Document::XMLNS) { @@ -101,12 +103,10 @@ private function mergeIn(DOMElement $contextChild, DOMElement $import): DOMEleme $contextChild->after(...$workContext); $contextChild->remove(); - return $import; + return; } $contextChild->append(...$workContext); - - return $import; } private function shouldReplaceCurrent(DOMElement $import, DOMElement $contextChild): bool { diff --git a/src/selectors/XPathSelector.php b/src/selectors/XPathSelector.php index 2311819..9a44c4e 100644 --- a/src/selectors/XPathSelector.php +++ b/src/selectors/XPathSelector.php @@ -20,14 +20,12 @@ use DOMXPath; class XPathSelector implements Selector { - /** @var string */ - private $queryString; + /** @psalm-var array */ + private array $prefixMap = []; - /** @var array */ - private $prefixMap = []; - - public function __construct(string $query) { - $this->queryString = $query; + public function __construct( + private string $queryString + ) { } public function registerPrefix(string $prefix, string $uri): void { diff --git a/src/serializer/EmptyElementsFilter.php b/src/serializer/EmptyElementsFilter.php index 845d163..2923469 100644 --- a/src/serializer/EmptyElementsFilter.php +++ b/src/serializer/EmptyElementsFilter.php @@ -14,7 +14,7 @@ class EmptyElementsFilter implements Filter { public function apply(string $content): string { - $tagList = [ + static $tagList = [ 'base', 'br', 'meta', 'link', 'img', 'input', 'button', 'hr', 'embed', 'param', 'source', 'track', 'area', 'keygen', ]; diff --git a/src/serializer/HTMLSerializer.php b/src/serializer/HTMLSerializer.php index 415f5f2..211471e 100644 --- a/src/serializer/HTMLSerializer.php +++ b/src/serializer/HTMLSerializer.php @@ -12,10 +12,13 @@ use DOMDocument; class HTMLSerializer implements Serializer { - private bool $stripRDFaFlag = false; - private bool $keepXMLHeaderFlag = false; + private bool $stripRDFaFlag = false; + + private bool $keepXMLHeaderFlag = false; + private bool $namespaceCleaningFlag = true; - private bool $withDoctypeFlag = true; + + private bool $withDoctypeFlag = true; private array $filters = []; diff --git a/src/serializer/XMLHeaderFilter.php b/src/serializer/XMLHeaderFilter.php index 9d6fc02..1e65582 100644 --- a/src/serializer/XMLHeaderFilter.php +++ b/src/serializer/XMLHeaderFilter.php @@ -9,6 +9,8 @@ */ namespace Templado\Engine; +use function preg_replace; + class XMLHeaderFilter implements Filter { public function apply(string $content): string { return preg_replace('#^(<\?xml.*\?>\s{0,})#', '', $content); diff --git a/src/transformation/NamespaceCleaningTransformation.php b/src/transformation/NamespaceCleaningTransformation.php index 41d7c23..25ae860 100644 --- a/src/transformation/NamespaceCleaningTransformation.php +++ b/src/transformation/NamespaceCleaningTransformation.php @@ -9,6 +9,7 @@ */ namespace Templado\Engine; +use function assert; use DOMAttr; use DOMDocument; use DOMElement; @@ -31,6 +32,7 @@ public function apply(DOMNode $context): void { $this->enforceProperNamespace($context); } } + private function enforceProperNamespace(DOMElement $context): void { assert($context->ownerDocument instanceof DOMDocument); diff --git a/src/transformation/TransformationProcessor.php b/src/transformation/TransformationProcessor.php index e8751d6..4645910 100644 --- a/src/transformation/TransformationProcessor.php +++ b/src/transformation/TransformationProcessor.php @@ -9,6 +9,7 @@ */ namespace Templado\Engine; +use function assert; use DOMElement; use DOMNode; diff --git a/src/viewmodel/ViewModelRenderer.php b/src/viewmodel/ViewModelRenderer.php index 33e65db..5fbb1c7 100644 --- a/src/viewmodel/ViewModelRenderer.php +++ b/src/viewmodel/ViewModelRenderer.php @@ -11,13 +11,17 @@ use function array_key_exists; use function array_reverse; +use function assert; +use function explode; use function gettype; +use function implode; use function is_iterable; use function is_object; use function is_string; use function lcfirst; use function method_exists; use function property_exists; +use function sprintf; use function str_contains; use DOMDocument; use DOMElement; @@ -27,12 +31,16 @@ final class ViewModelRenderer { /** @psalm-suppress PropertyNotSetInConstructor */ private object $rootModel; + /** @psalm-suppress PropertyNotSetInConstructor */ private DOMNode $pointer; + /** @psalm-suppress PropertyNotSetInConstructor */ private bool $supported; + /** @psalm-suppress PropertyNotSetInConstructor */ private DOMXPath $xp; + private array $prefixModels = []; public function render(DOMNode $context, object $model): void { @@ -581,7 +589,7 @@ private function objectApply(DOMElement $context, object $model): void { $context, $model, $name, - \sprintf('Unsupported type "%s" for attribute', gettype($result)), + sprintf('Unsupported type "%s" for attribute', gettype($result)), ), ViewModelRendererException::WrongTypeForAttribute ); @@ -643,7 +651,7 @@ private function getModelPath(DOMElement $context): string { } private function buildExceptionMessage(?DOMElement $context, object $model, string $method, string $message): string { - return \sprintf( + return sprintf( '%s: %s (%s)', $model::class . '::' . $method, $message, diff --git a/tests/csrfprotection/CSRFProtectionRendererTest.php b/tests/csrfprotection/CSRFProtectionRendererTest.php index aa80e1c..98a0099 100644 --- a/tests/csrfprotection/CSRFProtectionRendererTest.php +++ b/tests/csrfprotection/CSRFProtectionRendererTest.php @@ -3,11 +3,12 @@ use DOMDocument; use DOMElement; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\UsesClass; use PHPUnit\Framework\TestCase; -/** - * @covers \Templado\Engine\CSRFProtectionRenderer - */ +#[CoversClass(CSRFProtectionRenderer::class)] +#[UsesClass(CSRFProtection::class)] class CSRFProtectionRendererTest extends TestCase { use DomDocumentsEqualTrait; @@ -21,11 +22,7 @@ class CSRFProtectionRendererTest extends TestCase { private $expected; protected function setUp(): void { - $protection = $this->createMock(CSRFProtection::class); - $protection->method('fieldName')->willReturn('csrf'); - $protection->method('tokenValue')->willReturn('secure'); - - $this->protection = $protection; + $this->protection = new CSRFProtection('csrf', 'secure'); $this->renderer = new CSRFProtectionRenderer(); $this->expected = new DOMDocument(); @@ -39,7 +36,7 @@ public function testUsingContextElementWithoutOwnerDocumentThrowsException(): vo $this->expectException(CSRFProtectionRendererException::class); (new CSRFProtectionRenderer())->render( new DOMElement('dummmy'), - $this->createMock(CSRFProtection::class) + $this->protection ); } diff --git a/tests/document/DocumentTest.php b/tests/document/DocumentTest.php index 71be799..92e17b9 100644 --- a/tests/document/DocumentTest.php +++ b/tests/document/DocumentTest.php @@ -34,6 +34,7 @@ #[UsesClass(Signal::class)] #[UsesClass(StaticNodeList::class)] #[UsesClass(TransformationProcessor::class)] +#[UsesClass(CSRFProtection::class)] #[Small] class DocumentTest extends TestCase { use DomDocumentsEqualTrait; @@ -222,9 +223,7 @@ public function testCSRFProtectionCanBeApplied(): void { $dom = new DOMDocument(); $dom->loadXML('
'); - $protection = $this->createMock(CSRFProtection::class); - $protection->method('fieldName')->willReturn('csrf'); - $protection->method('tokenValue')->willReturn('secure'); + $protection = new CSRFProtection('csrf', 'secure'); $expected = new DOMDocument(); $expected->loadXML(