mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
feature #10688 MVP of the debug cart panel (, pamil)
This PR was merged into the 1.8-dev branch. Discussion ---------- | Q | A | --------------- | ----- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | License | MIT Why? Sometimes, you want to debug what was inside of the cart on a specific request. While on shop pages you will see the cart summary widget, you do not know the details (id, ids and codes of products/variants), etc. This is useful when debugging promotions, taxes, etc. This is an MVP done during a hackathon, but can be extended with more data and details, especially about $. <img width="1425" alt="Screenshot 2019-09-21 at 16 54 08" src="https://user-images.githubusercontent.com/614970/65375028-0ee88980-dc91-11e9-9b3d-ac9a089b9757.png"> <img width="288" alt="Screenshot 2019-09-21 at 16 54 11" src="https://user-images.githubusercontent.com/614970/65375029-0ee88980-dc91-11e9-9f8c-bbc69894453e.png"> <img width="582" alt="Sylius___Your_shopping_cart" src="https://user-images.githubusercontent.com/614970/65375030-0ee88980-dc91-11e9-88c9-4f4b439d2855.png"> Commits -------587581dd1dMVP of the debug cart panel0f81c57f16Improve cart collector
This commit is contained in:
commit
552c4a00e6
4 changed files with 249 additions and 0 deletions
134
src/Sylius/Bundle/CoreBundle/Collector/CartCollector.php
Normal file
134
src/Sylius/Bundle/CoreBundle/Collector/CartCollector.php
Normal 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';
|
||||
}
|
||||
}
|
||||
|
|
@ -72,6 +72,11 @@
|
|||
<tag name="data_collector" template="@SyliusCore/Collector/sylius.html.twig" id="sylius_core" priority="-512" />
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Bundle\CoreBundle\Collector\CartCollector" public="false">
|
||||
<argument type="service" id="sylius.context.cart" />
|
||||
<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">
|
||||
<argument type="service" id="sylius.repository.shipping_method" />
|
||||
<argument type="service" id="sylius.zone_matcher" />
|
||||
|
|
|
|||
|
|
@ -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 |
|
|
@ -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 %}
|
||||
Loading…
Add table
Reference in a new issue