Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shopware 6: Create inherited entity extension for products

Tags:

php

shopware

I want to create a product extension in Shopware 6.3.5.4 and I followed this guide. It should be a OneToOne Association and I want to fill this extension only for parent products, because the data in there is the same for all variants of a product. So if a variant is loaded it should load the extension of the parent.

This is my Extension:

class MyExtension extends EntityExtension
{
    public const EXTENSION_NAME = 'myExtension';

    public function extendFields(FieldCollection $collection): void
    {
        $collection->add(
            (new OneToOneAssociationField(
                self::EXTENSION_NAME,
                'id',
                'product_id',
                MyExtensionDefinition::class,
                true
            ))->addFlags(new Inherited())
        );
    }

    public function getDefinitionClass(): string
    {
        return ProductDefinition::class;
    }
}

This is the defineFields function of my extension definition:

protected function defineFields(): FieldCollection
{
    return new FieldCollection([
        (new IdField('id', 'id'))->addFlags(new Required(), new PrimaryKey()),
        new VersionField(),

        (new StringField('material_1', 'material1')),
        (new StringField('material_2', 'material2')),
        (new StringField('material_3', 'material3')),
        (new StringField('material_4', 'material4')),

        (new FkField('product_id', 'productId', ProductDefinition::class))->addFlags(new Required()),
        (new ReferenceVersionField(ProductDefinition::class))->addFlags(new Required()),
        new OneToOneAssociationField('product', 'product_id', 'id', ProductDefinition::class, false),
    ]);
}

This is my extension entity:

class MyExtensionEntity extends Entity
{
    use EntityIdTrait;

    protected string $productId;
    protected string $productVersionId;
    protected ?ProductEntity $product = null;
    protected ?string $material1 = null;
    protected ?string $material2 = null;
    protected ?string $material3 = null;
    protected ?string $material4 = null;

    // getters and setters
}

And finally my migration:

class Migration1622484776MyExtension extends MigrationStep
{
    use InheritanceUpdaterTrait;

    public function getCreationTimestamp(): int
    {
        return 1622484776;
    }

    public function update(Connection $connection): void
    {
        $sql = <<<SQL
            CREATE TABLE IF NOT EXISTS `my_extension` (
                `id`                        BINARY(16)      NOT NULL,
                `version_id`                BINARY(16)      NOT NULL,
                `material_1`                VARCHAR(255)    NULL,
                `material_2`                VARCHAR(255)    NULL,
                `material_3`                VARCHAR(255)    NULL,
                `material_4`                VARCHAR(255)    NULL,
                `product_id`                BINARY(16)      NOT NULL,
                `product_version_id`        BINARY(16)      NOT NULL,
                `created_at`                DATETIME(3)     NOT NULL,
                `updated_at`                DATETIME(3)     NULL,
                PRIMARY KEY (`id`, `version_id`),
                CONSTRAINT fk_my_extension__product 
                    FOREIGN KEY (`product_id`,`product_version_id`) REFERENCES `product` (`id`,`version_id`) ON DELETE CASCADE ON UPDATE CASCADE
            ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
SQL;
        $connection->executeUpdate($sql);

        $this->updateInheritance($connection, 'product', MyExtension::EXTENSION_NAME);
    }

    public function updateDestructive(Connection $connection): void
    {
        // implement update destructive
    }
}

After I run an import script which imports products and the extensions it looks fine in the database. There are only extensions for parent products and in the product table there is a new column "myExtension" for the inheritance. It is is filled with the parent product ID for all variants, so everything looks good. But if I load a variant via DAL the extension is always "null". It is not taken from the parent product. What is missing in my code to achieve that?

like image 851
Nono Avatar asked Nov 08 '25 00:11

Nono


1 Answers

I found my mistake. In my migration I created a new column for the product table by calling $this->updateInheritance($connection, 'product', MyExtension::EXTENSION_NAME). But in my EntityExtension I have used id as storage name (second argument) to the OneToOneAssociation. I have to use the new column as storage name like this:

public function extendFields(FieldCollection $collection): void
{
    $collection->add(
        (new OneToOneAssociationField(
            self::EXTENSION_NAME,
            self::EXTENSION_NAME,
            'product_id',
            MyExtensionDefinition::class,
            true
        ))->addFlags(new Inherited())
    );
}

Now the inheritance is working.

like image 65
Nono Avatar answered Nov 10 '25 16:11

Nono



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!