Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:
SYMFONY_REQUIRE: ${{ matrix.symfony }}
uses: ramsey/composer-install@v2
- name: Run test suite on PHP ${{ matrix.php }} and Symfony ${{ matrix.symfony }}
run: vendor/bin/simple-phpunit
run: vendor/bin/phpunit
- name: Run ECS
run: vendor/bin/ecs
- name: Run PHPStan
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ phpstan:

## PHP Unit tests
phpunit:
vendor/bin/simple-phpunit
vendor/bin/phpunit


6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
"symfony/translation": "^6.4|^7.0",
"symfony/form": "^6.4|^7.0",
"symfony/stopwatch": "^6.4|^7.0",
"symfony/test-pack": "^1.1.0",
"symfony/orm-pack": "^2.4.1"
},
"require-dev": {
Expand All @@ -38,7 +37,10 @@
"doctrine/doctrine-bundle": "^2.5.5",
"whatwedo/php-coding-standard": "^1.0",
"symfony/twig-bundle": "^6.4|^7.0",
"phpstan/phpstan": "^1.7"
"phpstan/phpstan": "^1.7",
"phpunit/phpunit": "^10",
"symfony/test-pack": "^1.0",
"slevomat/coding-standard": "8.22.1"
},
"autoload": {
"psr-4": {
Expand Down
2 changes: 0 additions & 2 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,3 @@ parameters:
paths:
- src
- tests
bootstrapFiles:
- vendor/bin/.phpunit/phpunit-9.6-0/vendor/autoload.php
13 changes: 13 additions & 0 deletions src/Formatter/AbstractFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

abstract class AbstractFormatter implements FormatterInterface
{
public const OPT_HTML_SAFE = 'html_safe';

/**
* @var array<string, mixed>
*/
Expand All @@ -34,7 +36,18 @@ public function processOptions(array $options = []): void
$this->options = $resolver->resolve($options);
}

public function isHtmlSafe(): bool
{
return (bool) ($this->options[self::OPT_HTML_SAFE] ?? false);
}

protected function escapeHTML(string $value): string
{
return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}

protected function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefault(self::OPT_HTML_SAFE, false);
}
}
3 changes: 2 additions & 1 deletion src/Formatter/BadgeFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function getHtml(mixed $value): string
{
$this->processOptions(($this->options[self::OPT_CONFIGURATION])($value, $this->options));
return $this->twig->render($this->options[self::OPT_TEMPLATE], [
'value' => $this->getString($value),
'value' => $this->escapeHTML($this->getString($value)),
'type' => $this->options[self::OPT_TYPE],
'background_color_class' => $this->options[self::OPT_BACKGROUND_COLOR_CLASS],
'background_color_hex' => $this->options[self::OPT_BACKGROUND_COLOR_HEX],
Expand All @@ -43,6 +43,7 @@ protected function configureOptions(OptionsResolver $resolver): void
self::OPT_TYPE => 'neutral',
self::OPT_LINK => null,
self::OPT_CONFIGURATION => static fn (mixed $value, array $options): array => $options,
self::OPT_HTML_SAFE => true,
]);
$resolver->setAllowedTypes(self::OPT_BACKGROUND_COLOR_CLASS, ['string', 'null']);
$resolver->setAllowedTypes(self::OPT_BACKGROUND_COLOR_HEX, ['string', 'null']);
Expand Down
9 changes: 8 additions & 1 deletion src/Formatter/CollectionFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace araise\CoreBundle\Formatter;

use Doctrine\Common\Collections\Collection;
use Symfony\Component\OptionsResolver\OptionsResolver;

class CollectionFormatter extends AbstractFormatter
{
Expand All @@ -29,9 +30,15 @@ public function getHtml(mixed $value): string
}
$str = '<ul>';
foreach ($value as $singleValue) {
$str .= '<li>'.$singleValue.'</li>';
$str .= '<li>'.$this->escapeHTML($singleValue).'</li>';
}

return $str.'</ul>';
}

protected function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefault(self::OPT_HTML_SAFE, true);
}
}
6 changes: 3 additions & 3 deletions src/Formatter/EmailFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public function getHtml(mixed $value): string

return $value ? sprintf(
'<a href="mailto:%s" title="%s">%s</a>',
$value,
$title,
$value
$this->escapeHTML($value),
$this->escapeHTML($title),
$this->escapeHTML($value)
) : '';
}
}
2 changes: 2 additions & 0 deletions src/Formatter/FormatterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ public function getHtml(mixed $value): string;
* @param array<string, mixed> $options
*/
public function processOptions(array $options = []): void;

public function isHtmlSafe(): bool;
}
10 changes: 9 additions & 1 deletion src/Formatter/Nl2brFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace araise\CoreBundle\Formatter;

use Symfony\Component\OptionsResolver\OptionsResolver;

