Search code examples
phpvue.jsshopwareshopware6

Attach Shopware 6 tags to Property values


Can someone advice on making it possible to attach Shopware 6 tags to Property (only one) values?

Is there a way to reuse some components? I assume tags are done using data associations.

--

I have set it up, but now I get this error (while not being able to open Property option detail modal on click in a backend administration options list):

app.js?16886789168584353:2 An error was captured in current module: ReferenceError: option is not defined

It opens well, when I remove the selector:

    <sw-entity-tag-select
        v-if="option"
        v-model="option.extensions.myTags"
        :label="$tc('global.sw-tag-field.title')"
    />

Here is the js:

Shopware.Component.override('sw-property-option-detail', {
    inject: [
        'repositoryFactory'
    ],

    template,

    data: function () {
        return {
            option: undefined
        }
    },

    computed: {
        repository() {
            return this.repositoryFactory.create('a7filter_property_group_option_tag');
        },
        criteria() {
            const criteria = new Criteria();
            criteria.addAssociation('myTags');

            return criteria;
        },
    },

    created() {
        this.repository = this.repositoryFactory.create('a7filter_property_group_option_tag');

        this.repository.search(this.criteria, Shopware.Context.api)
            .then(option => {
                this.option = option;
            });
    }
});

Maybe someone can give an advice?


Solution

  • Create a custom entity for the mapping

    class MyPropertyGroupOptionTagDefinition extends MappingEntityDefinition
    {
        final public const ENTITY_NAME = 'my_property_group_option_tag';
    
        public function getEntityName(): string
        {
            return self::ENTITY_NAME;
        }
    
        protected function defineFields(): FieldCollection
        {
            return new FieldCollection([
                (new FkField('option_id', 'optionId', PropertyGroupOptionDefinition::class))->addFlags(new PrimaryKey(), new Required()),
                (new FkField('tag_id', 'tagId', TagDefinition::class))->addFlags(new PrimaryKey(), new Required()),
                new ManyToOneAssociationField('option', 'option_id', PropertyGroupOptionDefinition::class, 'id', false),
                new ManyToOneAssociationField('tag', 'tag_id', TagDefinition::class, 'id', false),
            ]);
        }
    }
    

    Create an EntityExtension

    class PropertyGroupOptionExtension extends EntityExtension
    {
        public function extendFields(FieldCollection $collection): void
        {
            $collection->add(
                new ManyToManyAssociationField('myTags', TagDefinition::class, MyPropertyGroupOptionTagDefinition::class, 'option_id', 'tag_id'),
            );
        }
    
        public function getDefinitionClass(): string
        {
            return PropertyGroupOptionDefinition::class;
        }
    }
    

    Add association to criteria for property_group_option where they are fetched

    criteria.addAssociation('myTags');
    

    In the template of the component you can use sw-entity-tag-select for assigning tags

    <sw-entity-tag-select
        v-if="option"
        v-model="option.extensions.myTags"
        :label="$tc('global.sw-tag-field.title')"
    />