简体   繁体   中英

Sylius Not Remembering Cart After Adding an Item

I'm using the Sylius Cart and Order Bundles and trying to add an item to the cart and show a summary of the items in the cart. The problem I'm having is Symfony/Sylius forgets that it has made a cart and added items to it.

If I click a link going to the add page for the sylius cart, generated by

{{ path('sylius_cart_item_add', {'productId': class.ClassID}) }}

No error occurs. If I look in the database I can see that a new entry has been created in the sylius_cart table and the sylius_cart_item table, with the correct information; however, the cart summary page shows nothing and thinks the cart is empty.

If I try to add another item, it creates another new cart and promptly forgets that it made the cart.

I have the following bundles loading in AppKernel.php

public function registerBundles()
{
        $bundles = array(
            //bundles for using the shopping cart
            new FOS\RestBundle\FOSRestBundle(),
            new JMS\SerializerBundle\JMSSerializerBundle($this),
            new Sylius\Bundle\ResourceBundle\SyliusResourceBundle(),
            new WhiteOctober\PagerfantaBundle\WhiteOctoberPagerfantaBundle(),
            new Sylius\Bundle\MoneyBundle\SyliusMoneyBundle(),
            new Sylius\Bundle\OrderBundle\SyliusOrderBundle(),
            new Sylius\Bundle\CartBundle\SyliusCartBundle(),
            new Sylius\Bundle\SequenceBundle\SyliusSequenceBundle(),


            //bundles for styling with bootstrap 3
            new Mopa\Bundle\BootstrapBundle\MopaBootstrapBundle(),

            //mssql connection library
            new Realestate\MssqlBundle\RealestateMssqlBundle(),

            //default frameworks
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Symfony\Bundle\AsseticBundle\AsseticBundle(),
            new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
            new CE\CEBundle\CEBundle(),
        );

        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
            $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
            $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
        }

        return $bundles;
}

My ItemResolver class looks like

namespace CE\CEBundle\Cart;

use Sylius\Component\Cart\Model\CartItemInterface;
use Sylius\Component\Cart\Resolver\ItemResolverInterface;
use Sylius\Component\Cart\Resolver\ItemResolvingException;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManager;

class ItemResolver implements ItemResolverInterface
{
    private $entityManager;

    public function __construct(EntityManager $entityManager)
    {
        $this->entityManager = $entityManager;
    }


    public function resolve(CartItemInterface $item, $data)
    {
        //grab the product ID
        $productId = $data->get('productId');


        if (!$productId || !$product = $this->getProductRepository()->find($productId)) {
            throw new ItemResolvingException('Requested product was not found');
        }

        $item->setProductId($product->getId());
        $item->setUnitPrice($product->getClassFee() * 100);

        return $item;
    }

    private function getProductRepository()
    {
        return $this->entityManager->getRepository('CEBundle:Product');
    }
}

My CartItem class looks like

namespace CE\CEBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Cart\Model\CartItem as BaseCartItem;

/**
 * @ORM\Entity
 * @ORM\Table(name="sylius_cart_item")
 */
class CartItem extends BaseCartItem
{
    /**
     * @ORM\Column(type="string", name="product_id", length=8)
     */
    private $productId;

    public function getProductId()
    {
        return $this->productId;
    }

    public function setProductId($Id)
    {
        $this->productId = $Id;
    }
}

I have the following config in my config.yml

imports:
    - { resource: parameters.yml }
    - { resource: security.yml }

framework:
    #esi:             ~
    #translator:      { fallback: "%locale%" }
    secret:          "%secret%"
    router:
        resource: "%kernel.root_dir%/config/routing.yml"
        strict_requirements: ~
    form: ~

    csrf_protection: ~
    validation:      { enable_annotations: true }
    templating:
        engines: ['twig']
        #assets_version: SomeVersionScheme
    default_locale:  "%locale%"
    trusted_hosts:   ~
    trusted_proxies: ~
    session:
        # handler_id set to null will use default session handler from php.ini
        handler_id:  ~
        name: SYLIUS_SESSION
        cookie_lifetime: 72000
    fragments:       ~
    http_method_override: true

# Twig Configuration
twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"

# Assetic Configuration
assetic:
    debug:          "%kernel.debug%"
    use_controller: false
    bundles:        [ ]
    #java: /usr/bin/java
    filters:
        cssrewrite: ~
        #closure:
        #    jar: "%kernel.root_dir%/Resources/java/compiler.jar"
        #yui_css:
        #    jar: "%kernel.root_dir%/Resources/java/yuicompressor-2.4.7.jar"

# Doctrine Configuration
doctrine:
    dbal:
        default_connection: default
        connections:
            default:
                driver:   "%database_driver%"
                host:     "%database_host%"
                port:     "%database_port%"
                dbname:   "%database_name%"
                user:     "%database_user%"
                password: "%database_password%"
                charset:  UTF8
            mssqlDB:
                driver_class:   Realestate\MssqlBundle\Driver\PDODblib\Driver
                host:     %db.other.host%
                dbname:   %db.other.db_name%
                user:     %db.other.user%
                password: %db.other.password%
        # if using pdo_sqlite as your database driver, add the path in parameters.yml
        # e.g. database_path: "%kernel.root_dir%/data/data.db3"
        # path:     "%database_path%"

    orm:
        default_entity_manager: default
        entity_managers:
            default:
                connection: default
                mappings:
                    CEBundle: ~
            mssqlDB:
                connection: mssqlDB
                mappings:
                    CEBundle: ~

        auto_generate_proxy_classes: "%kernel.debug%"
        #auto_mapping: true


# Swiftmailer Configuration
swiftmailer:
    transport: "%mailer_transport%"
    host:      "%mailer_host%"
    username:  "%mailer_user%"
    password:  "%mailer_password%"
    spool:     { type: memory }

#sylius configuration
sylius_cart:
    resolver: ce.cart_item_resolver
    classes: ~
    provider: sylius.cart_provider.default
    storage:  sylius.storage.session

sylius_order:
    driver: doctrine/orm
    classes:
        order_item:
            model: CE\CEBundle\Entity\CartItem

sylius_sequence:
    driver: doctrine/orm

#mopa configuration for forms and bootstrap
mopa_bootstrap:
    form:
        checkbox_label: 'widget'

Of note, if I watch the Resources tab in the Chrome Developer Tools, I can see that SYLIUS_SESSION does get set when I add an item to the cart.

I've tried changing the storage to cookie instead of session and pouring over the documents, but I'm at a loss as to what to do to fix this. My guess is it's probably something small, I just don't know what it is.

Thank you for any help in advance.

In your config.yml file you are using sylius.cart_provider.default which means that you need to get the current Sylius Cart Provider before adding an item to it.

So that means in your controller, you will need to retrieve the cart_provider service like so:

// gets the current cart
$cart = $this->get('sylius.cart_provider')->getCart();

After that, you can create an $item like you are doing in the call to the ItemResolver::resolve() method and the item can be added to the cart.

You may also need to add the dispatcher events for the cart ITEM_ADD_INITIALIZE , CART_CHANGE , etc to your code to actually have the items appear in the cart.

Have a look at the CartItemEvent class for that. If you need help with that let me know.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM