Skip to content

API Refs v5.0.10 - #3360

Closed
ezrobot wants to merge 8 commits into
release_5.0.10from
api_refs_v5.0.10
Closed

API Refs v5.0.10#3360
ezrobot wants to merge 8 commits into
release_5.0.10from
api_refs_v5.0.10

Conversation

@ezrobot

@ezrobot ezrobot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

PHP API & REST API References update for v5.0.10

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

Preview of modified files

Preview of modified Markdown:

Preview of addition to PHP API Reference:

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

Summary

Status Count
🔍 Total 750685
🔗 Unique 15040
✅ Successful 6276
⏳ Timeouts 0
🔀 Redirected 8
👻 Excluded 744389
❓ Unknown 0
🚫 Errors 20
⛔ Unsupported 0

Errors per input

Errors in site/administration/configuration/configuration/index.html

Errors in site/api/php_api/php_api/index.html

Errors in site/multisite/translations_management/configure_translations_management/index.html

  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#add-new-translation (at 14811:25) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#manage-translation-services-and-language-pairs (at 14815:17) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#side-by-side-translation-view (at 14817:17) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#side-by-side-translation-view (at 14826:109) | Cannot find fragment

Errors in site/multisite/translations_management/translate_with_cli/index.html

  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#add-new-translation (at 14310:112) | Cannot find fragment

Errors in site/multisite/translations_management/translations_management_guide/index.html

  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#review-automatic-translation (at 14478:22) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#side-by-side-translation-view (at 14455:50) | Cannot find fragment

Errors in site/release_notes/ibexa_dxp_v4.6/index.html

  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-4.6/site/content_management/rich_text/extend_online_editor/index.html#provide-translations-for-custom-tags (at 17146:39) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-4.6/site/infrastructure_and_maintenance/background_tasks/index.html#siteaccessstamp (at 17142:44) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-4.6/site/update_and_migration/from_4.6/update_from_4.6/index.html#v4632 (at 17164:49) | Cannot find fragment

Errors in site/release_notes/ibexa_dxp_v5.0/index.html

  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-5.0/site/content_management/rich_text/extend_online_editor/index.html#provide-translations-for-custom-tags (at 15805:39) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-5.0/site/infrastructure_and_maintenance/background_tasks/index.html#siteaccessstamp (at 15801:44) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-5.0/site/multisite/translations_management/extend_translations_management/index.html (at 15751:39) | File not found. Check if file exists and path is correct
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-5.0/site/release_notes/cohesivo_v6.0_deprecations/index.html (at 15799:83) | File not found. Check if file exists and path is correct
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/devdoc-5.0/site/update_and_migration/from_5.0/update_from_5.0/index.html#v5010 (at 15821:49) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#side-by-side-translation-view (at 15731:15) | Cannot find fragment
  • [ERROR] file:///home/runner/work/documentation-developer/documentation-developer/repositories/userdoc-5.0/site/content_management/translate_content/index.html#side-by-side-translation-view (at 15733:39) | Cannot find fragment

Errors in site/search/search_criteria_and_sort_clauses/index.html

Redirects per input

Redirects in site/administration/back_office/customize_search_suggestion/index.html

Redirects in site/administration/project_organization/project_organization/index.html

Redirects in site/api/php_api/php_api/index.html

Redirects in site/api/rest_api/extending_rest_api/creating_new_rest_resource/index.html

Redirects in site/commerce/checkout/checkout/index.html

Redirects in site/commerce/checkout/configure_checkout/index.html

Redirects in site/content_management/field_types/type_and_value/index.html

Redirects in site/release_notes/ez_platform_v3.0_deprecations/index.html

Full Github Actions output

@mnocon
mnocon changed the base branch from 5.0 to release_5.0.10 August 21, 2026 07:38
@mnocon

mnocon commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

No changes between code freeze and final release

@mnocon mnocon closed this Aug 21, 2026
@github-actions

Copy link
Copy Markdown

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml

docs/content_management/rich_text/extend_online_editor.md@25:```yaml
docs/content_management/rich_text/extend_online_editor.md@26:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@27:```


code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml

docs/content_management/rich_text/extend_online_editor.md@25:```yaml
docs/content_management/rich_text/extend_online_editor.md@26:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@27:```

001⫶ibexa:
002⫶ system:
003⫶ admin_group:
004⫶ fieldtypes:
005⫶ ibexa_richtext:
006⫶ custom_tags: [factbox]
007⫶ toolbar:
008⫶ custom_tags_group:
009⫶ buttons:
010⫶ factbox:
011⫶ priority: 5
012⫶ibexa_fieldtype_richtext:
013⫶ custom_tags:
014⫶ factbox:
015⫶ template: '@ibexadesign/field_type/ibexa_richtext/custom_tags/factbox.html.twig'
016⫶ icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#info-square'
017⫶ attributes:
018⫶ name:
019⫶ type: string
020⫶ required: true
021⫶ style:
022⫶ type: choice
023⫶ required: true
024⫶ default_value: light
025⫶ choices: [light, dark]
001⫶ibexa_fieldtype_richtext:
002⫶ custom_tags:
003⫶ factbox:
004⫶ template: '@ibexadesign/field_type/ibexa_richtext/custom_tags/factbox.html.twig'
005⫶ icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#info-square' # Optional
006⫶ is_inline: false # Optional
007⫶ label: 'Factbox custom tag' # Optional
008⫶ description: 'Highlight a piece of information in a box' # Optional
009⫶ attributes:
010⫶ name:
011⫶ type: string
012⫶ required: true # Optional
013⫶ label: 'My name attribute' # Optional
014⫶ style:
015⫶ type: choice
016⫶ required: true # Optional
017⫶ default_value: light
018⫶ choices: [light, dark]
019⫶ label: 'My style attribute' # Optional
020⫶
021⫶ibexa:
022⫶ system:
023⫶ admin_group:
024⫶ fieldtypes:
025⫶ ibexa_richtext:
026⫶ custom_tags: [factbox]
027⫶ toolbar:
028⫶ custom_tags_group:
029⫶ buttons:
030⫶ factbox:
031⫶ priority: 5

docs/content_management/rich_text/extend_online_editor.md@107:```yaml hl_lines="7-8 13 19"
docs/content_management/rich_text/extend_online_editor.md@108:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/custom_tags.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@109:```

001⫶ibexa_fieldtype_richtext:
002⫶ custom_tags:
003⫶ factbox:
004⫶ template: '@ibexadesign/field_type/ibexa_richtext/custom_tags/factbox.html.twig'
005⫶ icon: '/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#info-square' # Optional
006⫶ is_inline: false # Optional
007❇️ label: 'Factbox custom tag' # Optional
008❇️ description: 'Highlight a piece of information in a box' # Optional
009⫶ attributes:
010⫶ name:
011⫶ type: string
012⫶ required: true # Optional
013❇️ label: 'My name attribute' # Optional
014⫶ style:
015⫶ type: choice
016⫶ required: true # Optional
017⫶ default_value: light
018⫶ choices: [light, dark]
019❇️ label: 'My style attribute' # Optional
020⫶
021⫶ibexa:
022⫶ system:
023⫶ admin_group:
024⫶ fieldtypes:
025⫶ ibexa_richtext:
026⫶ custom_tags: [factbox]
027⫶ toolbar:
028⫶ custom_tags_group:
029⫶ buttons:
030⫶ factbox:
031⫶ priority: 5


code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml



code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml

docs/content_management/rich_text/extend_online_editor.md@123:```yaml hl_lines="6 8-9"
docs/content_management/rich_text/extend_online_editor.md@124:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/packages/jms_translation.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@125:```

001⫶jms_translation:
002⫶ configs:
003⫶ app_translation_config:
004⫶ dirs: ['%kernel.project_dir%/src']
005⫶ output_dir: '%kernel.project_dir%/translations'
006❇️ output_format: yaml
007⫶ extractors:
008❇️ - 'app.translation_extractor.factbox'
009❇️ - 'app.translation_extractor.factbox_choice'


code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml


code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml

docs/content_management/rich_text/extend_online_editor.md@117:```yaml hl_lines="7 17"
docs/content_management/rich_text/extend_online_editor.md@118:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/config/services.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@119:```

001⫶services:
002⫶ app.extractor.custom_tag:
003⫶ class: Ibexa\FieldTypeRichText\Translation\Extractor\CustomTagExtractor
004⫶ arguments:
005⫶ $customTags: '%ibexa.field_type.richtext.custom_tags%'
006⫶ $domain: '%ibexa.field_type.richtext.custom_tags.translation_domain%'
007❇️ $allowlist: ['factbox']
008⫶ tags:
009⫶ - name: jms_translation.extractor
010⫶ alias: app.translation_extractor.factbox
011⫶
012⫶ app.extractor.custom_tag_choice:
013⫶ class: Ibexa\FieldTypeRichText\Translation\Extractor\ChoiceAttributeExtractor
014⫶ arguments:
015⫶ $customTags: '%ibexa.field_type.richtext.custom_tags%'
016⫶ $domain: '%ibexa.field_type.richtext.custom_tags.translation_domain%'
017❇️ $allowlist: ['factbox']
018⫶ tags:
019⫶ - name: jms_translation.extractor
020⫶ alias: app.translation_extractor.factbox_choice


code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ibexa_richtext/custom_tags/factbox.html.twig


code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ibexa_richtext/custom_tags/factbox.html.twig

docs/content_management/rich_text/extend_online_editor.md@40:```html+twig
docs/content_management/rich_text/extend_online_editor.md@41:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ibexa_richtext/custom_tags/factbox.html.twig') =]]
docs/content_management/rich_text/extend_online_editor.md@42:```

001⫶<div class="ibexa-factbox ibexa-factbox--{{ params.style }}">
002⫶ <p>{{ params.name }}</p>
003⫶ <div>
004⫶ {{ content|raw }}
005⫶ </div>
006⫶</div>
docs/content_management/rich_text/extend_online_editor.md@48:```html+twig
docs/content_management/rich_text/extend_online_editor.md@49:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/templates/themes/standard/field_type/ibexa_richtext/custom_tags/factbox.html.twig') =]]
docs/content_management/rich_text/extend_online_editor.md@50:```

001⫶{{ encore_entry_link_tags('factbox') }}
002⫶
003⫶<div class="ibexa-factbox ibexa-factbox--{{ params.style }}">
004⫶ <p>{{ params.name }}</p>
005⫶ <div>
006⫶ {{ content|raw }}
007⫶ </div>
008⫶</div>


code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml



code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml

docs/content_management/rich_text/extend_online_editor.md@57:```yaml
docs/content_management/rich_text/extend_online_editor.md@58:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@59:```
docs/content_management/rich_text/extend_online_editor.md@96:```yaml
docs/content_management/rich_text/extend_online_editor.md@97:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/translations/custom_tags.en.yaml') =]]
docs/content_management/rich_text/extend_online_editor.md@98:```

001⫶ibexa_richtext.custom_tags.factbox.label: 'Factbox'

001⫶ibexa_richtext.custom_tags.factbox.label: 'Factbox'
002⫶ibexa_richtext.custom_tags.factbox.attributes.name.label: 'Name'
003⫶ibexa_richtext.custom_tags.factbox.attributes.style.label: 'Style'
002⫶ibexa_richtext.custom_tags.factbox.description: 'Highlight a piece of information in a box'
003⫶ibexa_richtext.custom_tags.factbox.attributes.name.label: 'Name'
004⫶ibexa_richtext.custom_tags.factbox.attributes.style.label: 'Style'
005⫶ibexa_richtext.custom_tags.factbox.attributes.style.choice.dark.label: 'Dark'
006⫶ibexa_richtext.custom_tags.factbox.attributes.style.choice.light.label: 'Light'


code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js



code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js

docs/content_management/rich_text/extend_online_editor.md@82:``` js
docs/content_management/rich_text/extend_online_editor.md@83:[[= include_file('code_samples/back_office/online_editor/custom_tags/factbox/webpack.config.js') =]]
docs/content_management/rich_text/extend_online_editor.md@84:```

001⫶Encore.addStyleEntry('factbox', [
002⫶ path.resolve(__dirname, './assets/scss/factbox.scss'),
003⫶]);


code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php


code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php