class Nl2brFormatter extends AbstractFormatter
{
public function getString(mixed $value): string
Expand All @@ -13,6 +15,12 @@ public function getString(mixed $value): string

public function getHtml(mixed $value): string
{
return nl2br($value);
return nl2br($this->escapeHTML($value));
}

protected function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefault(self::OPT_HTML_SAFE, true);
}
}
1 change: 1 addition & 0 deletions src/Formatter/TwigFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@ protected function configureOptions(OptionsResolver $resolver): void
{
$resolver->setRequired(self::OPT_TEMPLATE);
$resolver->setAllowedTypes(self::OPT_TEMPLATE, 'string');
$resolver->setDefault(self::OPT_HTML_SAFE, true);
}
}
8 changes: 8 additions & 0 deletions src/Formatter/WysiwygFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

namespace araise\CoreBundle\Formatter;

use Symfony\Component\OptionsResolver\OptionsResolver;

class WysiwygFormatter extends AbstractFormatter
{
public function getString(mixed $value): string
Expand All @@ -42,4 +44,10 @@ public function getHtml(mixed $value): string

return $value ? sprintf('<blockquote>%s</blockquote>', $value) : '';
}

protected function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefault(self::OPT_HTML_SAFE, true);
}
}
68 changes: 68 additions & 0 deletions src/Twig/CoreExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

/*
* Copyright (c) 2025, whatwedo GmbH
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

namespace araise\CoreBundle\Twig;

use araise\CoreBundle\Manager\FormatterManager;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class CoreExtension extends AbstractExtension
{
public function __construct(
private FormatterManager $formatterManager
) {
}

public function getFunctions(): array
{
return [
new TwigFunction(
'wwd_is_html_safe',
$this->isHtmlSafe(...)
),
];
}

public function isHtmlSafe(mixed $object): bool
{
if (!method_exists($object, 'getOption')) {
return false;
}
$formatter = $object->getOption('formatter');
$formatterOptions = $object->getOption('formatter_options');

if (is_string($formatter)) {
$formatterObj = $this->formatterManager->getFormatter($formatter);
$formatterObj->processOptions($formatterOptions);
return $formatterObj->isHtmlSafe();
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use araise\CoreBundle\Manager\FormatterManager;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

abstract class AbstractFormatterTest extends KernelTestCase
abstract class AbstractFormatterTestBase extends KernelTestCase
{
protected function getFormatter(string $formatterClass): FormatterInterface
{
Expand Down
2 changes: 1 addition & 1 deletion tests/BadgeFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use araise\CoreBundle\Formatter\BadgeFormatter;

class BadgeFormatterTest extends AbstractFormatterTest
class BadgeFormatterTest extends AbstractFormatterTestBase
{
public function testGetHtml(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/BooleanFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\BooleanFormatter;

class BooleanFormatterTest extends AbstractFormatterTest
class BooleanFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/CollectionFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\CollectionFormatter;

class CollectionFormatterTest extends AbstractFormatterTest
class CollectionFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/CountryAlpha2FormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\CountryAlpha2Formatter;

class CountryAlpha2FormatterTest extends AbstractFormatterTest
class CountryAlpha2FormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/CountryAlpha3FormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\CountryAlpha3Formatter;

class CountryAlpha3FormatterTest extends AbstractFormatterTest
class CountryAlpha3FormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/DateFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\DateFormatter;

class DateFormatterTest extends AbstractFormatterTest
class DateFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/DateTimeFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\DateTimeFormatter;

class DateTimeFormatterTest extends AbstractFormatterTest
class DateTimeFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/DefaultFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\DefaultFormatter;

class DefaultFormatterTest extends AbstractFormatterTest
class DefaultFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/EmailFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\EmailFormatter;

class EmailFormatterTest extends AbstractFormatterTest
class EmailFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/EnumFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
use araise\CoreBundle\Formatter\EnumFormatter;
use araise\CoreBundle\Tests\App\Enum\TestEnum;

class EnumFormatterTest extends AbstractFormatterTest
class EnumFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/InfoFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\InfoFormatter;

class InfoFormatterTest extends AbstractFormatterTest
class InfoFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/MoneyFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\MoneyFormatter;

class MoneyFormatterTest extends AbstractFormatterTest
class MoneyFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/Nl2brFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\Nl2brFormatter;

class Nl2brFormatterTest extends AbstractFormatterTest
class Nl2brFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/PercentageFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\PercentageFormatter;

class PercentageFormatterTest extends AbstractFormatterTest
class PercentageFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
2 changes: 1 addition & 1 deletion tests/TranslationFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use araise\CoreBundle\Formatter\TranslationFormatter;

class TranslationFormatterTest extends AbstractFormatterTest
class TranslationFormatterTest extends AbstractFormatterTestBase
{
public function testFormatter(): void
{
Expand Down
Loading