Skip to content

Commit

Permalink
Upgrade for Magento 2
Browse files Browse the repository at this point in the history
  • Loading branch information
l1mosh authored and davidwindell committed Jun 25, 2018
1 parent d660117 commit eb67938
Show file tree
Hide file tree
Showing 14 changed files with 408 additions and 289 deletions.
194 changes: 194 additions & 0 deletions Block/Product/View/Type/Configurable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
<?php

namespace OuterEdge\ConfigProduct\Block\Product\View\Type;

use Magento\Swatches\Block\Product\Renderer\Configurable as SwatchConfigurable;
use Magento\Catalog\Block\Product\Context;
use Magento\Framework\Stdlib\ArrayUtils;
use Magento\Framework\Json\EncoderInterface;
use Magento\Framework\Json\DecoderInterface;
use Magento\ConfigurableProduct\Helper\Data;
use Magento\Catalog\Helper\Product as CatalogProduct;
use Magento\Customer\Helper\Session\CurrentCustomer;
use Magento\Framework\Pricing\PriceCurrencyInterface;
use Magento\ConfigurableProduct\Model\ConfigurableAttributeData;
use Magento\Swatches\Helper\Data as SwatchData;
use Magento\Swatches\Helper\Media;
use Magento\Swatches\Model\SwatchAttributesProvider;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Locale\Format;
use Magento\CatalogInventory\Api\Data\StockItemInterfaceFactory;

/**
* Class Configurable
* @package OuterEdge\ConfigProduct\Block\Product\View\Type
*/
class Configurable extends SwatchConfigurable
{
/**
* @var SwatchAttributesProvider
*/
private $swatchAttributesProvider;

/**
* @var Format
*/
private $localeFormat;

/**
* @var jsonDecoder interface
*/
protected $jsonDecoder;

/**
* @var StockRepository
*/
protected $_stockRepository;
/**
* @var Context
*/
private $context;
/**
* @var StockItemInterfaceFactory
*/
private $stockItemInterfaceFactory;

/**
* @param Context $context
* @param ArrayUtils $arrayUtils
* @param EncoderInterface $jsonEncoder
* @param DecoderInterface $jsonDecoder
* @param Data $helper
* @param CatalogProduct $catalogProduct
* @param CurrentCustomer $currentCustomer
* @param PriceCurrencyInterface $priceCurrency
* @param ConfigurableAttributeData $configurableAttributeData
* @param SwatchData $swatchHelper
* @param Media $swatchMediaHelper
* @param array $data other data
* @param SwatchAttributesProvider $swatchAttributesProvider
* @param Format|null $localeFormat
* @param StockItemInterfaceFactory $stockItemInterfaceFactory
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Context $context,
ArrayUtils $arrayUtils,
EncoderInterface $jsonEncoder,
DecoderInterface $jsonDecoder,
Data $helper,
CatalogProduct $catalogProduct,
CurrentCustomer $currentCustomer,
PriceCurrencyInterface $priceCurrency,
ConfigurableAttributeData $configurableAttributeData,
SwatchData $swatchHelper,
Media $swatchMediaHelper,
array $data = [],
SwatchAttributesProvider $swatchAttributesProvider = null,
Format $localeFormat = null,
StockItemInterfaceFactory $stockItemInterfaceFactory
){
$this->swatchHelper = $swatchHelper;
$this->swatchMediaHelper = $swatchMediaHelper;
$this->_stockRepository = $stockItemInterfaceFactory->create();
$this->swatchAttributesProvider = $swatchAttributesProvider
?: ObjectManager::getInstance()->get(SwatchAttributesProvider::class);
$this->localeFormat = $localeFormat ?: ObjectManager::getInstance()->get(Format::class);
$this->jsonDecoder =$jsonDecoder;

parent::__construct(
$context,
$arrayUtils,
$jsonEncoder,
$helper,
$catalogProduct,
$currentCustomer,
$priceCurrency,
$configurableAttributeData,
$swatchHelper,
$swatchMediaHelper,
$data
);
$this->context = $context;
$this->stockItemInterfaceFactory = $stockItemInterfaceFactory;
}

/**
* Sets product stock status.
*
* @param $productId
*
* @return array
*/
public function getStockItem($productId)
{
$stock_data = array();
$stock_data['out_stock'] = 0 ;

$stock = $this->_stockRepository->load($productId,'product_id');
if (!$stock->getIsInStock()) {
$stock_data['out_stock'] = 1;
}

return $stock_data;
}

/**
* Get Product Stock
*
* @return array
*/
public function getProductStock()
{
$stock = [];
$skipSaleableCheck=true;
$allProducts = $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null);

foreach ($allProducts as $product) {
if ($product->isSaleable() || $skipSaleableCheck) {
$stock[$product->getId()] = $this->getStockItem($product->getId());
}
}
return $stock;
}

