diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 3e5ea6e9..8c06c165 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -890,11 +890,6 @@ parameters: count: 1 path: src/lib/RichText/Converter/Render/Template.php - - - message: "#^Access to an undefined property Ibexa\\\\FieldTypeRichText\\\\RichText\\\\Converter\\\\Xslt\\:\\:\\$xsltProcessor\\.$#" - count: 1 - path: src/lib/RichText/Converter/Xslt.php - - message: "#^Cannot access property \\$firstChild on DOMElement\\|null\\.$#" count: 1 @@ -905,31 +900,11 @@ parameters: count: 1 path: src/lib/RichText/Converter/Xslt.php - - - message: "#^Method Ibexa\\\\FieldTypeRichText\\\\RichText\\\\Converter\\\\Xslt\\:\\:__construct\\(\\) has parameter \\$customStylesheets with no value type specified in iterable type array\\.$#" - count: 1 - path: src/lib/RichText/Converter/Xslt.php - - - - message: "#^Method Ibexa\\\\FieldTypeRichText\\\\RichText\\\\Converter\\\\Xslt\\:\\:convert\\(\\) should return DOMDocument but returns DOMDocument\\|false\\.$#" - count: 1 - path: src/lib/RichText/Converter/Xslt.php - - - - message: "#^Method Ibexa\\\\FieldTypeRichText\\\\RichText\\\\Converter\\\\Xslt\\:\\:getSortedCustomStylesheets\\(\\) return type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/lib/RichText/Converter/Xslt.php - - message: "#^Parameter \\#1 \\$source of method DOMDocument\\:\\:loadXML\\(\\) expects string, string\\|false given\\.$#" count: 1 path: src/lib/RichText/Converter/Xslt.php - - - message: "#^Property Ibexa\\\\FieldTypeRichText\\\\RichText\\\\Converter\\\\Xslt\\:\\:\\$customStylesheets type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/lib/RichText/Converter/Xslt.php - - message: "#^Cannot call method lookupNamespaceURI\\(\\) on DOMElement\\|null\\.$#" count: 2 @@ -1245,11 +1220,6 @@ parameters: count: 1 path: src/lib/RichText/XmlBase.php - - - message: "#^Parameter \\#2 \\$desc of method Ibexa\\\\FieldTypeRichText\\\\Translation\\\\Extractor\\\\OnlineEditorCustomAttributesExtractor\\:\\:createMessage\\(\\) expects string, int\\|string given\\.$#" - count: 1 - path: src/lib/Translation/Extractor/OnlineEditorCustomAttributesExtractor.php - - message: "#^Property Ibexa\\\\FieldTypeRichText\\\\Validator\\\\Constraints\\\\RichText\\:\\:\\$message has no type specified\\.$#" count: 1 @@ -2935,11 +2905,6 @@ parameters: count: 1 path: tests/lib/RichText/Validator/CustomTagsValidatorTest.php - - - message: "#^Method Ibexa\\\\Tests\\\\FieldTypeRichText\\\\RichText\\\\Validator\\\\CustomTagsValidatorTest\\:\\:testValidateDocumentAcceptsLegacyTags\\(\\) has no return type specified\\.$#" - count: 1 - path: tests/lib/RichText/Validator/CustomTagsValidatorTest.php - - message: "#^Call to method validateDocument\\(\\) on an unknown class Ibexa\\\\FieldTypeRichText\\\\RichText\\\\ValidatorInterface\\.$#" count: 1 diff --git a/src/bundle/Resources/config/fieldtype_services.yaml b/src/bundle/Resources/config/fieldtype_services.yaml index 90c1f461..222ec48f 100644 --- a/src/bundle/Resources/config/fieldtype_services.yaml +++ b/src/bundle/Resources/config/fieldtype_services.yaml @@ -73,7 +73,6 @@ services: # Note: should typically be the last one as it produces embeddable fragment Ibexa\FieldTypeRichText\RichText\Converter\Xslt: - class: Ibexa\FieldTypeRichText\RichText\Converter\Xslt arguments: ['%ibexa.field_type.richtext.converter.output.xhtml5.fragment.resources%'] tags: - {name: ibexa.field_type.richtext.converter.output.xhtml5, priority: 100} diff --git a/src/bundle/Resources/config/translation.yaml b/src/bundle/Resources/config/translation.yaml index 42c800cf..b2184732 100644 --- a/src/bundle/Resources/config/translation.yaml +++ b/src/bundle/Resources/config/translation.yaml @@ -4,13 +4,6 @@ services: autoconfigure: true public: false - Ibexa\FieldTypeRichText\Translation\Extractor\OnlineEditorCustomAttributesExtractor: - deprecated: 'Since ibexa/fieldtype-richtext 4.6.7 the "%service_id%" service is deprecated, will be removed in 5.0.0' - arguments: - $siteAccessList: '%ibexa.site_access.list%' - tags: - - { name: jms_translation.extractor, alias: ez_online_editor_attributes } - Ibexa\FieldTypeRichText\Translation\Extractor\CustomTagExtractor: arguments: $customTags: '%ibexa.field_type.richtext.custom_tags%' diff --git a/src/lib/RichText/Converter/Html5.php b/src/lib/RichText/Converter/Html5.php index fc016e64..449dc235 100644 --- a/src/lib/RichText/Converter/Html5.php +++ b/src/lib/RichText/Converter/Html5.php @@ -16,7 +16,7 @@ */ class Html5 extends XsltConverter { - public function __construct($stylesheet, ConfigResolverInterface $configResolver) + public function __construct(string $stylesheet, ConfigResolverInterface $configResolver) { $customStylesheets = $configResolver->getParameter('fieldtypes.ezrichtext.output_custom_xsl'); $customStylesheets = $customStylesheets ?: []; diff --git a/src/lib/RichText/Converter/Html5Edit.php b/src/lib/RichText/Converter/Html5Edit.php index 2b3c4025..80f3c225 100644 --- a/src/lib/RichText/Converter/Html5Edit.php +++ b/src/lib/RichText/Converter/Html5Edit.php @@ -16,7 +16,7 @@ */ class Html5Edit extends XsltConverter { - public function __construct($stylesheet, ConfigResolverInterface $configResolver) + public function __construct(string $stylesheet, ConfigResolverInterface $configResolver) { $customStylesheets = $configResolver->getParameter('fieldtypes.ezrichtext.edit_custom_xsl'); $customStylesheets = $customStylesheets ?: []; diff --git a/src/lib/RichText/Converter/Html5Input.php b/src/lib/RichText/Converter/Html5Input.php index e20928f1..4ec1f3fc 100644 --- a/src/lib/RichText/Converter/Html5Input.php +++ b/src/lib/RichText/Converter/Html5Input.php @@ -16,7 +16,7 @@ */ class Html5Input extends XsltConverter { - public function __construct($stylesheet, ConfigResolverInterface $configResolver) + public function __construct(string $stylesheet, ConfigResolverInterface $configResolver) { $customStylesheets = $configResolver->getParameter('fieldtypes.ezrichtext.input_custom_xsl'); $customStylesheets = $customStylesheets ?: []; diff --git a/src/lib/RichText/Converter/Xslt.php b/src/lib/RichText/Converter/Xslt.php index e5ca11b2..c591bee1 100644 --- a/src/lib/RichText/Converter/Xslt.php +++ b/src/lib/RichText/Converter/Xslt.php @@ -22,31 +22,29 @@ class Xslt extends XmlBase implements Converter { /** * Path to stylesheet to use. - * - * @var string */ - protected $stylesheet; + protected string $stylesheet; /** * Array of XSL stylesheets to add to the main one, grouped by priority. * - * @var array + * @var array> */ - protected $customStylesheets = []; + protected array $customStylesheets = []; + + private XSLTProcessor $xsltProcessor; /** - * Constructor. - * * @param string $stylesheet Stylesheet to use for conversion - * @param array $customStylesheets Array of XSL stylesheets. Each entry consists in a hash having "path" and "priority" keys. + * @param array $customStylesheets Array of XSL stylesheets. Each entry consists in a hash having "path" and "priority" keys. */ - public function __construct($stylesheet, array $customStylesheets = []) + public function __construct(string $stylesheet, array $customStylesheets = []) { $this->stylesheet = $stylesheet; // Grouping stylesheets by priority. foreach ($customStylesheets as $customStylesheet) { - $this->customStylesheets[$customStylesheet['priority']][] = $customStylesheet['path']; + $this->customStylesheets[(int)$customStylesheet['priority']][] = $customStylesheet['path']; } } @@ -54,10 +52,9 @@ public function __construct($stylesheet, array $customStylesheets = []) * Returns the XSLTProcessor to use to transform internal XML to HTML5. * * @throws \RuntimeException - * - * @return \XSLTProcessor + * @throws \DOMException */ - protected function getXSLTProcessor() + protected function getXSLTProcessor(): XSLTProcessor { if (isset($this->xsltProcessor)) { return $this->xsltProcessor; @@ -97,30 +94,23 @@ protected function getXSLTProcessor() * The order is from the lowest priority to the highest since in case of a conflict, * the last loaded XSL template always wins. * - * @return array + * @return list */ - protected function getSortedCustomStylesheets() + protected function getSortedCustomStylesheets(): array { - $sortedStylesheets = []; ksort($this->customStylesheets); - foreach ($this->customStylesheets as $stylesheets) { - $sortedStylesheets = array_merge($sortedStylesheets, $stylesheets); - } - return $sortedStylesheets; + // flatten [priority => stylesheet[]] array to return a simple list + return array_merge(...$this->customStylesheets); } /** * Performs conversion of the given $document using XSLT stylesheet. * - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException if stylesheet is not found - * @throws \Ibexa\Contracts\Core\Repository\Exceptions\InvalidArgumentException if document does not transform - * - * @param \DOMDocument $document - * - * @return \DOMDocument + * @throws \DOMException + * @throws \Ibexa\Core\Base\Exceptions\InvalidArgumentException */ - public function convert(DOMDocument $document) + public function convert(DOMDocument $xmlDoc): DOMDocument { if (!file_exists($this->stylesheet)) { throw new InvalidArgumentException( @@ -133,11 +123,11 @@ public function convert(DOMDocument $document) $this->startRecordingErrors(); - $document = $processor->transformToDoc($document); + $document = $processor->transformToDoc($xmlDoc); $errors = $this->collectErrors(); - if (!empty($errors)) { + if (!empty($errors) || $document === false) { throw new InvalidArgumentException( '$xmlDoc', 'Transformation of XML content failed: ' . implode("\n", $errors) diff --git a/src/lib/RichText/Validator/CustomTagsValidator.php b/src/lib/RichText/Validator/CustomTagsValidator.php index 5cd0f1c9..c5e0ca84 100644 --- a/src/lib/RichText/Validator/CustomTagsValidator.php +++ b/src/lib/RichText/Validator/CustomTagsValidator.php @@ -57,11 +57,7 @@ public function validateDocument(DOMDocument $xmlDocument): array } if (!isset($this->customTagsConfiguration[$tagName])) { - @trigger_error( - "Configuration for RichText Custom Tag '{$tagName}' not found. " . - 'Custom Tags configuration is required since 7.1, its lack will result in validation error in 8.x', - E_USER_DEPRECATED - ); + $errors[] = "Missing configuration for RichText CustomTag: '$tagName'"; continue; } @@ -92,7 +88,7 @@ public function validateDocument(DOMDocument $xmlDocument): array continue; } - if (!in_array($attributeName, $nonEmptyAttributes)) { + if (!in_array($attributeName, $nonEmptyAttributes, true)) { $errors[] = "The attribute '{$attributeName}' of RichText Custom Tag '{$tagName}' cannot be empty"; } } diff --git a/src/lib/Translation/Extractor/OnlineEditorCustomAttributesExtractor.php b/src/lib/Translation/Extractor/OnlineEditorCustomAttributesExtractor.php deleted file mode 100644 index 1d8fa074..00000000 --- a/src/lib/Translation/Extractor/OnlineEditorCustomAttributesExtractor.php +++ /dev/null @@ -1,113 +0,0 @@ -configResolver = $configResolver; - $this->siteAccessList = $siteAccessList; - } - - /** - * Iterate over each scope and extract custom attributes label names. - * - * @return \JMS\TranslationBundle\Model\MessageCatalogue - */ - public function extract(): MessageCatalogue - { - $catalogue = new MessageCatalogue(); - - $catalogue->add($this->createMessage(self::CLASS_LABEL_MESSAGE_ID, 'Class')); - - foreach ($this->siteAccessList as $scope) { - if (!$this->configResolver->hasParameter(RichText::ATTRIBUTES_SA_SETTINGS_ID)) { - continue; - } - $this->extractMessagesForScope($catalogue, $scope); - } - - return $catalogue; - } - - /** - * @param string $id - * @param string $desc - * - * @return \JMS\TranslationBundle\Model\Message\XliffMessage - */ - private function createMessage(string $id, string $desc): XliffMessage - { - $message = new XliffMessage($id, self::MESSAGE_DOMAIN); - $message->setNew(false); - $message->setMeaning($desc); - $message->setDesc($desc); - $message->setLocaleString($desc); - $message->addNote('key: ' . $id); - - return $message; - } - - /** - * Extract messages from the given scope into the catalogue. - * - * @param \JMS\TranslationBundle\Model\MessageCatalogue $catalogue - * @param string $scope - */ - private function extractMessagesForScope(MessageCatalogue $catalogue, string $scope): void - { - $attributes = $this->configResolver->getParameter( - RichText::ATTRIBUTES_SA_SETTINGS_ID, - null, - $scope - ); - foreach ($attributes as $elementName => $attributesConfig) { - foreach (array_keys($attributesConfig) as $attributeName) { - $messageId = sprintf( - '%s.%s.%s.label', - self::ATTRIBUTES_MESSAGE_ID_PREFIX, - $elementName, - $attributeName - ); - // by default let's use attribute name - $catalogue->add( - $this->createMessage($messageId, $attributeName) - ); - } - } - } -} diff --git a/tests/bundle/DependencyInjection/Configuration/Parser/FieldType/RichTextTest.php b/tests/bundle/DependencyInjection/Configuration/Parser/FieldType/RichTextTest.php index 32c63c08..0984426f 100644 --- a/tests/bundle/DependencyInjection/Configuration/Parser/FieldType/RichTextTest.php +++ b/tests/bundle/DependencyInjection/Configuration/Parser/FieldType/RichTextTest.php @@ -69,7 +69,7 @@ protected function configureAndLoad(array $configurationValues = []) $extensionAlias = $extension->getAlias(); // when loading extension, pass only relevant configuration - $extensionConfig = isset($configs[$extensionAlias]) ? $configs[$extensionAlias] : []; + $extensionConfig = $configs[$extensionAlias] ?? []; $extension->load([$extensionConfig], $this->container); } diff --git a/tests/lib/RichText/Validator/CustomTagsValidatorTest.php b/tests/lib/RichText/Validator/CustomTagsValidatorTest.php index ff2c5381..dae78990 100644 --- a/tests/lib/RichText/Validator/CustomTagsValidatorTest.php +++ b/tests/lib/RichText/Validator/CustomTagsValidatorTest.php @@ -14,16 +14,11 @@ use Symfony\Component\Yaml\Yaml; /** - * Test RichText CustomTagsValidator. - * - * @see \Ibexa\FieldTypeRichText\FieldType\RichText\CustomTagsValidator + * @covers \Ibexa\FieldTypeRichText\FieldType\RichText\CustomTagsValidator */ -class CustomTagsValidatorTest extends TestCase +final class CustomTagsValidatorTest extends TestCase { - /** - * @var \Ibexa\FieldTypeRichText\RichText\Validator\CustomTagsValidator - */ - private $validator; + private CustomTagsValidator $validator; public function setUp(): void { @@ -37,8 +32,6 @@ public function setUp(): void /** * Test validating DocBook document containing Custom Tags. * - * @covers \Ibexa\FieldTypeRichText\RichText\CustomTagsValidator::validateDocument - * * @dataProvider providerForTestValidateDocument * * @param \DOMDocument $document @@ -178,6 +171,7 @@ public function providerForTestValidateDocument() ), [ 'Missing RichText Custom Tag name', + "Missing configuration for RichText CustomTag: 'undefined_tag'", "Missing attribute name for RichText Custom Tag 'video'", "The attribute 'title' of RichText Custom Tag 'video' cannot be empty", "The attribute 'width' of RichText Custom Tag 'video' cannot be empty", @@ -187,31 +181,6 @@ public function providerForTestValidateDocument() ]; } - /** - * Test that defined but not configured yet Custom Tag doesn't cause validation error. - */ - public function testValidateDocumentAcceptsLegacyTags() - { - $document = $this->createDocument( - << -
- - Undefined - - Test - - -
-DOCBOOK - ); - - self::assertEmpty($this->validator->validateDocument($document)); - } - /** * @param string $source XML source *