Services API 

New in version 13.1.5

The new service architecture replaces legacy controllers with a clean pipeline: Parser → Resolver → Renderer.

The RTE CKEditor Image extension uses a three-service architecture following TYPO3 v13 best practices with clear separation of concerns.

Architecture overview 

ImageAttributeParserImageResolverServiceImageRenderingServiceRendered HTMLHTML ParsingDOMDocumentAttribute extractionBusiness LogicSecurity ValidationFAL ProcessingFluid RenderingViewFactoryInterfaceTemplate SelectionRaw attributesImageRenderingDto
Service pipeline architecture

ImageAttributeParser 

class ImageAttributeParser
Fully qualified name
\Netresearch\RteCKEditorImage\Service\ImageAttributeParser

Pure HTML parsing using DOMDocument - no business logic.

Responsibility 

  • Extract raw attributes from HTML strings.
  • Parse <img> tags within content.
  • Parse <a> tags containing <img> tags.
  • NO validation, NO sanitization - just parsing.

Methods 

parseImageAttributes() 

parseImageAttributes ( $html)

Parse attributes from <img> tag HTML string.

param string $html

HTML string containing <img> tag.

returntype

array<string,string>

Returns

Attribute name => value pairs.

Example:

Parsing image attributes
$parser = GeneralUtility::makeInstance(ImageAttributeParser::class);
$attributes = $parser->parseImageAttributes(
    '<img src="image.jpg" data-htmlarea-file-uid="123" alt="Example" />'
);
// Returns: ['src' => 'image.jpg', 'data-htmlarea-file-uid' => '123', 'alt' => 'Example']
Copied!

parseLinkWithImages() 

parseLinkWithImages ( $html)

Parse attributes from <a> tag containing <img> tags.

param string $html

HTML string containing <a><img /></a>.

returntype

array{link: array<string,string>, images: array}

Returns

Array with link and images keys.

Return structure:

Return value structure
[
    'link' => ['href' => 'page.html', 'title' => 'Link title'],
    'images' => [
        [
            'attributes' => ['src' => 'image.jpg', 'alt' => 'Alt text'],
            'originalHtml' => '<img src="image.jpg" alt="Alt text" />'
        ]
    ]
]
Copied!

ImageResolverService 

class ImageResolverService
Fully qualified name
\Netresearch\RteCKEditorImage\Service\ImageResolverService

Business logic, security validation, and FAL processing.

Responsibility 

  • Transform raw attributes into validated DTOs.
  • Resolve FAL file references.
  • Apply security checks (file visibility, protocol blocking).
  • Process images with quality settings.
  • ALL security validation happens here.

Security features 

New in version 13.1.5

The service includes comprehensive security measures:

  • File visibility validation: Prevents access to hidden/restricted files.
  • Protocol blocking: Blocks dangerous protocols (javascript:, file:, data:text/html, vbscript:).
  • XSS prevention: Uses htmlspecialchars() with ENT_QUOTES | ENT_HTML5.
  • Type safety: Read-only DTO properties prevent modification.

Quality settings 

New in version 13.1.5

The service supports quality multipliers for image processing:

Quality constants in ImageResolverService
const QUALITY_NONE     = 'none';     // N/A - Skip processing entirely
const QUALITY_LOW      = 'low';      // 0.9x - Performance optimized
const QUALITY_STANDARD = 'standard'; // 1.0x - Default
const QUALITY_RETINA   = 'retina';   // 2.0x - High-DPI displays
const QUALITY_ULTRA    = 'ultra';    // 3.0x - Extra sharp
const QUALITY_PRINT    = 'print';    // 6.0x - Print quality
Copied!

Methods 

resolve() 

resolve ( $attributes, $conf, $request, $linkAttributes = null)

Resolve image attributes to validated DTO.

param array $attributes

Raw attributes from parser.

param array $conf

TypoScript configuration.

param ServerRequestInterface $request

Current request.

param array|null $linkAttributes

Optional link attributes for linked images.

returntype

ImageRenderingDto|null

Returns

Validated DTO or null if validation fails.

Example:

Resolving image attributes to DTO
$resolver = GeneralUtility::makeInstance(ImageResolverService::class);
$dto = $resolver->resolve(
    $attributes,
    $typoScriptConfig,
    $request
);

if ($dto === null) {
    // Validation failed - return original content
    return $content;
}
Copied!

ImageRenderingService 

class ImageRenderingService
Fully qualified name
\Netresearch\RteCKEditorImage\Service\ImageRenderingService

Presentation layer using TYPO3 v13 ViewFactoryInterface.

Responsibility 

  • Render validated DTOs via Fluid templates.
  • Select appropriate template based on context.
  • NO business logic, NO validation - trusts the DTO.

Template selection 

The service automatically selects templates based on the rendering context:

Context Template
Standalone image Image/Standalone
Image with caption Image/WithCaption
Image within link Image/Link
Linked image with caption Image/LinkWithCaption
Image with zoom/popup Image/Popup
Popup image with caption Image/PopupWithCaption

Methods 

render() 

render ( ImageRenderingDto $imageData, ServerRequestInterface $request) : string

Render image HTML from validated DTO.

param ImageRenderingDto $imageData

Validated image data.

param ServerRequestInterface $request

Current request.

returntype

string

Returns

Rendered HTML.

Example:

Rendering image from DTO
$renderer = GeneralUtility::makeInstance(ImageRenderingService::class);
$html = $renderer->render($dto, $request);
Copied!

Service decoration 

To customize service behavior, use Symfony service decoration:

EXT:my_extension/Configuration/Services.yaml
App\Service\CustomImageResolver:
  decorates: Netresearch\RteCKEditorImage\Service\ImageResolverService
  arguments:
    $inner: '@.inner'
Copied!
EXT:my_extension/Classes/Service/CustomImageResolver.php
<?php

declare(strict_types=1);

namespace App\Service;

use Netresearch\RteCKEditorImage\Service\ImageResolverService;
use Netresearch\RteCKEditorImage\Domain\Model\ImageRenderingDto;

class CustomImageResolver
{
    public function __construct(
        private readonly ImageResolverService $inner
    ) {}

    public function resolve(...$args): ?ImageRenderingDto
    {
        // Custom pre-processing
        $dto = $this->inner->resolve(...$args);
        // Custom post-processing
        return $dto;
    }
}
Copied!