/**
* Extend the configuration for js to add stock values.
*
* @return string
*/
public function getJsonConfig()
{
$config = $this->jsonDecoder->decode(parent::getJsonConfig());
$currentProduct = $this->getProduct();
$options = $this->helper->getOptions($currentProduct, $this->getAllowProducts(),$this->getProductStock());
//Adding stock details to the config product options.
$config['stock']=isset($options['stock']) ? $options['stock'] : [];
return $this->jsonEncoder->encode($config);
}

/**
* Get Allowed Products
* Modified to set $skipSaleableCheck to true
*
* @return \Magento\Catalog\Model\Product[]
*/
public function getAllowProducts()
{
if (!$this->hasAllowProducts()) {
$products = [];
//$skipSaleableCheck = $this->catalogProduct->getSkipSaleableCheck();
//Setting $skipSaleableCheck true as it is hardcoded false in the parent.
$skipSaleableCheck=true;
$allProducts = $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null);
foreach ($allProducts as $product) {
if ($product->isSaleable() || $skipSaleableCheck) {
$products[] = $product;
}
}
$this->setAllowProducts($products);
}
return $this->getData('allow_products');
}

}
37 changes: 37 additions & 0 deletions Helper/Data.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace OuterEdge\ConfigProduct\Helper;

class Data extends \Magento\ConfigurableProduct\Helper\Data
{

/**
* Get Options for Configurable Product Options
*
* Modified to add out of stock status option.
*
* @param \Magento\Catalog\Model\Product $currentProduct
* @param array $allowedProducts
* @return array
*/
public function getOptions($currentProduct, $allowedProducts, $stockdata = null)
{
$options = [];
$allowAttributes = $this->getAllowAttributes($currentProduct);

foreach ($allowedProducts as $product) {
$productId = $product->getId();
foreach ($allowAttributes as $attribute) {
$productAttribute = $attribute->getProductAttribute();
$productAttributeId = $productAttribute->getId();
$attributeValue = $product->getData($productAttribute->getAttributeCode());

$options[$productAttributeId][$attributeValue][] = $productId;
$options['index'][$productId][$productAttributeId] = $attributeValue;
}
//Adding stock status in the option list.
$options['stock'][$productId][] = $stockdata[$productId]['out_stock'];
}
return $options;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

namespace OuterEdge\ConfigProduct\Plugin\Model\ResourceModel\Attribute;

use Magento\CatalogInventory\Api\StockConfigurationInterface;
use \Magento\ConfigurableProduct\Plugin\Model\ResourceModel\Attribute\InStockOptionSelectBuilder as MageInStockOptionSelectBuilder;
use Magento\CatalogInventory\Model\ResourceModel\Stock\Status;
use Magento\ConfigurableProduct\Model\ResourceModel\Attribute\OptionSelectBuilderInterface;
use Magento\Framework\DB\Select;

class InStockOptionSelectBuilder extends MageInStockOptionSelectBuilder
{
/**
* CatalogInventory Stock Status Resource Model.
*
* @var Status
*/
private $stockStatusResource;
/**
*
* @var Configuration
*/
private $stockConfiguration;
/**
* @param Status $stockStatusResource
*/

public function __construct(Status $stockStatusResource, StockConfigurationInterface $stockConfiguration)
{
$this->stockStatusResource = $stockStatusResource;
$this->stockConfiguration = $stockConfiguration;
}
/**
* Add stock status filter to select.
*
* @param OptionSelectBuilderInterface $subject
* @param Select $select
* @return Select
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterGetSelect(OptionSelectBuilderInterface $subject, Select $select)
{
//Ignore the stock status in the configuration option, if the show out of stock is set.
if (!$this->stockConfiguration->isShowOutOfStock()) {
$select->joinInner(
['stock' => $this->stockStatusResource->getMainTable()],
'stock.product_id = entity.entity_id',
[]
)->where(
'stock.stock_status = ?',
\Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK
);
}
return $select;
}
}
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@
All Configurable Options Module for Magento by outer/edge

This module will show all available options that are available for a configurable product, regardless of stock levels for the associated products. For example, if you have a clothing item available in three sizes - **Small**, **Medium** and **Large**, and the **Small** size is out of stock, Magento would not show this option. However, with this module all options will be displayed, but out of stock items will be disabled.

### Configuration

To show out of stock options in the configurable product, enable(set to'yes') "Display Out of Stock Products" in
Stores->Settings->Configuration->Catalogue->Inventory-> Stock Options
Loading

0 comments on commit eb67938

Please sign in to comment.