docs/infrastructure_and_maintenance/background_tasks.md@109:``` php
docs/infrastructure_and_maintenance/background_tasks.md@110:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 1, 3) =]]
docs/infrastructure_and_maintenance/background_tasks.md@111:
docs/infrastructure_and_maintenance/background_tasks.md@112:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 9, 14) =]]
docs/infrastructure_and_maintenance/background_tasks.md@113:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 16, 21) =]]
docs/infrastructure_and_maintenance/background_tasks.md@114:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 29, 30) =]]
docs/infrastructure_and_maintenance/background_tasks.md@115:```
docs/infrastructure_and_maintenance/background_tasks.md@116:``` php
docs/infrastructure_and_maintenance/background_tasks.md@117:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 1, 3) =]]
docs/infrastructure_and_maintenance/background_tasks.md@118:
docs/infrastructure_and_maintenance/background_tasks.md@119:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 5, 5) =]]
docs/infrastructure_and_maintenance/background_tasks.md@120:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 10, 15) =]]
docs/infrastructure_and_maintenance/background_tasks.md@121:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 17, 22) =]]
docs/infrastructure_and_maintenance/background_tasks.md@122:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 30, 31) =]]
docs/infrastructure_and_maintenance/background_tasks.md@123:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Dispatcher;
004⫶

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Dispatcher;
004⫶
005⫶use Symfony\Component\Messenger\MessageBusInterface;
006⫶
007⫶final readonly class SomeClassThatSchedulesExecutionInTheBackground
008⫶{
009⫶ public function __construct(
010⫶ private MessageBusInterface $bus,
011⫶ ) {
012⫶ }
013⫶
014⫶ public function schedule(object $message): void
015⫶ {
016⫶ $this->bus->dispatch($message);
017⫶ }
018⫶}

docs/infrastructure_and_maintenance/background_tasks.md@153:``` php
docs/infrastructure_and_maintenance/background_tasks.md@154:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 6, 6, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@155:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 9, 9, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@156:
docs/infrastructure_and_maintenance/background_tasks.md@157:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 27, 28, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@158:```
005⫶use App\Message\SomeMessage;
006⫶use Symfony\Component\Messenger\MessageBusInterface;
007⫶
008⫶final readonly class SomeClassThatSchedulesExecutionInTheBackground
009⫶{
010⫶ public function __construct(
011⫶ private MessageBusInterface $bus,
012⫶ ) {
013⫶ }
014⫶
015⫶ public function schedule(): void
016⫶ {
017⫶ $this->bus->dispatch(new SomeMessage());
018⫶ }
019⫶}

docs/infrastructure_and_maintenance/background_tasks.md@165:``` php
docs/infrastructure_and_maintenance/background_tasks.md@166:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 6, 6, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@167:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 9, 9, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@168:
docs/infrastructure_and_maintenance/background_tasks.md@169:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 27, 28, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@170:```


001⫶use Ibexa\Contracts\Messenger\Stamp\DeduplicateStamp;
002⫶use Symfony\Component\Messenger\MessageBusInterface;
003⫶
004⫶$deduplicationKey = 'my_message.project.<key_based_on_message>';
005⫶$this->bus->dispatch($message, [new DeduplicateStamp($deduplicationKey)]);

docs/infrastructure_and_maintenance/background_tasks.md@173:``` php
docs/infrastructure_and_maintenance/background_tasks.md@174:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 7, 7, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@175:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 9, 10, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@176:
docs/infrastructure_and_maintenance/background_tasks.md@177:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 25, 25, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@178:```

001⫶use Ibexa\Contracts\Messenger\Stamp\SudoStamp;
002⫶use Symfony\Component\Messenger\MessageBusInterface;
001⫶use Ibexa\Contracts\Core\Repository\PermissionResolver;
002⫶use Ibexa\Contracts\Messenger\Stamp\UserPermissionStamp;
003⫶
004⫶
003⫶
004⫶
005⫶$this->bus->dispatch($message, [new SudoStamp()]);
005⫶$deduplicationKey = 'my_message.project.<key_based_on_message>';


docs/infrastructure_and_maintenance/background_tasks.md@190:``` php
docs/infrastructure_and_maintenance/background_tasks.md@191:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 5, 5, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@192:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 8, 10, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@193:
docs/infrastructure_and_maintenance/background_tasks.md@194:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 23, 24, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@195:```
docs/infrastructure_and_maintenance/background_tasks.md@185:``` php
docs/infrastructure_and_maintenance/background_tasks.md@186:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 7, 7, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@187:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 9, 10, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@188:
docs/infrastructure_and_maintenance/background_tasks.md@189:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 25, 25, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@190:```


001⫶use Ibexa\Contracts\Core\Repository\PermissionResolver;
001⫶use Ibexa\Contracts\Messenger\Stamp\DeduplicateStamp;
002⫶use Ibexa\Contracts\Messenger\Stamp\UserPermissionStamp;
003⫶use Symfony\Component\Messenger\MessageBusInterface;
004⫶
002⫶use Ibexa\Contracts\Messenger\Stamp\UserPermissionStamp;
003⫶use Symfony\Component\Messenger\MessageBusInterface;
004⫶
005⫶$this->bus->dispatch(new SomeMessage(), [new UserPermissionStamp($currentUserId)]);

docs/infrastructure_and_maintenance/background_tasks.md@202:``` php
docs/infrastructure_and_maintenance/background_tasks.md@203:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 5, 5, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@204:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 8, 10, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@205:
docs/infrastructure_and_maintenance/background_tasks.md@206:[[= include_code('code_samples/background_tasks/src/Dispatcher/SomeClassThatSchedulesExecutionInTheBackground.php', 23, 24, remove_indent=True) =]]
docs/infrastructure_and_maintenance/background_tasks.md@207:```

001⫶use App\Message\SomeMessage;
002⫶use Ibexa\Contracts\Messenger\Stamp\SudoStamp;
003⫶use Ibexa\Contracts\Messenger\Stamp\UserPermissionStamp;
004⫶use Symfony\Component\Messenger\MessageBusInterface;
005⫶
005⫶
006⫶$currentUserId = $this->permissionResolver->getCurrentUserReference()->getUserId();
007⫶$this->bus->dispatch($message, [new UserPermissionStamp($currentUserId)]);
006⫶
007⫶$currentUserId = $this->permissionResolver->getCurrentUserReference()->getUserId();


code_samples/background_tasks/src/Messenger/SomeMessageProvider.php



code_samples/background_tasks/src/Messenger/SomeMessageProvider.php

docs/infrastructure_and_maintenance/background_tasks.md@275:``` php hl_lines="12"
docs/infrastructure_and_maintenance/background_tasks.md@276:[[= include_file('code_samples/background_tasks/src/Messenger/SomeMessageProvider.php') =]]
docs/infrastructure_and_maintenance/background_tasks.md@277:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Messenger;
004⫶
005⫶use App\Message\SomeMessage;
006⫶use Ibexa\Contracts\Messenger\Transport\MessageProviderInterface;
007⫶
008⫶final class SomeMessageProvider implements MessageProviderInterface
009⫶{
010⫶ public function getHandledClasses(): iterable
011⫶ {
012❇️ return [SomeMessage::class];
013⫶ }
014⫶}


code_samples/data_migration/examples/update_language.yaml


code_samples/data_migration/examples/update_language.yaml

docs/content_management/data_migration/importing_data.md@480:``` yaml
docs/content_management/data_migration/importing_data.md@481:[[= include_file('code_samples/data_migration/examples/update_language.yaml') =]]
docs/content_management/data_migration/importing_data.md@482:```

001⫶-
002⫶ type: language
003⫶ mode: update
004⫶ languageCode: ger-DE
005⫶ metadata:
006⫶ name: 'German (Germany)'
007⫶ enabled: true
008⫶ references:
009⫶ -
010⫶ name: ref__ger_de__language_id
011⫶ type: language_id


code_samples/translations_management/config/services.yaml


code_samples/translations_management/config/services.yaml

docs/multisite/translations_management/extend_translations_management.md@34:``` yaml
docs/multisite/translations_management/extend_translations_management.md@35:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 6) =]]
docs/multisite/translations_management/extend_translations_management.md@36:```

001⫶services:
002⫶ App\TranslationsManagement\MyCustomProvider:
003⫶ tags:
004⫶ - name: 'ibexa.translations_management.auto_translate.provider'
005⫶ identifier: 'my_custom_provider'
006⫶ validation_profile: 'my_custom_profile'

docs/multisite/translations_management/extend_translations_management.md@51:``` yaml
docs/multisite/translations_management/extend_translations_management.md@52:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 1) =]]
docs/multisite/translations_management/extend_translations_management.md@53:[[= include_code('code_samples/translations_management/config/services.yaml', 29, 33) =]]
docs/multisite/translations_management/extend_translations_management.md@54:```

