---
title: "Services API"
manual: "RTE CKEditor Image"
version: "main"
permalink: "https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:api-services@main"
source: "API/Services.rst"
rendered: "2026-10-01T01:27:51+00:00"
---

# Services API {#api-services}

<!-- TODO: no Markdown rendering for "versionadded" -->

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.

**Table of contents**

-   [Architecture overview](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:architecture-overview@main)
-   [ImageAttributeParser](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:imageattributeparser@main)
-   [ImageResolverService](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:imageresolverservice@main)
-   [ImageRenderingService](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:imagerenderingservice@main)
-   [Service decoration](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:service-decoration@main)
-   [Related documentation](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:related-documentation@main)

## Architecture overview {#architecture-overview}

```plantuml
skinparam componentStyle rectangle
skinparam backgroundColor white

component "ImageAttributeParser" as Parser
component "ImageResolverService" as Resolver
component "ImageRenderingService" as Renderer
component "Rendered HTML" as Output

note right of Parser
    HTML Parsing
    DOMDocument
    Attribute extraction
end note

note right of Resolver
    Business Logic
    Security Validation
    FAL Processing
end note

note right of Renderer
    Fluid Rendering
    ViewFactoryInterface
    Template Selection
end note

Parser --> Resolver : Raw attributes
Resolver --> Renderer : ImageRenderingDto
Renderer --> Output
```

Service pipeline architecture

## ImageAttributeParser {#api-imageattributeparser}

-   **class ImageAttributeParser**

    -   *Fully qualified name:* `\Netresearch\RteCKEditorImage\Service\ImageAttributeParser`

    Pure HTML parsing using `DOMDocument` \- no business logic.

### Responsibility {#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 {#methods}

#### parseImageAttributes() {#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**

```php
$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']
```

#### parseLinkWithImages() {#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**

```php
[
    'link' => ['href' => 'page.html', 'title' => 'Link title'],
    'images' => [
        [
            'attributes' => ['src' => 'image.jpg', 'alt' => 'Alt text'],
            'originalHtml' => '<img src="image.jpg" alt="Alt text" />'
        ]
    ]
]
```

## ImageResolverService {#api-imageresolverservice}

-   **class ImageResolverService**

    -   *Fully qualified name:* `\Netresearch\RteCKEditorImage\Service\ImageResolverService`

    Business logic, security validation, and FAL processing.

### Responsibility {#responsibility-1}

-   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 {#security-features}

<!-- TODO: no Markdown rendering for "versionadded" -->

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 {#quality-settings}

<!-- TODO: no Markdown rendering for "versionadded" -->

The service supports quality multipliers for image processing:

**Quality constants in ImageResolverService**

```php
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
```

### Methods {#methods-1}

#### resolve() {#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**

```php
$resolver = GeneralUtility::makeInstance(ImageResolverService::class);
$dto = $resolver->resolve(
    $attributes,
    $typoScriptConfig,
    $request
);

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

## ImageRenderingService {#api-imagerenderingservice}

-   **class ImageRenderingService**

    -   *Fully qualified name:* `\Netresearch\RteCKEditorImage\Service\ImageRenderingService`

    Presentation layer using TYPO3 v13 `ViewFactoryInterface`.

### Responsibility {#responsibility-2}

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

### Template selection {#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 {#methods-2}

#### render() {#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**

```php
$renderer = GeneralUtility::makeInstance(ImageRenderingService::class);
$html = $renderer->render($dto, $request);
```

## Service decoration {#service-decoration}

To customize service behavior, use Symfony service decoration:

**EXT:my_extension/Configuration/Services.yaml**

```yaml
App\Service\CustomImageResolver:
  decorates: Netresearch\RteCKEditorImage\Service\ImageResolverService
  arguments:
    $inner: '@.inner'
```

**EXT:my_extension/Classes/Service/CustomImageResolver.php**

```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;
    }
}
```

## Related documentation {#related-documentation}

-   [DTOs](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:api-dtos@main) \- Data transfer objects.
-   [Controllers API](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:api-controllers@main) \- TypoScript adapter.
-   [Template Overrides](https://docs.typo3.org/permalink/netresearch/rte-ckeditor-image:examples-template-overrides@main) \- Customizing output.
