diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index d6c37897..a2f4e81c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -37,7 +37,6 @@ jobs: ${{ runner.os }}-${{ matrix.setup }}-v2-php-${{ matrix.php }}- - name: Code Climate Test Reporter Preparation - if: matrix.php == '7.4' && matrix.setup == 'stable' run: | curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter chmod +x ./cc-test-reporter @@ -56,7 +55,7 @@ jobs: run: vendor/bin/phpunit --coverage-text --coverage-clover=coverage.xml - name: Code Climate Test Reporter - if: ${{ matrix.php == '7.4' && matrix.setup == 'stable' && env.CC_TEST_REPORTER_ID != '' }} + if: ${{ env.CC_TEST_REPORTER_ID != '' }} run: | cp coverage.xml clover.xml bash <(curl -s https://codecov.io/bash) diff --git a/composer.json b/composer.json index 1eb6a234..32b20d77 100644 --- a/composer.json +++ b/composer.json @@ -7,9 +7,12 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" + }, + { + "name": "Torben Koehn", + "email": "torben@talesoft.codes" } ], "support": { diff --git a/src/Phug/Ast/Ast/Node.php b/src/Phug/Ast/Ast/Node.php index defe9ca6..8b646c30 100644 --- a/src/Phug/Ast/Ast/Node.php +++ b/src/Phug/Ast/Ast/Node.php @@ -4,6 +4,7 @@ use InvalidArgumentException; use Phug\AstException; +use ReturnTypeWillChange; /** * Represents a node in a tree-like data structure. @@ -418,6 +419,7 @@ public function findArray(callable $callback, $depth = null) /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function getIterator() { foreach ($this->children as $child) { @@ -428,6 +430,7 @@ public function getIterator() /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function count() { return $this->getChildCount(); @@ -436,6 +439,7 @@ public function count() /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function offsetExists($offset) { return $this->hasChildAt($offset); @@ -444,6 +448,7 @@ public function offsetExists($offset) /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function offsetGet($offset) { return $this->getChildAt($offset); @@ -452,6 +457,7 @@ public function offsetGet($offset) /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function offsetSet($offset, $value) { if (!($value instanceof NodeInterface)) { @@ -475,6 +481,7 @@ public function offsetSet($offset, $value) /** * {@inheritdoc} */ + #[ReturnTypeWillChange] public function offsetUnset($offset) { $this->removeChildAt($offset); diff --git a/src/Phug/Ast/composer.json b/src/Phug/Ast/composer.json index 6a469a5e..2dfd8424 100644 --- a/src/Phug/Ast/composer.json +++ b/src/Phug/Ast/composer.json @@ -11,8 +11,7 @@ "email": "torben@talesoft.codes" }, { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" } ], diff --git a/src/Phug/Compiler/Compiler/NodeCompiler/ImportNodeCompiler.php b/src/Phug/Compiler/Compiler/NodeCompiler/ImportNodeCompiler.php index 9bde2648..45263ff6 100644 --- a/src/Phug/Compiler/Compiler/NodeCompiler/ImportNodeCompiler.php +++ b/src/Phug/Compiler/Compiler/NodeCompiler/ImportNodeCompiler.php @@ -23,7 +23,7 @@ class ImportNodeCompiler extends AbstractNodeCompiler protected function isPugImport($path) { $compiler = $this->getCompiler(); - $extension = pathinfo($path, PATHINFO_EXTENSION) ?: ''; + $extension = pathinfo((string) $path, PATHINFO_EXTENSION); $extensions = $compiler->getOption('extensions'); if ($extension === '') { @@ -72,7 +72,7 @@ public function compileNode(NodeInterface $node, ElementInterface $parent = null $paths = $isAbsolutePath ? null - : [dirname($compiler->getPath()) ?: '.']; + : [dirname((string) $compiler->getPath()) ?: '.']; $path = $compiler->resolve($node->getPath(), $paths); $compiler->registerImportPath($path); diff --git a/src/Phug/Compiler/composer.json b/src/Phug/Compiler/composer.json index 36795913..b1eeeb5f 100644 --- a/src/Phug/Compiler/composer.json +++ b/src/Phug/Compiler/composer.json @@ -7,9 +7,12 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" + }, + { + "name": "Torben Koehn", + "email": "torben@talesoft.codes" } ], "support": { diff --git a/src/Phug/DependencyInjection/composer.json b/src/Phug/DependencyInjection/composer.json index 96a59f65..23e3abe7 100644 --- a/src/Phug/DependencyInjection/composer.json +++ b/src/Phug/DependencyInjection/composer.json @@ -11,8 +11,7 @@ "email": "torben@talesoft.codes" }, { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" } ], diff --git a/src/Phug/Event/Event/ListenerQueue.php b/src/Phug/Event/Event/ListenerQueue.php index 09201cee..fe175ff2 100644 --- a/src/Phug/Event/Event/ListenerQueue.php +++ b/src/Phug/Event/Event/ListenerQueue.php @@ -2,10 +2,12 @@ namespace Phug\Event; +use ReturnTypeWillChange; use SplPriorityQueue; class ListenerQueue extends SplPriorityQueue { + #[ReturnTypeWillChange] public function compare($priority, $priorityToCompare) { if ($priority === $priorityToCompare) { @@ -15,6 +17,7 @@ public function compare($priority, $priorityToCompare) return $priority > $priorityToCompare ? -1 : 1; } + #[ReturnTypeWillChange] public function insert($value, $priority) { if (!is_callable($value)) { diff --git a/src/Phug/Event/composer.json b/src/Phug/Event/composer.json index b68d62bb..aaf49e9d 100644 --- a/src/Phug/Event/composer.json +++ b/src/Phug/Event/composer.json @@ -11,8 +11,7 @@ "email": "torben@talesoft.codes" }, { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" } ], diff --git a/src/Phug/Formatter/Formatter/AbstractFormat.php b/src/Phug/Formatter/Formatter/AbstractFormat.php index 835af671..963297f4 100644 --- a/src/Phug/Formatter/Formatter/AbstractFormat.php +++ b/src/Phug/Formatter/Formatter/AbstractFormat.php @@ -51,7 +51,7 @@ abstract class AbstractFormat implements FormatInterface, OptionInterface is_object($_pug_temp = %s) && method_exists($_pug_temp, "__toBoolean") ? $_pug_temp->__toBoolean() : $_pug_temp'; - const HTML_EXPRESSION_ESCAPE = 'htmlspecialchars(%s)'; + const HTML_EXPRESSION_ESCAPE = 'htmlspecialchars((string) (%s))'; const HTML_TEXT_ESCAPE = 'htmlspecialchars'; const PAIR_TAG = '%s%s%s'; const TRANSFORM_EXPRESSION = '%s'; diff --git a/src/Phug/Formatter/Formatter/Element/AssignmentElement.php b/src/Phug/Formatter/Formatter/Element/AssignmentElement.php index 21ec40fd..f4ed42cf 100644 --- a/src/Phug/Formatter/Formatter/Element/AssignmentElement.php +++ b/src/Phug/Formatter/Formatter/Element/AssignmentElement.php @@ -6,10 +6,11 @@ use Phug\Formatter\AbstractElement; use Phug\Formatter\AssignmentContainerInterface; use Phug\Parser\NodeInterface as ParserNode; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class AssignmentElement extends AbstractElement +class AssignmentElement extends AbstractElement implements AttributesInterface { use AttributeTrait; use NameTrait; diff --git a/src/Phug/Formatter/Formatter/Element/MarkupElement.php b/src/Phug/Formatter/Formatter/Element/MarkupElement.php index ad979604..b8182bd6 100644 --- a/src/Phug/Formatter/Formatter/Element/MarkupElement.php +++ b/src/Phug/Formatter/Formatter/Element/MarkupElement.php @@ -4,10 +4,11 @@ use Phug\Ast\NodeInterface; use Phug\Parser\NodeInterface as ParserNode; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class MarkupElement extends AbstractMarkupElement +class MarkupElement extends AbstractMarkupElement implements AttributesInterface { use AttributeTrait; use NameTrait; diff --git a/src/Phug/Formatter/Formatter/Element/MixinCallElement.php b/src/Phug/Formatter/Formatter/Element/MixinCallElement.php index a886101b..0241e3f4 100644 --- a/src/Phug/Formatter/Formatter/Element/MixinCallElement.php +++ b/src/Phug/Formatter/Formatter/Element/MixinCallElement.php @@ -2,10 +2,11 @@ namespace Phug\Formatter\Element; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class MixinCallElement extends AbstractAssignmentContainerElement +class MixinCallElement extends AbstractAssignmentContainerElement implements AttributesInterface { use AttributeTrait; use NameTrait; diff --git a/src/Phug/Formatter/Formatter/Element/MixinElement.php b/src/Phug/Formatter/Formatter/Element/MixinElement.php index c88dcd43..9f0bbdd5 100644 --- a/src/Phug/Formatter/Formatter/Element/MixinElement.php +++ b/src/Phug/Formatter/Formatter/Element/MixinElement.php @@ -3,10 +3,11 @@ namespace Phug\Formatter\Element; use Phug\Formatter\AbstractElement; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class MixinElement extends AbstractElement +class MixinElement extends AbstractElement implements AttributesInterface { use AttributeTrait; use NameTrait; diff --git a/src/Phug/Formatter/Formatter/Format/XmlFormat.php b/src/Phug/Formatter/Formatter/Format/XmlFormat.php index 2d90de69..a801f939 100644 --- a/src/Phug/Formatter/Formatter/Format/XmlFormat.php +++ b/src/Phug/Formatter/Formatter/Format/XmlFormat.php @@ -2,8 +2,10 @@ namespace Phug\Formatter\Format; +use Generator; use Phug\Formatter; use Phug\Formatter\AbstractFormat; +use Phug\Formatter\AssignmentContainerInterface; use Phug\Formatter\Element\AbstractValueElement; use Phug\Formatter\Element\AssignmentElement; use Phug\Formatter\Element\AttributeElement; @@ -16,6 +18,7 @@ use Phug\Formatter\MarkupInterface; use Phug\Formatter\Partial\AssignmentHelpersTrait; use Phug\FormatterException; +use Phug\Util\AttributesInterface; use Phug\Util\Joiner; use SplObjectStorage; @@ -163,7 +166,7 @@ protected function formatAttributeElement(AttributeElement $element) $nonEmptyAttribute = ($name === 'class' || $name === 'id'); if ($nonEmptyAttribute && ( !$value || - ($value instanceof TextElement && ($value->getValue() ?: '') === '') || + ($value instanceof TextElement && ((string) $value->getValue()) === '') || (is_string($value) && in_array(trim($value), ['', '""', "''"])) )) { return ''; @@ -266,25 +269,78 @@ protected function yieldAssignmentElement(AssignmentElement $element) /* @var MarkupElement $markup */ $markup = $element->getContainer(); + $arguments = $markup instanceof AssignmentContainerInterface + ? $this->formatAttributeAssignments($markup) + : []; + + $arguments = array_merge( + $markup instanceof AttributesInterface + ? $this->formatMarkupAttributes($markup) + : [], + $arguments + ); + + foreach ($markup->getAssignments() as $assignment) { + /* @var AssignmentElement $assignment */ + $this->throwException( + 'Unable to handle '.$assignment->getName().' assignment', + $assignment + ); + } + + if (count($arguments)) { + yield $this->attributesAssignmentsFromPairs($arguments); + } + } + + /** + * @param AssignmentContainerInterface $markup + * + * @return array + */ + protected function formatAttributeAssignments(AssignmentContainerInterface $markup) + { $arguments = []; + foreach ($this->yieldAssignmentAttributes($markup) as $attribute) { + $checked = method_exists($attribute, 'isChecked') && $attribute->isChecked(); + + while (method_exists($attribute, 'getValue')) { + $attribute = $attribute->getValue(); + } + + $arguments[] = $this->formatCode($attribute, $checked); + } + + return $arguments; + } + + /** + * @param AssignmentContainerInterface $markup + * + * @return Generator|AbstractValueElement[] + */ + protected function yieldAssignmentAttributes(AssignmentContainerInterface $markup) + { foreach ($markup->getAssignmentsByName('attributes') as $attributesAssignment) { /* @var AssignmentElement $attributesAssignment */ foreach ($attributesAssignment->getAttributes() as $attribute) { /* @var AbstractValueElement $attribute */ - $value = $attribute; - $checked = method_exists($value, 'isChecked') && $value->isChecked(); - - while (method_exists($value, 'getValue')) { - $value = $value->getValue(); - } - - $arguments[] = $this->formatCode($value, $checked); + yield $attribute; } $markup->removedAssignment($attributesAssignment); } + } + /** + * @param AttributesInterface $markup + * + * @return array + */ + protected function formatMarkupAttributes(AttributesInterface $markup) + { + $arguments = []; $attributes = $markup->getAttributes(); foreach ($attributes as $attribute) { @@ -294,17 +350,7 @@ protected function yieldAssignmentElement(AssignmentElement $element) $attributes->removeAll($attributes); - foreach ($markup->getAssignments() as $assignment) { - /* @var AssignmentElement $assignment */ - $this->throwException( - 'Unable to handle '.$assignment->getName().' assignment', - $assignment - ); - } - - if (count($arguments)) { - yield $this->attributesAssignmentsFromPairs($arguments); - } + return $arguments; } /** diff --git a/src/Phug/Formatter/Formatter/Partial/AssignmentHelpersTrait.php b/src/Phug/Formatter/Formatter/Partial/AssignmentHelpersTrait.php index 8147753f..93c87071 100644 --- a/src/Phug/Formatter/Formatter/Partial/AssignmentHelpersTrait.php +++ b/src/Phug/Formatter/Formatter/Partial/AssignmentHelpersTrait.php @@ -202,11 +202,14 @@ protected function provideStyleAttributeAssignment() if (is_string($value) && mb_substr($value, 0, 7) === '{"') { $value = json_decode(htmlspecialchars_decode($value)); } + $styles = isset($attributes['style']) ? array_filter(explode(';', $attributes['style'])) : []; + foreach ((array) $value as $propertyName => $propertyValue) { if (!is_int($propertyName)) { $propertyValue = $propertyName.':'.$propertyValue; } + $styles[] = $propertyValue; } diff --git a/src/Phug/Formatter/composer.json b/src/Phug/Formatter/composer.json index 49045eea..4a1a72ea 100644 --- a/src/Phug/Formatter/composer.json +++ b/src/Phug/Formatter/composer.json @@ -7,8 +7,7 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" }, { diff --git a/src/Phug/Invoker/composer.json b/src/Phug/Invoker/composer.json index 06ab73e2..36d019d2 100644 --- a/src/Phug/Invoker/composer.json +++ b/src/Phug/Invoker/composer.json @@ -7,9 +7,12 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" + }, + { + "name": "Torben Koehn", + "email": "torben@talesoft.codes" } ], "support": { diff --git a/src/Phug/Lexer/Lexer/Scanner/AttributeScanner.php b/src/Phug/Lexer/Lexer/Scanner/AttributeScanner.php index f46bbe4c..877d7607 100644 --- a/src/Phug/Lexer/Lexer/Scanner/AttributeScanner.php +++ b/src/Phug/Lexer/Lexer/Scanner/AttributeScanner.php @@ -30,7 +30,7 @@ private function isTruncatedValue($expression) $expression = preg_replace('/ "(?:\\\\[\\S\\s]|[^"\\\\])*"| \'(?:\\\\[\\S\\s]|[^\'\\\\])*\' - /x', '0', $expression); + /x', '0', (string) $expression); $expression = preg_replace('/\\s*( (\\[([^\\[\\]]+|(?1))*\\]) | (\\(([^\\(\\)]+|(?1))*\\)) | @@ -42,6 +42,8 @@ private function isTruncatedValue($expression) private function isTruncatedExpression(Reader $reader, &$expression) { + $expression = (string) $expression; + if (mb_substr($expression, -3) === 'new' || mb_substr($expression, -5) === 'clone') { $expression .= $reader->getLastPeekResult(); $reader->consume(); diff --git a/src/Phug/Lexer/Lexer/Scanner/FilterScanner.php b/src/Phug/Lexer/Lexer/Scanner/FilterScanner.php index 28b36231..57c82dd2 100644 --- a/src/Phug/Lexer/Lexer/Scanner/FilterScanner.php +++ b/src/Phug/Lexer/Lexer/Scanner/FilterScanner.php @@ -55,7 +55,7 @@ public function scan(State $state) $token = $state->createToken(TextToken::class); if ($maxIndent > 0 && $maxIndent < INF) { foreach ($lines as &$line) { - $line = mb_substr($line, $maxIndent) ?: ''; + $line = mb_substr((string) $line, $maxIndent); } } $token->setValue(implode("\n", $lines)); diff --git a/src/Phug/Lexer/Lexer/Scanner/MultilineScanner.php b/src/Phug/Lexer/Lexer/Scanner/MultilineScanner.php index 9baba845..77a988a9 100644 --- a/src/Phug/Lexer/Lexer/Scanner/MultilineScanner.php +++ b/src/Phug/Lexer/Lexer/Scanner/MultilineScanner.php @@ -92,7 +92,7 @@ private function yieldLines(State $state, array $lines, LineAnalyzer $analyzer) if ($maxIndent > 0 && $maxIndent < INF) { foreach ($lines as &$line) { if (count($line) && is_string($line[0])) { - $line[0] = mb_substr($line[0], $maxIndent) ?: ''; + $line[0] = mb_substr((string) $line[0], $maxIndent); } } } diff --git a/src/Phug/Lexer/Lexer/Scanner/TextScanner.php b/src/Phug/Lexer/Lexer/Scanner/TextScanner.php index 00efef84..5938085c 100644 --- a/src/Phug/Lexer/Lexer/Scanner/TextScanner.php +++ b/src/Phug/Lexer/Lexer/Scanner/TextScanner.php @@ -19,7 +19,7 @@ class TextScanner implements ScannerInterface private function isTextStartToTrim(State $state, $text) { - return in_array(mb_substr($text, 0, 1), [' ', "\t"]) && !$state->isAfterInterpolation(); + return in_array(mb_substr((string) $text, 0, 1), [' ', "\t"]) && !$state->isAfterInterpolation(); } private function leftTrimValueIfNotAfterInterpolation(State $state, TextToken $token) @@ -27,7 +27,7 @@ private function leftTrimValueIfNotAfterInterpolation(State $state, TextToken $t $text = $token->getValue(); if ($this->isTextStartToTrim($state, $text)) { - $token->setValue(mb_substr($text, 1) ?: ''); + $token->setValue(mb_substr((string) $text, 1)); } } @@ -87,7 +87,7 @@ public function scan(State $state) $text = mb_substr($text, 1); } - $text = preg_replace('/\\\\([#!]\\[|#\\{)/', '$1', $text); + $text = preg_replace('/\\\\([#!]\\[|#{)/', '$1', $text); $token->setValue($text); yield $state->endToken($token); diff --git a/src/Phug/Lexer/composer.json b/src/Phug/Lexer/composer.json index 8d68e412..e083b080 100644 --- a/src/Phug/Lexer/composer.json +++ b/src/Phug/Lexer/composer.json @@ -11,8 +11,7 @@ "email": "torben@talesoft.codes" }, { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" } ], diff --git a/src/Phug/Parser/Parser/Node/AssignmentNode.php b/src/Phug/Parser/Parser/Node/AssignmentNode.php index bb307266..10a383fd 100644 --- a/src/Phug/Parser/Parser/Node/AssignmentNode.php +++ b/src/Phug/Parser/Parser/Node/AssignmentNode.php @@ -3,10 +3,11 @@ namespace Phug\Parser\Node; use Phug\Parser\Node; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class AssignmentNode extends Node +class AssignmentNode extends Node implements AttributesInterface { use NameTrait; use AttributeTrait; diff --git a/src/Phug/Parser/Parser/Node/ElementNode.php b/src/Phug/Parser/Parser/Node/ElementNode.php index 44faafbb..edf1c8ff 100644 --- a/src/Phug/Parser/Parser/Node/ElementNode.php +++ b/src/Phug/Parser/Parser/Node/ElementNode.php @@ -3,11 +3,12 @@ namespace Phug\Parser\Node; use Phug\Parser\Node; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AssignmentTrait; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class ElementNode extends Node +class ElementNode extends Node implements AttributesInterface { use NameTrait; use AttributeTrait; diff --git a/src/Phug/Parser/Parser/Node/FilterNode.php b/src/Phug/Parser/Parser/Node/FilterNode.php index db407dc7..a95a3d50 100644 --- a/src/Phug/Parser/Parser/Node/FilterNode.php +++ b/src/Phug/Parser/Parser/Node/FilterNode.php @@ -3,10 +3,11 @@ namespace Phug\Parser\Node; use Phug\Parser\Node; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class FilterNode extends Node +class FilterNode extends Node implements AttributesInterface { use NameTrait; use AttributeTrait; diff --git a/src/Phug/Parser/Parser/Node/MixinCallNode.php b/src/Phug/Parser/Parser/Node/MixinCallNode.php index 3d43347d..9e8da4f8 100644 --- a/src/Phug/Parser/Parser/Node/MixinCallNode.php +++ b/src/Phug/Parser/Parser/Node/MixinCallNode.php @@ -3,11 +3,12 @@ namespace Phug\Parser\Node; use Phug\Parser\Node; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AssignmentTrait; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class MixinCallNode extends Node +class MixinCallNode extends Node implements AttributesInterface { use NameTrait; use AttributeTrait; diff --git a/src/Phug/Parser/Parser/Node/MixinNode.php b/src/Phug/Parser/Parser/Node/MixinNode.php index 02636736..c4f91027 100644 --- a/src/Phug/Parser/Parser/Node/MixinNode.php +++ b/src/Phug/Parser/Parser/Node/MixinNode.php @@ -3,11 +3,12 @@ namespace Phug\Parser\Node; use Phug\Parser\Node; +use Phug\Util\AttributesInterface; use Phug\Util\Partial\AssignmentTrait; use Phug\Util\Partial\AttributeTrait; use Phug\Util\Partial\NameTrait; -class MixinNode extends Node +class MixinNode extends Node implements AttributesInterface { use NameTrait; use AttributeTrait; diff --git a/src/Phug/Parser/composer.json b/src/Phug/Parser/composer.json index b48a4756..3c296275 100644 --- a/src/Phug/Parser/composer.json +++ b/src/Phug/Parser/composer.json @@ -11,8 +11,7 @@ "email": "torben@talesoft.codes" }, { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" } ], diff --git a/src/Phug/Phug/composer.json b/src/Phug/Phug/composer.json index b966abff..cad0f5f0 100644 --- a/src/Phug/Phug/composer.json +++ b/src/Phug/Phug/composer.json @@ -7,9 +7,12 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" + }, + { + "name": "Torben Koehn", + "email": "torben@talesoft.codes" } ], "support": { diff --git a/src/Phug/Reader/Reader.php b/src/Phug/Reader/Reader.php index 6a7f537a..5cc93461 100644 --- a/src/Phug/Reader/Reader.php +++ b/src/Phug/Reader/Reader.php @@ -323,7 +323,7 @@ public function peek($length = null, $start = null) */ public function match($pattern, $modifiers = null, $ignoredSuffixes = null) { - $modifiers = $modifiers ?: ''; + $modifiers = (string) $modifiers; $ignoredSuffixes = $ignoredSuffixes ?: "\n"; $matches = null; $this->lastMatchResult = null; @@ -572,7 +572,7 @@ public function peekQuote() */ public function peekSpace() { - return ctype_space($this->peek()); + return ctype_space((string) $this->peek()); } /** @@ -584,7 +584,7 @@ public function peekSpace() */ public function peekDigit() { - return ctype_digit($this->peek()); + return ctype_digit((string) $this->peek()); } /** @@ -596,7 +596,7 @@ public function peekDigit() */ public function peekAlpha() { - return ctype_alpha($this->peek()); + return ctype_alpha((string) $this->peek()); } /** @@ -608,7 +608,7 @@ public function peekAlpha() */ public function peekAlphaNumeric() { - return ctype_alnum($this->peek()); + return ctype_alnum((string) $this->peek()); } /** @@ -658,7 +658,7 @@ public function readIndentation() */ public function readUntilNewLine() { - return $this->readUntil([$this, 'peekNewLine']); + return (string) $this->readUntil([$this, 'peekNewLine']); } /** diff --git a/src/Phug/Reader/composer.json b/src/Phug/Reader/composer.json index dcabc09f..d9dbc391 100644 --- a/src/Phug/Reader/composer.json +++ b/src/Phug/Reader/composer.json @@ -9,6 +9,10 @@ { "name": "Torben Koehn", "email": "torben@talesoft.codes" + }, + { + "name": "kylekatarnls", + "homepage": "http://github.com/kylekatarnls" } ], "support": { diff --git a/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php b/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php index 5b4cbcd7..bde9953c 100644 --- a/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php +++ b/src/Phug/Renderer/Renderer/Adapter/FileAdapter.php @@ -364,8 +364,8 @@ private function checkPathExpiration(&$path) * Return true if the file or content is up to date in the cache folder, * false else. * - * @param &string $path to be filled - * @param string $input file or pug code + * @param string &$path to be filled + * @param string $input file or pug code * * @return bool */ diff --git a/src/Phug/Renderer/Renderer/Partial/Debug/DebuggerTrait.php b/src/Phug/Renderer/Renderer/Partial/Debug/DebuggerTrait.php index 2a1c7380..fe5c1aec 100644 --- a/src/Phug/Renderer/Renderer/Partial/Debug/DebuggerTrait.php +++ b/src/Phug/Renderer/Renderer/Partial/Debug/DebuggerTrait.php @@ -105,7 +105,7 @@ private function getErrorMessage($error, SourceLocation $location, $data) $contextLines = $data->options['error_context_lines']; $code = ''; $sourceOffset = max(0, $line - 1); - $untilOffset = isset($source[$sourceOffset]) ? (mb_substr($source[$sourceOffset], 0, $offset ?: 0) ?: '') : ''; + $untilOffset = isset($source[$sourceOffset]) ? mb_substr((string) $source[$sourceOffset], 0, $offset ?: 0) : ''; $htmlError = $data->options['html_error']; $start = null; foreach ($source as $index => $lineText) { diff --git a/src/Phug/Renderer/composer.json b/src/Phug/Renderer/composer.json index 6e4ab646..d88ecc89 100644 --- a/src/Phug/Renderer/composer.json +++ b/src/Phug/Renderer/composer.json @@ -7,9 +7,12 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", + "name": "kylekatarnls", "homepage": "http://github.com/kylekatarnls" + }, + { + "name": "Torben Koehn", + "email": "torben@talesoft.codes" } ], "support": { diff --git a/src/Phug/Util/Util/AttributesInterface.php b/src/Phug/Util/Util/AttributesInterface.php new file mode 100644 index 00000000..903c8e68 --- /dev/null +++ b/src/Phug/Util/Util/AttributesInterface.php @@ -0,0 +1,16 @@ +Iterator or Traversable */ + #[ReturnTypeWillChange] public function getIterator() { return $this->traversable instanceof Traversable ? $this->traversable : $this->getGenerator(); diff --git a/src/Phug/Util/Util/TestCase.php b/src/Phug/Util/Util/TestCase.php index 8f4b95d6..5cbf7faf 100644 --- a/src/Phug/Util/Util/TestCase.php +++ b/src/Phug/Util/Util/TestCase.php @@ -54,8 +54,8 @@ public function cleanupTempDirectory() protected function removeFile($file) { if (is_dir($file)) { - $this->emptyDirectory($file); - rmdir($file); + @$this->emptyDirectory($file); + @rmdir($file); return; } diff --git a/src/Phug/Util/composer.json b/src/Phug/Util/composer.json index 1ed8367f..2b3a6933 100644 --- a/src/Phug/Util/composer.json +++ b/src/Phug/Util/composer.json @@ -7,13 +7,12 @@ "homepage": "http://phug-lang.com", "authors": [ { - "name": "Torben Koehn", - "email": "torben@talesoft.codes" + "name": "kylekatarnls", + "homepage": "http://github.com/kylekatarnls" }, { - "name": "KyleKatarn", - "email": "jade-php@selfbuild.fr", - "homepage": "http://github.com/kylekatarnls" + "name": "Torben Koehn", + "email": "torben@talesoft.codes" } ], "support": { diff --git a/tests/Phug/Compiler/NodeCompiler/AssignmentNodeCompilerTest.php b/tests/Phug/Compiler/NodeCompiler/AssignmentNodeCompilerTest.php index 04b98895..adc08544 100644 --- a/tests/Phug/Compiler/NodeCompiler/AssignmentNodeCompilerTest.php +++ b/tests/Phug/Compiler/NodeCompiler/AssignmentNodeCompilerTest.php @@ -26,6 +26,18 @@ public function testCompile() '', 'a.foo(class=["bar", "biz"])&attributes(["class" => "bar fiz"])' ); + $this->assertRender( + '', + 'a.foo(class=["bar", "biz"])&attributes(["class" => "bar fiz"])' + ); + $this->assertRender( + '', + 'a(href="#")&attributes(["href" => "/"])' + ); + $this->assertRender( + '', + 'a&attributes(["href" => "/"])(href="#")' + ); } /** diff --git a/tests/Phug/Compiler/NodeCompiler/ExpressionNodeCompilerTest.php b/tests/Phug/Compiler/NodeCompiler/ExpressionNodeCompilerTest.php index e6b07bfd..53179fb2 100644 --- a/tests/Phug/Compiler/NodeCompiler/ExpressionNodeCompilerTest.php +++ b/tests/Phug/Compiler/NodeCompiler/ExpressionNodeCompilerTest.php @@ -22,7 +22,7 @@ public function testCompile() 'p?!=$foo' ); $this->assertCompile( - '

', + '

', 'p=$foo' ); } diff --git a/tests/Phug/Compiler/NodeCompiler/VariableNodeCompilerTest.php b/tests/Phug/Compiler/NodeCompiler/VariableNodeCompilerTest.php index 6725ff4f..b1659663 100644 --- a/tests/Phug/Compiler/NodeCompiler/VariableNodeCompilerTest.php +++ b/tests/Phug/Compiler/NodeCompiler/VariableNodeCompilerTest.php @@ -19,7 +19,7 @@ public function testCompile() { $this->assertCompile('', '$answer != 42'); $this->assertCompile( - '', + '', '$answer ?= $foo' ); } diff --git a/tests/Phug/Compiler/NodeCompiler/WhileNodeCompilerTest.php b/tests/Phug/Compiler/NodeCompiler/WhileNodeCompilerTest.php index 17636428..d841989b 100644 --- a/tests/Phug/Compiler/NodeCompiler/WhileNodeCompilerTest.php +++ b/tests/Phug/Compiler/NodeCompiler/WhileNodeCompilerTest.php @@ -48,7 +48,7 @@ public function testCompile() '', ], diff --git a/tests/Phug/Element/AssignmentElementTest.php b/tests/Phug/Element/AssignmentElementTest.php index 025b9615..e618b078 100644 --- a/tests/Phug/Element/AssignmentElementTest.php +++ b/tests/Phug/Element/AssignmentElementTest.php @@ -41,6 +41,9 @@ class AssignmentElementTest extends TestCase * @covers \Phug\Formatter\Format\XmlFormat::formatAttributeAsArrayItem * @covers \Phug\Formatter\Format\XmlFormat::formatAssignmentElement * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentElement + * @covers \Phug\Formatter\Format\XmlFormat::formatAttributeAssignments + * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentAttributes + * @covers \Phug\Formatter\Format\XmlFormat::formatMarkupAttributes * @covers \Phug\Formatter\Format\XmlFormat::formatAttributes */ public function testAttributeElement() @@ -66,7 +69,7 @@ public function testAttributeElement() ob_end_clean(); self::assertSame( - 'Foo', + 'Foo', $actual ); @@ -81,7 +84,7 @@ public function testAttributeElement() $assignment = new AssignmentElement('attributes', $data, $img); $img->getAssignments()->attach($assignment); $img->getAttributes()->attach(new AttributeElement('class', 'foo bar')); - $img->getAttributes()->attach(new AttributeElement('style', 'height: 100px; z-index: 9;')); + $img->getAttributes()->attach(new AttributeElement('style', 'height: 100px; z-index: 9')); ob_start(); $php = $formatter->format($img); @@ -90,7 +93,7 @@ public function testAttributeElement() ob_end_clean(); self::assertSame( - '', + '', $actual ); @@ -114,7 +117,7 @@ public function testAttributeElement() ob_end_clean(); self::assertSame( - '', + '', $actual ); @@ -147,7 +150,7 @@ public function testAttributeElement() ob_end_clean(); self::assertSame( - '', + '', $actual ); } @@ -156,6 +159,9 @@ public function testAttributeElement() * @covers \Phug\Formatter\AbstractFormat::throwException * @covers \Phug\Formatter\Format\XmlFormat::formatAssignmentElement * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentElement + * @covers \Phug\Formatter\Format\XmlFormat::formatAttributeAssignments + * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentAttributes + * @covers \Phug\Formatter\Format\XmlFormat::formatMarkupAttributes * @expectedException \Phug\FormatterException * @expectedExceptionMessage Unable to handle class assignment */ @@ -175,6 +181,9 @@ public function testFormatAssignmentElementException() /** * @covers \Phug\Formatter\Format\XmlFormat::formatAssignmentElement * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentElement + * @covers \Phug\Formatter\Format\XmlFormat::formatAttributeAssignments + * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentAttributes + * @covers \Phug\Formatter\Format\XmlFormat::formatMarkupAttributes * @covers \Phug\Formatter\Element\ExpressionElement:: * @covers \Phug\Util\Partial\TransformableTrait::preventFromTransformation * @covers \Phug\Util\Partial\TransformableTrait::isTransformationAllowed @@ -226,7 +235,7 @@ function (AssignmentElement $element) { ob_end_clean(); self::assertSame( - '', + '', $actual ); } @@ -235,6 +244,9 @@ function (AssignmentElement $element) { * @covers \Phug\Formatter\Element\AssignmentElement::detach * @covers \Phug\Formatter\Format\XmlFormat::formatAssignmentElement * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentElement + * @covers \Phug\Formatter\Format\XmlFormat::formatAttributeAssignments + * @covers \Phug\Formatter\Format\XmlFormat::yieldAssignmentAttributes + * @covers \Phug\Formatter\Format\XmlFormat::formatMarkupAttributes * @covers \Phug\Formatter\Partial\HandleVariable::isInComplexInterpolation */ public function testAssignmentHandlersWithYield() diff --git a/tests/Phug/Element/VariableElementTest.php b/tests/Phug/Element/VariableElementTest.php index 70747a19..95fb3948 100644 --- a/tests/Phug/Element/VariableElementTest.php +++ b/tests/Phug/Element/VariableElementTest.php @@ -46,6 +46,9 @@ public function testVariableElement() $document = new DocumentElement(); $document->appendChild($variable); - self::assertSame('', $formatter->format($document)); + self::assertSame( + '', + $formatter->format($document) + ); } } diff --git a/tests/Phug/Format/HtmlFormatTest.php b/tests/Phug/Format/HtmlFormatTest.php index 08185e9e..f7e22815 100644 --- a/tests/Phug/Format/HtmlFormatTest.php +++ b/tests/Phug/Format/HtmlFormatTest.php @@ -53,7 +53,7 @@ public function testDependencies() { $formatter = new HtmlFormat(); - self::assertSame('htmlspecialchars("<")', $formatter->escapeHtml('"<"')); + self::assertSame('htmlspecialchars((string) ("<"))', $formatter->escapeHtml('"<"')); } /** diff --git a/tests/Phug/Format/XmlFormatTest.php b/tests/Phug/Format/XmlFormatTest.php index cebfc227..eb5091f0 100644 --- a/tests/Phug/Format/XmlFormatTest.php +++ b/tests/Phug/Format/XmlFormatTest.php @@ -632,6 +632,9 @@ public function testNativePhpHelperCall() * @covers ::formatAssignmentValue * @covers ::formatAssignmentElement * @covers ::yieldAssignmentElement + * @covers ::formatAttributeAssignments + * @covers ::yieldAssignmentAttributes + * @covers ::formatMarkupAttributes * @covers ::formatAttributes */ public function testAttributeAssignmentsOption() @@ -661,7 +664,7 @@ public function testAttributeAssignmentsOption() ob_end_clean(); self::assertSame( - '', + '', $actual ); } diff --git a/tests/Phug/FormatterTest.php b/tests/Phug/FormatterTest.php index 76de1815..0ca905f4 100644 --- a/tests/Phug/FormatterTest.php +++ b/tests/Phug/FormatterTest.php @@ -557,8 +557,8 @@ public function testExpressionElement() $formatter = new Formatter(); self::assertSame( - '") '. - '? var_export($_pug_temp, true) : $_pug_temp)) ?>', + '") '. + '? var_export($_pug_temp, true) : $_pug_temp))) ?>', $formatter->format($answer, HtmlFormat::class) ); @@ -566,8 +566,8 @@ public function testExpressionElement() $formatter = new Formatter(); self::assertSame( - '") '. - '? var_export($_pug_temp, true) : $_pug_temp)) ?>', + '") '. + '? var_export($_pug_temp, true) : $_pug_temp))) ?>', $formatter->format($answer, HtmlFormat::class) ); diff --git a/tests/Phug/RendererTest.php b/tests/Phug/RendererTest.php index 2f20bcd0..e9b83823 100644 --- a/tests/Phug/RendererTest.php +++ b/tests/Phug/RendererTest.php @@ -1314,37 +1314,6 @@ public function testCacheDirectoryPreserveDependencies() self::assertSame('

biz

', trim($contents)); } - /** - * @throws RendererException - */ - public function testBooleanCastAbleObject() - { - include_once __DIR__.'/Utils/BooleanAble.php'; - - $pug = new Renderer([ - 'modules' => [JsPhpizePhug::class], - ]); - $data = [ - 'trueObj' => new BooleanAble(true), - 'falseObj' => new BooleanAble(false), - 'whileObj' => new BooleanAble(2), - ]; - $code = implode("\n", [ - 'if trueObj', - ' p if true', - 'if falseObj', - ' p if false', - 'unless trueObj', - ' p unless true', - 'unless falseObj', - ' p unless false', - 'while whileObj', - ' p while', - ]); - - self::assertSame('

if true

unless false

while

while

', trim($pug->render($code, $data))); - } - /** * @throws RendererException */ @@ -1418,6 +1387,37 @@ public function testIssetCompatibility() } } + /** + * @throws RendererException + */ + public function testBooleanCastAbleObject() + { + include_once __DIR__.'/Utils/BooleanAble.php'; + + $pug = new Renderer([ + 'modules' => [JsPhpizePhug::class], + ]); + $data = [ + 'trueObj' => new BooleanAble(true), + 'falseObj' => new BooleanAble(false), + 'whileObj' => new BooleanAble(2), + ]; + $code = implode("\n", [ + 'if trueObj', + ' p if true', + 'if falseObj', + ' p if false', + 'unless trueObj', + ' p unless true', + 'unless falseObj', + ' p unless false', + 'while whileObj', + ' p while', + ]); + + self::assertSame('

if true

unless false

while

while

', trim($pug->render($code, $data))); + } + private function getJsPhpizeVersion() { $directory = __DIR__.'/../../vendor/composer';