商店用品 6 |克隆 CmsElement 并获取 null 作为数据
Shopware 6 | Cloning CmsElement and get null as data
我尝试克隆内容元素 image-slider
或 image-gallery
(两者都会出错)以扩展它们。首先,我像原来的 一样注册了一个新的 CmsElement,仅 将名称从 image-slider
更改为 image-slider-example
import './component';
import './config';
import './preview';
Shopware.Service('cmsService').registerCmsElement({
name: 'image-slider-example',
label: 'sw-cms.elements.imageSlider.label',
component: 'sw-cms-el-image-slider',
configComponent: 'sw-cms-el-config-image-slider',
previewComponent: 'sw-cms-el-preview-image-slider',
defaultConfig: {
sliderItems: {
source: 'static',
value: [],
required: true,
entity: {
name: 'media'
}
},
displayMode: {
source: 'static',
value: 'standard'
},
minHeight: {
source: 'static',
value: '300px'
},
verticalAlign: {
source: 'static',
value: null
}
},
enrich: function enrich(elem, data) {
if (Object.keys(data).length < 1) {
return;
}
Object.keys(elem.config).forEach((configKey) => {
const entity = elem.config[configKey].entity;
if (!entity) {
return;
}
const entityKey = entity.name;
if (!data[`entity-${entityKey}`]) {
return;
}
elem.data[configKey] = [];
elem.config[configKey].value.forEach((sliderItem) => {
elem.data[configKey].push({
newTab: sliderItem.newTab,
url: sliderItem.url,
media: data[`entity-${entityKey}`].get(sliderItem.mediaId)
});
});
});
}
});
现在它向我展示了购物体验中的新元素,我可以在其中使用它。
之后,我为店面创建 cms-element-image-slider-example.html.twig
文件,该文件将由 Shopware 加载。
{% sw_extends '@Storefront/storefront/element/cms-element-image-slider.html.twig' %}
{% block element_image_slider_alignment %}
<pre>
{{ dump(element) }}
</pre>
{{ parent() }}
{% endblock %}
现在我扩展了我从中克隆的原始店面元素并添加了 dump
以查看所有数据。但是我有一个问题,element.data
是 null
但应该存储所有图像。
您需要创建一个如下所示的数据解析器:
<?php declare(strict_types=1);
namespace PluginName\Core\Content\Media\Cms;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\DataResolver\CriteriaCollection;
use Shopware\Core\Content\Cms\DataResolver\Element\AbstractCmsElementResolver;
use Shopware\Core\Content\Cms\DataResolver\Element\ElementDataCollection;
use Shopware\Core\Content\Cms\DataResolver\FieldConfig;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\EntityResolverContext;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ImageStruct;
use Shopware\Core\Content\Media\MediaDefinition;
use Shopware\Core\Content\Media\MediaEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
class ImageCmsElementResolver extends AbstractCmsElementResolver
{
public function getType(): string
{
return 'image';
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$config = $slot->getFieldConfig();
$mediaConfig = $config->get('media');
if (!$mediaConfig || $mediaConfig->isMapped() || $mediaConfig->getValue() === null) {
return null;
}
$criteria = new Criteria([$mediaConfig->getValue()]);
$criteriaCollection = new CriteriaCollection();
$criteriaCollection->add('media_' . $slot->getUniqueIdentifier(), MediaDefinition::class, $criteria);
return $criteriaCollection;
}
public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
{
$config = $slot->getFieldConfig();
$image = new ImageStruct();
$slot->setData($image);
if ($urlConfig = $config->get('url')) {
if ($urlConfig->isStatic()) {
$image->setUrl($urlConfig->getValue());
}
if ($urlConfig->isMapped() && $resolverContext instanceof EntityResolverContext) {
$url = $this->resolveEntityValue($resolverContext->getEntity(), $urlConfig->getValue());
if ($url) {
$image->setUrl($url);
}
}
if ($newTabConfig = $config->get('newTab')) {
$image->setNewTab($newTabConfig->getValue());
}
}
$mediaConfig = $config->get('media');
if ($mediaConfig && $mediaConfig->getValue()) {
$this->addMediaEntity($slot, $image, $result, $mediaConfig, $resolverContext);
}
}
private function addMediaEntity(CmsSlotEntity $slot, ImageStruct $image, ElementDataCollection $result, FieldConfig $config, ResolverContext $resolverContext): void
{
if ($config->isMapped() && $resolverContext instanceof EntityResolverContext) {
/** @var MediaEntity|null $media */
$media = $this->resolveEntityValue($resolverContext->getEntity(), $config->getValue());
if ($media !== null) {
$image->setMediaId($media->getUniqueIdentifier());
$image->setMedia($media);
}
}
if ($config->isStatic()) {
$image->setMediaId($config->getValue());
$searchResult = $result->get('media_' . $slot->getUniqueIdentifier());
if (!$searchResult) {
return;
}
/** @var MediaEntity|null $media */
$media = $searchResult->get($config->getValue());
if (!$media) {
return;
}
$image->setMedia($media);
}
}
}
如果您创建解析器,则需要在 src/Resources/config/services.xml
中注册解析器
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="PluginName\Core\Content\Media\Cms\ImageCmsElementResolver">
<tag name="shopware.cms.data_resolver"/>
</service>
</services>
</container>
我尝试克隆内容元素 image-slider
或 image-gallery
(两者都会出错)以扩展它们。首先,我像原来的 一样注册了一个新的 CmsElement,仅 将名称从 image-slider
更改为 image-slider-example
import './component';
import './config';
import './preview';
Shopware.Service('cmsService').registerCmsElement({
name: 'image-slider-example',
label: 'sw-cms.elements.imageSlider.label',
component: 'sw-cms-el-image-slider',
configComponent: 'sw-cms-el-config-image-slider',
previewComponent: 'sw-cms-el-preview-image-slider',
defaultConfig: {
sliderItems: {
source: 'static',
value: [],
required: true,
entity: {
name: 'media'
}
},
displayMode: {
source: 'static',
value: 'standard'
},
minHeight: {
source: 'static',
value: '300px'
},
verticalAlign: {
source: 'static',
value: null
}
},
enrich: function enrich(elem, data) {
if (Object.keys(data).length < 1) {
return;
}
Object.keys(elem.config).forEach((configKey) => {
const entity = elem.config[configKey].entity;
if (!entity) {
return;
}
const entityKey = entity.name;
if (!data[`entity-${entityKey}`]) {
return;
}
elem.data[configKey] = [];
elem.config[configKey].value.forEach((sliderItem) => {
elem.data[configKey].push({
newTab: sliderItem.newTab,
url: sliderItem.url,
media: data[`entity-${entityKey}`].get(sliderItem.mediaId)
});
});
});
}
});
现在它向我展示了购物体验中的新元素,我可以在其中使用它。
之后,我为店面创建 cms-element-image-slider-example.html.twig
文件,该文件将由 Shopware 加载。
{% sw_extends '@Storefront/storefront/element/cms-element-image-slider.html.twig' %}
{% block element_image_slider_alignment %}
<pre>
{{ dump(element) }}
</pre>
{{ parent() }}
{% endblock %}
现在我扩展了我从中克隆的原始店面元素并添加了 dump
以查看所有数据。但是我有一个问题,element.data
是 null
但应该存储所有图像。
您需要创建一个如下所示的数据解析器:
<?php declare(strict_types=1);
namespace PluginName\Core\Content\Media\Cms;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\DataResolver\CriteriaCollection;
use Shopware\Core\Content\Cms\DataResolver\Element\AbstractCmsElementResolver;
use Shopware\Core\Content\Cms\DataResolver\Element\ElementDataCollection;
use Shopware\Core\Content\Cms\DataResolver\FieldConfig;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\EntityResolverContext;
use Shopware\Core\Content\Cms\DataResolver\ResolverContext\ResolverContext;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ImageStruct;
use Shopware\Core\Content\Media\MediaDefinition;
use Shopware\Core\Content\Media\MediaEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
class ImageCmsElementResolver extends AbstractCmsElementResolver
{
public function getType(): string
{
return 'image';
}
public function collect(CmsSlotEntity $slot, ResolverContext $resolverContext): ?CriteriaCollection
{
$config = $slot->getFieldConfig();
$mediaConfig = $config->get('media');
if (!$mediaConfig || $mediaConfig->isMapped() || $mediaConfig->getValue() === null) {
return null;
}
$criteria = new Criteria([$mediaConfig->getValue()]);
$criteriaCollection = new CriteriaCollection();
$criteriaCollection->add('media_' . $slot->getUniqueIdentifier(), MediaDefinition::class, $criteria);
return $criteriaCollection;
}
public function enrich(CmsSlotEntity $slot, ResolverContext $resolverContext, ElementDataCollection $result): void
{
$config = $slot->getFieldConfig();
$image = new ImageStruct();
$slot->setData($image);
if ($urlConfig = $config->get('url')) {
if ($urlConfig->isStatic()) {
$image->setUrl($urlConfig->getValue());
}
if ($urlConfig->isMapped() && $resolverContext instanceof EntityResolverContext) {
$url = $this->resolveEntityValue($resolverContext->getEntity(), $urlConfig->getValue());
if ($url) {
$image->setUrl($url);
}
}
if ($newTabConfig = $config->get('newTab')) {
$image->setNewTab($newTabConfig->getValue());
}
}
$mediaConfig = $config->get('media');
if ($mediaConfig && $mediaConfig->getValue()) {
$this->addMediaEntity($slot, $image, $result, $mediaConfig, $resolverContext);
}
}
private function addMediaEntity(CmsSlotEntity $slot, ImageStruct $image, ElementDataCollection $result, FieldConfig $config, ResolverContext $resolverContext): void
{
if ($config->isMapped() && $resolverContext instanceof EntityResolverContext) {
/** @var MediaEntity|null $media */
$media = $this->resolveEntityValue($resolverContext->getEntity(), $config->getValue());
if ($media !== null) {
$image->setMediaId($media->getUniqueIdentifier());
$image->setMedia($media);
}
}
if ($config->isStatic()) {
$image->setMediaId($config->getValue());
$searchResult = $result->get('media_' . $slot->getUniqueIdentifier());
if (!$searchResult) {
return;
}
/** @var MediaEntity|null $media */
$media = $searchResult->get($config->getValue());
if (!$media) {
return;
}
$image->setMedia($media);
}
}
}
如果您创建解析器,则需要在 src/Resources/config/services.xml
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="PluginName\Core\Content\Media\Cms\ImageCmsElementResolver">
<tag name="shopware.cms.data_resolver"/>
</service>
</services>
</container>