Merge pull request #6134 from Zales0123/merge-cart-into-order

[Cart][Order] Merge Cart into Order
This commit is contained in:
Michał Marcinkowski 2016-09-22 09:23:04 +02:00 committed by GitHub
commit cf65873491
220 changed files with 952 additions and 3712 deletions

View file

@ -3,6 +3,10 @@ UPGRADE
## From 0.19 to 1.0.0-alpha ## From 0.19 to 1.0.0-alpha
### CartBundle
* Merge ``Cart`` component and ``CartBundle`` into ``Order\Core`` component and ``Order\CoreBundle``.
### WebBundle ### WebBundle
* Removed ``WebBundle``. See ``ShopBundle`` for the website and ``AdminBundle`` for administration-related. * Removed ``WebBundle``. See ``ShopBundle`` for the website and ``AdminBundle`` for administration-related.

View file

@ -0,0 +1,34 @@
<?php
namespace Sylius\Migrations;
use Doctrine\DBAL\Migrations\AbstractMigration;
use Doctrine\DBAL\Schema\Schema;
/**
* Auto-generated Migration: Please modify to your needs!
*/
class Version20160916102213 extends AbstractMigration
{
/**
* @param Schema $schema
*/
public function up(Schema $schema)
{
// this up() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE sylius_order DROP expires_at');
}
/**
* @param Schema $schema
*/
public function down(Schema $schema)
{
// this down() migration is auto-generated, please modify it to your needs
$this->abortIf($this->connection->getDatabasePlatform()->getName() != 'mysql', 'Migration can only be executed safely on \'mysql\'.');
$this->addSql('ALTER TABLE sylius_order ADD expires_at DATETIME NOT NULL');
}
}

View file

@ -107,8 +107,6 @@
"sylius/api-bundle": "self.version", "sylius/api-bundle": "self.version",
"sylius/attribute": "self.version", "sylius/attribute": "self.version",
"sylius/attribute-bundle": "self.version", "sylius/attribute-bundle": "self.version",
"sylius/cart": "self.version",
"sylius/cart-bundle": "self.version",
"sylius/contact": "self.version", "sylius/contact": "self.version",
"sylius/contact-bundle": "self.version", "sylius/contact-bundle": "self.version",
"sylius/content-bundle": "self.version", "sylius/content-bundle": "self.version",

4
composer.lock generated
View file

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"hash": "05caca106f21c28a54127196c06fe568", "hash": "d308d31d83d68c7ccd95683741636967",
"content-hash": "123d4c1758852746f34859c4b6bc8ecd", "content-hash": "eee22d786706c5a0524d00d64c57a8fa",
"packages": [ "packages": [
{ {
"name": "behat/transliterator", "name": "behat/transliterator",

View file

@ -1,22 +0,0 @@
SyliusCartBundle
================
A generic solution for a cart system inside a Symfony application.
It doesn't matter if you are starting a new project or you need to implement this feature for an existing system - this bundle should be helpful.
Currently only the Doctrine ORM driver is implemented, so we'll use it here as an example.
There are two main models inside the bundle, `Cart` and `CartItem`.
There are also 2 main services, **Provider** and **ItemResolver**.
You'll get familiar with them in further parts of the documentation.
.. toctree::
:numbered:
installation
models
actions
services
templating
summary

View file

@ -1,371 +0,0 @@
Installation
============
We assume you're familiar with `Composer <http://packagist.org>`_, a dependency manager for PHP.
Use the following command to add the bundle to your `composer.json` and download package.
If you have `Composer installed globally <http://getcomposer.org/doc/00-intro.md#globally>`_.
.. code-block:: bash
$ composer require sylius/cart-bundle
Otherwise you have to download .phar file.
.. code-block:: bash
$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require sylius/cart-bundle
Adding required bundles to the kernel
-------------------------------------
First, you need to enable the bundle inside the kernel. If you're not using
any other Sylius bundles, you will also need to add the following bundles and
their dependencies to the kernel:
- `SyliusResourceBundle`
- `SyliusMoneyBundle`
- `SyliusOrderBundle`
Don't worry, everything was automatically installed via Composer.
.. note::
Please register the bundle **before** *DoctrineBundle*. This is important
as we use listeners which have to be processed first. It is generally a
good idea to place all of the Sylius bundles at the beginning of the
bundles list, as it is done in the `Sylius-Standard` project.
.. code-block:: php
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
new Sylius\Bundle\ResourceBundle\SyliusResourceBundle(),
new Sylius\Bundle\MoneyBundle\SyliusMoneyBundle(),
new Sylius\Bundle\OrderBundle\SyliusOrderBundle(),
new Sylius\Bundle\CartBundle\SyliusCartBundle(),
// Other bundles...
new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
new FOS\RestBundle\FOSRestBundle(),
new JMS\SerializerBundle\JMSSerializerBundle($this),
);
}
Creating your entities
----------------------
This is no longer a required step in the latest version of the
`SyliusCartBundle`, and if you are happy with the default implementation (which
is ``Sylius\Bundle\CartBundle\Model\CartItem``), you can just skip to the next
section.
You can create your **CartItem** entity, living inside your application code.
We think that **keeping the application-specific and simple bundle structure** is a good practice, so
let's assume you have your ``AppBundle`` registered under ``App\AppBundle`` namespace.
.. code-block:: php
<?php
// src/App/AppBundle/Entity/CartItem.php
namespace App\AppBundle\Entity;
use Sylius\Component\Cart\Model\CartItem as BaseCartItem;
class CartItem extends BaseCartItem
{
}
Now we need to define a simple mapping for this entity to map its fields.
You should create a mapping file in your ``AppBundle``, put it inside the doctrine mapping directory ``src/App/AppBundle/Resources/config/doctrine/CartItem.orm.xml``.
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="App\AppBundle\Entity\CartItem" table="app_cart_item">
</entity>
</doctrine-mapping>
You do **not** have to map the *ID* field because it is already mapped in the
``Sylius\Component\Cart\Model\CartItem`` class, together with the relation
between **Cart** and **CartItem**.
Let's assume you have a *Product* entity, which represents your main merchandise within your webshop.
.. note::
Please remember that you can use anything else, *Product* here is just an obvious example, but it will work in a similar way with other entities.
We need to modify the *CartItem* entity and its mapping a bit, so it allows us to put a product inside the cart item.
.. code-block:: php
<?php
// src/App/AppBundle/Entity/CartItem.php
namespace App\AppBundle\Entity;
use Sylius\Component\Cart\Model\CartItem as BaseCartItem;
class CartItem extends BaseCartItem
{
private $product;
public function getProduct()
{
return $this->product;
}
public function setProduct(Product $product)
{
$this->product = $product;
}
}
We added a "product" property, and a simple getter and setter.
We have to also map the *Product* to *CartItem*, let's create this relation in mapping files.
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="App\AppBundle\Entity\CartItem" table="app_cart_item">
<many-to-one field="product" target-entity="App\AppBundle\Entity\Product">
<join-column name="product_id" referenced-column-name="id" />
</many-to-one>
</entity>
</doctrine-mapping>
Similarly, you can create a custom entity for orders. The class that you need
to extend is ``Sylius\Component\Cart\Model\Cart``. Carts and Orders in
Sylius are in fact the same thing. Do not forget to create the mapping file.
But, again, do not put a mapping for the *ID* field — it is already mapped in
the parent class.
And that would be all about entities. Now we need to create a really simple service.
Creating ItemResolver service
-----------------------------
The **ItemResolver** will be used by the controller to resolve the new cart item - based on a user request information.
Its only requirement is to implement ``Sylius\Component\Cart\Resolver\ItemResolverInterface``.
.. code-block:: php
<?php
// src/App/AppBundle/Cart/ItemResolver.php
namespace App\AppBundle\Cart;
use Sylius\Component\Cart\Model\CartItemInterface;
use Sylius\Component\Cart\Resolver\ItemResolverInterface;
class ItemResolver implements ItemResolverInterface
{
public function resolve(CartItemInterface $item, $request)
{
}
}
The class is in place, well done.
We need to do some more coding, so the service is actually doing its job.
In our example we want to put *Product* in our cart, so we should
inject the entity manager into our resolver service.
.. code-block:: php
<?php
// src/App/AppBundle/Cart/ItemResolver.php
namespace App\AppBundle\Cart;
use Sylius\Component\Cart\Model\CartItemInterface;
use Sylius\Component\Cart\Resolver\ItemResolverInterface;
use Doctrine\ORM\EntityManager;
class ItemResolver implements ItemResolverInterface
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function resolve(CartItemInterface $item, $request)
{
}
private function getProductRepository()
{
return $this->entityManager->getRepository('AppBundle:Product');
}
}
We also added a simple method ``getProductRepository()`` to keep the resolving code cleaner.
We must use this repository to find a product with `id`, given by the user via the request.
This can be done in various ways, but to keep the example simple - we'll use a query parameter.
.. code-block:: php
<?php
// src/App/AppBundle/Cart/ItemResolver.php
namespace App\AppBundle\Cart;
use Sylius\Component\Cart\Model\CartItemInterface;
use Sylius\Component\Cart\Resolver\ItemResolverInterface;
use Sylius\Component\Cart\Resolver\ItemResolvingException;
use Doctrine\ORM\EntityManager;
class ItemResolver implements ItemResolverInterface
{
private $entityManager;
public function __construct(EntityManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function resolve(CartItemInterface $item, $request)
{
$productId = $request->query->get('productId');
// 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');
}
// Assign the product to the item and define the unit price.
$item->setVariant($product);
$item->setUnitPrice($product->getPrice());
// Everything went fine, return the item.
return $item;
}
private function getProductRepository()
{
return $this->entityManager->getRepository('AppBundle:Product');
}
}
.. note::
Please remember that **item accepts only integers as price and quantity**.
Register our brand new service in the container. We'll use XML as an example, but you are free to pick any other format.
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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="App\AppBundle\Cart\ItemResolver">
<argument type="service" id="doctrine.orm.entity_manager" />
</service>
</services>
</container>
The bundle requires also a simple configuration...
Container configuration
-----------------------
Put this minimal configuration inside your ``app/config/config.yml``.
.. code-block:: yaml
sylius_cart:
resolver: app.cart_item_resolver # The id of our newly created service.
classes: ~ # This key can be empty but it must be present in the configuration.
sylius_order:
driver: doctrine/orm # Configure the doctrine orm driver used in documentation.
sylius_money: ~
**Or**, if you have created any custom entities, use this:
.. code-block:: yaml
sylius_cart:
resolver: app.cart_item_resolver # The id of our newly created service.
classes: ~ # This key can be empty but it must be present in the configuration.
sylius_order:
driver: doctrine/orm # Configure the doctrine orm driver used in documentation.
classes:
order:
model: App\AppBundle\Entity\Cart # If you have created a custom Cart entity.
order_item:
model: App\AppBundle\Entity\CartItem # If you have created a custom CartItem entity.
sylius_money: ~
Importing routing configuration
-------------------------------
Import the default routing from your ``app/config/routing.yml``.
.. code-block:: yaml
sylius_cart:
resource: "@SyliusCartBundle/Resources/config/routing.yml"
prefix: /cart
Updating database schema
------------------------
Remember to update your database schema.
For "**doctrine/orm**" driver run the following command.
.. code-block:: bash
$ php app/console doctrine:schema:update --force
.. warning::
This should be done only in **dev** environment! We recommend using Doctrine migrations, to safely update your schema.
Templates
---------
We think that providing a sensible default template is really difficult, especially when a cart summary is not the simplest page.
This is the reason why we do not currently include any, but if you have an idea for a good starter template, let us know!
The bundle requires only the ``summary.html.twig`` template for cart summary page.
The easiest way to override the view is by placing it here ``app/Resources/SyliusCartBundle/views/Cart/summary.html.twig``.
.. note::
You can use `the templates from our Sylius app as inspiration <https://github.com/Sylius/Sylius/blob/master/src/Sylius/Bundle/WebBundle/Resources/views/Frontend/Cart/summary.html.twig>`_.

View file

@ -1,54 +0,0 @@
The Cart and CartItem
=====================
Here is a quick reference of what the default models can do for you.
Cart
----
You can access the cart total value using the ``->getTotal()`` method. The denormalized number of cart items is available via ``->getTotalItems()`` method.
Recalculation of totals can happen by calling ``->calculateTotal()`` method, using the simplest possible math. It will also update the item totals.
The carts have their expiration time - ``->getExpiresAt()`` returns that time and ``->incrementExpiresAt()`` sets it to +3 hours from now by default.
The collection of items (Implementing the ``Doctrine\Common\Collections\Collection`` interface) can be obtained using the ``->getItems()``.
CartItem
--------
Just like for the cart, the total is available via the same method (``->getTotal()``), but the unit price is accessible using the ``->getUnitPrice()``
Each item also can calculate its total, using the quantity (``->getQuantity()``) and the unit price.
It also has a very important method called ``->equals(CartItemInterface $item)``, which decides whether the items are "same" or not.
If they are, it should return *true*, *false* otherwise. This is taken into account when adding an item to the cart.
**If the added item is equal to an existing one, their quantities are summed, but no new item is added to the cart**.
By default, it compares the ids, but for our example we would prefer to check the products. We can easily modify our *CartItem* entity to do that correctly.
.. code-block:: php
<?php
// src/App/AppBundle/Entity/CartItem.php
namespace App/AppBundle/Entity;
use Sylius\Bundle\Component\Cart\CartItem as BaseCartItem;
use Sylius\Bundle\Component\Cart\CartItemInterface;
class CartItem extends BaseCartItem
{
private $product;
public function getProduct()
{
return $this->product;
}
public function setProduct(Product $product)
{
$this->product = $product;
}
public function equals(CartItemInterface $item)
{
return $this->product === $item->getProduct();
}
}
If the user tries to add the same product twice or more, it will just sum the quantities, instead of adding duplicates to the cart.

View file

@ -1,64 +0,0 @@
Using the services
==================
When using the bundle, you have access to several handy services.
You can use them to manipulate and manage the cart.
Managers and Repositories
-------------------------
.. note::
Sylius uses ``Doctrine\Common\Persistence`` interfaces.
You have access to following services which are used to manage and retrieve resources.
This set of default services is shared across almost all Sylius bundles, but this is just a convention.
You're interacting with them like you usually do with own entities in your project.
.. code-block:: php
<?php
// ...
public function saveAction(Request $request)
{
// ObjectManager which is capable of managing the Cart resource.
// For *doctrine/orm* driver it will be EntityManager.
$this->get('sylius.manager.cart');
// ObjectRepository for the Cart resource, it extends the base EntityRepository.
// You can use it like usual entity repository in project.
$this->get('sylius.repository.cart');
// Same pair for CartItem resource.
$this->get('sylius.manager.cart_item');
$this->get('sylius.repository.cart_item');
// Those repositories have some handy default methods, for example...
$item = $this->get('sylius.repository.cart')->createNew();
}
Provider
--------
There is also 1 more service for you.
You use the provider to obtain the current user cart, if there is none, a new one is created and saved.
The ``->setCart()`` method also allows you to replace the current cart.
``->abandonCart()`` is resetting the current cart, a new one will be created on the next ``->getCart()`` call.
This is useful, for example, when after completing an order you want to start with a brand new and clean cart.
.. code-block:: php
<?php
// ...
public function saveAction(Request $request)
{
$provider = $this->get('sylius.cart_provider'); // Implements the CartProviderInterface.
$currentCart = $provider->getCart();
$provider->setCart($customCart);
$provider->abandonCart();
}

View file

@ -1,45 +0,0 @@
Summary
=======
Configuration reference
-----------------------
.. code-block:: yaml
sylius_cart:
# The driver used for persistence layer.
driver: ~
# Service id of cart item resolver.
resolver: ~
# Cart provider service id.
provider: sylius.cart_provider.default
# The id of cart storage for default provider.
storage: sylius.cart_storage.session
resources:
cart:
classes:
controller: Sylius\Bundle\CartBundle\Controller\CartController
form: Sylius\Bundle\CartBundle\Form\Type\CartType
validation_groups:
default: [ sylius ]
cart_item:
classes:
controller: Sylius\Bundle\CartBundle\Controller\CartItemController
form: Sylius\Bundle\CartBundle\Form\Type\CartItemType
validation_groups:
default: [ sylius ]
`phpspec2 <http://phpspec.net>`_ examples
-----------------------------------------
.. code-block:: bash
$ composer install
$ bin/phpspec run -f pretty
Bug tracking
------------
This bundle uses `GitHub issues <https://github.com/Sylius/Sylius/issues>`_.
If you have found bug, please create an issue.

View file

@ -1,30 +0,0 @@
In templates
============
When using Twig as your template engine, you have access to 2 handy functions.
The ``sylius_cart_get`` function uses the provider to get the current cart.
.. code-block:: jinja
{% set cart = sylius_cart_get() %}
Current cart totals: {{ cart.total }} for {{ cart.totalItems }} items!
The ``sylius_cart_form`` returns the form view for the CartItem form. It allows you to easily build more complex actions for
adding items to cart. In this simple example we allow to provide the quantity of item. You'll need to process this form in your resolver.
.. code-block:: jinja
{% set form = sylius_cart_form({'product': product}) %} {# You can pass options as an argument. #}
<form action="{{ path('sylius_cart_item_add', {'productId': product.id}) }}" method="post">
{{ form_row(form.quantity)}}
{{ form_widget(form._token) }}
<input type="submit" value="Add to cart">
</form>
.. note::
An example with multiple variants of this form `can be found in Sylius Sandbox app <https://github.com/Sylius/Sylius-Sandbox/blob/master/src/Sylius/Bundle/SandboxBundle/Form/Type/CartItemType.php>`_.
It allows for selecting a variation/options/quantity of the product. It also adapts to the product type.

View file

@ -14,5 +14,6 @@ It also includes a super flexible adjustments feature, which serves as a basis f
adjustments adjustments
builder builder
services services
cart_actions
summary summary
processors processors

View file

@ -7,7 +7,6 @@ Symfony Bundles
general/index general/index
SyliusAddressingBundle/index SyliusAddressingBundle/index
SyliusAttributeBundle/index SyliusAttributeBundle/index
SyliusCartBundle/index
SyliusFixturesBundle/index SyliusFixturesBundle/index
SyliusGridBundle/index SyliusGridBundle/index
SyliusInventoryBundle/index SyliusInventoryBundle/index

View file

@ -1,7 +1,6 @@
* :doc:`/bundles/general/index` * :doc:`/bundles/general/index`
* :doc:`/bundles/SyliusAddressingBundle/index` * :doc:`/bundles/SyliusAddressingBundle/index`
* :doc:`/bundles/SyliusAttributeBundle/index` * :doc:`/bundles/SyliusAttributeBundle/index`
* :doc:`/bundles/SyliusCartBundle/index`
* :doc:`/bundles/SyliusFixturesBundle/index` * :doc:`/bundles/SyliusFixturesBundle/index`
* :doc:`/bundles/SyliusGridBundle/index` * :doc:`/bundles/SyliusGridBundle/index`
* :doc:`/bundles/SyliusInventoryBundle/index` * :doc:`/bundles/SyliusInventoryBundle/index`

View file

@ -1,29 +0,0 @@
Basic Usage
===========
.. note::
The cart is basically an order with an appropriate state.
Check Order's :doc:`/components/Order/state_machine`.
.. hint::
For more examples go to Order :doc:`/components/Order/basic_usage`.
CartContext
-----------
The **CartContext** provides you with useful tools to
set and retrieve current cart identifier based on storage.
.. code-block:: php
<?php
use Sylius\Component\Cart\Context\CartContext;
use Sylius\Component\Cart;
$context = new CartContext();
$cart = new Cart();
$currentCartIdentifier = $context->getCurrentCartIdentifier();
$context->setCurrentCartIdentifier($cart);
$context->resetCurrentCartIdentifier();

View file

@ -1,13 +0,0 @@
Cart
====
Common models, services and interface to handle a shopping cart in PHP e-commerce application.
It is strictly related to Order model.
.. toctree::
:maxdepth: 2
installation
basic_usage
models
interfaces

View file

@ -1,11 +0,0 @@
Installation
============
You can install the component in 2 different ways:
* :doc:`Install it via Composer </components/general/using_components>` (``sylius/cart`` on `Packagist`_);
* Use the official Git repository (https://github.com/Sylius/Cart).
.. include:: /components/require_autoload.rst.inc
.. _Packagist: https://packagist.org/packages/sylius/cart

View file

@ -1,105 +0,0 @@
Interfaces
==========
Model Interfaces
----------------
.. _component_cart_model_cart-interface:
CartInterface
~~~~~~~~~~~~~
This interface should be implemented by model representing a single Cart.
.. note::
This interface extends the :ref:`component_order_model_order-interface`
For more detailed information go to `Sylius API CartInterface`_.
.. _Sylius API CartInterface: http://api.sylius.org/Sylius/Component/Cart/Model/CartInterface.html
.. _component_cart_model_cart-item-interface:
CartItemInterface
~~~~~~~~~~~~~~~~~
This interface should be implemented by model representing a single CartItem.
.. note::
This interface extends the :ref:`component_order_model_order-item-interface`
For more detailed information go to `Sylius API CartItemInterface`_.
.. _Sylius API CartItemInterface: http://api.sylius.org/Sylius/Component/Cart/Model/CartItemInterface.html
Service Interfaces
------------------
.. _component_cart_provider_cart-provider-interface:
CartProviderInterface
~~~~~~~~~~~~~~~~~~~~~
A cart provider retrieves existing cart or create new one based on the storage. To characterize an object which is a **Provider**,
it needs to implement the ``CartProviderInterface``.
.. note::
For more detailed information go to `Sylius API CartProviderInterface`_.
.. _Sylius API CartProviderInterface: http://api.sylius.org/Sylius/Component/Cart/Provider/CartProviderInterface.html
.. _component_cart_purger_purger-interface:
PurgerInterface
~~~~~~~~~~~~~~~
A cart purger purges all expired carts. To characterize an object which is a **Purger**, it needs to implement the ``PurgerInterface``.
.. note::
For more detailed information go to `Sylius API PurgerInterface`_.
.. _Sylius API PurgerInterface: http://api.sylius.org/Sylius/Component/Cart/Purger/PurgerInterface.html
.. _component_cart_resolver_item-resolver-interface:
ItemResolverInterface
~~~~~~~~~~~~~~~~~~~~~
A cart resolver returns cart item that needs to be added based on given data. To characterize an object which is a **Resolver**,
it needs to implement the ``ItemResolverInterface``.
.. note::
For more detailed information go to `Sylius API ItemResolverInterface`_.
.. _Sylius API ItemResolverInterface: http://api.sylius.org/Sylius/Component/Cart/Resolver/ItemResolverInterface.html
.. caution::
This method throws `ItemResolvingException`_ if an error occurs.
.. _ItemResolvingException: http://api.sylius.org/Sylius/Component/Cart/Resolver/ItemResolvingException.html
.. _component_cart_repository_cart-repository-interface:
CartRepositoryInterface
~~~~~~~~~~~~~~~~~~~~~~~
In order to decouple from storage that provides expired carts, you should create repository class which implements this interface.
.. note::
This interface extends the :ref:`component_order_repository_order-repository-interface`
For more detailed information go to `Sylius API CartRepositoryInterface`_.
.. _Sylius API CartRepositoryInterface: http://api.sylius.org/Sylius/Component/Cart/Repository/CartRepositoryInterface.html
CartContextInterface
~~~~~~~~~~~~~~~~~~~~
This interface is implemented by the services responsible for setting and retrieving current cart identifier based on storage.
To characterize an object which is a **CartContext** it needs to implement the ``CartContextInterface``
.. note::
For more detailed information go to `Sylius API CartContextInterface`_.
.. _Sylius API CartContextInterface: http://api.sylius.org/Sylius/Component/Cart/Context/CartContextInterface.html

View file

@ -1,30 +0,0 @@
Models
======
.. _component_cart_model_cart:
Cart
----
The cart is represented by **Cart** instance. It inherits all the properties from :ref:`component_order_model_order` and add one property:
+-----------------+-------------------------------------+------------+
| Method | Description | Type |
+=================+=====================================+============+
| expiresAt | Expiration time | \DateTime |
+-----------------+-------------------------------------+------------+
.. note::
This model implements the :ref:`component_cart_model_cart-interface`
.. _component_cart_model_cart-item:
CartItem
--------
The items of the cart are represented by the **CartItem** instances. **CartItem** has no properties but it inherits from :ref:`component_order_model_order-item`.
.. note::
This model implements the :ref:`component_cart_model_cart-item-interface`

View file

@ -16,7 +16,6 @@ We recommend checking out :doc:`/components/general/index`, which will get you s
general/index general/index
Addressing/index Addressing/index
Attribute/index Attribute/index
Cart/index
Channel/index Channel/index
Currency/index Currency/index
Grid/index Grid/index

View file

@ -1,7 +1,6 @@
* :doc:`/components/general/index` * :doc:`/components/general/index`
* :doc:`/components/Addressing/index` * :doc:`/components/Addressing/index`
* :doc:`/components/Attribute/index` * :doc:`/components/Attribute/index`
* :doc:`/components/Cart/index`
* :doc:`/components/Channel/index` * :doc:`/components/Channel/index`
* :doc:`/components/Currency/index` * :doc:`/components/Currency/index`
* :doc:`/components/Grid/index` * :doc:`/components/Grid/index`

View file

@ -3,7 +3,6 @@ suites:
Addressing: { namespace: Sylius\Component\Addressing, psr4_prefix: Sylius\Component\Addressing, spec_path: src/Sylius/Component/Addressing, src_path: src/Sylius/Component/Addressing } Addressing: { namespace: Sylius\Component\Addressing, psr4_prefix: Sylius\Component\Addressing, spec_path: src/Sylius/Component/Addressing, src_path: src/Sylius/Component/Addressing }
Archetype: { namespace: Sylius\Component\Archetype, psr4_prefix: Sylius\Component\Archetype, spec_path: src/Sylius/Component/Archetype, src_path: src/Sylius/Component/Archetype } Archetype: { namespace: Sylius\Component\Archetype, psr4_prefix: Sylius\Component\Archetype, spec_path: src/Sylius/Component/Archetype, src_path: src/Sylius/Component/Archetype }
Attribute: { namespace: Sylius\Component\Attribute, psr4_prefix: Sylius\Component\Attribute, spec_path: src/Sylius/Component/Attribute, src_path: src/Sylius/Component/Attribute } Attribute: { namespace: Sylius\Component\Attribute, psr4_prefix: Sylius\Component\Attribute, spec_path: src/Sylius/Component/Attribute, src_path: src/Sylius/Component/Attribute }
Cart: { namespace: Sylius\Component\Cart, psr4_prefix: Sylius\Component\Cart, spec_path: src/Sylius/Component/Cart, src_path: src/Sylius/Component/Cart }
Channel: { namespace: Sylius\Component\Channel, psr4_prefix: Sylius\Component\Channel, spec_path: src/Sylius/Component/Channel, src_path: src/Sylius/Component/Channel } Channel: { namespace: Sylius\Component\Channel, psr4_prefix: Sylius\Component\Channel, spec_path: src/Sylius/Component/Channel, src_path: src/Sylius/Component/Channel }
Contact: { namespace: Sylius\Component\Contact, psr4_prefix: Sylius\Component\Contact, spec_path: src/Sylius/Component/Contact, src_path: src/Sylius/Component/Contact } Contact: { namespace: Sylius\Component\Contact, psr4_prefix: Sylius\Component\Contact, spec_path: src/Sylius/Component/Contact, src_path: src/Sylius/Component/Contact }
Core: { namespace: Sylius\Component\Core, psr4_prefix: Sylius\Component\Core, spec_path: src/Sylius/Component/Core, src_path: src/Sylius/Component/Core } Core: { namespace: Sylius\Component\Core, psr4_prefix: Sylius\Component\Core, spec_path: src/Sylius/Component/Core, src_path: src/Sylius/Component/Core }
@ -36,7 +35,6 @@ suites:
ApiBundle: { namespace: Sylius\Bundle\ApiBundle, psr4_prefix: Sylius\Bundle\ApiBundle, spec_path: src/Sylius/Bundle/ApiBundle, src_path: src/Sylius/Bundle/ApiBundle } ApiBundle: { namespace: Sylius\Bundle\ApiBundle, psr4_prefix: Sylius\Bundle\ApiBundle, spec_path: src/Sylius/Bundle/ApiBundle, src_path: src/Sylius/Bundle/ApiBundle }
ArchetypeBundle: { namespace: Sylius\Bundle\ArchetypeBundle, psr4_prefix: Sylius\Bundle\ArchetypeBundle, spec_path: src/Sylius/Bundle/ArchetypeBundle, src_path: src/Sylius/Bundle/ArchetypeBundle } ArchetypeBundle: { namespace: Sylius\Bundle\ArchetypeBundle, psr4_prefix: Sylius\Bundle\ArchetypeBundle, spec_path: src/Sylius/Bundle/ArchetypeBundle, src_path: src/Sylius/Bundle/ArchetypeBundle }
AttributeBundle: { namespace: Sylius\Bundle\AttributeBundle, psr4_prefix: Sylius\Bundle\AttributeBundle, spec_path: src/Sylius/Bundle/AttributeBundle, src_path: src/Sylius/Bundle/AttributeBundle } AttributeBundle: { namespace: Sylius\Bundle\AttributeBundle, psr4_prefix: Sylius\Bundle\AttributeBundle, spec_path: src/Sylius/Bundle/AttributeBundle, src_path: src/Sylius/Bundle/AttributeBundle }
CartBundle: { namespace: Sylius\Bundle\CartBundle, psr4_prefix: Sylius\Bundle\CartBundle, spec_path: src/Sylius/Bundle/CartBundle, src_path: src/Sylius/Bundle/CartBundle }
ChannelBundle: { namespace: Sylius\Bundle\ChannelBundle, psr4_prefix: Sylius\Bundle\ChannelBundle, spec_path: src/Sylius/Bundle/ChannelBundle, src_path: src/Sylius/Bundle/ChannelBundle } ChannelBundle: { namespace: Sylius\Bundle\ChannelBundle, psr4_prefix: Sylius\Bundle\ChannelBundle, spec_path: src/Sylius/Bundle/ChannelBundle, src_path: src/Sylius/Bundle/ChannelBundle }
ContactBundle: { namespace: Sylius\Bundle\ContactBundle, psr4_prefix: Sylius\Bundle\ContactBundle, spec_path: src/Sylius/Bundle/ContactBundle, src_path: src/Sylius/Bundle/ContactBundle } ContactBundle: { namespace: Sylius\Bundle\ContactBundle, psr4_prefix: Sylius\Bundle\ContactBundle, spec_path: src/Sylius/Bundle/ContactBundle, src_path: src/Sylius/Bundle/ContactBundle }
ContentBundle: { namespace: Sylius\Bundle\ContentBundle, psr4_prefix: Sylius\Bundle\ContentBundle, spec_path: src/Sylius/Bundle/ContentBundle, src_path: src/Sylius/Bundle/ContentBundle } ContentBundle: { namespace: Sylius\Bundle\ContentBundle, psr4_prefix: Sylius\Bundle\ContentBundle, spec_path: src/Sylius/Bundle/ContentBundle, src_path: src/Sylius/Bundle/ContentBundle }

View file

@ -264,7 +264,7 @@ class SummaryPage extends SymfonyPage implements SummaryPageInterface
'cart_items' => '#sylius-cart-items', 'cart_items' => '#sylius-cart-items',
'cart_total' => '#sylius-cart-button', 'cart_total' => '#sylius-cart-button',
'clear_button' => '#sylius-cart-clear', 'clear_button' => '#sylius-cart-clear',
'coupon_field' => '#sylius_cart_promotionCoupon', 'coupon_field' => '#sylius_order_promotionCoupon',
'grand_total' => '#sylius-cart-grand-total', 'grand_total' => '#sylius-cart-grand-total',
'product_discounted_total' => '#sylius-cart-items tr:contains("%name%") .sylius-discounted-total', 'product_discounted_total' => '#sylius-cart-items tr:contains("%name%") .sylius-discounted-total',
'product_row' => '#sylius-cart-items tbody tr:contains("%name%")', 'product_row' => '#sylius-cart-items tbody tr:contains("%name%")',

View file

@ -1,5 +0,0 @@
vendor/
bin/
composer.phar
composer.lock

View file

@ -1,63 +0,0 @@
CHANGELOG
=========
### v0.10.0
* Twig extension was renamed from `SyliusCartExtension` into `CartExtension`,
also the service name was changed from `sylius.cart_twig` to `sylius.twig.extension.cart`.
### v0.9.0
* Release before components.
* Fixed double cart refresh.
### v0.8.0
* Convert translation files to YAML.
### v0.7.0
* Introduce cart provider events.
### v0.6.0
* Release before components introduction. (delayed)
### v0.5.0
* Symfony 2.3 compatible version.
* Removed `Entity` classes.
* Based on SyliusSalesBundle order model.
### v0.4.0
* Last Symfony 2.2 compatible version.
### v0.3.0
* Remove `CartOperator` & `CartOperatorInterface`.
* Introduce `SyliusCartEvents` & event listeners.
* Removed the ``sylius_cart`` prefix from services and models, used ``sylius`` instead.
* All money values are represented as integers.
### v0.2.0
* Introduce default cart entity.
* Use Doctrine RTEL to map interfaces instead of real entities.
* Rename `CartController::showAction` to `CartController::summaryAction`.
* Renamed `SyliusCartBundle:Cart:show.html` template to ``SyliusCartBundle:Cart:summary.html`.
* Add base controller.
### v0.1.0
* First development release.
* Introduced ItemResolvingException.
* More complete set of [phpspec2](http://phpspec.net) examples.
* Changed configuration schema.
* Bundle now uses [SyliusResourceBundle](http://github.com/Sylius/SyliusResourceBundle) for model persistence.
* Models now depend on Doctrine collections.
* New controller.
* Renamed **Item** to **CartItem**.
* Renamed **ItemType** to **CartItemType**.
* Introduce specs with [phpspec2](http://phpspec.net).
* Renamed **CartFormType** to **CartType** to be consistent.

View file

@ -1,42 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Command;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* Command to purge expired carts
*
* @author Alexandre Bacco <alexandre.bacco@gmail.com>
*/
class PurgeCartsCommand extends ContainerAwareCommand
{
protected function configure()
{
$this
->setName('sylius:cart:purge')
->setDescription('Purge expired carts')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln('Purging expired carts...');
$cartsPurger = $this->getContainer()->get('sylius.cart.purger');
$cartsPurger->purge();
$output->writeln('Expired carts purged.');
}
}

View file

@ -1,147 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Controller;
use FOS\RestBundle\View\View;
use Sylius\Component\Cart\SyliusCartEvents;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
* @author Grzegorz Sadowski <grzegorz.sadowski@lakion.com>
*/
class CartController extends Controller
{
/**
* @param Request $request
*
* @return Response
*/
public function summaryAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$cart = $this->getCurrentCart();
$form = $this->resourceFormFactory->create($configuration, $cart);
$view = View::create()
->setTemplate($configuration->getTemplate('summary.html'))
->setData([
'cart' => $cart,
'form' => $form->createView(),
])
;
return $this->viewHandler->handle($configuration, $view);
}
/**
* @param Request $request
*
* @return Response
*/
public function saveAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::UPDATE);
$resource = $this->getCurrentCart();
$form = $this->resourceFormFactory->create($configuration, $resource);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH']) && $form->submit($request, !$request->isMethod('PATCH'))->isValid()) {
$resource = $form->getData();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToResource($configuration, $resource);
}
if ($configuration->hasStateMachine()) {
$this->stateMachine->apply($configuration, $resource);
}
$this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->getEventDispatcher()->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($resource));
$this->manager->flush();
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
return $this->redirectHandler->redirectToResource($configuration, $resource);
}
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
}
$view = View::create()
->setData([
'configuration' => $configuration,
$this->metadata->getName() => $resource,
'form' => $form->createView(),
])
->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
;
return $this->viewHandler->handle($configuration, $view);
}
/**
* @param Request $request
*
* @return Response
*/
public function clearAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::DELETE);
$resource = $this->getCurrentCart();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
$this->repository->remove($resource);
$this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
}

View file

@ -1,162 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Controller;
use Doctrine\ORM\EntityManagerInterface;
use FOS\RestBundle\View\View;
use Sylius\Component\Cart\CartActions;
use Sylius\Component\Cart\Modifier\CartModifierInterface;
use Sylius\Component\Cart\SyliusCartEvents;
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpException;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
* @author Grzegorz Sadowski <grzegorz.sadowski@lakion.com>
*/
class CartItemController extends Controller
{
/**
* @param Request $request
*
* @return Response
*/
public function addAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::CREATE);
$newResource = $this->newResourceFactory->create($configuration, $this->factory);
$this->getItemQuantityModifier()->modify($newResource, 1);
$form = $this->resourceFormFactory->create($configuration, $newResource);
if ($request->isMethod('POST') && $form->submit($request)->isValid()) {
$newResource = $form->getData();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $newResource);
}
$cart = $this->getCurrentCart();
$this->getCartModifier()->addToCart($cart, $newResource);
$cartManager = $this->getCartManager();
$cartManager->persist($cart);
$cartManager->flush();
$this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
return $this->redirectHandler->redirectToResource($configuration, $newResource);
}
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
}
$view = View::create()
->setData([
'configuration' => $configuration,
$this->metadata->getName() => $newResource,
'form' => $form->createView(),
])
->setTemplate($configuration->getTemplate(CartActions::ADD . '.html'))
;
return $this->viewHandler->handle($configuration, $view);
}
/**
* @param Request $request
*
* @return Response
*/
public function removeAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::DELETE);
$resource = $this->findOr404($configuration);
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
$cart = $this->getCurrentCart();
$this->getCartModifier()->removeFromCart($cart, $resource);
$this->repository->remove($resource);
$cartManager = $this->getCartManager();
$cartManager->persist($cart);
$cartManager->flush();
$this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
/**
* @return OrderItemQuantityModifierInterface
*/
private function getItemQuantityModifier()
{
return $this->get('sylius.order_item_quantity_modifier');
}
/**
* @return CartModifierInterface
*/
private function getCartModifier()
{
return $this->get('sylius.cart.cart_modifier');
}
/**
* @return EntityManagerInterface
*/
private function getCartManager()
{
return $this->get('sylius.manager.cart');
}
}

View file

@ -1,71 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Controller;
use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Sylius\Component\Cart\Context\CartContextInterface;
use Sylius\Component\Cart\Model\CartInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
abstract class Controller extends ResourceController
{
/**
* @param RequestConfiguration $configuration
*
* @return RedirectResponse
*/
protected function redirectToCartSummary(RequestConfiguration $configuration)
{
if (null === $configuration->getParameters()->get('redirect')) {
return $this->redirectHandler->redirectToRoute($configuration, $this->getCartSummaryRoute());
}
return $this->redirectHandler->redirectToRoute($configuration, $configuration->getParameters()->get('redirect'));
}
/**
* @return string
*/
protected function getCartSummaryRoute()
{
return 'sylius_cart_summary';
}
/**
* @return CartInterface
*/
protected function getCurrentCart()
{
return $this->getContext()->getCart();
}
/**
* @return CartContextInterface
*/
protected function getContext()
{
return $this->container->get('sylius.context.cart');
}
/**
* @return EventDispatcherInterface
*/
protected function getEventDispatcher()
{
return $this->container->get('event_dispatcher');
}
}

View file

@ -1,137 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\DependencyInjection;
use Sylius\Bundle\CartBundle\Controller\CartController;
use Sylius\Bundle\CartBundle\Controller\CartItemController;
use Sylius\Bundle\CartBundle\Form\Type\CartItemType;
use Sylius\Bundle\CartBundle\Form\Type\CartType;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
use Sylius\Component\Cart\Model\Cart;
use Sylius\Component\Cart\Model\CartInterface;
use Sylius\Component\Cart\Model\CartItem;
use Sylius\Component\Cart\Model\CartItemInterface;
use Sylius\Component\Resource\Factory\Factory;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This class contains the configuration information for the bundle.
*
* This information is solely responsible for how the different configuration
* sections are normalized, and merged.
*
* @author Paweł Jędrzejewski <pawel@sylius.org>
* @author Saša Stamenković <umpirsky@gmail.com>
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritdoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('sylius_cart');
$rootNode
->addDefaultsIfNotSet()
->children()
->scalarNode('driver')->defaultValue(SyliusResourceBundle::DRIVER_DOCTRINE_ORM)->cannotBeEmpty()->end()
->end()
;
$this->addResourcesSection($rootNode);
return $treeBuilder;
}
/**
* @param ArrayNodeDefinition $node
*/
private function addResourcesSection(ArrayNodeDefinition $node)
{
$node
->children()
->arrayNode('resources')
->isRequired()
->addDefaultsIfNotSet()
->children()
->arrayNode('cart')
->addDefaultsIfNotSet()
->children()
->variableNode('options')->end()
->arrayNode('classes')
->addDefaultsIfNotSet()
->children()
->scalarNode('model')->defaultValue(Cart::class)->cannotBeEmpty()->end()
->scalarNode('interface')->defaultValue(CartInterface::class)->cannotBeEmpty()->end()
->scalarNode('controller')->defaultValue(CartController::class)->cannotBeEmpty()->end()
->scalarNode('repository')->cannotBeEmpty()->end()
->scalarNode('factory')->defaultValue(Factory::class)->cannotBeEmpty()->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('default')->defaultValue(CartType::class)->cannotBeEmpty()->end()
->end()
->end()
->end()
->end()
->arrayNode('validation_groups')
->addDefaultsIfNotSet()
->children()
->arrayNode('default')
->prototype('scalar')->end()
->defaultValue(['sylius'])
->end()
->end()
->end()
->end()
->end()
->arrayNode('cart_item')
->addDefaultsIfNotSet()
->children()
->variableNode('options')->end()
->arrayNode('classes')
->addDefaultsIfNotSet()
->children()
->scalarNode('model')->defaultValue(CartItem::class)->cannotBeEmpty()->end()
->scalarNode('interface')->defaultValue(CartItemInterface::class)->cannotBeEmpty()->end()
->scalarNode('controller')->defaultValue(CartItemController::class)->cannotBeEmpty()->end()
->scalarNode('repository')->cannotBeEmpty()->end()
->scalarNode('factory')->defaultValue(Factory::class)->cannotBeEmpty()->end()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('default')->defaultValue(CartItemType::class)->cannotBeEmpty()->end()
->end()
->end()
->end()
->end()
->arrayNode('validation_groups')
->addDefaultsIfNotSet()
->children()
->arrayNode('default')
->prototype('scalar')->end()
->defaultValue(['sylius'])
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end()
;
}
}

View file

@ -1,80 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\DependencyInjection;
use Sylius\Bundle\ResourceBundle\DependencyInjection\Extension\AbstractResourceExtension;
use Sylius\Component\Cart\Model\Cart;
use Sylius\Component\Cart\Model\CartItem;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
* @author Saša Stamenković <umpirsky@gmail.com>
* @author Jérémy Leherpeur <jeremy@leherpeur.net>
*/
class SyliusCartExtension extends AbstractResourceExtension implements PrependExtensionInterface
{
/**
* {@inheritdoc}
*/
public function load(array $config, ContainerBuilder $container)
{
$config = $this->processConfiguration($this->getConfiguration($config, $container), $config);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load(sprintf('driver/%s.xml', $config['driver']));
$this->registerResources('sylius', $config['driver'], $config['resources'], $container);
$configFiles = [
'services.xml',
'templating.xml',
'twig.xml',
];
foreach ($configFiles as $configFile) {
$loader->load($configFile);
}
$definition = $container->getDefinition('sylius.form.type.cart_item');
$definition->addArgument(new Reference('sylius.form.data_mapper.order_item_quantity'));
}
/**
* {@inheritdoc}
*/
public function prepend(ContainerBuilder $container)
{
if (!$container->hasExtension('sylius_order')) {
throw new \RuntimeException('Please install and configure SyliusOrderBundle in order to use SyliusCartBundle.');
}
$container->prependExtensionConfig('sylius_order', [
'resources' => [
'order' => [
'classes' => [
'model' => Cart::class,
],
],
'order_item' => [
'classes' => [
'model' => CartItem::class,
],
],
], ]
);
}
}

View file

@ -1,58 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Doctrine\ORM;
use Sylius\Bundle\OrderBundle\Doctrine\ORM\OrderRepository;
use Sylius\Component\Cart\Repository\CartRepositoryInterface;
use Sylius\Component\Order\Model\OrderInterface;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
* @author Alexandre Bacco <alexandre.bacco@gmail.com>
*/
class CartRepository extends OrderRepository implements CartRepositoryInterface
{
/**
* {@inheritdoc}
*/
public function findCartById($id)
{
return $this->createQueryBuilder('o')
->where('o.id = :id')
->andWhere('o.state = :state')
->setParameter('state', OrderInterface::STATE_CART)
->setParameter('id', $id)
->getQuery()
->getOneOrNullResult()
;
}
/**
* {@inheritdoc}
*/
public function findExpiredCarts()
{
$queryBuilder = $this->createQueryBuilder('o')
->leftJoin('o.items', 'item')
->addSelect('item')
;
$queryBuilder
->andWhere($queryBuilder->expr()->lt('o.expiresAt', ':now'))
->andWhere($queryBuilder->expr()->eq('o.state', ':state'))
->setParameter('now', new \DateTime())
->setParameter('state', OrderInterface::STATE_CART)
;
return $queryBuilder->getQuery()->getResult();
}
}

View file

@ -1,60 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Form\Type;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\FormBuilderInterface;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
class CartItemType extends AbstractResourceType
{
/**
* @var DataMapperInterface
*/
protected $orderItemQuantityDataMapper;
/**
* @param string $dataClass
* @param array $validationGroups
* @param DataMapperInterface $orderItemQuantityDataMapper
*/
public function __construct($dataClass, array $validationGroups = [], DataMapperInterface $orderItemQuantityDataMapper)
{
parent::__construct($dataClass, $validationGroups);
$this->orderItemQuantityDataMapper = $orderItemQuantityDataMapper;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('quantity', 'integer', [
'attr' => ['min' => 1],
'label' => 'sylius.form.cart_item.quantity',
])
->setDataMapper($this->orderItemQuantityDataMapper);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'sylius_cart_item';
}
}

View file

@ -1,45 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Form\Type;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Cart form form.
* It is built from collection of cart items forms.
*
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
class CartType extends AbstractResourceType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('items', 'collection', [
'type' => 'sylius_cart_item',
])
->add('notes')
;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'sylius_cart';
}
}

View file

@ -1,69 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle\Purger;
use Doctrine\Common\Persistence\ObjectManager;
use Sylius\Component\Cart\Model\CartInterface;
use Sylius\Component\Cart\Purger\PurgerInterface;
use Sylius\Component\Cart\Repository\CartRepositoryInterface;
/**
* Default cart purger.
*
* @author Alexandre Bacco <alexandre.bacco@gmail.com>
*/
class ExpiredCartsPurger implements PurgerInterface
{
/**
* Cart manager.
*
* @var ObjectManager
*/
protected $manager;
/**
* Cart repository.
*
* @var CartRepositoryInterface
*/
protected $repository;
public function __construct(ObjectManager $manager, CartRepositoryInterface $repository)
{
$this->manager = $manager;
$this->repository = $repository;
}
/**
* {@inheritdoc}
*/
public function purge()
{
$cartsToPurge = $this->repository->findExpiredCarts();
foreach ($cartsToPurge as $cart) {
$this->purgeCart($cart);
}
$this->manager->flush();
}
/**
* Purge a cart
*
* @param CartInterface $cart
*/
protected function purgeCart(CartInterface $cart)
{
$this->manager->remove($cart);
}
}

View file

@ -1,75 +0,0 @@
SyliusCartBundle [![Build status...](https://secure.travis-ci.org/Sylius/SyliusCartBundle.png?branch=master)](http://travis-ci.org/Sylius/SyliusCartBundle)
================
Flexible cart engine for Symfony2. Should be considered as a base for building solution that fits your exact needs.
[Read the documentation](http://docs.sylius.org/en/latest/bundles/SyliusCartBundle/index.html) to know more features.
Sylius
------
**Sylius** - Modern ecommerce solution Symfony2. Visit [Sylius.org](http://sylius.org).
[phpspec](http://phpspec.net) examples
--------------------------------------
```bash
$ composer install
$ bin/phpspec run -f pretty
```
Documentation
-------------
Documentation is available on [**docs.sylius.org**](http://docs.sylius.org/en/latest/bundles/SyliusCartBundle/index.html).
Contributing
------------
All informations about contributing to Sylius can be found on [this page](http://docs.sylius.org/en/latest/contributing/index.html).
Mailing lists
-------------
### Users
Questions? Feel free to ask on [users mailing list](http://groups.google.com/group/sylius).
### Developers
To contribute and develop this bundle, use the [developers mailing list](http://groups.google.com/group/sylius-dev).
Sylius twitter account
----------------------
If you want to keep up with updates, [follow the official Sylius account on twitter](http://twitter.com/Sylius).
Bug tracking
------------
This bundle uses [GitHub issues](https://github.com/Sylius/Sylius/issues).
If you have found bug, please create an issue.
Versioning
----------
Releases will be numbered with the format `major.minor.patch`.
And constructed with the following guidelines.
* Breaking backwards compatibility bumps the major.
* New additions without breaking backwards compatibility bumps the minor.
* Bug fixes and misc changes bump the patch.
For more information on SemVer, please visit [semver.org website](http://semver.org/).
This versioning method is same for all **Sylius** bundles and applications.
MIT License
-----------
License can be found [here](https://github.com/Sylius/SyliusCartBundle/blob/master/Resources/meta/LICENSE).
Authors
-------
The bundle was originally created by [Paweł Jędrzejewski](http://pjedrzejewski.com).
See the list of [contributors](https://github.com/Sylius/SyliusCartBundle/contributors).

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="Sylius\Component\Cart\Model\Cart" table="sylius_cart">
<field name="expiresAt" column="expires_at" type="datetime" />
</mapped-superclass>
</doctrine-mapping>

View file

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<mapped-superclass name="Sylius\Component\Cart\Model\CartItem" table="sylius_cart_item">
</mapped-superclass>
</doctrine-mapping>

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.repository.cart.class">Sylius\Bundle\CartBundle\Doctrine\ORM\CartRepository</parameter>
</parameters>
</container>

View file

@ -1,22 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius_cart_summary:
path: /
defaults: { _controller: sylius.controller.cart:summaryAction }
sylius_cart_save:
path: /save
defaults: { _controller: sylius.controller.cart:saveAction }
sylius_cart_clear:
path: /clear
defaults: { _controller: sylius.controller.cart:clearAction }
sylius_cart_item_add:
path: /add
defaults: { _controller: sylius.controller.cart_item:addAction }
sylius_cart_item_remove:
path: /{id}/remove
defaults: { _controller: sylius.controller.cart_item:removeAction }

View file

@ -1,53 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.listener.session_cart.class">Sylius\Bundle\CartBundle\EventListener\SessionCartSubscriber</parameter>
<parameter key="sylius.cart.purger.class">Sylius\Bundle\CartBundle\Purger\ExpiredCartsPurger</parameter>
</parameters>
<services>
<service id="sylius.cart.cart_modifier" class="Sylius\Component\Cart\Modifier\CartModifier">
<argument type="service" id="sylius.order_processing.order_processor" />
<argument type="service" id="sylius.order_item_quantity_modifier" />
</service>
<service id="sylius.context.cart_new" class="Sylius\Component\Cart\Context\CartContext">
<argument type="service" id="sylius.factory.cart" />
<tag name="sylius.cart_context" priority="-999" />
</service>
<service id="sylius.context.cart_session_based" class="Sylius\Bundle\CartBundle\Context\SessionBasedCartContext">
<argument type="service" id="session" />
<argument>_sylius.cart</argument>
<argument type="service" id="sylius.repository.cart" />
<tag name="sylius.cart_context" priority="-777" />
</service>
<service id="sylius.context.cart" class="Sylius\Component\Cart\Context\CompositeCartContext" />
<service id="sylius.listener.session_cart" class="%sylius.listener.session_cart.class%">
<argument type="service" id="sylius.context.cart" />
<argument>_sylius.cart</argument>
<tag name="kernel.event_subscriber" />
</service>
<service id="sylius.cart.purger" class="%sylius.cart.purger.class%">
<argument type="service" id="sylius.manager.cart" />
<argument type="service" id="sylius.repository.cart" />
</service>
</services>
</container>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.templating.helper.cart.class">Sylius\Bundle\CartBundle\Templating\Helper\CartHelper</parameter>
</parameters>
<services>
<service id="sylius.templating.helper.cart" class="%sylius.templating.helper.cart.class%" lazy="true">
<argument type="service" id="sylius.context.cart" />
<argument type="service" id="sylius.factory.cart_item" />
<argument type="service" id="form.factory" />
<argument type="service" id="sylius.order_item_quantity_modifier" />
<tag name="templating.helper" alias="sylius_cart" />
</service>
</services>
</container>

View file

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="sylius.twig.extension.cart.class">Sylius\Bundle\CartBundle\Twig\CartExtension</parameter>
</parameters>
<services>
<service id="sylius.twig.extension.cart" class="%sylius.twig.extension.cart.class%" public="false">
<argument type="service" id="sylius.templating.helper.cart" />
<tag name="twig.extension" />
</service>
</services>
</container>

View file

@ -1,41 +0,0 @@
<?xml version="1.0"?>
<!--
This file is part of the Sylius package.
(c) Paweł Jędrzejewski
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
-->
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping
http://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
<class name="Sylius\Component\Cart\Model\Cart">
<property name="items">
<constraint name="Valid" />
</property>
</class>
<class name="Sylius\Component\Cart\Model\CartItem">
<property name="quantity">
<constraint name="NotBlank">
<option name="groups">sylius</option>
</constraint>
<constraint name="Type">
<option name="type">integer</option>
<option name="groups">sylius</option>
</constraint>
<constraint name="Range">
<option name="min">1</option>
<option name="groups">sylius</option>
</constraint>
</property>
</class>
</constraint-mapping>

View file

@ -1,19 +0,0 @@
Copyright (c) 2011-2016 Paweł Jędrzejewski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Колькасць

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Quantitat

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Počet

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Mængde

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Stückzahl

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Stückzahl

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Ποσότητα

View file

@ -1,5 +0,0 @@
sylius:
form:
cart_item:
quantity: Quantity

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Cantidad

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: تعداد

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Quantité

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Količina

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Mennyiség

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Kuantitas

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Quantità

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Kiekis

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Hoeveelheid

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Antall

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Ilość

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Quantidade

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Quantidade

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Cantitate

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Количество

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Množstvo

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Količina

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Sasia

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Antal

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: จำนวน

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Adet

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: Кількість

View file

@ -1,7 +0,0 @@
# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski
sylius:
form:
cart_item:
quantity: 数量

View file

@ -1,59 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CartBundle;
use Sylius\Bundle\CartBundle\DependencyInjection\Compiler\RegisterCartContextsPass;
use Sylius\Bundle\ResourceBundle\AbstractResourceBundle;
use Sylius\Bundle\ResourceBundle\SyliusResourceBundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
class SyliusCartBundle extends AbstractResourceBundle
{
/**
* {@inheritdoc}
*/
public function getSupportedDrivers()
{
return [
SyliusResourceBundle::DRIVER_DOCTRINE_ORM,
];
}
/**
* {@inheritdoc}
*/
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new RegisterCartContextsPass());
}
/**
* {@inheritdoc}
*/
protected function getBundlePrefix()
{
return 'sylius_order';
}
/**
* {@inheritdoc}
*/
protected function getModelNamespace()
{
return 'Sylius\Component\Cart\Model';
}
}

View file

@ -1,85 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CoreBundle\Tests\DependencyInjection\Compiler;
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractCompilerPassTestCase;
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\DefinitionHasMethodCallConstraint;
use Sylius\Bundle\CartBundle\DependencyInjection\Compiler\RegisterCartContextsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
/**
* @author Arkadiusz Krakowiak <arkadiusz.krakowiak@lakion.com>
*/
class RegisterCartContextsPassTest extends AbstractCompilerPassTestCase
{
/**
* @test
*/
public function it_registers_defined_cart_contexts()
{
$this->setDefinition('sylius.context.cart', new Definition());
$cartContextDefinition = new Definition();
$cartContextDefinition->addTag('sylius.cart_context');
$this->setDefinition('sylius.context.cart_new', $cartContextDefinition);
$this->compile();
$this->assertContainerBuilderHasServiceDefinitionWithMethodCall(
'sylius.context.cart',
'addContext',
[
new Reference('sylius.context.cart_new'),
0
]
);
}
/**
* @test
*/
public function it_does_not_register_cart_contexts_if_there_is_no_cart_contexts()
{
$this->setDefinition('sylius.context.cart', new Definition());
$this->compile();
$this->assertContainerBuilderDoesNotHaveServiceDefinitionWithMethodCall(
'sylius.context.cart',
'addContext'
);
}
/**
* {@inheritdoc}
*/
public function registerCompilerPass(ContainerBuilder $container)
{
$container->addCompilerPass(new RegisterCartContextsPass());
}
/**
* @param string $serviceId
* @param string $method
*/
private function assertContainerBuilderDoesNotHaveServiceDefinitionWithMethodCall($serviceId, $method)
{
$definition = $this->container->findDefinition($serviceId);
self::assertThat(
$definition,
new \PHPUnit_Framework_Constraint_Not(new DefinitionHasMethodCallConstraint($method))
);
}
}

View file

@ -1,58 +0,0 @@
{
"name": "sylius/cart-bundle",
"type": "symfony-bundle",
"description": "Cart engine for your next Symfony2 application.",
"keywords": ["shop", "ecommerce", "cart", "carts", "sylius"],
"homepage": "http://sylius.org",
"license": "MIT",
"authors": [
{
"name": "Paweł Jędrzejewski",
"homepage": "http://pjedrzejewski.com"
},
{
"name": "Sylius project",
"homepage": "http://sylius.org"
},
{
"name": "Community contributions",
"homepage": "http://github.com/Sylius/Sylius/contributors"
}
],
"require": {
"php": "^5.6|^7.0",
"sylius/cart": "^1.0",
"sylius/order-bundle": "^1.0",
"symfony/framework-bundle": "^2.8"
},
"require-dev": {
"phpspec/phpspec": "^3.0",
"symfony/form": "^2.8",
"symfony/validator": "^2.8",
"doctrine/orm": "^2.4.8,<2.5",
"twig/twig": "^1.0"
},
"config": {
"bin-dir": "bin"
},
"autoload": {
"psr-4": { "Sylius\\Bundle\\CartBundle\\": "" }
},
"autoload-dev": {
"psr-4": { "Sylius\\Bundle\\CartBundle\\spec\\": "spec/" }
},
"minimum-stability": "dev",
"prefer-stable": true,
"repositories": [
{
"type": "path",
"url": "../../*/*"
}
],
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
}
}

View file

@ -1,5 +0,0 @@
suites:
main:
namespace: Sylius\Bundle\CartBundle
psr4_prefix: Sylius\Bundle\CartBundle
src_path: .

View file

@ -1,54 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace spec\Sylius\Bundle\CartBundle\Command;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Cart\Purger\PurgerInterface;
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
final class PurgeCartsCommandSpec extends ObjectBehavior
{
function it_is_initializable()
{
$this->shouldHaveType('Sylius\Bundle\CartBundle\Command\PurgeCartsCommand');
}
public function it_is_a_command()
{
$this->shouldHaveType(ContainerAwareCommand::class);
}
public function it_has_a_name()
{
$this->getName()->shouldReturn('sylius:cart:purge');
}
public function it_imports_the_vet(
ContainerInterface $container,
InputInterface $input,
OutputInterface $output,
PurgerInterface $purger
) {
$output->writeln('Purging expired carts...')->shouldBeCalled();
$container->get('sylius.cart.purger')->shouldBeCalled()->willReturn($purger);
$purger->purge()->shouldBeCalled();
$output->writeln('Expired carts purged.')->shouldBeCalled();
$this->setContainer($container);
$this->run($input, $output);
}
}

View file

@ -1,70 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace spec\Sylius\Bundle\CartBundle\Form\Type;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
final class CartItemTypeSpec extends ObjectBehavior
{
function let(DataMapperInterface $orderItemQuantityDataMapper)
{
$this->beConstructedWith('CartItem', ['sylius'], $orderItemQuantityDataMapper);
}
function it_is_initializable()
{
$this->shouldHaveType('Sylius\Bundle\CartBundle\Form\Type\CartItemType');
}
function it_is_a_form_type()
{
$this->shouldImplement(FormTypeInterface::class);
}
function it_builds_form_with_quantity_field($orderItemQuantityDataMapper, FormBuilder $builder)
{
$builder
->add('quantity', 'integer', Argument::any())
->shouldBeCalled()
->willReturn($builder)
;
$builder
->setDataMapper($orderItemQuantityDataMapper)
->shouldBeCalled()
->willReturn($builder)
;
$this->buildForm($builder, []);
}
function it_defines_assigned_data_class(OptionsResolver $resolver)
{
$resolver
->setDefaults([
'data_class' => 'CartItem',
'validation_groups' => ['sylius'],
])
->shouldBeCalled()
;
$this->configureOptions($resolver);
}
}

View file

@ -1,66 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace spec\Sylius\Bundle\CartBundle\Form\Type;
use PhpSpec\ObjectBehavior;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* @author Paweł Jędrzejewski <pawel@sylius.org>
*/
final class CartTypeSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('Cart', ['sylius']);
}
function it_is_initializable()
{
$this->shouldHaveType('Sylius\Bundle\CartBundle\Form\Type\CartType');
}
function it_is_a_form_type()
{
$this->shouldImplement(FormTypeInterface::class);
}
function it_builds_form_with_items_collection(FormBuilder $builder)
{
$builder
->add('items', 'collection', ['type' => 'sylius_cart_item'])
->willReturn($builder)
;
$builder
->add('notes')
->willReturn($builder)
;
$this->buildForm($builder, []);
}
function it_defines_assigned_data_class(OptionsResolver $resolver)
{
$resolver
->setDefaults([
'data_class' => 'Cart',
'validation_groups' => ['sylius'],
])
->shouldBeCalled()
;
$this->configureOptions($resolver);
}
}

View file

@ -1,39 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace spec\Sylius\Bundle\CartBundle\Purger;
use Doctrine\Common\Persistence\ObjectManager;
use PhpSpec\ObjectBehavior;
use Sylius\Component\Cart\Model\CartInterface;
use Sylius\Component\Cart\Repository\CartRepositoryInterface;
final class ExpiredCartsPurgerSpec extends ObjectBehavior
{
function let(ObjectManager $manager, CartRepositoryInterface $repository)
{
$this->beConstructedWith($manager, $repository);
}
function it_is_initializable()
{
$this->shouldHaveType('Sylius\Bundle\CartBundle\Purger\ExpiredCartsPurger');
}
function it_purge_cart($manager, $repository, CartInterface $cart)
{
$repository->findExpiredCarts()->shouldBeCalled()->willReturn([$cart]);
$manager->remove($cart)->shouldBeCalled();
$manager->flush()->shouldBeCalled();
$this->purge();
}
}

View file

@ -39,7 +39,6 @@ class Kernel extends HttpKernel
new \Sylius\Bundle\MoneyBundle\SyliusMoneyBundle(), new \Sylius\Bundle\MoneyBundle\SyliusMoneyBundle(),
new \Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle(), new \Sylius\Bundle\CurrencyBundle\SyliusCurrencyBundle(),
new \Sylius\Bundle\LocaleBundle\SyliusLocaleBundle(), new \Sylius\Bundle\LocaleBundle\SyliusLocaleBundle(),
new \Sylius\Bundle\CartBundle\SyliusCartBundle(),
new \Sylius\Bundle\ProductBundle\SyliusProductBundle(), new \Sylius\Bundle\ProductBundle\SyliusProductBundle(),
new \Sylius\Bundle\ChannelBundle\SyliusChannelBundle(), new \Sylius\Bundle\ChannelBundle\SyliusChannelBundle(),
new \Sylius\Bundle\VariationBundle\SyliusVariationBundle(), new \Sylius\Bundle\VariationBundle\SyliusVariationBundle(),

View file

@ -12,9 +12,9 @@
namespace Sylius\Bundle\CoreBundle\Checkout; namespace Sylius\Bundle\CoreBundle\Checkout;
use SM\Factory\FactoryInterface; use SM\Factory\FactoryInterface;
use Sylius\Component\Cart\Context\CartContextInterface;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\OrderCheckoutTransitions; use Sylius\Component\Core\OrderCheckoutTransitions;
use Sylius\Component\Order\Context\CartContextInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;

View file

@ -11,11 +11,11 @@
namespace Sylius\Bundle\CoreBundle\Context; namespace Sylius\Bundle\CoreBundle\Context;
use Sylius\Component\Cart\Context\CartContextInterface; use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Cart\Context\CartNotFoundException; use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Channel\Context\ChannelContextInterface; use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Channel\Context\ChannelNotFoundException; use Sylius\Component\Channel\Context\ChannelNotFoundException;
use Sylius\Component\Core\Repository\CartRepositoryInterface; use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
/** /**
@ -34,9 +34,9 @@ final class SessionAndChannelBasedCartContext implements CartContextInterface
private $sessionKeyName; private $sessionKeyName;
/** /**
* @var CartRepositoryInterface * @var OrderRepositoryInterface
*/ */
private $cartRepository; private $orderRepository;
/** /**
* @var ChannelContextInterface * @var ChannelContextInterface
@ -47,18 +47,18 @@ final class SessionAndChannelBasedCartContext implements CartContextInterface
* @param SessionInterface $session * @param SessionInterface $session
* @param string $sessionKeyName * @param string $sessionKeyName
* @param ChannelContextInterface $channelContext * @param ChannelContextInterface $channelContext
* @param CartRepositoryInterface $cartRepository * @param OrderRepositoryInterface $orderRepository
*/ */
public function __construct( public function __construct(
SessionInterface $session, SessionInterface $session,
$sessionKeyName, $sessionKeyName,
ChannelContextInterface $channelContext, ChannelContextInterface $channelContext,
CartRepositoryInterface $cartRepository OrderRepositoryInterface $orderRepository
) { ) {
$this->session = $session; $this->session = $session;
$this->sessionKeyName = $sessionKeyName; $this->sessionKeyName = $sessionKeyName;
$this->channelContext = $channelContext; $this->channelContext = $channelContext;
$this->cartRepository = $cartRepository; $this->orderRepository = $orderRepository;
} }
/** /**
@ -76,7 +76,7 @@ final class SessionAndChannelBasedCartContext implements CartContextInterface
throw new CartNotFoundException('Sylius was not able to find the cart in session'); throw new CartNotFoundException('Sylius was not able to find the cart in session');
} }
$cart = $this->cartRepository->findCartByIdAndChannel( $cart = $this->orderRepository->findCartByIdAndChannel(
$this->session->get(sprintf('%s.%s', $this->sessionKeyName, $channel->getCode())), $this->session->get(sprintf('%s.%s', $this->sessionKeyName, $channel->getCode())),
$channel $channel
); );

View file

@ -18,12 +18,20 @@ use Payum\Core\Registry\RegistryInterface;
use Payum\Core\Security\GenericTokenFactoryInterface; use Payum\Core\Security\GenericTokenFactoryInterface;
use Payum\Core\Security\HttpRequestVerifierInterface; use Payum\Core\Security\HttpRequestVerifierInterface;
use Sylius\Bundle\PayumBundle\Request\GetStatus; use Sylius\Bundle\PayumBundle\Request\GetStatus;
use Sylius\Bundle\ResourceBundle\Controller\RequestConfiguration;
use Sylius\Bundle\ResourceBundle\Controller\ResourceController; use Sylius\Bundle\ResourceBundle\Controller\ResourceController;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\OrderProcessing\StateResolverInterface; use Sylius\Component\Core\OrderProcessing\StateResolverInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Model\OrderInterface;
use Sylius\Component\Order\SyliusCartEvents;
use Sylius\Component\Resource\ResourceActions;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\GenericEvent;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Webmozart\Assert\Assert; use Webmozart\Assert\Assert;
@ -127,7 +135,7 @@ class OrderController extends ResourceController
{ {
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request); $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$orderId = $this->getSession()->get('sylius_order_id'); $orderId = $this->get('session')->get('sylius_order_id');
Assert::notNull($orderId); Assert::notNull($orderId);
$order = $this->repository->findOneForPayment($orderId); $order = $this->repository->findOneForPayment($orderId);
Assert::notNull($order); Assert::notNull($order);
@ -140,6 +148,173 @@ class OrderController extends ResourceController
return $this->render($configuration->getParameters()->get('template'), ['order' => $order]); return $this->render($configuration->getParameters()->get('template'), ['order' => $order]);
} }
/**
* @param Request $request
*
* @return Response
*/
public function summaryAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$cart = $this->getCurrentCart();
$form = $this->resourceFormFactory->create($configuration, $cart);
$view = View::create()
->setTemplate($configuration->getTemplate('summary.html'))
->setData([
'cart' => $cart,
'form' => $form->createView(),
])
;
return $this->viewHandler->handle($configuration, $view);
}
/**
* @param Request $request
*
* @return Response
*/
public function saveAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::UPDATE);
$resource = $this->getCurrentCart();
$form = $this->resourceFormFactory->create($configuration, $resource);
if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && $form->submit($request, !$request->isMethod('PATCH'))->isValid()) {
$resource = $form->getData();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToResource($configuration, $resource);
}
if ($configuration->hasStateMachine()) {
$this->stateMachine->apply($configuration, $resource);
}
$this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->getEventDispatcher()->dispatch(SyliusCartEvents::CART_CHANGE, new GenericEvent($resource));
$this->manager->flush();
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
return $this->redirectHandler->redirectToResource($configuration, $resource);
}
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
}
$view = View::create()
->setData([
'configuration' => $configuration,
$this->metadata->getName() => $resource,
'form' => $form->createView(),
'cart' => $resource,
])
->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
;
return $this->viewHandler->handle($configuration, $view);
}
/**
* @param Request $request
*
* @return Response
*/
public function clearAction(Request $request)
{
$configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
$this->isGrantedOr403($configuration, ResourceActions::DELETE);
$resource = $this->getCurrentCart();
$event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
if ($event->isStopped() && !$configuration->isHtmlRequest()) {
throw new HttpException($event->getErrorCode(), $event->getMessage());
}
if ($event->isStopped()) {
$this->flashHelper->addFlashFromEvent($configuration, $event);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
$this->repository->remove($resource);
$this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
if (!$configuration->isHtmlRequest()) {
return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
}
$this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
return $this->redirectHandler->redirectToIndex($configuration, $resource);
}
/**
* @param RequestConfiguration $configuration
*
* @return RedirectResponse
*/
protected function redirectToCartSummary(RequestConfiguration $configuration)
{
if (null === $configuration->getParameters()->get('redirect')) {
return $this->redirectHandler->redirectToRoute($configuration, $this->getCartSummaryRoute());
}
return $this->redirectHandler->redirectToRoute($configuration, $configuration->getParameters()->get('redirect'));
}
/**
* @return string
*/
protected function getCartSummaryRoute()
{
return 'sylius_cart_summary';
}
/**
* @return OrderInterface
*/
protected function getCurrentCart()
{
return $this->getContext()->getCart();
}
/**
* @return CartContextInterface
*/
protected function getContext()
{
return $this->get('sylius.context.cart');
}
/**
* @return EventDispatcherInterface
*/
protected function getEventDispatcher()
{
return $this->container->get('event_dispatcher');
}
/** /**
* @return StateResolverInterface * @return StateResolverInterface
*/ */
@ -148,14 +323,6 @@ class OrderController extends ResourceController
return $this->get('sylius.order_processing.state_resolver'); return $this->get('sylius.order_processing.state_resolver');
} }
/**
* @return SessionInterface
*/
private function getSession()
{
return $this->get('session');
}
/** /**
* @return EntityManager * @return EntityManager
*/ */

View file

@ -1,40 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CoreBundle\Doctrine\ORM;
use Sylius\Bundle\CartBundle\Doctrine\ORM\CartRepository as BaseCartRepository;
use Sylius\Component\Channel\Model\ChannelInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\CartRepositoryInterface;
/**
* @author Anna Walasek <anna.walasek@lakion.com>
*/
class CartRepository extends BaseCartRepository implements CartRepositoryInterface
{
/**
* {@inheritdoc}
*/
public function findCartByIdAndChannel($id, ChannelInterface $channel)
{
return $this->createQueryBuilder('o')
->where('o.id = :id')
->andWhere('o.state = :state')
->andWhere('o.channel = :channel')
->setParameter('id', $id)
->setParameter('state', OrderInterface::STATE_CART)
->setParameter('channel', $channel)
->getQuery()
->getOneOrNullResult()
;
}
}

View file

@ -12,13 +12,14 @@
namespace Sylius\Bundle\CoreBundle\Doctrine\ORM; namespace Sylius\Bundle\CoreBundle\Doctrine\ORM;
use Doctrine\ORM\QueryBuilder; use Doctrine\ORM\QueryBuilder;
use Sylius\Bundle\CoreBundle\Doctrine\ORM\CartRepository; use Sylius\Bundle\OrderBundle\Doctrine\ORM\OrderRepository as BaseOrderRepository;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\CouponInterface; use Sylius\Component\Core\Model\CouponInterface;
use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface; use Sylius\Component\Core\Repository\OrderRepositoryInterface;
class OrderRepository extends CartRepository implements OrderRepositoryInterface class OrderRepository extends BaseOrderRepository implements OrderRepositoryInterface
{ {
/** /**
* {@inheritdoc} * {@inheritdoc}
@ -377,6 +378,23 @@ class OrderRepository extends CartRepository implements OrderRepositoryInterface
; ;
} }
/**
* {@inheritdoc}
*/
public function findCartByIdAndChannel($id, ChannelInterface $channel)
{
return $this->createQueryBuilder('o')
->where('o.id = :id')
->andWhere('o.state = :state')
->andWhere('o.channel = :channel')
->setParameter('id', $id)
->setParameter('state', OrderInterface::STATE_CART)
->setParameter('channel', $channel)
->getQuery()
->getOneOrNullResult()
;
}
/** /**
* @param \DateTime $from * @param \DateTime $from
* @param \DateTime $to * @param \DateTime $to

View file

@ -13,8 +13,8 @@ namespace Sylius\Bundle\CoreBundle\EventListener;
use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\ObjectManager;
use Sylius\Bundle\UserBundle\Event\UserEvent; use Sylius\Bundle\UserBundle\Event\UserEvent;
use Sylius\Component\Cart\Context\CartContextInterface; use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Cart\Context\CartNotFoundException; use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShopUserInterface; use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Resource\Exception\UnexpectedTypeException; use Sylius\Component\Resource\Exception\UnexpectedTypeException;

View file

@ -11,8 +11,8 @@
namespace Sylius\Bundle\CoreBundle\EventListener; namespace Sylius\Bundle\CoreBundle\EventListener;
use Sylius\Component\Cart\Context\CartContextInterface; use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Cart\Context\CartNotFoundException; use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Processor\OrderProcessorInterface; use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Sylius\Component\Resource\Exception\UnexpectedTypeException; use Sylius\Component\Resource\Exception\UnexpectedTypeException;

View file

@ -11,9 +11,11 @@
namespace Sylius\Bundle\CoreBundle\Form\Type; namespace Sylius\Bundle\CoreBundle\Form\Type;
use Sylius\Bundle\CartBundle\Form\Type\CartItemType as BaseCartItemType; use Sylius\Bundle\OrderBundle\Form\Type\OrderItemType as BaseOrderItemType;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Sylius\Component\Core\Model\Product; use Sylius\Component\Core\Model\Product;
use Sylius\Component\Core\Model\ProductInterface; use Sylius\Component\Core\Model\ProductInterface;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
@ -25,14 +27,37 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
* *
* @author Paweł Jędrzejewski <pawel@sylius.org> * @author Paweł Jędrzejewski <pawel@sylius.org>
*/ */
class CartItemType extends BaseCartItemType class CartItemType extends AbstractResourceType
{ {
/**
* @var DataMapperInterface
*/
protected $orderItemQuantityDataMapper;
/**
* @param string $dataClass
* @param array $validationGroups
* @param DataMapperInterface $orderItemQuantityDataMapper
*/
public function __construct($dataClass, array $validationGroups = [], DataMapperInterface $orderItemQuantityDataMapper)
{
parent::__construct($dataClass, $validationGroups);
$this->orderItemQuantityDataMapper = $orderItemQuantityDataMapper;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function buildForm(FormBuilderInterface $builder, array $options) public function buildForm(FormBuilderInterface $builder, array $options)
{ {
parent::buildForm($builder, $options); $builder
->add('quantity', 'integer', [
'attr' => ['min' => 1],
'label' => 'sylius.ui.quantity',
])
->setDataMapper($this->orderItemQuantityDataMapper)
;
if (isset($options['product']) && $options['product']->hasVariants() && !$options['product']->isSimple()) { if (isset($options['product']) && $options['product']->hasVariants() && !$options['product']->isSimple()) {
$type = Product::VARIANT_SELECTION_CHOICE === $options['product']->getVariantSelectionMethod() ? 'sylius_product_variant_choice' : 'sylius_product_variant_match'; $type = Product::VARIANT_SELECTION_CHOICE === $options['product']->getVariantSelectionMethod() ? 'sylius_product_variant_choice' : 'sylius_product_variant_match';
@ -61,4 +86,12 @@ class CartItemType extends BaseCartItemType
->setAllowedTypes('product', ProductInterface::class) ->setAllowedTypes('product', ProductInterface::class)
; ;
} }
/**
* {@inheritdoc}
*/
public function getName()
{
return 'sylius_cart_item';
}
} }

View file

@ -1,41 +0,0 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Bundle\CoreBundle\Form\Type;
use Sylius\Bundle\CartBundle\Form\Type\CartType as BaseCartType;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
/**
* @author Julien Janvier <j.janvier@gmail.com>
* @author Mateusz Zalewski <mateusz.zalewski@lakion.com>
*/
class CartType extends BaseCartType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder
->add('promotionCoupon', 'sylius_promotion_coupon_to_code', [
'by_reference' => false,
'label' => 'sylius.form.cart.coupon',
'required' => false,
])
;
}
}

View file

@ -19,8 +19,6 @@ use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
/** /**
* Order item type.
*
* @author Paweł Jędrzejewski <pawel@sylius.org> * @author Paweł Jędrzejewski <pawel@sylius.org>
*/ */
class OrderItemType extends BaseOrderItemType class OrderItemType extends BaseOrderItemType
@ -32,13 +30,21 @@ class OrderItemType extends BaseOrderItemType
{ {
parent::buildForm($builder, $options); parent::buildForm($builder, $options);
$builder->remove('unitPrice');
$builder $builder
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) { ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
$data = $event->getData(); $data = $event->getData();
if (isset($data['variant'])) { if (isset($data['variant'])) {
$event->getForm()->add('variant', 'entity_hidden', [ $form = $event->getForm();
'data_class' => $options['variant_data_class'], $form
]); ->add('variant', 'entity_hidden', [
'data_class' => $options['variant_data_class'],
])
->add('unitPrice', 'integer', [
'data' => $data['variant']->getPrice()
])
;
} }
}) })
; ;

View file

@ -32,6 +32,11 @@ class OrderType extends BaseOrderType
$builder $builder
->add('shippingAddress', 'sylius_address') ->add('shippingAddress', 'sylius_address')
->add('billingAddress', 'sylius_address') ->add('billingAddress', 'sylius_address')
->add('promotionCoupon', 'sylius_promotion_coupon_to_code', [
'by_reference' => false,
'label' => 'sylius.form.cart.coupon',
'required' => false,
])
; ;
} }
} }

View file

@ -12,14 +12,14 @@
namespace Sylius\Bundle\CoreBundle\Handler; namespace Sylius\Bundle\CoreBundle\Handler;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
use Sylius\Component\Cart\Context\CartContextInterface;
use Sylius\Component\Cart\Context\CartNotFoundException;
use Sylius\Component\Cart\Event\CartEvent;
use Sylius\Component\Cart\SyliusCartEvents;
use Sylius\Component\Core\Currency\Handler\CurrencyChangeHandlerInterface; use Sylius\Component\Core\Currency\Handler\CurrencyChangeHandlerInterface;
use Sylius\Component\Core\Exception\HandleException; use Sylius\Component\Core\Exception\HandleException;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Updater\OrderUpdaterInterface; use Sylius\Component\Core\Updater\OrderUpdaterInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Order\Event\CartEvent;
use Sylius\Component\Order\SyliusCartEvents;
use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/** /**

View file

@ -12,8 +12,8 @@
namespace Sylius\Bundle\CoreBundle\Handler; namespace Sylius\Bundle\CoreBundle\Handler;
use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\ObjectManager;
use Sylius\Component\Cart\Context\CartContextInterface; use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Cart\Context\CartNotFoundException; use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\Component\Core\Exception\HandleException; use Sylius\Component\Core\Exception\HandleException;
use Sylius\Component\Core\Locale\Handler\LocaleChangeHandlerInterface; use Sylius\Component\Core\Locale\Handler\LocaleChangeHandlerInterface;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;

View file

@ -13,7 +13,7 @@ namespace Sylius\Bundle\CoreBundle\Purger;
use Doctrine\Common\Persistence\ObjectManager; use Doctrine\Common\Persistence\ObjectManager;
use SM\Factory\FactoryInterface; use SM\Factory\FactoryInterface;
use Sylius\Component\Cart\Purger\PurgerInterface; use Sylius\Component\Order\Purger\PurgerInterface;
use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface; use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Inventory\Model\InventoryUnitInterface; use Sylius\Component\Inventory\Model\InventoryUnitInterface;

View file

@ -26,20 +26,6 @@ sylius_association:
model: Sylius\Component\Product\Model\ProductAssociation model: Sylius\Component\Product\Model\ProductAssociation
interface: Sylius\Component\Product\Model\ProductAssociationInterface interface: Sylius\Component\Product\Model\ProductAssociationInterface
sylius_cart:
resources:
cart:
classes:
model: "%sylius.model.order.class%"
repository: Sylius\Bundle\CoreBundle\Doctrine\ORM\OrderRepository
form:
default: Sylius\Bundle\CoreBundle\Form\Type\CartType
cart_item:
classes:
model: "%sylius.model.order_item.class%"
form:
default: Sylius\Bundle\CoreBundle\Form\Type\CartItemType
sylius_channel: sylius_channel:
resources: resources:
channel: channel:

Some files were not shown because too many files have changed in this diff Show more