How to Create a Custom Entity and the Screens to Manage it¶
Note
The code inside this cookbook entry is visible in src directory, you can clone pim-dev then do a symlink and install
Creating the Entity¶
As Akeneo relies heavily on standard tools like Doctrine, creating the entity is quite straightforward for any developer with Doctrine experience.
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | # /src/Acme/Bundle/IcecatDemoBundle/Entity/Vendor.php
<?php
namespace Acme\Bundle\IcecatDemoBundle\Entity;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
use Pim\Bundle\CatalogBundle\Model\ReferableInterface;
/**
* @UniqueEntity(fields="code", message="This code is already taken")
*/
class Vendor implements ReferableInterface
{
protected $id;
/**
* @Assert\Regex(pattern="/^[a-zA-Z0-9_]+$/")
* @Assert\Length(max=100, min=1)
*/
protected $code;
/**
* @Assert\Length(max=250, min=1)
*/
protected $label;
protected $responsible;
protected $created;
protected $updated;
public function getId()
{
return $this->id;
}
public function getCode()
{
return $this->code;
}
public function getLabel()
{
return $this->label;
}
public function setCode($code)
{
$this->code = $code;
return $this;
}
public function setLabel($label)
{
$this->label = $label;
return $this;
}
public function getResponsible()
{
return $this->responsible;
}
public function setResponsible($responsible)
{
$this->responsible = $responsible;
}
public function setCreated($created)
{
$this->created = $created;
return $this;
}
public function getCreated()
{
return $this->created;
}
public function setUpdated($updated)
{
$this->updated = $updated;
return $this;
}
public function getUpdated()
{
return $this->updated;
}
public function __toString()
{
return $this->code;
}
public function getReference()
{
return $this->code;
}
}
|
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | # /src/Acme/Bundle/IcecatDemoBundle/Resources/config/doctrine/Vendor.orm.yml
Acme\Bundle\IcecatDemoBundle\Entity\Vendor:
type: entity
table: pim_icecatdemo_vendor
repositoryClass: Pim\Bundle\CatalogBundle\Entity\Repository\ReferableEntityRepository
uniqueConstraints:
pim_icecatdemo_vendor_code:
columns:
- code
fields:
id:
type: integer
scale: 0
length: null
unique: false
nullable: false
precision: 0
id: true
generator:
strategy: IDENTITY
code:
type: string
scale: 0
length: 100
unique: false
nullable: false
precision: 0
label:
type: string
scale: 0
length: 250
unique: false
nullable: false
precision: 0
responsible:
type: string
scale: 0
length: null
unique: false
nullable: false
precision: 0
created:
type: datetime
gedmo:
timestampable:
on: create
updated:
type: datetime
gedmo:
timestampable:
on: update
lifecycleCallbacks: { }
|
Also add parameters for your entity in the DIC :
1 2 3 | # /src/Acme/Bundle/IcecatDemoBundle/Resources/config/entities.yml
parameters:
pim_catalog.entity.vendor.class: Acme\Bundle\IcecatDemoBundle\Entity\Vendor
|
Note
We have added a code attribute in order to get a non technical unique key. We already have the id, which is the primary key, but this primary key is really dependent of Akeneo, it’s an internal id that does not carry any meaning for the user. The role of the code is to be a unique identifier that will make sense for the user and that will be used with other applications.
In the very case of our manufacturer data, they will certainly come from the ERP, with their own code that we will store in this attribute.
Creating the Entity Management Screens¶
The Grid¶
To benefit from the grid component (which comes natively with filtering and sorting), you can define the vendor grid as following :
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | # /src/Acme/Bundle/IcecatDemoBundle/Resources/config/datagrid.yml
datagrid:
vendor-grid:
options:
entityHint: vendor
source:
type: pim_orm
entity: '%pim_catalog.entity.vendor.class%'
properties:
id: ~
edit_link:
type: custom_entity_url
route: pim_customentity_edit{customEntityName:vendor}
params:
- id
delete_link:
type: custom_entity_url
route: pim_customentity_remove{customEntityName:vendor}
params:
- id
columns:
code:
label: Code
label:
label: Label
responsible:
label: Responsible
created:
label: Created
frontend_type: datetime
updated:
label: Updated
frontend_type: datetime
actions:
edit:
type: navigate
label: Edit
icon: edit
link: edit_link
rowAction: true
delete:
type: delete
label: Delete
icon: trash
link: delete_link
sorters:
columns:
code:
data_name: o.code
label:
data_name: o.label
responsible:
data_name: o.responsible
created:
data_name: o.created
updated:
data_name: o.updated
default:
code: '%oro_datagrid.extension.orm_sorter.class%::DIRECTION_ASC'
filters:
columns:
code:
type: string
label: Code
data_name: o.code
label:
type: string
label: Label
data_name: o.label
responsible:
type: string
label: Responsible
data_name: o.responsible
created:
type: datetime
label: Created
data_name: o.created
updated:
type: datetime
label: Updated
data_name: o.updated
|
Creating the Form Type for this Entity¶
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 33 | # /src/Acme/Bundle/IcecatDemoBundle/Form/Type/VendorType.php
<?php
namespace Acme\Bundle\IcecatDemoBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class VendorType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('code')
->add('label')
->add('responsible');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Acme\Bundle\IcecatDemoBundle\Entity\Vendor',
)
);
}
public function getName()
{
return 'pim_icecatdemo_vendor';
}
}
|
Creating the CRUD¶
A complete CRUD can be easily obtained by defining a service for its configuration:
1 2 3 4 5 6 7 8 9 10 11 12 13 | # /src/Acme/Bundle/IcecatDemoBundle/Resources/config/custom_entities.yml
services:
pim_icecat_demo.custom_entity.configuration:
class: '%pim_custom_entity.configuration.default.class%'
arguments:
- vendor
- '@pim_custom_entity.manager.orm'
- '@pim_custom_entity.controller.strategy.crud'
- entity_class: Acme\Bundle\IcecatDemoBundle\Entity\Vendor
edit_form_type: pim_icecatdemo_vendor
datagrid_namespace: pim_icecatdemo
tags:
- { name: pim_custom_entity.configuration }
|
From this point a working grid screen is visible at /app_dev.php/enrich/vendor
.
If some vendors are manually added to the database, the pagination will be visible as well.
Note
Have a look at the Cookbook recipe “How to add an menu entry” to add your own link in the menu to this grid.