How to Use a Custom Entity as an Attribute Type¶
Note
The code inside this cookbook entry is visible in src directory, you can clone pim-dev then do a symlink and install
Note
The code inside this cookbook entry requires you to install the `akeneo/custom-entity-bundle`_ package.
Overriding the Product Value to Link it to the Custom Entity¶
We now have a custom attribute type that will allow to select instance of our entity, but we still need to provide a way to link the product to the entity we have on the Doctrine side (via its product value).
For this, we need to extend and replace to the native Akeneo ProductValue :
You will also need to add the mapping for the entity. To do this, copy the
src/Pim/Bundle/CatalogBundle/Resources/config/model/doctrine/ProductValue.orm.yml
file of the PIM
inside the Resources/config/doctrine
folder of one of your bundles.
First, replace the name of the class by your own class, and change the name of the table:
1 2 3 4 | # /src/Acme/Bundle/CatalogBundle/Resources/config/doctrine/MyProductValue.orm.yml
Acme\Bundle\CatalogBundle\Entity\MyProductValue:
type: entity
table: acme_catalog_product_value
|
The name of the join tables for all ManyToMany associations must also be changed :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # /src/Acme/Bundle/CatalogBundle/Resources/config/doctrine/MyProductValue.orm.yml
manyToMany:
options:
targetEntity: Pim\Bundle\CatalogBundle\Entity\AttributeOption
cascade:
- refresh
joinTable:
name: acme_catalog_product_value_option
joinColumns:
value_id:
referencedColumnName: id
nullable: true
onDelete: CASCADE
inverseJoinColumns:
option_id:
referencedColumnName: id
nullable: true
onDelete: CASCADE
|
Finally, add your custom relations to the mapping :
1 2 3 4 5 6 7 8 9 10 11 | # /src/Acme/Bundle/CatalogBundle/Resources/config/doctrine/MyProductValue.orm.yml
manyToOne:
color:
targetEntity: Acme\Bundle\CatalogBundle\Entity\Color
cascade:
- persist
- refresh
joinColumns:
color_id:
referencedColumnName: id
onDelete: 'SET NULL'
|
Registering the New Product Value Class¶
Configure the parameter for the ProductValue class :
1 2 3 | # /src/Acme/Bundle/IcecatDemoBundle/Resources/config/entities.yml
parameters:
pim_catalog.entity.product_value.class: Acme\Bundle\CatalogBundle\Entity\MyProductValue
|
After a Doctrine schema update, you should be able to create a new attribute using this new attribute type, and link your manufacturer to your product.
Creating the Attribute Type¶
To create a simple select attribute based on your entity, use the following configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # /src/Acme/Bundle/CatalogBundle/Resources/config/attribute_types.yml
parameters:
pim_datagrid.product.attribute_type.acme_color:
column:
type: flexible_option
selector: flexible_option
filter:
type: flexible_choice
parent_type: ajax_choice
options:
field_options:
multiple: true
sorter: flexible_field
services:
acme_catalog.attributetype.color:
class: '%pim_custom_entity.attribute_type.custom_option_simple_select.class%'
arguments:
- color
- pim_ajax_entity
- '@pim_catalog.validator.attribute_constraint_guesser'
- acme_catalog_color
- Acme\Bundle\CatalogBundle\Entity\Color
tags:
- { name: pim_catalog.attribute_type, alias: acme_catalog_color, entity: '%pim_catalog.entity.product.class%' }
|
Adding validation¶
For the given example, validation is not really needed, but it might be if your custom attribute includes values of its own.
To add validation for a ProductValue, you must create an constraint guesser which will add constraints on the fly if the product has values for your attribute :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # /src/Acme/Bundle/CatalogBundle/Validator/ConstraintGuesser/CustomConstraintGuesser.php
<?php
namespace Acme\Bundle\CatalogBundle\Validator\ConstraintGuesser;
use Acme\Bundle\CatalogBundle\Validator\Constraints\CustomConstraint;
class CustomConstraintGuesser implements ConstraintGuesserInterface
{
/**
* {@inheritdoc}
*/
public function supportAttribute(AbstractAttribute $attribute)
{
return in_array(
$attribute->getAttributeType(),
array(
'acme_catalog_color',
)
);
}
/**
* {@inheritdoc}
*/
public function guessConstraints(AbstractAttribute $attribute)
{
return array(
new CustomConstraint
);
}
}
|
The validator for the created custom constraint will be supplied the value of the attribute.