Trying to extend property with one to many relation to be able to categorize each property group. I did the extension and the migrations. all Seems to be working fine except from saving the relation in the admin panel property details page "/sw/property/detail/{id}" where I added a dropdown field using the sw-entity-single-select. Any help is appreciated. Here is my currently code:
class PropertyGroupExtension extends EntityExtension
{
public function getDefinitionClass(): string
{
return PropertyGroupDefinition::class;
}
public function extendFields(FieldCollection $collection): void
{
$collection->add(
(new FkField(
'property_group_category_id',
'propertyGroupCategoryId',
PropertyGroupCategoryDefinition::class
))->addFlags(new ApiAware())
);
$collection->add(
(new ManyToOneAssociationField(
'propertyGroupCategory',
'property_group_category_id',
PropertyGroupCategoryDefinition::class,
'id',
false
))->addFlags(new ApiAware())
);
}
}
class PropertyGroupCategoryDefinition extends EntityDefinition
{
public const ENTITY_NAME = 'property_group_category';
public function getEntityName(): string
{
return self::ENTITY_NAME;
}
public function getEntityClass(): string
{
return PropertyGroupCategoryEntity::class;
}
protected function defineFields(): FieldCollection
{
return new FieldCollection([
(new IdField('id', 'id'))->addFlags(new ApiAware(), new PrimaryKey(), new Required()),
(new StringField('name', 'name'))->addFlags(new ApiAware(), new Required()),
(new OneToManyAssociationField('propertyGroups', PropertyGroupDefinition::class, 'property_group_category_id'))->addFlags(new ApiAware()),
]);
}
}
class PropertyGroupCategoryEntity extends Entity
{
use EntityIdTrait;
/**
* @var string
*/
protected $name;
/**
* @var PropertyGroupCollection|null
*/
protected $propertyGroups;
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getPropertyGroups(): ?PropertyGroupCollection
{
return $this->propertyGroups;
}
public function setPropertyGroups(PropertyGroupCollection $propertyGroups): void
{
$this->propertyGroups = $propertyGroups;
}
}
#[Package('core')]
class Migration1726207525CreatePropertyGroupCategory extends MigrationStep
{
public function getCreationTimestamp(): int
{
return 1726207525;
}
public function update(Connection $connection): void
{
$connection->executeStatement('
CREATE TABLE `property_group_category` (
`id` BINARY(16) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`created_at` DATETIME(3) NOT NULL,
`updated_at` DATETIME(3) NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
');
$connection->executeStatement('
ALTER TABLE `property_group`
ADD COLUMN `property_group_category_id` BINARY(16) NULL AFTER `filterable`,
ADD CONSTRAINT `fk.property_group.property_group_category_id` FOREIGN KEY (`property_group_category_id`)
REFERENCES `property_group_category` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
');
}
}
and here is where i need the help. this is the admin shopware component already overridden by my plugin.
import template from './sw-property-group-detail.html.twig';
import {Component} from 'Shopware';
Component.override('sw-property-detail-base', {
template,
inject: ['repositoryFactory'],
computed: {
propertyGroupRepository() {
return this.repositoryFactory.create('property_group');
},
propertyGroupCategoryRepository() {
return this.repositoryFactory.create('property_group_category');
},
},
methods: {
onChange(id) {
this.propertyGroup.propertyGroupCategoryId = id;
if (id) {
this.propertyGroupCategoryRepository.get(id).then((category) => {
this.propertyGroup.propertyGroupCategory = category;
});
} else {
this.propertyGroup.propertyGroupCategory = null;
}
console.log(this.propertyGroup) // the data is here but is not saved on click the save button. is there anything here i am missing out?
},
}
});
template
{% block sw_property_detail_base_visible_on_detail %}
{% parent %}
<sw-entity-single-select
id="propertyGroupCategory"
ref="propertyGroupCategory"
entity="property_group_category"
:criteria="propertyGroupCategoryCriteria"
:value="propertyGroup.propertyGroupCategoryId"
label="Group By"
placeholder="Group By"
@update:value="onChange"
></sw-entity-single-select>
{% endblock %}
sw/property/detail/
services:
<service id="MyProjectCoreContentPropertyPropertyGroupExtension">
<tag name="shopware.entity_extension" />
</service>
<service id="MyProjectCoreContentPropertyGroupCategoryPropertyGroupCategoryDefinition">
<tag name="shopware.entity.definition" entity="property_group_category" />
</service>
2
Answers
The reason was not working its because of the way was registered in the service definition. specifically was a typo in the tag name.
Instead of
should be
The correct tag name for the
EntityExtension
isshopware.entity.extension
To expand on the accepted answer:
It’s recommended to automatically tag all classes that extend
ShopwareCoreFrameworkDataAbstractionLayerEntityExtension
with the tagshopware.entity.extension
. This can be achieved with the following code inside the services file (this example uses a services.yaml) by using autoconfigure: