When create my own CartItem, reading this http://docs.sylius.org/en/latest/bundles/SyliusCartBundle/installation.html#creating-your-entities
I add some attribute to CartItem like this:
namespace AppBundle\Entity;
use Sylius\Component\Cart\Model\CartItem as BaseCartItem;
class CartItem extends BaseCartItem
{
private $product;
private $attribute;
public function getProduct()
{
return $this->product;
}
public function setProduct(Product $product)
{
$this->product = $product;
}
public function getAttribute()
{
return $this->attribute;
}
public function setAttribute($attribute)
{
$this->attribute = $attribute;
}
}
And create ItemResolver:
namespace AppBundle\Cart;
use Sylius\Component\Cart\Model\CartItemInterface;
use Sylius\Component\Cart\Resolver\ItemResolverInterface;
use Sylius\Component\Cart\Resolver\ItemResolvingException;
use Doctrine\ORM\EntityManager;
use Symfony\Component\HttpFoundation\Request;
class ItemResolver implements ItemResolverInterface
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* {@inheritdoc}
*/
public function resolve(CartItemInterface $item, $data)
{
$productId = $this->resolveItemIdentifier($data);
// If no product id given, or product not found, we throw exception with nice message.
if (!$productId || !$product = $this->getProductRepository()->find($productId)) {
throw new ItemResolvingException('Requested product was not found');
}
$item-setVariant($product);
$item->setUnitPrice($product->getPrice());
$item->setAttribute($this->resolveAttribute($data));
return $item;
}
public function getProductRepository()
{
return $this->entityManager->getReposirory('AppBundle:Product');
}
public function resolveItemIdentifier($request)
{
if (!$request instanceof Request) {
throw new ItemResolvingException('Invalid request data.');
}
if (!$request->isMethod('POST') && !$request->isMethod('PUT')) {
throw new ItemResolvingException('Invalid request method.');
}
/*
* We're getting here product id via query but you can easily override route
* pattern and use attributes, which are available through request object.
*/
if (!$id = $request->get('id')) {
throw new ItemResolvingException('Error while trying to add item to cart.');
}
return $id;
}
public function resolveAttribute($request)
{
if (!$request instanceof Request) {
throw new ItemResolvingException('Invalid request data.');
}
if (!$request->isMethod('POST') && !$request->isMethod('PUT')) {
throw new ItemResolvingException('Invalid request method.');
}
/*
* We're getting here product id via query but you can easily override route
* pattern and use attributes, which are available through request object.
*/
if (!$attribute = $request->get('attribute')) {
throw new ItemResolvingException('Error while trying to add item to cart.');
}
return $attribute;
}
}
In config file add:
sylius_order:
driver: doctrine/orm
resources:
order_item:
classes:
model: AppBundle\Entity\CartItem
sylius_cart:
resolver: app.cart_item_resolver
And services.xml:
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="app.cart_item_resolver" class="AppBundle\Cart\ItemResolver">
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
</services>
So, when in show single product, have such fatal:
An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Argument 1 passed to Sylius\Component\Core\Model\OrderItemUnit::__construct() must implement interface Sylius\Component\Core\Model\OrderItemInterface, instance of AppBundle\Entity\CartItem given, called in /var/www/html/sylius.local/vendor/sylius/sylius/src/Sylius/Component/Order/Factory/OrderItemUnitFactory.php on line 51 and defined") in AppBundle:Frontend/Product:_single.html.twig at line 24
What could i forget? Anybody has ideas??
the constructor of OrderItemUnit must implement Sylius\Component\Core\Model\OrderItemInterface, but you give AppBundle\Entity\CartItem instead, look this way.
I also see this)) but why, i already have
use Sylius\Component\Cart\Model\CartItem as BaseCartItem;
class CartItem extends BaseCartItem
With Sylius\Component\Cart\Model\CartItem (implement Sylius\Component\Core\Model\OrderItemInterface) all is ok and when i extend it in own CartItem, like in docs,i have this problem:(
Did you also add the CartItem.orm.xml into AppBundle/Resources/config/doctrine ?
of course:
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="AppBundle\Entity\CartItem" table="app_cart_item">
<many-to-one field="product" target-entity="AppBundle\Entity\Product">
<join-column name="product_id" referenced-column-name="id" />
</many-to-one>
<field name="attribute" column="attribute" type="integer" />
</entity>
It seems you try to override the CartItem from Sylius\Component\Cart\Model\CartItem,
so not using a full Sylius installation right ?
Otherwise you must extend Sylius\Component\Core\Model\OrderItem instead.
I use full Sylius instalation, it means that i must extend Sylius\Component\Core\Model\OrderItem?
Yeah.
In fact, everything is glued into CoreBundle, and if it is not enough, you have to override models from here.
Have a look at http://docs.sylius.org/en/latest/customization/model.html
To know which model to extend, you can run
app/console debug:container --parameter=sylius.model.order_item.class
Thank you so much!
Now i use Sylius\Component\Core\Model\OrderItem, have no errors, but after redirect(after adding product to cart) i have empty cart, without any errors.. Idont use my own Controller only CartItem entity and ItemResolver. Any ideas?
Did you :
1) Create a new bundle named AppBundle that extends SyliusWebBundle ?
2) Add your new CartItem entity in AppBundle\Entity that extends Sylius\Component\Core\Model\OrderItem ?
3) Add your OrderItem.orm.xml in the Resource/config/doctrine repository ?
4) Overrided the definition in the sylius.yml configuration as following :
sylius_order:
resources:
order_item:
classes:
model: AppBundle\Entity\OrderItem
5) Defined the Entity.OrderItem.yml in the Resource/config/serializer repository ?
You'd better look at the code in the CoreBundle and not the documentation in the Symfony2 Bundles part.
To clarify things, all these bundles are used to build the Sylius platform you installed, glued into the CoreBundle. These bundles can be used in various projects, not only e-commerce. As you are customizing an E-Commerce platform, check the customization guide here http://docs.sylius.org/en/latest/customization/index.html
1, 2, 3, 4 - Yes.
5 - Nope. I dont see this. it must looks like Sylius\Component\Core\Model\OrderItem ?
I tried this:
AppBundle\Entity\OrderItem:
exclusion_policy: ALL
xml_root_name: order
properties:
variant:
expose: true
relations:
- rel: product
exclusion:
exclude_if: expr(!object.getVariant())
href:
route: sylius_api_product_show
parameters:
id: expr(object.getVariant().getProduct().getId())
- rel: variant
exclusion:
exclude_if: expr(!object.getVariant())
href:
route: sylius_api_product_variant_show
parameters:
id: expr(object.getVariant().getId())
productId: expr(object.getVariant().getProduct().getId())
and have no result.
Here is mine, just added an attribute on my OrderItem (put you code comments into triple backquotes to keep indentation of yml, please :))
AppBundle\Entity\OrderItem:
exclusion_policy: ALL
properties:
status:
expose: true
type: string
Any result(with your variant too).. sory for yml:)
What does prompt your
app/console debug:container | grep controller.order_item
app/console debug:container --parameter=sylius.model.order_item.class
do you have something in your sylius_cart_item ?
No logs in app/logs ?
Did you tried to debug you vendor/sylius/sylius/src/Sylius/Bundle/CartBundle/Controller/CartItemController.php or the overrided one ?
app/console debug:container | grep controller.order_item:
sylius.controller.order_item Sylius\Bundle\OrderBundle\Controller\OrderItemController
sylius.controller.order_item_unit Sylius\Bundle\ResourceBundle\Controller\ResourceController
app/console debug:container --parameter=sylius.model.order_item.class:
`------------------------------- ----------------------------
Parameter Value
sylius.model.order_item.class AppBundle\Entity\OrderItem
------------------------------- ---------------------------- `
I got confused about cart_item & order_item.
Check the CartItemController.php, that's the one :)
I found error in logs, with CartItem form, create my own, add attribute to it. now have An exception has been thrown during the rendering of a template ("The option "product" does not exist
in tamplate it's throwing in this code:
{% set form = sylius_cart_form({'product': product}) %}
Please post such questions on stackoverflow under "sylius" tag, it's the official support channel, maybe someone will be able to help you there.
Most helpful comment
Yeah.
In fact, everything is glued into CoreBundle, and if it is not enough, you have to override models from here.
Have a look at http://docs.sylius.org/en/latest/customization/model.html
To know which model to extend, you can run
app/console debug:container --parameter=sylius.model.order_item.class