Create a product¶
Before we start adding any products, we will have to create a prototype. A prototype is mandatory for any product definition. It can be compared to its skeleton in the application.
In our case, we will need two kind of items:
- a bowl prototype that will have no specific options,
- a spoon, which can provide various sizes.
In order to create these 2 prototypes, a command has been implemented to quickly generate the required files.
Product without variation¶
We will start with the easiest kind of product: the bowl prototype. This step will be splitted in two parts:
- configuration via files’ edition, to provide every required element
- configuration via the backoffice, to create the product itself
Configuration - files’ edition¶
Run the following command to create the files:
1 | bin/console sonata:product:generate Bowl sonata.ecommerce_demo.product.bowl
|
The required base files will be created in src/Sonata/ProductBundle
.
To finalize the installation, we have to define the missing parameters like the type
itself and the related manager. These data have to be provided in
src/Sonata/ProductBundle/Resources/config/product.yaml
.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # src/Sonata/ProductBundle/Resources/config/product.yaml
services:
sonata.ecommerce_demo.product.bowl.manager:
class: Sonata\ProductBundle\Entity\ProductManager
arguments:
- App\Sonata\ProductBundle\Entity\Bowl
- '@sonata.product.entity_manager'
sonata.ecommerce_demo.product.bowl.type:
class: App\Sonata\ProductBundle\Provider\BowlProductProvider
arguments:
- '@serializer'
|
Don’t forget to load this file by adding the following lines in the app/config/config.yaml
1 2 3 4 | # app/config/config.yaml
imports:
- { resource: '@ApplicationSonataProductBundle/Resources/config/product.yaml' }
|
And finally, add in the app/config/sonata/sonata_product.yaml
the following data:
1 2 3 4 5 6 7 | # app/config/sonata/sonata_product.yaml
sonata_product:
products:
sonata.ecommerce_demo.product.bowl:
provider: sonata.ecommerce_demo.product.bowl.type
manager: sonata.ecommerce_demo.product.bowl.manager
|
This being done, edit the src/Sonata/ProductBundle/Entity/Bowl.php
to make it inherits the Product
class.
Configuration - Backoffice¶
Now that we have all the required files, we can process the creation of the Product itself.
Go to the admin dashboard and select Product in the e-commerce menu. After clicking on
Add new
on the top right of the page, a list with 3 items type should be displayed:
- sonata.ecommerce_demo.product.goodie
- sonata.ecommerce_demo.product.training
- sonata.ecommerce_demo.product.bowl
In the first tab, note that the VAT type of field must be a percent. The goodie and training are part of the original sandbox so we will select the bowl one.
Now switch to the Categories tab, and attach our product to the correct category, “Dishes” in our case. Don’t forget to enable the relation by checking the checkbox.
We will repeat the same process in the “Collection” tab using the “Bowls” collection that we have previously created.
Since the delivery part is covered in a whole chapter, we won’t provide any information about it for now.
You should now be able to browse your first product on the frontoffice!
Product with variation(s)¶
Configuration - files’ edition¶
In order to create a Product with a variation (a spoon in our example), we will have to repeat
the same steps as explained in the previous section, in the Configuration - files’ edition part.
For the purpose of this example, we will use Spoon
as entity name and
sonata.ecommerce_demo.product.spoon
as service name.
Once you’ve completed the whole process, we will now learn how to add variable fields. In our case,
it will be the size. To do so, add the “size” property in the entity
(src/Sonata/ProductBundle/Entity/Spoon.php
):
// src/Sonata/ProductBundle/Entity/Spoon.php
protected $size;
public function setSize(string $size)
{
$this->size = $size;
}
public function getSize(): string
{
return $this->size;
}
Still in the same file, we will provide a list of possible values for this field by adding the size list:
// src/Sonata/ProductBundle/Entity/Spoon.php
const SIZE_TSP = 'Small (Tea spoon)';
const SIZE_S = 'Medium (Spoon)';
const SIZE_TBSP = 'Large (Tablespoon)';
public static function getSizeList(): array
{
return [
static::SIZE_TSP => static::SIZE_TSP,
static::SIZE_S => static::SIZE_S,
static::SIZE_TBSP => static::SIZE_TBSP,
];
}
Now, we have to add this field in our entity. Considering you are using Doctrine ORM, you should add the
following line in src/Sonata/ProductBundle/Resources/config/doctrine/Jersey.orm.xml
:
1 2 3 | // src/Sonata/ProductBundle/Resources/config/doctrine/Jersey.orm.xml
<field name="size" column="size" type="string" length="50" nullable="true"/>
|
Finally, tell our app that we will be using the “size” field as a variation. To define this, in the
app/config/sonata/sonata_product.yaml
, after the manager definition line of our prototype, add the
following code:
1 2 3 4 | # app/config/sonata/sonata_product.yaml
variations:
fields: [size]
|
As the variation is stored as a real field in our model, we now have to update our database’s schema. Run the following command to control everything works as expected:
1 | bin/console doctrine:schema:update --dump-sql
|
And if everything is ok, perform to the modification:
1 | bin/console doctrine:schema:update --force
|
If you go back to the product creation page, you should be able to see our provider and display
its page without any error. Though, the size field is not available yet. We have to enable it
manually by overriding the SpoonProductProvider::buildEditForm()
method.
You first should add the usage of App\Sonata\ProductBundle\Entity\Spoon
class:
public function buildEditForm(FormMapper $formMapper, $isVariation = false)
{
parent::buildEditForm($formMapper, $isVariation);
if ($isVariation) {
$formMapper
->with('Product')
->add('size', 'choice', [
'choices' => Spoon::getSizeList(),
'translation_domain' => 'ApplicationSonataProductBundle',
])
->end();
}
}
Once we have done this, we should still have no error but the size field shouldn’t be available yet. It’s simply because we first have to create a base product and each of its variations will be real products.
You can picture this as an abstract class (the base product) extended by many concrete classes (one per variation). Let’s do this !
Configuration - Backoffice¶
Repeat the same steps as indicated for products with no variations. Once you have completed this step, you should be able to browse the created product, without any variation yet.
This is the default behavior : as long as you enable a product supposed to have any variations, it will be displayed if none are provided. If you have one disabled, the product will be considered as disabled. But let’s get back to our product.
Go to the list page. Check the checkbox in front of our recently created product (“Mommy’s tea spoon”) and in the dropdown menu select and validate the “Create a variation” option. You should be prompted to confirm the variation creation. As you can see, the created variation is disabled by default so we need to first edit it, and then enable it. You might have noticed that the product is not available in the frontend anymore as explained previously. The “edit” page should now look a bit different : less fields, but we have the “size” one !
Once you have edited the product and enabled it, it should now appear in the frontoffice. Congratulations, you have created your first variation!