001⫶services:
002⫶ App\TranslationsManagement\MyCustomAiProvider:
003⫶ tags:
004⫶ - name: 'ibexa.translations_management.auto_translate.provider'
005⫶ identifier: 'my_custom_ai_provider'
006⫶ validation_profile: 'ai_generic'

docs/multisite/translations_management/extend_translations_management.md@73:``` yaml
docs/multisite/translations_management/extend_translations_management.md@74:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 1) =]]
docs/multisite/translations_management/extend_translations_management.md@75:[[= include_code('code_samples/translations_management/config/services.yaml', 34, 37) =]]
docs/multisite/translations_management/extend_translations_management.md@76:```

001⫶services:
002⫶ App\TranslationsManagement\MyCustomLanguageNormalizer:
003⫶ tags:
004⫶ - name: 'ibexa.translations_management.auto_translate.provider.language_normalizer'
005⫶ priority: 10

docs/multisite/translations_management/extend_translations_management.md@93:``` yaml
docs/multisite/translations_management/extend_translations_management.md@94:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 1) =]]
docs/multisite/translations_management/extend_translations_management.md@95:[[= include_code('code_samples/translations_management/config/services.yaml', 7, 10) =]]
docs/multisite/translations_management/extend_translations_management.md@96:```

001⫶services:
002⫶ App\TranslationsManagement\MyProviderValidator:
003⫶ tags:
004⫶ - name: 'ibexa.translations_management.auto_translate.provider.validator'
005⫶ profile: 'my_custom_profile'

docs/multisite/translations_management/extend_translations_management.md@124:``` yaml
docs/multisite/translations_management/extend_translations_management.md@125:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 1) =]]
docs/multisite/translations_management/extend_translations_management.md@126:[[= include_code('code_samples/translations_management/config/services.yaml', 11, 14) =]]
docs/multisite/translations_management/extend_translations_management.md@127:```

001⫶services:
002⫶ App\TranslationsManagement\ImageAltTextTransformer:
003⫶ tags:
004⫶ - name: 'ibexa.translations_management.auto_translate.field_value_transformer'
005⫶ field_type_identifier: 'ibexa_image'

docs/multisite/translations_management/extend_translations_management.md@153:``` yaml
docs/multisite/translations_management/extend_translations_management.md@154:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 1) =]]
docs/multisite/translations_management/extend_translations_management.md@155:[[= include_code('code_samples/translations_management/config/services.yaml', 15, 18) =]]
docs/multisite/translations_management/extend_translations_management.md@156:```

001⫶services:
002⫶ App\TranslationsManagement\MyCustomExclusionRule:
003⫶ tags:
004⫶ - { name: 'ibexa.translations_management.side_by_side.exclusion_rule' }
005⫶ app.translations_management.exclusion_rule.custom_field_types:

docs/multisite/translations_management/extend_translations_management.md@172:``` yaml
docs/multisite/translations_management/extend_translations_management.md@173:[[= include_code('code_samples/translations_management/config/services.yaml', 1, 1) =]]
docs/multisite/translations_management/extend_translations_management.md@174:[[= include_code('code_samples/translations_management/config/services.yaml', 24, 28) =]]
docs/multisite/translations_management/extend_translations_management.md@175:```

001⫶services:
002⫶ App\TranslationsManagement\TwigComponent\MyTranslationModalFooter:
003⫶ tags:
004⫶ - name: ibexa.twig.component
005⫶ group: 'admin-ui-content-translation-modal-footer'
006⫶ priority: 10


code_samples/translations_management/install/schema.mysql.sql


code_samples/translations_management/install/schema.mysql.sql

docs/multisite/translations_management/configure_translations_management.md@46:    ```sql
docs/multisite/translations_management/configure_translations_management.md@47: [[= include_code('code_samples/translations_management/install/schema.mysql.sql', indent_level=1) =]]
docs/multisite/translations_management/configure_translations_management.md@48: ```

001⫶ CREATE TABLE IF NOT EXISTS ibexa_auto_translation (
002⫶ id INT AUTO_INCREMENT NOT NULL,
003⫶ provider_identifier VARCHAR(190) NOT NULL,
004⫶ content_id INT NOT NULL,
005⫶ version_no INT NOT NULL,
006⫶ source_language_id BIGINT NOT NULL,
007⫶ target_language_id BIGINT NOT NULL,
008⫶ review_status VARCHAR(64) NOT NULL,
009⫶ created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)',
010⫶ updated_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)',
011⫶ INDEX ibexa_auto_translation_content_version_idx (content_id, version_no),
012⫶ INDEX ibexa_auto_translation_target_language_idx (target_language_id),
013⫶ INDEX ibexa_auto_translation_review_status_idx (review_status),
014⫶ UNIQUE INDEX ibexa_auto_translation_context_uidx (content_id, version_no, source_language_id, target_language_id),
015⫶ PRIMARY KEY(id)
016⫶ ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_520_ci` ENGINE = InnoDB;
017⫶
018⫶ CREATE TABLE IF NOT EXISTS ibexa_auto_translation_review_log (
019⫶ id INT AUTO_INCREMENT NOT NULL,
020⫶ auto_translation_id INT DEFAULT NULL,
021⫶ user_id INT NOT NULL,
022⫶ status VARCHAR(64) NOT NULL,
023⫶ operation VARCHAR(64) NOT NULL,
024⫶ created_at DATETIME NOT NULL COMMENT '(DC2Type:datetime_immutable)',
025⫶ INDEX IDX_325A3B737CE350E8 (auto_translation_id),
026⫶ INDEX ibexa_auto_translation_review_log_auto_translation_created_idx (auto_translation_id, created_at, id),
027⫶ INDEX ibexa_auto_translation_review_log_status_created_idx (status, created_at),
028⫶ INDEX ibexa_auto_translation_review_log_user_idx (user_id),
029⫶ PRIMARY KEY(id)
030⫶ ) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_520_ci` ENGINE = InnoDB;
031⫶
032⫶ ALTER TABLE ibexa_auto_translation_review_log ADD CONSTRAINT ibexa_auto_translation_review_log_auto_translation_fk
033⫶ FOREIGN KEY (auto_translation_id) REFERENCES ibexa_auto_translation (id) ON UPDATE CASCADE ON DELETE SET NULL;
034⫶ ALTER TABLE ibexa_auto_translation_review_log ADD CONSTRAINT ibexa_auto_translation_review_log_user_fk
035⫶ FOREIGN KEY (user_id) REFERENCES ibexa_user (contentobject_id) ON UPDATE CASCADE ON DELETE RESTRICT;


code_samples/translations_management/install/schema.postgresql.sql


code_samples/translations_management/install/schema.postgresql.sql

docs/multisite/translations_management/configure_translations_management.md@52:    ```sql
docs/multisite/translations_management/configure_translations_management.md@53: [[= include_code('code_samples/translations_management/install/schema.postgresql.sql', indent_level=1) =]]
docs/multisite/translations_management/configure_translations_management.md@54: ```

001⫶ CREATE TABLE IF NOT EXISTS ibexa_auto_translation (
002⫶ id SERIAL NOT NULL,
003⫶ provider_identifier VARCHAR(190) NOT NULL,
004⫶ content_id INT NOT NULL,
005⫶ version_no INT NOT NULL,
006⫶ source_language_id BIGINT NOT NULL,
007⫶ target_language_id BIGINT NOT NULL,
008⫶ review_status VARCHAR(64) NOT NULL,
009⫶ created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
010⫶ updated_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
011⫶ PRIMARY KEY(id)
012⫶ );
013⫶
014⫶ CREATE INDEX IF NOT EXISTS ibexa_auto_translation_content_version_idx ON ibexa_auto_translation (content_id, version_no);
015⫶ CREATE INDEX IF NOT EXISTS ibexa_auto_translation_target_language_idx ON ibexa_auto_translation (target_language_id);
016⫶ CREATE INDEX IF NOT EXISTS ibexa_auto_translation_review_status_idx ON ibexa_auto_translation (review_status);
017⫶ CREATE UNIQUE INDEX IF NOT EXISTS ibexa_auto_translation_context_uidx ON ibexa_auto_translation (content_id, version_no, source_language_id, target_language_id);
018⫶ COMMENT ON COLUMN ibexa_auto_translation.created_at IS '(DC2Type:datetime_immutable)';
019⫶ COMMENT ON COLUMN ibexa_auto_translation.updated_at IS '(DC2Type:datetime_immutable)';
020⫶
021⫶ CREATE TABLE IF NOT EXISTS ibexa_auto_translation_review_log (
022⫶ id SERIAL NOT NULL,
023⫶ auto_translation_id INT DEFAULT NULL,
024⫶ user_id INT NOT NULL,
025⫶ status VARCHAR(64) NOT NULL,
026⫶ operation VARCHAR(64) NOT NULL,
027⫶ created_at TIMESTAMP(0) WITHOUT TIME ZONE NOT NULL,
028⫶ PRIMARY KEY(id)
029⫶ );
030⫶
031⫶ CREATE INDEX IF NOT EXISTS IDX_325A3B737CE350E8 ON ibexa_auto_translation_review_log (auto_translation_id);
032⫶ CREATE INDEX IF NOT EXISTS ibexa_auto_translation_review_log_auto_translation_created_idx ON ibexa_auto_translation_review_log (auto_translation_id, created_at, id);
033⫶ CREATE INDEX IF NOT EXISTS ibexa_auto_translation_review_log_status_created_idx ON ibexa_auto_translation_review_log (status, created_at);
034⫶ CREATE INDEX IF NOT EXISTS ibexa_auto_translation_review_log_user_idx ON ibexa_auto_translation_review_log (user_id);
035⫶ COMMENT ON COLUMN ibexa_auto_translation_review_log.created_at IS '(DC2Type:datetime_immutable)';
036⫶
037⫶ ALTER TABLE ibexa_auto_translation_review_log ADD CONSTRAINT ibexa_auto_translation_review_log_auto_translation_fk
038⫶ FOREIGN KEY (auto_translation_id) REFERENCES ibexa_auto_translation (id) ON UPDATE CASCADE ON DELETE SET NULL;
039⫶ ALTER TABLE ibexa_auto_translation_review_log ADD CONSTRAINT ibexa_auto_translation_review_log_user_fk
040⫶ FOREIGN KEY (user_id) REFERENCES ibexa_user (contentobject_id) ON UPDATE CASCADE ON DELETE RESTRICT;


