1 Commits

Author SHA1 Message Date
Jérémy J
bc672e136b Ibexa 5.x support 2025-11-05 14:06:22 +01:00
39 changed files with 337 additions and 250 deletions

View File

@@ -30,13 +30,17 @@
outline: none;
}
}
.row .col-1 {
padding: 0;
}
}
.imagemap-go-up {
height: 0;
position: sticky;
top: 10px;
margin-left: -60px;
margin-left: -42px;
svg {
width: 50px;

View File

@@ -106,7 +106,7 @@ const initImageMap = function (imageMap) {
const prototype = areas.parentNode.dataset.prototype;
const map = imageMap.querySelector('.imagemap-map');
const image = imageMap.querySelector('.ez-field-edit-preview__media');
const image = imageMap.querySelector('.ibexa-field-edit-preview__media');
const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const draw = SVG(svg);
const parent = image.parentNode;
@@ -168,6 +168,18 @@ const initArea = function (area, map, draw) {
target.querySelector('option[value="popin"]').hidden = true;
}
const dropdowns = area.querySelectorAll('.ibexa-dropdown');
dropdowns.forEach((dropdownContainer) => {
if (dropdownContainer.ibexaInstance) {
return;
}
const dropdown = new window.ibexa.core.Dropdown({
container: dropdownContainer,
});
dropdown.init();
});
recreateShape(area, draw);
}
@@ -227,26 +239,23 @@ const changeLinkType = function (area) {
}
}
const confirmUDW = function (widget, container, e) {
const confirmUDW = function (widget, udwRoot, e) {
const source = widget.querySelector('.imagemap-relation-source');
source.value = 'ezobject://'+e[0].ContentInfo.Content._id;
widget.querySelector('.imagemap-relation-name').textContent = e[0].ContentInfo.Content.TranslatedName;
ReactDOM.unmountComponentAtNode(container);
udwRoot.unmount();
}
const showUDW = function (config, widget) {
const container = document.querySelector('#react-udw');
const token = document.querySelector('meta[name="CSRF-Token"]').content;
const siteaccess = document.querySelector('meta[name="SiteAccess"]').content;
ReactDOM.render(React.createElement(eZ.modules.UniversalDiscovery, {
restInfo: {
token,
siteaccess,
},
onConfirm: confirmUDW.bind(null, widget, container),
onCancel: () => ReactDOM.unmountComponentAtNode(container),
...config
}), container);
const udwRoot = window.ReactDOMClient.createRoot(container);
udwRoot.render(
React.createElement(window.ibexa.modules.UniversalDiscovery, {
onConfirm: confirmUDW.bind(null, widget, udwRoot),
onCancel: () => udwRoot.unmount(),
...config,
}),
);
}
const initUDW = function (widget) {

View File

@@ -1,6 +1,6 @@
{
"name": "onisep/ibexa-imagemap-bundle",
"description": "Image map field type for Ibexa 3.3",
"description": "Image map field type for Ibexa 5.0+",
"type": "symfony-bundle",
"keywords": ["ibexa", "image map"],
"license": "MIT",
@@ -34,14 +34,22 @@
}
},
"require": {
"php": ">=7.4",
"php": ">=8.3",
"ext-json": "*",
"ezsystems/ezplatform-admin-ui": "^2.3",
"ezsystems/ezplatform-kernel": "^1.3"
"guzzlehttp/promises": "^2.3",
"ibexa/admin-ui": "^5.0",
"ibexa/core": "^5.0",
"nyholm/psr7": "^1.8"
},
"minimum-stability": "dev",
"prefer-stable": true,
"config": {
"sort-packages": true
"sort-packages": true,
"allow-plugins": {
"php-http/discovery": true
}
},
"require-dev": {
"ibexa/rector": "^5.0"
}
}

View File

@@ -23,5 +23,8 @@
"dev": "encore dev",
"watch": "encore dev --watch",
"build": "encore production"
},
"dependencies": {
"core-js": "^3.46.0"
}
}

45
rector.php Normal file
View File

@@ -0,0 +1,45 @@
<?php
use Ibexa\Contracts\Rector\Sets\IbexaSetList;
use Rector\Config\RectorConfig;
use Rector\Symfony\Set\SymfonySetList;
return RectorConfig::configure()
->withPaths(
[
__DIR__ . '/src',
]
)
->withSets(
[
IbexaSetList::IBEXA_50->value,
SymfonySetList::SYMFONY_54, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-54
SymfonySetList::SYMFONY_60, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-60
SymfonySetList::SYMFONY_61, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-61
SymfonySetList::SYMFONY_62, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-62
SymfonySetList::SYMFONY_63, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-63
SymfonySetList::SYMFONY_64, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-64
SymfonySetList::SYMFONY_70, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-70
SymfonySetList::SYMFONY_71, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-71
SymfonySetList::SYMFONY_72, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-72
SymfonySetList::SYMFONY_73, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-symfonysymfony-73
SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES,
]
)
->withPhpSets()
->withComposerBased(twig: true, symfony: true)
->withAttributesSets(symfony: true, sensiolabs: true)
->withPreparedSets(
deadCode: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-dead-code
codeQuality: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-code-quality
codingStyle: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-coding-style
typeDeclarations: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-type-declarations
privatization: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-privatization
naming: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-naming
instanceOf: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-instanceof
earlyReturn: true, // https://getrector.com/find-rule?activeRectorSetGroup=core&rectorSet=core-early-return
rectorPreset: true,
symfonyCodeQuality: true, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-code-quality
symfonyConfigs: true, // https://getrector.com/find-rule?activeRectorSetGroup=symfony&rectorSet=symfony-configs
)
;

View File

@@ -6,57 +6,43 @@ namespace Onisep\IbexaImageMapBundle\Command;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\DBAL\Schema\Table;
use Onisep\IbexaImageMapBundle\Database\ImageMapRepository;
use Onisep\IbexaImageMapBundle\Database\SchemaProvider;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Attribute\Option;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class SchemaCommand extends Command
#[AsCommand(name: 'onisep:imagemap:dump-schema', description: 'Generates schema create / update SQL queries', help: <<<'TXT'
The <info>%command.name%</info> help you to generate SQL Query to create or update your database schema for this bundle
TXT)]
class SchemaCommand
{
protected static $defaultName = 'onisep:imagemap:dump-schema';
private Connection $connection;
public function __construct(Connection $connection)
public function __construct(private readonly Connection $connection)
{
parent::__construct();
$this->connection = $connection;
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$this
->setDescription('Generates schema create / update SQL queries')
->setHelp('The <info>%command.name%</info> help you to generate SQL Query to create or update your database schema for this bundle')
->addOption('update', null, InputOption::VALUE_NONE, 'Dump only the update SQL queries.')
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
public function __invoke(
#[Option(description: 'Dump only the update SQL queries.', name: 'update')]
bool $update = false,
?SymfonyStyle $symfonyStyle = null
): int
{
$schemaProvider = new SchemaProvider();
$schema = $schemaProvider->createSchema();
$sqls = $schema->toSql($this->connection->getDatabasePlatform());
if ($input->getOption('update')) {
if ($update) {
$sm = $this->connection->getSchemaManager();
$tableArray = [ImageMapRepository::TABLE_NAME];
$tables = [];
foreach ($sm->listTables() as $table) {
/** @var Table $table */
/** @var \Doctrine\DBAL\Schema\Table $table */
if (in_array($table->getName(), $tableArray)) {
$tables[] = $table;
}
@@ -78,11 +64,9 @@ class SchemaCommand extends Command
$sqls = $schema->getMigrateFromSql($oldSchema, $this->connection->getDatabasePlatform());
}
$io = new SymfonyStyle($input, $output);
$io->text('Execute these SQL Queries on your database:');
$symfonyStyle->text('Execute these SQL Queries on your database:');
foreach ($sqls as $sql) {
$io->text($sql.';');
$symfonyStyle->text($sql.';');
}
return 0;

View File

@@ -4,20 +4,40 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\DataTransformer;
use EzSystems\EzPlatformContentForms\FieldType\DataTransformer\ImageValueTransformer;
use Ibexa\ContentForms\FieldType\DataTransformer\AbstractBinaryBaseTransformer;
use Onisep\IbexaImageMapBundle\FieldType\ImageMap\Value;
use Symfony\Component\Form\DataTransformerInterface;
class ImageMapTransformer extends ImageValueTransformer
class ImageMapTransformer extends AbstractBinaryBaseTransformer implements DataTransformerInterface
{
public function transform($value)
#[\Override]
public function transform(mixed $value): array
{
return ['map' => $value->map] + parent::transform($value);
if (null === $value) {
$value = $this->fieldType->getEmptyValue();
}
return array_merge(
$this->getDefaultProperties(),
[
'alternativeText' => $value->alternativeText,
'additionalData' => $value->additionalData,
'map' => $value->map,
]
);
}
public function reverseTransform($value)
#[\Override]
public function reverseTransform(mixed $value): Value
{
/** @var Value $valueObject */
$valueObject = parent::reverseTransform($value);
$valueObject = $this->getReverseTransformedValue($value);
if (!$this->fieldType->isEmptyValue($valueObject)) {
$valueObject->alternativeText = $value['alternativeText'];
$valueObject->additionalData = $value['additionalData'];
}
$valueObject->map = $value['map'];
return $valueObject;

View File

@@ -9,13 +9,10 @@ use Doctrine\DBAL\Types\Types;
class ImageMapRepository
{
public const TABLE_NAME = 'onisep_imagemap';
public const string TABLE_NAME = 'onisep_imagemap';
private Connection $connection;
public function __construct(Connection $connection)
public function __construct(private readonly Connection $connection)
{
$this->connection = $connection;
}
public function create(int $fieldId, int $version, array $map): void
@@ -47,17 +44,17 @@ class ImageMapRepository
public function get(int $fieldId, int $version): ?array
{
$query = $this->connection->createQueryBuilder();
$query
$queryBuilder = $this->connection->createQueryBuilder();
$queryBuilder
->select('map')
->from(self::TABLE_NAME)
->where('field_id = :fieldId')
->andWhere('version = :version')
->setParameter(':fieldId', $fieldId)
->setParameter(':version', $version)
->setParameter('fieldId', $fieldId)
->setParameter('version', $version)
;
$results = $query->execute()->fetchOne();
$results = $queryBuilder->executeQuery()->fetchOne();
return $results ? json_decode($results, true) : null;
}

View File

@@ -9,22 +9,22 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
class AddDefaultViewTemplatePass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
$parameter = $container->getParameter('ezsettings.default.content_view_defaults');
$parameter = $container->getParameter('ibexa.site_access.config.default.content_view_defaults');
$parameter['imagemap_embed'] = [
'default' => [
'template' => '@ezdesign/default/content/imagemap_embed.html.twig',
'template' => '@ibexadesign/default/content/imagemap_embed.html.twig',
'match' => [],
],
];
$parameter['imagemap_popin'] = [
'default' => [
'template' => '@ezdesign/default/content/imagemap_popin.html.twig',
'template' => '@ibexadesign/default/content/imagemap_popin.html.twig',
'match' => [],
],
];
$container->setParameter('ezsettings.default.content_view_defaults', $parameter);
$container->setParameter('ibexa.site_access.config.default.content_view_defaults', $parameter);
}
}

View File

@@ -14,17 +14,17 @@ use Symfony\Component\Yaml\Yaml;
class OnisepImageMapExtension extends Extension implements PrependExtensionInterface
{
public function load(array $configs, ContainerBuilder $container)
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yaml');
$yamlFileLoader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$yamlFileLoader->load('services.yaml');
}
public function prepend(ContainerBuilder $container)
public function prepend(ContainerBuilder $container): void
{
$adminUiFormsConfigFile = __DIR__.'/../Resources/config/admin_ui_forms.yaml';
$config = Yaml::parseFile($adminUiFormsConfigFile);
$container->prependExtensionConfig('ezpublish', $config);
$container->prependExtensionConfig('ibexa', $config);
$container->addResource(new FileResource($adminUiFormsConfigFile));
}
}

View File

@@ -4,18 +4,20 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\FieldType\ImageMap;
use eZ\Publish\Core\FieldType\FieldSettings;
use eZ\Publish\Core\Persistence\Legacy\Content\FieldValue\Converter\ImageConverter;
use eZ\Publish\Core\Persistence\Legacy\Content\StorageFieldDefinition;
use eZ\Publish\SPI\Persistence\Content\Type\FieldDefinition;
use Ibexa\Core\FieldType\FieldSettings;
use Ibexa\Core\Persistence\Legacy\Content\FieldValue\Converter\ImageConverter;
use Ibexa\Core\Persistence\Legacy\Content\StorageFieldDefinition;
use Ibexa\Contracts\Core\Persistence\Content\Type\FieldDefinition;
class FieldValueConverter extends ImageConverter
{
#[\Override]
public function toStorageFieldDefinition(FieldDefinition $fieldDef, StorageFieldDefinition $storageDef): void
{
$storageDef->dataText5 = serialize($fieldDef->fieldTypeConstraints->fieldSettings['selectionContentTypes'] ?? []);
}
#[\Override]
public function toFieldDefinition(StorageFieldDefinition $storageDef, FieldDefinition $fieldDef): void
{
$fieldDef->fieldTypeConstraints->fieldSettings = new FieldSettings([

View File

@@ -4,22 +4,19 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\FieldType\ImageMap\ImageMapStorage\Gateway;
use eZ\Publish\SPI\Persistence\Content\Field;
use eZ\Publish\SPI\Persistence\Content\VersionInfo;
use Ibexa\Contracts\Core\Persistence\Content\Field;
use Ibexa\Contracts\Core\Persistence\Content\VersionInfo;
use Onisep\IbexaImageMapBundle\Database\ImageMapRepository;
class LegacyStorage
{
private ImageMapRepository $repository;
public function __construct(ImageMapRepository $repository)
public function __construct(private readonly ImageMapRepository $imageMapRepository)
{
$this->repository = $repository;
}
public function getMap(int $fieldId, int $version): ?array
{
return $this->repository->get($fieldId, $version);
return $this->imageMapRepository->get($fieldId, $version);
}
public function saveMap(VersionInfo $versionInfo, Field $field): void
@@ -27,14 +24,14 @@ class LegacyStorage
$fieldId = $field->id;
$version = $versionInfo->versionNo;
$exists = $this->repository->get($fieldId, $version);
$exists = $this->imageMapRepository->get($fieldId, $version);
if ($exists) {
$this->repository->update($fieldId, $version, $field->value->data['map']);
$this->imageMapRepository->update($fieldId, $version, $field->value->data['map']);
return;
}
$this->repository->create($fieldId, $version, $field->value->data['map']);
$this->imageMapRepository->create($fieldId, $version, $field->value->data['map']);
}
}

View File

@@ -4,16 +4,15 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\FieldType\ImageMap;
use eZ\Publish\Core\Base\Utils\DeprecationWarnerInterface as DeprecationWarner;
use eZ\Publish\Core\FieldType\Image\AliasCleanerInterface;
use eZ\Publish\Core\FieldType\Image\ImageStorage;
use eZ\Publish\Core\FieldType\Image\ImageStorage\Gateway as ImageStorageGateway;
use eZ\Publish\Core\FieldType\Image\PathGenerator;
use eZ\Publish\Core\IO\FilePathNormalizerInterface;
use eZ\Publish\Core\IO\IOServiceInterface;
use eZ\Publish\Core\IO\MetadataHandler;
use eZ\Publish\SPI\Persistence\Content\Field;
use eZ\Publish\SPI\Persistence\Content\VersionInfo;
use Ibexa\Contracts\Core\Persistence\Content\Field;
use Ibexa\Contracts\Core\Persistence\Content\VersionInfo;
use Ibexa\Core\FieldType\Image\AliasCleanerInterface;
use Ibexa\Core\FieldType\Image\ImageStorage;
use Ibexa\Core\FieldType\Image\ImageStorage\Gateway as ImageStorageGateway;
use Ibexa\Core\FieldType\Image\PathGenerator;
use Ibexa\Core\FieldType\Validator\FileExtensionBlackListValidator;
use Ibexa\Core\IO\FilePathNormalizerInterface;
use Ibexa\Core\IO\IOServiceInterface;
use Onisep\IbexaImageMapBundle\FieldType\ImageMap\ImageMapStorage\Gateway\LegacyStorage as ImageMapStorageGateway;
/**
@@ -21,41 +20,38 @@ use Onisep\IbexaImageMapBundle\FieldType\ImageMap\ImageMapStorage\Gateway\Legacy
*/
class Storage extends ImageStorage
{
private ImageMapStorageGateway $imageMapGateway;
public function __construct(
ImageStorageGateway $baseGateway,
IOServiceInterface $IOService,
IOServiceInterface $ioService,
PathGenerator $pathGenerator,
MetadataHandler $imageSizeMetadataHandler,
DeprecationWarner $deprecationWarner,
ImageMapStorageGateway $imageMapGateway,
AliasCleanerInterface $aliasCleaner,
FilePathNormalizerInterface $filePathNormalizer
FilePathNormalizerInterface $filePathNormalizer,
FileExtensionBlackListValidator $fileExtensionBlackListValidator,
private readonly ImageMapStorageGateway $imageMapStorageGateway,
) {
parent::__construct($baseGateway, $IOService, $pathGenerator, $imageSizeMetadataHandler, $deprecationWarner, $aliasCleaner, $filePathNormalizer);
$this->imageMapGateway = $imageMapGateway;
parent::__construct($baseGateway, $ioService, $pathGenerator, $aliasCleaner, $filePathNormalizer, $fileExtensionBlackListValidator);
}
public function storeFieldData(VersionInfo $versionInfo, Field $field, array $context)
#[\Override]
public function storeFieldData(VersionInfo $versionInfo, Field $field): bool
{
if (isset($field->value->data['fileName']) || isset($field->value->externalData['fileName'])) {
parent::storeFieldData($versionInfo, $field, $context);
parent::storeFieldData($versionInfo, $field);
}
if (isset($field->value->data['map'])) {
$this->imageMapGateway->saveMap($versionInfo, $field);
$this->imageMapStorageGateway->saveMap($versionInfo, $field);
}
return true;
}
public function getFieldData(VersionInfo $versionInfo, Field $field, array $context)
#[\Override]
public function getFieldData(VersionInfo $versionInfo, Field $field): void
{
parent::getFieldData($versionInfo, $field, $context);
parent::getFieldData($versionInfo, $field);
$map = $this->imageMapGateway->getMap($field->id, $versionInfo->versionNo);
$map = $this->imageMapStorageGateway->getMap($field->id, $versionInfo->versionNo);
$field->value->data['map'] = $map;
}

View File

@@ -4,30 +4,34 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\FieldType\ImageMap;
use eZ\Publish\Core\FieldType\Image\Type as ImageType;
use eZ\Publish\SPI\FieldType\Value as SPIValue;
use eZ\Publish\SPI\Persistence\Content\FieldValue as PersistenceValue;
use Ibexa\Core\FieldType\Image\Type as ImageType;
use Ibexa\Contracts\Core\FieldType\Value as SPIValue;
use Ibexa\Contracts\Core\Persistence\Content\FieldValue as PersistenceValue;
/**
* The ImageMap field type.
*/
class Type extends ImageType
{
public function getFieldTypeIdentifier()
#[\Override]
public function getFieldTypeIdentifier(): string
{
return 'imagemap';
}
public function validateFieldSettings($fieldSettings)
#[\Override]
public function validateFieldSettings($fieldSettings): array
{
return [];
}
#[\Override]
public function fromHash($hash)
{
return empty($hash) ? $this->getEmptyValue() : new Value($hash);
}
#[\Override]
public function toHash(SPIValue $value)
{
$parentHash = parent::toHash($value);
@@ -38,11 +42,13 @@ class Type extends ImageType
return $parentHash + ['map' => $value->map];
}
#[\Override]
public function getEmptyValue()
{
return new Value();
}
#[\Override]
public function fromPersistenceValue(PersistenceValue $fieldValue)
{
if (null === $fieldValue->data) {

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\FieldType\ImageMap;
use eZ\Publish\Core\FieldType\Image\Value as ImageValue;
use Ibexa\Core\FieldType\Image\Value as ImageValue;
/**
* Value for ImageMap field type.

View File

@@ -4,18 +4,19 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\Form;
use EzSystems\EzPlatformContentForms\Form\Type\FieldType\ImageFieldType;
use Ibexa\ContentForms\Form\Type\FieldType\ImageFieldType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class ImageMapType extends AbstractType
{
public function getParent()
#[\Override]
public function getParent(): ?string
{
return ImageFieldType::class;
}
public function buildForm(FormBuilderInterface $builder, array $options)
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('map', MapAreasType::class, [
@@ -32,7 +33,8 @@ class ImageMapType extends AbstractType
;
}
public function getBlockPrefix()
#[\Override]
public function getBlockPrefix(): string
{
return 'imagemap';
}

View File

@@ -4,7 +4,7 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\Form;
use eZ\Publish\API\Repository\ContentService;
use Ibexa\Contracts\Core\Repository\ContentService;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormInterface;
@@ -12,30 +12,29 @@ use Symfony\Component\Form\FormView;
class LinkType extends AbstractType
{
private ContentService $contentService;
public function __construct(ContentService $contentService)
public function __construct(private readonly ContentService $contentService)
{
$this->contentService = $contentService;
}
public function getParent()
#[\Override]
public function getParent(): ?string
{
return TextType::class;
}
public function getBlockPrefix()
#[\Override]
public function getBlockPrefix(): string
{
return 'imagemap_link';
}
public function buildView(FormView $view, FormInterface $form, array $options)
public function buildView(FormView $view, FormInterface $form, array $options): void
{
$content = null;
if (preg_match('~^ezobject://~', $form->getData() ?? '')) {
try {
$content = $this->contentService->loadContent((int) substr($form->getData(), 11));
} catch (\Throwable $e) {
$content = $this->contentService->loadContent((int) substr((string) $form->getData(), 11));
} catch (\Throwable) {
// Not found, do nothing.
}
}

View File

@@ -12,7 +12,7 @@ use Symfony\Component\Form\FormBuilderInterface;
class MapAreaType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('shape', ChoiceType::class, [
@@ -50,7 +50,8 @@ class MapAreaType extends AbstractType
;
}
public function getBlockPrefix()
#[\Override]
public function getBlockPrefix(): string
{
return 'imagemap_map_area';
}

View File

@@ -9,12 +9,14 @@ use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class MapAreasType extends AbstractType
{
public function getParent()
#[\Override]
public function getParent(): ?string
{
return CollectionType::class;
}
public function getBlockPrefix()
#[\Override]
public function getBlockPrefix(): string
{
return 'imagemap_map_areas';
}

View File

@@ -4,13 +4,13 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\FormMapper;
use eZ\Publish\API\Repository\ContentTypeService;
use eZ\Publish\API\Repository\FieldTypeService;
use eZ\Publish\API\Repository\LocationService;
use EzSystems\EzPlatformAdminUi\FieldType\Mapper\AbstractRelationFormMapper;
use EzSystems\EzPlatformAdminUi\Form\Data\FieldDefinitionData;
use EzSystems\EzPlatformContentForms\Data\Content\FieldData;
use EzSystems\EzPlatformContentForms\FieldType\FieldValueFormMapperInterface;
use Ibexa\Contracts\Core\Repository\ContentTypeService;
use Ibexa\Contracts\Core\Repository\FieldTypeService;
use Ibexa\Contracts\Core\Repository\LocationService;
use Ibexa\AdminUi\FieldType\Mapper\AbstractRelationFormMapper;
use Ibexa\AdminUi\Form\Data\FieldDefinitionData;
use Ibexa\Contracts\ContentForms\Data\Content\FieldData;
use Ibexa\Contracts\ContentForms\FieldType\FieldValueFormMapperInterface;
use Onisep\IbexaImageMapBundle\DataTransformer\ImageMapTransformer;
use Onisep\IbexaImageMapBundle\FieldType\ImageMap\Value;
use Onisep\IbexaImageMapBundle\Form\ImageMapType;
@@ -19,16 +19,12 @@ use Symfony\Component\Form\FormInterface;
class ImageMapFormMapper extends AbstractRelationFormMapper implements FieldValueFormMapperInterface
{
private FieldTypeService $fieldTypeService;
public function __construct(
ContentTypeService $contentTypeService,
LocationService $locationService,
FieldTypeService $fieldTypeService
private readonly FieldTypeService $fieldTypeService
) {
parent::__construct($contentTypeService, $locationService);
$this->fieldTypeService = $fieldTypeService;
}
public function mapFieldDefinitionForm(FormInterface $fieldDefinitionForm, FieldDefinitionData $data): void
@@ -41,17 +37,17 @@ class ImageMapFormMapper extends AbstractRelationFormMapper implements FieldValu
'multiple' => true,
'required' => false,
'property_path' => 'fieldSettings[selectionContentTypes]',
'label' => 'field_definition.ezobjectrelationlist.selection_content_types',
'label' => 'field_definition.ibexa_object_relation_list.selection_content_types',
'disabled' => $isTranslation,
])
;
}
public function mapFieldValueForm(FormInterface $fieldForm, FieldData $data)
public function mapFieldValueForm(FormInterface $fieldForm, FieldData $data): void
{
$fieldDefinition = $data->fieldDefinition;
$fieldDefinition = $data->getFieldDefinition();
$formConfig = $fieldForm->getConfig();
$fieldType = $this->fieldTypeService->getFieldType($fieldDefinition->fieldTypeIdentifier);
$fieldType = $this->fieldTypeService->getFieldType($fieldDefinition->getFieldTypeIdentifier());
$fieldForm
->add(
@@ -60,12 +56,12 @@ class ImageMapFormMapper extends AbstractRelationFormMapper implements FieldValu
'value',
ImageMapType::class,
[
'required' => $fieldDefinition->isRequired,
'required' => $fieldDefinition->isRequired(),
'label' => $fieldDefinition->getName(),
'is_alternative_text_required' => false,
]
)
->addModelTransformer(new ImageMapTransformer($fieldType, $data->value, Value::class))
->addModelTransformer(new ImageMapTransformer($fieldType, $data->getValue(), Value::class))
->setAutoInitialize(false)
->getForm()
);

View File

@@ -11,13 +11,14 @@ use Symfony\Component\HttpKernel\Bundle\Bundle;
class OnisepImageMapBundle extends Bundle
{
protected $name = 'OnisepImageMapBundle';
protected string $name = 'OnisepImageMapBundle';
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container): void
{
$container->addCompilerPass(new AddDefaultViewTemplatePass());
}
#[\Override]
protected function getContainerExtensionClass(): string
{
return OnisepImageMapExtension::class;

View File

@@ -1,9 +1,10 @@
system:
admin_group:
admin_ui_forms:
content_edit_form_templates:
- { template: '@ezdesign/content/imagemap_form_fields.html.twig', priority: 1 }
content_edit:
form_templates:
- {template: '@ibexadesign/content/imagemap_form_fields.html.twig', priority: 1}
default:
field_templates:
- { template: '@ezdesign/fields/imagemap_content_fields.html.twig', priority: 0 }
- {template: '@ibexadesign/fields/imagemap_content_fields.html.twig', priority: 0}

View File

@@ -1,51 +1,54 @@
services:
Onisep\IbexaImageMapBundle\FieldType\ImageMap\Type:
arguments:
- ['@ezpublish.fieldType.validator.black_list', '@ezpublish.fieldType.validator.image']
parent: ezpublish.fieldType
$validators:
- '@Ibexa\Core\FieldType\Validator\FileExtensionBlackListValidator'
- '@Ibexa\Core\FieldType\Validator\ImageValidator'
parent: Ibexa\Core\FieldType\FieldType
tags:
- { name: ezplatform.field_type, alias: imagemap }
- {name: ibexa.field_type, alias: imagemap}
Onisep\IbexaImageMapBundle\FieldType\ImageMap\Storage:
arguments:
- '@ezpublish.fieldType.ezimage.storage_gateway'
- '@ezpublish.fieldType.ezimage.io_service'
- '@ezpublish.fieldType.ezimage.pathGenerator'
- '@ezpublish.fieldType.metadataHandler.imagesize'
- '@ezpublish.utils.deprecation_warner'
- '@Onisep\IbexaImageMapBundle\FieldType\ImageMap\ImageMapStorage\Gateway\LegacyStorage'
- '@?ezpublish.image_alias.imagine.alias_cleaner'
- '@eZ\Publish\Core\IO\FilePathNormalizerInterface'
$baseGateway: '@Ibexa\Core\FieldType\Image\ImageStorage\Gateway\DoctrineStorage'
$ioService: '@Ibexa\Core\FieldType\Image\IO\Legacy'
$pathGenerator: '@Ibexa\Core\FieldType\Image\PathGenerator\LegacyPathGenerator'
$aliasCleaner: '@Ibexa\Core\FieldType\Image\AliasCleanerInterface'
$filePathNormalizer: '@Ibexa\Core\IO\FilePathNormalizerInterface'
$fileExtensionBlackListValidator: '@Ibexa\Core\FieldType\Validator\FileExtensionBlackListValidator'
$imageMapStorageGateway: '@Onisep\IbexaImageMapBundle\FieldType\ImageMap\ImageMapStorage\Gateway\LegacyStorage'
tags:
- { name: ezplatform.field_type.external_storage_handler, alias: imagemap }
- {name: ibexa.field_type.storage.external.handler, alias: imagemap}
Onisep\IbexaImageMapBundle\FieldType\ImageMap\FieldValueConverter:
arguments:
- '@ezpublish.fieldType.ezimage.io_service'
- '@ezpublish.core.io.image_fieldtype.legacy_url_redecorator'
$imageIoService: '@Ibexa\Core\FieldType\Image\IO\Legacy'
$urlRedecorator: '@Ibexa\Core\IO\UrlRedecorator'
tags:
- { name: ezplatform.field_type.legacy_storage.converter, alias: imagemap, lazy: true, callback: '::create' }
- {name: ibexa.field_type.storage.legacy.converter, alias: imagemap, lazy: true, callback: '::create'}
Onisep\IbexaImageMapBundle\FieldType\ImageMap\ImageMapStorage\Gateway\LegacyStorage:
arguments: ['@Onisep\IbexaImageMapBundle\Database\ImageMapRepository']
arguments:
$imageMapRepository: '@Onisep\IbexaImageMapBundle\Database\ImageMapRepository'
tags:
- { name: ezplatform.field_type.external_storage_handler.gateway, alias: imagemap, identifier: LegacyStorage }
- {name: ibexa.field_type.storage.external.handler.gateway, alias: imagemap, identifier: LegacyStorage}
Onisep\IbexaImageMapBundle\Database\ImageMapRepository:
arguments: ['@ezpublish.persistence.connection']
arguments:
$connection: '@ibexa.persistence.connection'
Onisep\IbexaImageMapBundle\Twig\ImageMapExtension:
tags: ['twig.extension']
Onisep\IbexaImageMapBundle\Twig\ImageMapRuntime:
arguments:
$locationService: '@eZ\Publish\API\Repository\LocationService'
$contentService: '@eZ\Publish\API\Repository\ContentService'
$locationService: '@Ibexa\Contracts\Core\Repository\LocationService'
$contentService: '@Ibexa\Contracts\Core\Repository\ContentService'
tags: ['twig.runtime']
Onisep\IbexaImageMapBundle\Form\LinkType:
arguments:
$contentService: '@eZ\Publish\API\Repository\ContentService'
$contentService: '@Ibexa\Contracts\Core\Repository\ContentService'
tags: ['form.type']
Onisep\IbexaImageMapBundle\Form\MapAreaType:
@@ -59,19 +62,19 @@ services:
Onisep\IbexaImageMapBundle\FormMapper\ImageMapFormMapper:
arguments:
$contentTypeService: '@eZ\Publish\API\Repository\ContentTypeService'
$locationService: '@eZ\Publish\API\Repository\LocationService'
$fieldTypeService: '@eZ\Publish\API\Repository\FieldTypeService'
$contentTypeService: '@Ibexa\Contracts\Core\Repository\ContentTypeService'
$locationService: '@Ibexa\Contracts\Core\Repository\LocationService'
$fieldTypeService: '@Ibexa\Contracts\Core\Repository\FieldTypeService'
tags:
- { name: ezplatform.field_type.form_mapper.definition, fieldType: imagemap }
- { name: ezplatform.field_type.form_mapper.value, fieldType: imagemap }
- {name: ibexa.admin_ui.field_type.form.mapper.definition, fieldType: imagemap}
- {name: ibexa.admin_ui.field_type.form.mapper.value, fieldType: imagemap}
Onisep\IbexaImageMapBundle\Command\SchemaCommand:
arguments:
$connection: '@ezpublish.persistence.connection'
$connection: '@ibexa.persistence.connection'
tags: ['console.command']
onisep.imagemap.unindexed:
class: eZ\Publish\Core\FieldType\Unindexed
class: Ibexa\Core\FieldType\Unindexed
tags:
- { name: ezplatform.field_type.indexable, alias: imagemap }
- {name: ibexa.field_type.indexable, alias: imagemap}

View File

@@ -1,23 +1,23 @@
const path = require('path');
module.exports = (eZConfig, eZConfigManager) => {
eZConfigManager.add({
eZConfig,
entryName: 'ezplatform-admin-ui-content-edit-parts-js',
module.exports = (ibexaConfig, ibexaConfigManager) => {
ibexaConfigManager.add({
ibexaConfig,
entryName: 'ibexa-admin-ui-content-edit-parts-js',
newItems: [
path.resolve(__dirname, '../public/build/imagemap_edit.js'),
],
});
eZConfigManager.add({
eZConfig,
entryName: 'ezplatform-admin-ui-layout-js',
ibexaConfigManager.add({
ibexaConfig,
entryName: 'ibexa-admin-ui-layout-js',
newItems: [
path.resolve(__dirname, '../public/build/imagemap.js'),
],
});
eZConfigManager.add({
eZConfig,
entryName: 'ezplatform-admin-ui-layout-css',
ibexaConfigManager.add({
ibexaConfig,
entryName: 'ibexa-admin-ui-layout-css',
newItems: [
path.resolve(__dirname, '../public/build/imagemap_edit_styles.css'),
path.resolve(__dirname, '../public/build/imagemap_styles.css'),

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
.imagemap-area{border:2px dashed #dbdbdb;border-radius:.25rem;padding:1rem;position:relative}.imagemap-area .imagemap-handle{cursor:grabbing;height:25px;margin-right:10px;transform:rotate(45deg);width:25px}.imagemap-area .imagemap-area-buttons{padding-right:0}.imagemap-area .imagemap-popin{background:#fff;border:1px solid #000}.imagemap-area .imagemap-popin svg{fill:#17a2b8;height:40px;width:40px}.imagemap-area .imagemap-popin a:focus{outline:none}.imagemap-go-up{height:0;margin-left:-60px;position:sticky;top:10px}.imagemap-go-up svg{fill:#17a2b8;height:50px;width:50px}.imagemap-shape{cursor:pointer}
.imagemap-area{border:2px dashed #dbdbdb;border-radius:.25rem;padding:1rem;position:relative}.imagemap-area .imagemap-handle{cursor:grabbing;height:25px;margin-right:10px;transform:rotate(45deg);width:25px}.imagemap-area .imagemap-area-buttons{padding-right:0}.imagemap-area .imagemap-popin{background:#fff;border:1px solid #000}.imagemap-area .imagemap-popin svg{fill:#17a2b8;height:40px;width:40px}.imagemap-area .imagemap-popin a:focus{outline:none}.imagemap-area .row .col-1{padding:0}.imagemap-go-up{height:0;margin-left:-42px;position:sticky;top:10px}.imagemap-go-up svg{fill:#17a2b8;height:50px;width:50px}.imagemap-shape{cursor:pointer}

View File

@@ -7,4 +7,7 @@
<path fill="none" d="M0 0h24v24H0z"/>
<path d="M12 2c5.52 0 10 4.48 10 10s-4.48 10-10 10S2 17.52 2 12 6.48 2 12 2zm1 10V8h-2v4H8l4 4 4-4h-3z"/>
</symbol>
<symbol viewBox="0 0 24 24" id="ri-arrow-up-long-fill">
<path d="M11.0001 22.0003L13 22.0004L13 8.41421L18.4142 8.41421L12 2L5.58575 8.41421L11 8.41421L11.0001 22.0003Z" />
</symbol>
</svg>

Before

Width:  |  Height:  |  Size: 565 B

After

Width:  |  Height:  |  Size: 764 B

View File

@@ -1,24 +1,24 @@
{% trans_default_domain 'ezrepoforms_content' %}
{% trans_default_domain 'ibexa_content_forms_content' %}
{% block imagemap_row %}
<div class="imagemap-edit" id="imagemap-container-{{ form.parent.vars.data.field.id }}">
{% set label_wrapper_attr = label_wrapper_attr|default({})|merge({'class': (label_wrapper_attr.class|default('') ~ 'ez-field-edit__label-wrapper')|trim}) %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' ez-field-edit__label')|trim}) %}
{% set label_wrapper_attr = label_wrapper_attr|default({})|merge({'class': (label_wrapper_attr.class|default('') ~ 'ibexa-field-edit__label-wrapper')|trim}) %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' ibexa-field-edit__label')|trim}) %}
<div{% with { attr: label_wrapper_attr } %}{{ block('attributes') }}{% endwith %}>
{{- block('form_label') }}
</div>
<div>
<button type="button" class="btn btn-info imagemap-draw-rect">{{ 'imagemap.button.draw.rect'|trans }}</button>
<button type="button" class="btn btn-info imagemap-draw-circle">{{ 'imagemap.button.draw.circle'|trans }}</button>
<button type="button" class="btn btn-info imagemap-draw-poly">{{ 'imagemap.button.draw.poly'|trans }}</button>
<button type="button" class="ibexa-btn btn ibexa-btn--info imagemap-draw-rect">{{ 'imagemap.button.draw.rect'|trans }}</button>
<button type="button" class="ibexa-btn btn ibexa-btn--info imagemap-draw-circle">{{ 'imagemap.button.draw.circle'|trans }}</button>
<button type="button" class="ibexa-btn btn ibexa-btn--info imagemap-draw-poly">{{ 'imagemap.button.draw.poly'|trans }}</button>
<div hidden class="imagemap-help-rect">{{ 'imagemap.help.rect'|trans }}</div>
<div hidden class="imagemap-help-circle">{{ 'imagemap.help.circle'|trans }}</div>
<div hidden class="imagemap-help-poly">{{ 'imagemap.help.poly'|trans }}</div>
</div>
{% set preview_block_name = 'ezimage_preview' %}
{% set preview_block_name = 'ibexa_image_preview' %}
{% set max_file_size = max_upload_size|round %}
{% set attr = attr|merge({'accept': 'image/*'}) %}
{% set wrapper_attr = {'class': 'ez-field-edit--ezimage'} %}
{% set wrapper_attr = {'class': 'ibexa-field-edit--ibexa_image'} %}
{% set label_wrapper_attr = {'hidden': true} %}
{{ block('binary_base_row') }}
{{ form_row(form.map) }}
@@ -42,7 +42,7 @@
<div class="imagemap-go-up">
<a href="#imagemap-container-{{ form.parent.parent.vars.data.field.id }}">
<svg>
<use href="{{ asset('/bundles/onisepimagemap/images/remixicon.svg#ri-arrow-up-circle-fill') }}"></use>
<use href="{{ asset('/bundles/onisepimagemap/images/remixicon.svg#ri-arrow-up-long-fill') }}"></use>
</svg>
</a>
</div>
@@ -57,16 +57,16 @@
{% block imagemap_map_area_row %}
<div class="imagemap-area">
<div class="row">
<div class="col-1">
<button class="btn btn-danger imagemap-remove" type="button" title="{{ 'imagemap.area.button.delete.label'|trans }}">
<svg class="ez-icon ez-icon--medium ez-icon--light">
<use xlink:href="/bundles/ezplatformadminui/img/ez-icons.svg#trash"></use>
</svg>
</button>
</div>
<div class="col-11">
{{ form_row(form.link) }}
</div>
<div class="col-1">
<button class="ibexa-btn btn ibexa-btn--primary ibexa-btn--no-text imagemap-remove" type="button" title="{{ 'imagemap.area.button.delete.label'|trans }}">
<svg class="ibexa-icon ibexa-icon--medium ibexa-icon--light">
<use xlink:href="/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#trash"></use>
</svg>
</button>
</div>
</div>
<div class="row">
<div class="col-3">
@@ -92,29 +92,41 @@
{% block imagemap_link_row %}
{% set internal = content is not null %}
<div class="imagemap-relation row" data-udw-config="{{ ez_udw_config('single', {
<div class="imagemap-relation row" data-udw-config="{{ ibexa_udw_config('single', {
'type': 'object_relation',
'allowed_content_types': form.parent.parent.parent.parent.vars.data.fieldDefinition.fieldSettings.selectionContentTypes
}) }}">
<div class="col-3">
<select class="imagemap-relation-select form-control">
<option value="internal" {{ internal ? 'selected' }}>{{ 'imagemap.link.internal'|trans }}</option>
<option value="external" {{ not internal ? 'selected' }}>{{ 'imagemap.link.external'|trans }}</option>
</select>
<div class="col-4">
{% set source %}
<select class="form-control ibexa-input imagemap-relation-select">
<option value="internal" {{ internal ? 'selected' }}>{{ 'imagemap.link.internal'|trans }}</option>
<option value="external" {{ not internal ? 'selected' }}>{{ 'imagemap.link.external'|trans }}</option>
</select>
{% endset %}
{% include '@ibexadesign/ui/component/dropdown/dropdown.html.twig' with {
source: source,
choices: [{'value': 'internal', 'label': 'imagemap.link.internal'|trans}, {'value': 'external', 'label': 'imagemap.link.external'|trans}],
value: internal ? 'internal' : 'external',
is_small: true,
} %}
</div>
<div class="col-9">
<div class="col-8">
<div class="imagemap-relation-internal" {{ not internal ? 'hidden' }}>
<button class="btn btn-info imagemap-relation-browse" type="button" title="{{ 'imagemap.link.select_content'|trans }}">
<svg class="ez-icon ez-icon--medium ez-icon--light">
<use xlink:href="/bundles/ezplatformadminui/img/ez-icons.svg#browse"></use>
<svg class="ibexa-icon ibexa-icon--medium ibexa-icon--light">
<use xlink:href="/bundles/ibexaadminuiassets/vendors/ids-assets/dist/img/all-icons.svg#folder-browse"></use>
</svg>
</button>
<span class="imagemap-relation-name">
{{ content ? ez_content_name(content) : 'imagemap.link.no_content'|trans }}
{{ content ? ibexa_content_name(content) : 'imagemap.link.no_content'|trans }}
</span>
</div>
<div class="imagemap-relation-external" {{ internal ? 'hidden' }}>
<input type="text" class="imagemap-relation-external-link form-control" value="{{ not internal ? value }}" />
{%- embed '@ibexadesign/ui/component/input_text.html.twig' -%}
{% block content %}
<input type="text" class="imagemap-relation-external-link ibexa-input--small ibexa-input ibexa-input--text form-control" value="{{ not internal ? value }}" />
{% endblock %}
{%- endembed -%}
</div>
</div>

View File

@@ -1 +1 @@
{{ ez_render_content(content, {'viewType': 'embed'}) }}
{{ ibexa_render_content(content, {'viewType': 'embed'}) }}

View File

@@ -1 +1 @@
{{ ez_render_content(content, {'viewType': 'embed'}) }}
{{ ibexa_render_content(content, {'viewType': 'embed'}) }}

View File

@@ -23,7 +23,7 @@
{% elseif item.target == 'popin' %}
{% set link = '#imagemap-target-' ~ field.id ~ '-' ~ item.content.id %}
{% else %}
{% set link = path('ez_urlalias', {'contentId': item.content.id}) %}
{% set link = path('ibexa.url.alias', {'contentId': item.content.id}) %}
{% endif %}
{% endif %}
@@ -39,7 +39,7 @@
{% for item in items|filter((item) => item.target == 'embed')|filter((item) => item.content is defined) %}
{% set id = item.anchor ?: 'imagemap-target-' ~ field.id ~ '-' ~ item.content.id %}
<div id="{{ id }}" class="imagemap__embeds__item" hidden>
{{ ez_render_content(item.content, {'viewType': 'imagemap_embed'}) }}
{{ ibexa_render_content(item.content, {'viewType': 'imagemap_embed'}) }}
</div>
{% endfor %}
</div>
@@ -48,7 +48,7 @@
<div id="imagemap-target-{{ field.id}}-{{ item.content.id }}" class="imagemap__popins__item">
<div class="imagemap__popins__item__bg imagemap__popins__item__exit"></div>
<div class="imagemap__popins__item__container">
{{ ez_render_content(item.content, {'viewType': 'imagemap_popin'}) }}
{{ ibexa_render_content(item.content, {'viewType': 'imagemap_popin'}) }}
<button class="imagemap__popins__item__close imagemap__popins__item__exit">X</button>
</div>
</div>

View File

@@ -9,6 +9,7 @@ use Twig\TwigFunction;
class ImageMapExtension extends AbstractExtension
{
#[\Override]
public function getFunctions()
{
return [

View File

@@ -4,21 +4,16 @@ declare(strict_types=1);
namespace Onisep\IbexaImageMapBundle\Twig;
use eZ\Publish\API\Repository\ContentService;
use eZ\Publish\API\Repository\LocationService;
use eZ\Publish\API\Repository\Values\Content\Field;
use eZ\Publish\Core\Base\Exceptions\NotFoundException;
use Ibexa\Contracts\Core\Repository\ContentService;
use Ibexa\Contracts\Core\Repository\LocationService;
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
use Ibexa\Core\Base\Exceptions\NotFoundException;
use Twig\Extension\RuntimeExtensionInterface;
class ImageMapRuntime implements RuntimeExtensionInterface
{
private LocationService $locationService;
private ContentService $contentService;
public function __construct(LocationService $locationService, ContentService $contentService)
public function __construct(private readonly LocationService $locationService, private readonly ContentService $contentService)
{
$this->locationService = $locationService;
$this->contentService = $contentService;
}
public function loadImageMapItems(Field $field): array
@@ -39,7 +34,7 @@ class ImageMapRuntime implements RuntimeExtensionInterface
continue;
}
$linkContentId = (int) substr($map['link'], 11);
$linkContentId = (int) substr((string) $map['link'], 11);
try {
$linkLocation = $this->locationService->loadLocation(
$this->contentService->loadContentInfo($linkContentId)->mainLocationId
@@ -50,7 +45,7 @@ class ImageMapRuntime implements RuntimeExtensionInterface
$map['content'] = $this->contentService->loadContent($linkContentId);
$map['link'] = '#';
} catch (NotFoundException $e) {
} catch (NotFoundException) {
continue;
}