Skip to content

Commit

Permalink
MC-30989: Adding a configurable product to the cart from the cross-se…
Browse files Browse the repository at this point in the history
…lls tab shows a 404
  • Loading branch information
nikita-shcherbatykh committed Feb 18, 2020
1 parent a25c107 commit 909d479
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 38 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\ViewModel\Product\Listing;

use Magento\Framework\View\Element\Block\ArgumentInterface;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\Url\Helper\Data as UrlHelper;

/**
* Check is available add to compare.
*/
class PreparePostData implements ArgumentInterface
{
/**
* @var UrlHelper
*/
private $urlHelper;

/**
* @param UrlHelper $urlHelper
*/
public function __construct(UrlHelper $urlHelper)
{
$this->urlHelper = $urlHelper;
}

/**
* Wrapper for the PostHelper::getPostData()
*
* @param string $url
* @param array $data
* @return array
*/
public function getPostData(string $url, array $data = []):array
{
if (!isset($data[ActionInterface::PARAM_NAME_URL_ENCODED])) {
$data[ActionInterface::PARAM_NAME_URL_ENCODED] = $this->urlHelper->getEncodedUrl();
}
return ['action' => $url, 'data' => $data];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
<block class="Magento\Catalog\Block\Product\ProductList\Related" name="catalog.product.related" template="Magento_Catalog::product/list/items.phtml">
<arguments>
<argument name="type" xsi:type="string">related</argument>
<argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
</arguments>
<block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="related.product.addto" as="addto">
<block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
Expand All @@ -185,6 +186,7 @@
<block class="Magento\Catalog\Block\Product\ProductList\Upsell" name="product.info.upsell" template="Magento_Catalog::product/list/items.phtml">
<arguments>
<argument name="type" xsi:type="string">upsell</argument>
<argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
</arguments>
<block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="upsell.product.addto" as="addto">
<block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* See COPYING.txt for license details.
*/

use Magento\Catalog\ViewModel\Product\Listing\PreparePostData;
use Magento\Framework\App\ActionInterface;

// phpcs:disable Magento2.Templates.ThisInTemplate.FoundThis
// phpcs:disable Generic.WhiteSpace.ScopeIndent.Incorrect
// phpcs:disable Generic.Files.LineLength
Expand Down Expand Up @@ -156,6 +159,7 @@ switch ($type = $block->getType()) {
default:
$exist = null;
}
$_item = null;
?>

<?php if ($exist):?>
Expand All @@ -170,13 +174,15 @@ switch ($type = $block->getType()) {
<div class="block <?= $block->escapeHtmlAttr($class) ?>">
<?php endif; ?>
<div class="block-title title">
<strong id="block-<?= $block->escapeHtmlAttr($class) ?>-heading" role="heading" aria-level="2"><?= $block->escapeHtml($title) ?></strong>
<strong id="block-<?= $block->escapeHtmlAttr($class) ?>-heading" role="heading"
aria-level="2"><?= $block->escapeHtml($title) ?></strong>
</div>
<div class="block-content content" aria-labelledby="block-<?= $block->escapeHtmlAttr($class) ?>-heading">
<?php if ($type == 'related' && $canItemsAddToCart):?>
<div class="block-actions">
<?= $block->escapeHtml(__('Check items to add to the cart or')) ?>
<button type="button" class="action select" data-role="select-all"><span><?= $block->escapeHtml(__('select all')) ?></span></button>
<button type="button" class="action select"
data-role="select-all"><span><?= $block->escapeHtml(__('select all')) ?></span></button>
</div>
<?php endif; ?>
<div class="products wrapper grid products-grid products-<?= $block->escapeHtmlAttr($type) ?>">
Expand All @@ -195,11 +201,15 @@ switch ($type = $block->getType()) {
<?php endif; ?>
<div class="product-item-info <?= /* @noEscape */ $available ?>">
<?= /* @noEscape */ '<!-- ' . $image . '-->' ?>
<a href="<?= $block->escapeUrl($block->getProductUrl($_item)) ?>" class="product photo product-item-photo">
<a href="<?= $block->escapeUrl($block->getProductUrl($_item)) ?>"
class="product photo product-item-photo">
<?= $block->getImage($_item, $image)->toHtml() ?>
</a>
<div class="product details product-item-details">
<strong class="product name product-item-name"><a class="product-item-link" title="<?= $block->escapeHtml($_item->getName()) ?>" href="<?= $block->escapeUrl($block->getProductUrl($_item)) ?>">
<strong class="product name product-item-name"><a
class="product-item-link"
title="<?= $block->escapeHtmlAttr($_item->getName()) ?>"
href="<?= $block->escapeUrl($block->getProductUrl($_item)) ?>">
<?= $block->escapeHtml($_item->getName()) ?></a>
</strong>

Expand All @@ -209,52 +219,88 @@ switch ($type = $block->getType()) {
<?= $block->getReviewsSummaryHtml($_item, $templateType) ?>
<?php endif; ?>

<?php if ($canItemsAddToCart && !$_item->isComposite() && $_item->isSaleable() && $type == 'related'):?>
<?php if ($canItemsAddToCart && !$_item->isComposite() && $_item->isSaleable()
&& $type == 'related'):?>
<?php if (!$_item->getRequiredOptions()):?>
<div class="field choice related">
<input type="checkbox" class="checkbox related" id="related-checkbox<?= $block->escapeHtmlAttr($_item->getId()) ?>" name="related_products[]" value="<?= $block->escapeHtmlAttr($_item->getId()) ?>" />
<label class="label" for="related-checkbox<?= $block->escapeHtmlAttr($_item->getId()) ?>"><span><?= $block->escapeHtml(__('Add to Cart')) ?></span></label>
<div class="field choice related"><input
type="checkbox"
class="checkbox related"
id="related-checkbox<?= $block->escapeHtmlAttr($_item->getId()) ?>"
name="related_products[]"
value="<?= $block->escapeHtmlAttr($_item->getId()) ?>" />
<label
class="label"
for="related-checkbox<?= $block->escapeHtmlAttr(
$_item->getId()
) ?>"><span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
</label>
</div>
<?php endif; ?>
<?php endif; ?>

<?php if ($showAddTo || $showCart):?>
<?php // phpcs:disable ?>
<div class="product actions product-item-actions">
<?php if ($showCart):?>
<div class="actions-primary">
<?php if ($_item->isSaleable()):?>
<?php if ($_item->getTypeInstance()->hasRequiredOptions($_item)):?>
<button class="action tocart primary" data-mage-init='{"redirectUrl": {"url": "<?= $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>">
<span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
</button>
<?php else:?>
<?php $postDataHelper = $this->helper(Magento\Framework\Data\Helper\PostHelper::class);
$postData = $postDataHelper->getPostData($block->escapeUrl($block->getAddToCartUrl($_item)), ['product' => $_item->getEntityId()])
?>
<button class="action tocart primary"
data-post='<?= /* @noEscape */ $postData ?>'
type="button" title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>">
<?php if ($_item->isSaleable()):?>
<div class="actions-primary">
<?php if (!$_item->getTypeInstance()->isPossibleBuyFromList($_item)):?>
<button
class="action tocart primary"
data-mage-init='{"redirectUrl": {"url": "<?= $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"}}' type="button" title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>">
<span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
</button>
<?php else :?>
<?php
/** @var $viewModel PreparePostData */
$viewModel = $block->getViewModel();
$postArray = $viewModel->getPostData(
$block->escapeUrl($block->getAddToCartUrl($_item)),
['product' => $_item->getEntityId()]
);
$value = $postArray['data'][ActionInterface::PARAM_NAME_URL_ENCODED];
?>
<form data-role="tocart-form"
data-product-sku="<?= $block->escapeHtmlAttr($_item->getSku()) ?>"
action="<?= $block->escapeUrl($block->getAddToCartUrl($_item)) ?>"
method="post">
<input type="hidden" name="product"
value="<?= /* @noEscape */ (int)$_item->getEntityId() ?>">
<input type="hidden"
name="<?= /* @noEscape */ ActionInterface::PARAM_NAME_URL_ENCODED?>"
value="<?= /* @noEscape */ $value ?>">
<?= $block->getBlockHtml('formkey') ?>
<button type="submit"
title="<?= $block->escapeHtmlAttr(__('Add to Cart')) ?>"
class="action tocart primary">
<span><?= $block->escapeHtml(__('Add to Cart')) ?></span>
</button>
<?php endif; ?>
</form>
<?php endif; ?>
<?php else:?>
<?php if ($_item->getIsSalable()):?>
<div class="stock available">
<span><?= $block->escapeHtml(__('In stock')) ?></span>
</div>
<?php else:?>
<?php if ($_item->getIsSalable()):?>
<div class="stock available"><span><?= $block->escapeHtml(__('In stock')) ?></span></div>
<?php else:?>
<div class="stock unavailable"><span><?= $block->escapeHtml(__('Out of stock')) ?></span></div>
<?php endif; ?>
<div class="stock unavailable">
<span><?= $block->escapeHtml(__('Out of stock')) ?></span>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php endif; ?>

<?php if ($showAddTo):?>
<div class="secondary-addto-links actions-secondary" data-role="add-to-links">
<div class="secondary-addto-links actions-secondary"
data-role="add-to-links">
<?php if ($addToBlock = $block->getChildBlock('addto')):?>
<?= $addToBlock->setProduct($_item)->getChildHtml() ?>
<?php endif; ?>
</div>
<?php endif; ?>
</div>
<?php // phpcs:enable ?>
<?php endif; ?>
</div>
</div>
Expand All @@ -264,4 +310,15 @@ switch ($type = $block->getType()) {
</div>
</div>
</div>
<?php if (!$block->isRedirectToCartEnabled() && $_item):?>
<script type="text/x-magento-init">
{
"[data-role=tocart-form], .form.map.checkout": {
"catalogAddToCart": {
"product_sku": "<?= $block->escapeJs($_item->getSku()) ?>"
}
}
}
</script>
<?php endif;?>
<?php endif;?>
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
<block class="Magento\Checkout\Block\Cart\Crosssell" name="checkout.cart.crosssell" template="Magento_Catalog::product/list/items.phtml" after="-" ifconfig="checkout/cart/crosssell_enabled">
<arguments>
<argument name="type" xsi:type="string">crosssell</argument>
<argument name="view_model" xsi:type="object">Magento\Catalog\ViewModel\Product\Listing\PreparePostData</argument>
</arguments>
<block class="Magento\Catalog\Block\Product\ProductList\Item\Container" name="crosssell.product.addto" as="addto">
<block class="Magento\Catalog\Block\Product\ProductList\Item\AddTo\Compare"
Expand Down
3 changes: 2 additions & 1 deletion app/code/Magento/Checkout/view/frontend/requirejs-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ var config = {
sidebar: 'Magento_Checkout/js/sidebar',
checkoutLoader: 'Magento_Checkout/js/checkout-loader',
checkoutData: 'Magento_Checkout/js/checkout-data',
proceedToCheckout: 'Magento_Checkout/js/proceed-to-checkout'
proceedToCheckout: 'Magento_Checkout/js/proceed-to-checkout',
catalogAddToCart: 'Magento_Catalog/js/catalog-add-to-cart'
}
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -1270,14 +1270,8 @@ private function getCatalogConfig()
*/
public function isPossibleBuyFromList($product)
{
$isAllCustomOptionsDisplayed = true;
foreach ($this->getConfigurableAttributes($product) as $attribute) {
$eavAttribute = $attribute->getProductAttribute();

$isAllCustomOptionsDisplayed = ($isAllCustomOptionsDisplayed && $eavAttribute->getUsedInProductListing());
}

return $isAllCustomOptionsDisplayed;
//such cases already handled by add to cart action
return true;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,15 @@ public function testAll()
$block = $objectManager->get(\Magento\Framework\View\LayoutInterface::class)
->createBlock(\Magento\Catalog\Block\Product\ProductList\Crosssell::class);
$block->setLayout($objectManager->get(\Magento\Framework\View\LayoutInterface::class));
$block->setViewModel($objectManager->get(\Magento\Catalog\ViewModel\Product\Listing\PreparePostData::class));
$block->setTemplate('Magento_Catalog::product/list/items.phtml');
$block->setType('crosssell');
$block->setItemCount(1);
$html = $block->toHtml();
$this->assertNotEmpty($html);
$this->assertContains('Simple Cross Sell', $html);
/* name */
$this->assertContains('product\/' . $firstProduct->getId() . '\/', $html);
$this->assertContains('product/' . $firstProduct->getId() . '/', $html);
/* part of url */
$this->assertInstanceOf(
\Magento\Catalog\Model\ResourceModel\Product\Link\Product\Collection::class,
Expand Down

0 comments on commit 909d479

Please sign in to comment.