code_samples/translations_management/src/TranslationsManagement/ImageAltTextTransformer.php


code_samples/translations_management/src/TranslationsManagement/ImageAltTextTransformer.php

docs/multisite/translations_management/extend_translations_management.md@116:``` php hl_lines="21 31 37 46-58"
docs/multisite/translations_management/extend_translations_management.md@117:[[= include_code('code_samples/translations_management/src/TranslationsManagement/ImageAltTextTransformer.php') =]]
docs/multisite/translations_management/extend_translations_management.md@118:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\TranslationsManagement;
006⫶
007⫶use Ibexa\Contracts\Core\Repository\Values\Content\Field;
008⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Transformer\Field\EncodedFieldValue;
009⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Transformer\Field\FieldValueTransformerInterface;
010⫶use Ibexa\Core\Base\Exceptions\InvalidArgumentException;
011⫶use Ibexa\Core\FieldType\Image\Value as ImageValue;
012⫶use Ibexa\Core\FieldType\Value;
013⫶
014⫶final class ImageAltTextTransformer implements FieldValueTransformerInterface
015⫶{
016⫶ public function getFieldTypeIdentifier(): string
017⫶ {
018⫶ return 'ibexa_image';
019⫶ }
020⫶
021❇️ public function encode(Field $field): EncodedFieldValue
022⫶ {
023⫶ $value = $field->getValue();
024⫶ if (!$value instanceof ImageValue) {
025⫶ throw new InvalidArgumentException(
026⫶ '$field',
027⫶ sprintf('Expected %s, got %s.', ImageValue::class, get_debug_type($value))
028⫶ );
029⫶ }
030⫶
031❇️ return new EncodedFieldValue($value->alternativeText ?? '');
032⫶ }
033⫶
034⫶ /**
035⫶ * @param array<string, mixed> $metadata
036⫶ */
037❇️ public function decode(string $value, mixed $previousFieldValue, array $metadata): Value
038⫶ {
039⫶ if (!$previousFieldValue instanceof ImageValue) {
040⫶ throw new InvalidArgumentException(
041⫶ '$previousFieldValue',
042⫶ sprintf('Expected %s, got %s.', ImageValue::class, get_debug_type($previousFieldValue))
043⫶ );
044⫶ }
045⫶
046❇️ return new ImageValue([
047❇️ 'id' => $previousFieldValue->id,
048❇️ 'fileName' => $previousFieldValue->fileName,
049❇️ 'fileSize' => $previousFieldValue->fileSize,
050❇️ 'uri' => $previousFieldValue->uri,
051❇️ 'imageId' => $previousFieldValue->imageId,
052❇️ 'inputUri' => $previousFieldValue->inputUri,
053❇️ 'width' => $previousFieldValue->width,
054❇️ 'height' => $previousFieldValue->height,
055❇️ 'alternativeText' => $value,
056❇️ 'additionalData' => $previousFieldValue->additionalData,
057❇️ 'mime' => $previousFieldValue->mime,
058❇️ ]);
059⫶ }
060⫶}


code_samples/translations_management/src/TranslationsManagement/MyApiClient.php


code_samples/translations_management/src/TranslationsManagement/MyCustomAiProvider.php


code_samples/translations_management/src/TranslationsManagement/MyApiClient.php


code_samples/translations_management/src/TranslationsManagement/MyCustomAiProvider.php

docs/multisite/translations_management/extend_translations_management.md@44:``` php hl_lines="53 60"
docs/multisite/translations_management/extend_translations_management.md@45:[[= include_code('code_samples/translations_management/src/TranslationsManagement/MyCustomAiProvider.php') =]]
docs/multisite/translations_management/extend_translations_management.md@46:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\TranslationsManagement;
006⫶
007⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Provider\AiTranslationProviderInterface;
008⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\TranslationDataInterface;
009⫶
010⫶final readonly class MyCustomAiProvider implements AiTranslationProviderInterface
011⫶{
012⫶ /**
013⫶ * Replace MyApiClient with your HTTP client, SDK wrapper, or any service
014⫶ * that communicates with the external AI translation API.
015⫶ */
016⫶ public function __construct(
017⫶ private MyApiClient $apiClient,
018⫶ private string $actionConfigurationIdentifier,
019⫶ ) {
020⫶ }
021⫶
022⫶ public function getIdentifier(): string
023⫶ {
024⫶ return 'my_custom_ai_provider';
025⫶ }
026⫶
027⫶ public function getName(): string
028⫶ {
029⫶ return 'My AI Translation Service';
030⫶ }
031⫶
032⫶ public function getVendorName(): string
033⫶ {
034⫶ return 'My Company Ltd';
035⫶ }
036⫶
037⫶ public function translate(TranslationDataInterface $translationData): string
038⫶ {
039⫶ return $this->apiClient->translate(
040⫶ $translationData->getText(),
041⫶ $translationData->getSourceLanguage(),
042⫶ $translationData->getTargetLanguage()
043⫶ );
044⫶ }
045⫶
046⫶ /** @return array<string> */
047⫶ public function getSupportedLanguageCodes(): array
048⫶ {
049⫶ return ['eng-GB', 'ger-DE', 'fre-FR'];
050⫶ }
051⫶
052⫶ /** @return array<string, mixed> */
053❇️ public function getConfiguration(): array
054⫶ {
055⫶ return [
056⫶ 'actionConfigurationIdentifier' => $this->actionConfigurationIdentifier,
057⫶ ];
058⫶ }
059⫶
060❇️ public function isConfigured(): bool
061⫶ {
062⫶ return $this->actionConfigurationIdentifier !== '';
063⫶ }
064⫶}


code_samples/translations_management/src/TranslationsManagement/MyCustomExclusionRule.php


code_samples/translations_management/src/TranslationsManagement/MyCustomExclusionRule.php

docs/multisite/translations_management/extend_translations_management.md@146:``` php
docs/multisite/translations_management/extend_translations_management.md@147:[[= include_code('code_samples/translations_management/src/TranslationsManagement/MyCustomExclusionRule.php') =]]
docs/multisite/translations_management/extend_translations_management.md@148:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\TranslationsManagement;
006⫶
007⫶use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo;
008⫶use Ibexa\Contracts\TranslationsManagement\SideBySide\Service\SideBySideExclusionRuleInterface;
009⫶
010⫶final class MyCustomExclusionRule implements SideBySideExclusionRuleInterface
011⫶{
012⫶ public function isExcluded(ContentInfo $contentInfo): bool
013⫶ {
014⫶ return $contentInfo->getContentType()->identifier === 'my_excluded_type';
015⫶ }
016⫶}


code_samples/translations_management/src/TranslationsManagement/MyCustomLanguageCodeNormalizer.php


code_samples/translations_management/src/TranslationsManagement/MyCustomLanguageCodeNormalizer.php

docs/multisite/translations_management/extend_translations_management.md@64:``` php
docs/multisite/translations_management/extend_translations_management.md@65:[[= include_code('code_samples/translations_management/src/TranslationsManagement/MyCustomLanguageCodeNormalizer.php') =]]
docs/multisite/translations_management/extend_translations_management.md@66:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\TranslationsManagement;
006⫶
007⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Exception\UnsupportedLanguageException;
008⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Provider\LanguageNormalizer\LanguageNormalizerInterface;
009⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Provider\TranslationProviderInterface;
010⫶
011⫶final class MyCustomLanguageCodeNormalizer implements LanguageNormalizerInterface
012⫶{
013⫶ private const array LANGUAGE_MAP = [
014⫶ 'eng-GB' => 'en-GB',
015⫶ 'ger-DE' => 'de',
016⫶ 'fre-FR' => 'fr',
017⫶ ];
018⫶
019⫶ public function supports(TranslationProviderInterface $provider): bool
020⫶ {
021⫶ return $provider->getIdentifier() === 'my_custom_ai_provider';
022⫶ }
023⫶
024⫶ public function normalize(
025⫶ TranslationProviderInterface $provider,
026⫶ string $languageCode
027⫶ ): string {
028⫶ if (isset(self::LANGUAGE_MAP[$languageCode])) {
029⫶ return self::LANGUAGE_MAP[$languageCode];
030⫶ }
031⫶
032⫶ throw new UnsupportedLanguageException(
033⫶ $languageCode,
034⫶ $provider->getIdentifier(),
035⫶ array_values(self::LANGUAGE_MAP)
036⫶ );
037⫶ }
038⫶}


code_samples/translations_management/src/TranslationsManagement/MyCustomProvider.php


code_samples/translations_management/src/TranslationsManagement/MyCustomProvider.php

docs/multisite/translations_management/extend_translations_management.md@27:``` php hl_lines="36-49"
docs/multisite/translations_management/extend_translations_management.md@28:[[= include_code('code_samples/translations_management/src/TranslationsManagement/MyCustomProvider.php') =]]
docs/multisite/translations_management/extend_translations_management.md@29:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\TranslationsManagement;
006⫶
007⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\Provider\TranslationProviderInterface;
008⫶use Ibexa\Contracts\TranslationsManagement\AutoTranslate\TranslationDataInterface;
009⫶
010⫶final readonly class MyCustomProvider implements TranslationProviderInterface
011⫶{
012⫶ /**
013⫶ * Replace MyApiClient with your HTTP client, SDK wrapper, or any service
014⫶ * that communicates with the external translation API.
015⫶ */
016⫶ public function __construct(
017⫶ private MyApiClient $apiClient,
018⫶ ) {
019⫶ }
020⫶
021⫶ public function getIdentifier(): string
022⫶ {
023⫶ return 'my_custom_provider';
024⫶ }
025⫶
026⫶ public function getName(): string
027⫶ {
028⫶ return 'My Translation Service';
029⫶ }
030⫶
031⫶ public function getVendorName(): string
032⫶ {
033⫶ return 'My Company Ltd';
034⫶ }
035⫶
036❇️ public function translate(TranslationDataInterface $translationData): string
037❇️ {
038❇️ return $this->apiClient->translate(
039❇️ $translationData->getText(),
040❇️ $translationData->getSourceLanguage(),
041❇️ $translationData->getTargetLanguage()
042❇️ );
043❇️ }
044❇️
045❇️ /** @return array<string> */
046❇️ public function getSupportedLanguageCodes(): array
047❇️ {
048❇️ return ['eng-GB', 'ger-DE', 'fre-FR'];
049❇️ }
050⫶}

Download colorized diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants