diff --git a/code_samples/back_office/images/config/packages/views.yaml b/code_samples/back_office/images/config/packages/views.yaml index be4cc1200c..6d97f044e2 100644 --- a/code_samples/back_office/images/config/packages/views.yaml +++ b/code_samples/back_office/images/config/packages/views.yaml @@ -1,5 +1,5 @@ parameters: - ibexa..image_asset_view_defaults: + ibexa.site_access.config..image_asset_view_defaults: full: commons: template: '@@ibexadesign/commons_asset_view.html.twig' diff --git a/code_samples/back_office/images/config/services.yaml b/code_samples/back_office/images/config/services.yaml index 1fc1cc90dc..bc4f51e06b 100644 --- a/code_samples/back_office/images/config/services.yaml +++ b/code_samples/back_office/images/config/services.yaml @@ -8,18 +8,26 @@ services: - '@Ibexa\Core\Helper\TranslationHelper' App\Connector\Dam\Handler\WikimediaCommonsHandler: - arguments: - $httpClient: '@http_client' tags: - - { name: 'ibexa.platform.connector.dam.handler', source: 'commons' } + - { name: 'ibexa.platform.connector.dam.handler', source: 'commons' } - App\Connector\Dam\Transformation\TransformationFactory: - arguments: - $httpClient: '@http_client' + App\Connector\Dam\Transformation\WikimediaCommonsTransformationFactory: tags: - { name: 'ibexa.platform.connector.dam.transformation_factory', source: 'commons' } commons_asset_variation_generator: class: Ibexa\Connector\Dam\Variation\URLBasedVariationGenerator tags: - - { name: ibexa.platform.connector.dam.variation_generator, source: commons } + - { name: 'ibexa.platform.connector.dam.variation_generator', source: 'commons' } + + commons_search_tab: + class: Ibexa\Platform\Connector\Dam\View\Search\Tab\GenericSearchTab + public: false + arguments: + $identifier: 'commons' + $source: 'commons' + $name: 'Wikimedia Commons' + $searchFormType: 'Ibexa\Platform\Connector\Dam\Form\Search\GenericSearchType' + $formFactory: '@form.factory' + tags: + - { name: 'ibexa.admin_ui.tab', group: 'connector-dam-search' } diff --git a/code_samples/back_office/images/src/Connector/Dam/Handler/WikimediaCommonsHandler.php b/code_samples/back_office/images/src/Connector/Dam/Handler/WikimediaCommonsHandler.php index f22dccc157..32398396d8 100644 --- a/code_samples/back_office/images/src/Connector/Dam/Handler/WikimediaCommonsHandler.php +++ b/code_samples/back_office/images/src/Connector/Dam/Handler/WikimediaCommonsHandler.php @@ -35,10 +35,7 @@ public function search(Query $query, int $offset = 0, int $limit = 20): AssetSea $assets = []; foreach ($response['query']['search'] as $result) { $identifier = str_replace('File:', '', $result['title']); - $asset = $this->fetchAsset($identifier); - if ($asset) { - $assets[] = $asset; - } + $assets[] = $this->fetchAsset($identifier); } return new AssetSearchResult( @@ -47,7 +44,7 @@ public function search(Query $query, int $offset = 0, int $limit = 20): AssetSea ); } - public function fetchAsset(string $id): ?Asset + public function fetchAsset(string $id): Asset { $metadataUrl = 'https://commons.wikimedia.org/w/api.php?action=query&prop=imageinfo&iiprop=extmetadata&format=json' . '&titles=File%3a' . urlencode($id) @@ -55,17 +52,17 @@ public function fetchAsset(string $id): ?Asset $jsonResponse = file_get_contents($metadataUrl); if ($jsonResponse === false) { - return null; + throw new \RuntimeException('Couldn\'t retrieve asset metadata'); } $response = json_decode($jsonResponse, true); if (!isset($response['query']['pages'])) { - return null; + throw new \RuntimeException('Couldn\'t parse asset metadata'); } $pageData = array_values($response['query']['pages'])[0] ?? null; if (!isset($pageData['imageinfo'][0]['extmetadata'])) { - return null; + throw new \RuntimeException('Couldn\'t parse image asset metadata'); } $imageInfo = $pageData['imageinfo'][0]['extmetadata']; diff --git a/code_samples/back_office/images/src/Connector/Dam/Transformation/WikimediaCommonsTransformationFactory.php b/code_samples/back_office/images/src/Connector/Dam/Transformation/WikimediaCommonsTransformationFactory.php index 466739b9ae..7b46a12079 100644 --- a/code_samples/back_office/images/src/Connector/Dam/Transformation/WikimediaCommonsTransformationFactory.php +++ b/code_samples/back_office/images/src/Connector/Dam/Transformation/WikimediaCommonsTransformationFactory.php @@ -7,11 +7,20 @@ class WikimediaCommonsTransformationFactory implements TransformationFactoryInterface { - public function build(?string $transformationName = null, array $transformationParameters = []): ?Transformation + /** @param array $transformationParameters */ + public function build(?string $transformationName = null, array $transformationParameters = []): Transformation { + if (null === $transformationName) { + return new Transformation(null, array_map('strval', $transformationParameters)); + } + $transformations = $this->buildAll(); - return $transformations[$transformationName] ?? null; + if (array_key_exists($transformationName, $transformations)) { + return $transformations[$transformationName]; + } + + throw new \InvalidArgumentException(sprintf('Unknown transformation "%s".', $transformationName)); } public function buildAll(): array diff --git a/code_samples/back_office/images/translations/ibexa_fieldtypes_preview.en.yaml b/code_samples/back_office/images/translations/ibexa_fieldtypes_preview.en.yaml new file mode 100644 index 0000000000..c1cdfa4d4e --- /dev/null +++ b/code_samples/back_office/images/translations/ibexa_fieldtypes_preview.en.yaml @@ -0,0 +1,4 @@ +ezimageasset.dam_asset.page_url: Image page +ezimageasset.dam_asset.author: Image author +ezimageasset.dam_asset.license: License +ezimageasset.dam_asset.license_url: License page diff --git a/docs/content_management/images/add_image_asset_from_dam.md b/docs/content_management/images/add_image_asset_from_dam.md index 5de397327d..f66fb172bc 100644 --- a/docs/content_management/images/add_image_asset_from_dam.md +++ b/docs/content_management/images/add_image_asset_from_dam.md @@ -94,9 +94,11 @@ To extend the DAM support built into [[= product_name =]], you must create a cus ### Create DAM handler -This class handles searching through Wikimedia Commons for images and fetching assets. +This class handles searching through Wikimedia Commons for images and fetching image assets. -In `src\Connector\Dam\Handler` folder, create the `WikimediaCommonsHandler.php` file that resembles the following example, which uses `search()` and `fetchAsset()` functions to query the server for images and return asset objects, respectively: +In `src\Connector\Dam\Handler` folder, create the `WikimediaCommonsHandler.php` file that resembles the following example, +which implements [`search()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Connector-Dam-Handler-Handler.html#method_search) to query the server +and [`fetchAsset()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Connector-Dam-Handler-Handler.html#method_fetchAsset) to return asset objects: ```php [[= include_file('code_samples/back_office/images/src/Connector/Dam/Handler/WikimediaCommonsHandler.php') =]] @@ -105,15 +107,17 @@ In `src\Connector\Dam\Handler` folder, create the `WikimediaCommonsHandler.php` Then, in `config\services.yaml`, register the handler as a service: ```yaml -[[= include_file('code_samples/back_office/images/config/services.yaml', 9, 14) =]] +[[= include_file('code_samples/back_office/images/config/services.yaml', 9, 12) =]] ``` +The `source` parameter passed in the tag is an identifier of this new DAM connector and is used in other places to glue elements together. + ### Create transformation factory The transformation factory maps [[= product_name =]]'s image variations to corresponding variations from Wikimedia Commons. -In `src\Connector\Dam\Transformation` folder, create the `WikimediaCommonsTransformationFactory.php` file that resembles the following example: - +In `src\Connector\Dam\Transformation` folder, create the `WikimediaCommonsTransformationFactory.php` file that resembles the following example, +which implements the [`TransformationFactory` interface](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Connector-Dam-Variation-TransformationFactory.html): ```php [[= include_file('code_samples/back_office/images/src/Connector/Dam/Transformation/WikimediaCommonsTransformationFactory.php') =]] @@ -122,7 +126,7 @@ In `src\Connector\Dam\Transformation` folder, create the `WikimediaCommonsTransf Then register the transformation factory as a service: ```yaml -[[= include_file('code_samples/back_office/images/config/services.yaml', 15, 20) =]] +[[= include_file('code_samples/back_office/images/config/services.yaml', 13, 16) =]] ``` ### Register variations generator @@ -130,7 +134,7 @@ Then register the transformation factory as a service: The variation generator applies map parameters coming from the transformation factory to build a fetch request to the DAM. The solution uses the built-in `URLBasedVariationGenerator` class, which adds all the map elements as query parameters to the request. -For example, the handler generates the following URL with `new AssetUri()`: +For example, the handler generates the following URL with [`new AssetUri()`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-Connector-Dam-AssetUri.html#method___construct): `https://commons.wikimedia.org/w/index.php?title=Special:Redirect/file/Ibexa_Logo.svg` @@ -141,28 +145,57 @@ When the user requests a specific variation of the image, for example, "large", For this to happen, register the variations generator as a service: ```yaml -[[= include_file('code_samples/back_office/images/config/services.yaml', 21, 25) =]] +[[= include_file('code_samples/back_office/images/config/services.yaml', 17, 21) =]] ``` -### Create Twig template for Admin UI +### Set tab for "Select from DAM" modal + +To select an image from the DAM, a modal window pop in with tabs & panels for different search sub-interfaces. + +In this example, the search only use the main text input. +Its tab and its corresponding panel are a service created by combining existing components (as many [back office tabs](back_office_tabs.md)). + +The tab service uses directly the dedicated base tab `GenericSearchTab`, +passes it the dedicated base form `GenericSearchType`, +links it to `commons` DAM source, +is identified as `commons`, +is tagged with `ibexa.admin_ui.tab` tag, +and set in the `connector-dam-search` [tab group](back_office_tabs.md#tab-groups). + +```yaml +[[= include_file('code_samples/back_office/images/config/services.yaml', 22, 33) =]] +``` -The template defines how images that come from Wikimedia Commons appear in the back office. +### Create Twig template -In `templates/bundles/WikimediaCommonsConnector/`, add the `commons_asset_view.html.twig` file that resembles the following example: +The template defines how images that come from Wikimedia Commons appear. + +In `templates/themes/standard/`, add the `commons_asset_view.html.twig` file that resembles the following example: ```html+twig [[= include_file('code_samples/back_office/images/templates/themes/standard/commons_asset_view.html.twig') =]] ``` -Then, register the template and a fallback template in configuration files: +Then, register the template and a fallback template in configuration files +(replace `` with [appropriate value](siteaccess_aware_configuration.md) like `default` so it's used everywhere including the back office): ```yaml [[= include_file('code_samples/back_office/images/config/packages/views.yaml') =]] ``` +### Provide back office translation + +In the back office, an image asset field is displayed followed by a table of metadata. + +As some new specific ones are used in this example, some new translations are needed. + +```yaml +[[= include_file('code_samples/back_office/images/translations/ibexa_fieldtypes_preview.en.yaml') =]] +``` + ### Add Wikimedia Commons connection to DAM configuration -You can now configure a connection with Wikimedia Commons under the `ibexa.system..content.dam` key: +You can now configure a connection with Wikimedia Commons under the `ibexa.system..content.dam` key using the source identifier `commons`: ```yaml ibexa: