Improve cart collector

This commit is contained in:
Kamil Kokot 2020-05-20 18:59:00 +02:00
parent 587581dd1d
commit 0f81c57f16
No known key found for this signature in database
GPG key ID: 7BD76F7054D93C89
6 changed files with 246 additions and 232 deletions

View file

@ -0,0 +1,134 @@
<?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.
*/
declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Collector;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Context\CartNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
/**
* @internal
*/
final class CartCollector extends DataCollector
{
/** @var CartContextInterface */
private $cartContext;
public function __construct(CartContextInterface $cartContext)
{
$this->cartContext = $cartContext;
$this->data = [];
}
public function hasCart(): bool
{
return $this->data !== [];
}
public function getId(): ?int
{
return $this->data['id'];
}
public function getTotal(): ?int
{
return $this->data['total'];
}
public function getSubtotal(): ?int
{
return $this->data['subtotal'];
}
public function getCurrency(): ?string
{
return $this->data['currency'];
}
public function getLocale(): ?string
{
return $this->data['locale'];
}
public function getQuantity(): ?int
{
return $this->data['quantity'];
}
public function getItems(): ?array
{
return $this->data['items'];
}
public function getStates(): ?array
{
return $this->data['states'];
}
public function collect(Request $request, Response $response, \Exception $exception = null): void
{
try {
/** @var OrderInterface $cart */
$cart = $this->cartContext->getCart();
$itemsData = $cart->getItems()->map(static function (OrderItemInterface $item): array {
$variant = $item->getVariant();
$product = $variant->getProduct();
return [
'id' => $item->getId(),
'variantName' => $variant->getName(),
'variantId' => $variant->getId(),
'variantCode' => $variant->getCode(),
'quantity' => $item->getQuantity(),
'productName' => $product->getName(),
'productCode' => $product->getCode(),
'productId' => $product->getId(),
];
})->toArray();
$this->data = [
'id' => $cart->getId(),
'total' => $cart->getTotal(),
'subtotal' => $cart->getItemsTotal(),
'currency' => $cart->getCurrencyCode(),
'locale' => $cart->getLocaleCode(),
'quantity' => count($cart->getItems()),
'items' => $itemsData,
'states' => [
'main' => $cart->getState(),
'checkout' => $cart->getCheckoutState(),
'shipping' => $cart->getShippingState(),
'payment' => $cart->getPaymentState(),
]
];
} catch (CartNotFoundException $exception) {
$this->data = [];
}
}
public function reset(): void
{
$this->data = [];
}
public function getName(): string
{
return 'sylius_cart';
}
}

View file

@ -1,132 +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.
*/
declare(strict_types=1);
namespace Sylius\Bundle\CoreBundle\Collector;
use Sylius\Bundle\CoreBundle\Application\Kernel;
use Sylius\Component\Channel\Context\ChannelNotFoundException;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Currency\Context\CurrencyNotFoundException;
use Sylius\Component\Locale\Context\LocaleNotFoundException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
final class DebugCartCollector extends DataCollector
{
/** @var CartContextInterface */
private $cartContext;
public function __construct(
CartContextInterface $cartContext
) {
$this->cartContext = $cartContext;
$cart = $cartContext->getCart();
$items = [];
foreach ($cart->getItems() as $item) {
$variant = $item->getVariant();
$product = $variant->getProduct();
$items[] = [
'id' => $item->getId(),
'variantName' => $variant->getName(),
'variantId' => $variant->getId(),
'variantCode' => $variant->getCode(),
'quantity' => $item->getQuantity(),
'productName' => $product->getName(),
'productId' => $product->getId(),
];
}
$this->data = [
'cart_id' => $cart->getId(),
'total' => $cart->getTotal(),
'subtotal' => $cart->getItemsTotal(),
'currency' => $cart->getCurrencyCode(),
'locale' => $cart->getLocaleCode(),
'quantity' => count($cart->getItems()),
'items' => $items,
'states' => [
'main' => $cart->getState(),
'checkout' => $cart->getCheckoutState(),
'shipping' => $cart->getShippingState(),
'payment' => $cart->getPaymentState(),
]
];
}
public function getCartId(): ?int
{
return $this->data['cart_id'];
}
public function getTotal(): ?int
{
return $this->data['total'];
}
public function getSubtotal(): ?int
{
return $this->data['subtotal'];
}
public function getCurrency(): ?string
{
return $this->data['currency'];
}
public function getLocale(): ?string
{
return $this->data['locale'];
}
public function getQuantity(): ?int
{
return $this->data['quantity'];
}
public function getItems(): ?array
{
return $this->data['items'];
}
public function getStates(): ?array
{
return $this->data['states'];
}
/**
* {@inheritdoc}
*/
public function collect(Request $request, Response $response, \Exception $exception = null): void
{
}
/**
* {@inheritdoc}
*/
public function reset(): void
{
$this->data['cart_id'] = null;
}
/**
* {@inheritdoc}
*/
public function getName(): string
{
return 'sylius_core_debug_cart';
}
}

View file

@ -72,9 +72,9 @@
<tag name="data_collector" template="@SyliusCore/Collector/sylius.html.twig" id="sylius_core" priority="-512" />
</service>
<service id="sylius.collector.core_debug_cart" class="Sylius\Bundle\CoreBundle\Collector\DebugCartCollector" public="false">
<service id="Sylius\Bundle\CoreBundle\Collector\CartCollector" public="false">
<argument type="service" id="sylius.context.cart" />
<tag name="data_collector" template="@SyliusCore/Collector/debug_cart.html.twig" id="sylius_core_debug_cart" priority="-512" />
<tag name="data_collector" template="@SyliusCore/Collector/cart.html.twig" id="sylius_cart" priority="-512" />
</service>
<service id="sylius.shipping_methods_resolver.zones_and_channel_based" class="Sylius\Component\Core\Resolver\ZoneAndChannelBasedShippingMethodsResolver">

View file

@ -0,0 +1,2 @@
<!-- Icon by fontawesome.com, color modified to #AAAAAA, https://fontawesome.com/license -->
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="shopping-cart" class="svg-inline--fa fa-shopping-cart fa-w-18" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="#AAAAAA" d="M528.12 301.319l47.273-208C578.806 78.301 567.391 64 551.99 64H159.208l-9.166-44.81C147.758 8.021 137.93 0 126.529 0H24C10.745 0 0 10.745 0 24v16c0 13.255 10.745 24 24 24h69.883l70.248 343.435C147.325 417.1 136 435.222 136 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-15.674-6.447-29.835-16.824-40h209.647C430.447 426.165 424 440.326 424 456c0 30.928 25.072 56 56 56s56-25.072 56-56c0-22.172-12.888-41.332-31.579-50.405l5.517-24.276c3.413-15.018-8.002-29.319-23.403-29.319H218.117l-6.545-32h293.145c11.206 0 20.92-7.754 23.403-18.681z"></path></svg>

After

Width:  |  Height:  |  Size: 871 B

View file

@ -0,0 +1,108 @@
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
{% block toolbar %}
{% if collector.hasCart %}
{% import "@SyliusShop/Common/Macro/money.html.twig" as money %}
{% set icon %}
{{ include('@SyliusCore/Collector/Icon/cart.svg') }}
<span class="sf-toolbar-value">{{ collector.quantity|default(0) }}</span>
{% endset %}
{% set text %}
<div class="sf-toolbar-info-group">
<div class="sf-toolbar-info-piece">
<b>ID</b>
<span>{{ collector.id }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Subtotal</b>
<span>{{ money.convertAndFormat(collector.subtotal, collector.currency) }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Total</b>
<span>{{ money.convertAndFormat(collector.total, collector.currency) }}</span>
</div>
</div>
<div class="sf-toolbar-info-group">
<div class="sf-toolbar-info-piece">
<span><a href="{{ profiler_url ~ '?panel=sylius_cart' }}" rel="help">View details</a></span>
</div>
</div>
{% endset %}
{% include '@WebProfiler/Profiler/toolbar_item.html.twig' with {'link': profiler_url} %}
{% endif %}
{% endblock %}
{% block menu %}
{% if collector.hasCart %}
<span class="label {% if collector.quantity|default(0) == 0 %}disabled{% endif %}">
<span class="icon">{{ include('@SyliusCore/Collector/Icon/cart.svg') }}</span>
<strong>Cart</strong>
<span class="count">
<span>{{ collector.quantity|default(0) }}</span>
</span>
</span>
{% endif %}
{% endblock %}
{% block panel %}
{% if collector.hasCart %}
{% import "@SyliusShop/Common/Macro/money.html.twig" as money %}
<h2>Cart</h2>
<table>
<tr>
<th>ID</th>
<th>Currency</th>
<th>Locale</th>
<th>Subtotal</th>
<th>Total</th>
</tr>
<tr>
<td>{{ collector.id }}</td>
<td>{{ collector.currency }}</td>
<td>{{ collector.locale }}</td>
<td>{{ money.convertAndFormat(collector.subtotal, collector.currency) }}</td>
<td>{{ money.convertAndFormat(collector.total, collector.currency) }}</td>
</tr>
</table>
<h2>States</h2>
<table>
<tr>
<th>Main</th>
<th>Checkout</th>
<th>Shipping</th>
<th>Payment</th>
</tr>
<tr>
<td>{{ collector.states.main }}</td>
<td>{{ collector.states.checkout }}</td>
<td>{{ collector.states.shipping }}</td>
<td>{{ collector.states.payment }}</td>
</tr>
</table>
{% if collector.items|length > 0 %}
<h2>Items</h2>
<table>
<tr>
<th>ID</th>
<th>Product (Code, ID)</th>
<th>Variant (Code, ID)</th>
<th>Quantity</th>
</tr>
{% for item in collector.items %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.productName }} ({{ item.productCode }}, {{ item.productId }})</td>
<td>{{ item.variantName }} ({{ item.variantCode }}, {{ item.variantId }})</td>
<td>{{ item.quantity }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endif %}
{% endblock %}

View file

@ -1,98 +0,0 @@
{% extends '@WebProfiler/Profiler/layout.html.twig' %}
{% block toolbar %}
{% import "@SyliusShop/Common/Macro/money.html.twig" as money %}
{% set icon %}
<span class="sf-toolbar-value">Cart ({{ collector.quantity|default(0) }})</span>
{% endset %}
{% set text %}
<div class="sf-toolbar-info-group">
<div class="sf-toolbar-info-piece">
<b>ID</b>
<span>{{ collector.cartId }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Subtotal</b>
<span>{{ money.convertAndFormat(collector.subtotal, collector.currency) }}</span>
</div>
<div class="sf-toolbar-info-piece">
<b>Total</b>
<span>{{ money.convertAndFormat(collector.total, collector.currency) }}</span>
</div>
</div>
<div class="sf-toolbar-info-group">
<div class="sf-toolbar-info-piece">
<span><a href="{{ profiler_url ~ '?panel=sylius_core_debug_cart' }}" rel="help">View details</a></span>
</div>
</div>
{% endset %}
{% include '@WebProfiler/Profiler/toolbar_item.html.twig' with {'link': profiler_url} %}
{% endblock %}
{% block menu %}
<span class="label">
<span class="icon">{{ include('@WebProfiler/Icon/form.svg') }}</span>
<strong>Cart</strong>
</span>
{% endblock %}
{% block panel %}
{% import "@SyliusShop/Common/Macro/money.html.twig" as money %}
<h2>Cart</h2>
<table>
<tr>
<th>ID</th>
<th>Currency</th>
<th>Locale</th>
<th>Subtotal</th>
<th>Total</th>
</tr>
<tr>
<td>{{ collector.cartId }}</td>
<td>{{ collector.currency }}</td>
<td>{{ collector.locale }}</td>
<td>{{ money.convertAndFormat(collector.subtotal, collector.currency) }}</td>
<td>{{ money.convertAndFormat(collector.total, collector.currency) }}</td>
</tr>
</table>
<h2>States</h2>
<table>
<tr>
<th>Main</th>
<th>Checkout</th>
<th>Shipping</th>
<th>Payment</th>
</tr>
<tr>
<td>{{ collector.states.main }}</td>
<td>{{ collector.states.checkout }}</td>
<td>{{ collector.states.shipping }}</td>
<td>{{ collector.states.payment }}</td>
</tr>
</table>
{% if collector.items|length > 0 %}
<h2>Items</h2>
<table>
<tr>
<th>ID</th>
<th>Product (ID)</th>
<th>Variant (ID / Code)</th>
<th>Quantity</th>
</tr>
{% for item in collector.items %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.productName }} ({{item.productId}})</td>
<td>{{ item.variantName }} ({{ item.variantId }} / {{ item.variantCode }})</td>
<td>{{ item.quantity }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% endblock %}