ConfigurableProduct: How to get the configurable products out of stock?












0















I want to show the all attributes from my configurable product on my select. I followed this tutorial: Magento 2.2 How to show out of stock in configurable product, with some changes and fixes.



Well, my module is like this now:




Vendor/ConfigurableProduct/etc/di.xml




<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

<preference for="MagentoSwatchesBlockProductRendererConfigurable" type="VendorConfigurableProductBlockProductViewTypeConfigurable" />

<preference for="MagentoConfigurableProductModelConfigurableAttributeData" type="VendorConfigurableProductModelRewriteConfigurableAttributeData" />

<preference for="MagentoConfigurableProductHelperData" type="VendorConfigurableProductHelperData" />
</config>



Vendor/ConfigurableProduct/Block/ConfigurableProduct.php




<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace VendorConfigurableProductBlock;

use MagentoFrameworkViewElementTemplate;

class ConfigurableProduct extends Template
{
protected $_storeManager;

public function __construct(
MagentoFrameworkViewElementTemplateContext $context,
array $data =
){
parent::__construct($context, $data);
$this->_storeManager = $context->getStoreManager();
}
}



Vendor/ConfigurableProduct/Block/Product/View/Type/Configurable.php




<?php

namespace VendorConfigurableProductBlockProductViewType;

uses...

class Configurable extends MagentoSwatchesBlockProductRendererConfigurable
{
public function beforeSetTemplate(
MagentoSwatchesBlockProductRendererConfigurable $subject,
$template
) {
return ['Vendor_ConfigurableProduct::configurable.phtml'];
}

public function beforeSetName(MagentoCatalogModelProduct $subject, $name)
{
return ['(' . $name . ')'];
}

public function __construct(
Context $context,
ArrayUtils $arrayUtils,
EncoderInterface $jsonEncoder,
Data $helper,
CatalogProduct $catalogProduct,
CurrentCustomer $currentCustomer,
PriceCurrencyInterface $priceCurrency,
ConfigurableAttributeData $configurableAttributeData,
SwatchData $swatchHelper,
Media $swatchMediaHelper,
array $data =
){
$this->swatchHelper = $swatchHelper;
$this->swatchMediaHelper = $swatchMediaHelper;
parent::__construct(
$context,
$arrayUtils,
$jsonEncoder,
$helper,
$catalogProduct,
$currentCustomer,
$priceCurrency,
$configurableAttributeData,
$swatchHelper,
$swatchMediaHelper,
$data
);
}

public function getJsonConfig()
{
$store = $this->getCurrentStore();
$currentProduct = $this->getProduct();

$regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price');
$finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price');

$options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
$attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

$config = [
'attributes' => $attributesData['attributes'],
'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
'optionPrices' => $this->getOptionPrices(),
'optionStock' => $this->getOptionStocks(),
'prices' => [
'oldPrice' => [
'amount' => $this->_registerJsPrice($regularPrice->getAmount()->getValue()),
],
'basePrice' => [
'amount' => $this->_registerJsPrice(
$finalPrice->getAmount()->getBaseAmount()
),
],
'finalPrice' => [
'amount' => $this->_registerJsPrice($finalPrice->getAmount()->getValue()),

],
],

'productId' => $currentProduct->getId(),
'chooseText' => __('Choose an Option...'),
'images' => isset($options['images']) ? $options['images'] : ,
'index' => isset($options['index']) ? $options['index'] : ,
];

if ($currentProduct->hasPreconfiguredValues() && !empty($attributesData['defaultValues'])) {
$config['defaultValues'] = $attributesData['defaultValues'];
}

$config = array_merge($config, $this->_getAdditionalConfig());

return $this->jsonEncoder->encode($config);
}


/*-----------------------custom code----------------------*/

protected function getOptionStocks()
{


$stocks = ;
$objectManager = MagentoFrameworkAppObjectManager::getInstance();
$stockObject=$objectManager->get('MagentoCatalogInventoryApiStockRegistryInterface');

foreach ($this->getAllowProducts() as $product) {

$productStockObj = $stockObject->getStockItem($product->getId());
$isInStock = $productStockObj['is_in_stock'];
$stocks[$product->getId()] = ['stockStatus' => $isInStock];
}
return $stocks;
}

public function getAllowProducts()
{
if (!$this->hasAllowProducts()){
$skipSaleableCheck = 1;
$products = $skipSaleableCheck ?
$this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null) :
$this->getProduct()->getTypeInstance()->getSalableUsedProducts($this->getProduct(), null);
$this->setAllowProducts($products);
}
return $this->getData('allow_products');
}

public function getAllowAttributes()
{
return $this->getProduct()->getTypeInstance()->getConfigurableAttributes($this->getProduct());
}

}

> Vendor/ConfigurableProduct/Helper/Data.php

<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/

namespace VendorConfigurableProductHelper;

use MagentoCatalogModelProduct;

/**
* Class Data
* Helper class for getting options
*
*/
class Data extends MagentoConfigurableProductHelperData
{
/**
* Get Options for Configurable Product Options
*
* @param MagentoCatalogModelProduct $currentProduct
* @param array $allowedProducts
* @return array
*/
public function getOptions($currentProduct, $allowedProducts)
{
$options = ;
foreach ($allowedProducts as $product) {
$productId = $product->getId();
$images = $this->getGalleryImages($product);
if ($images) {
foreach ($images as $image) {
$options['images'][$productId] =
[
'thumb' => $image->getData('small_image_url'),
'img' => $image->getData('medium_image_url'),
'full' => $image->getData('large_image_url'),
'caption' => $image->getLabel(),
'position' => $image->getPosition(),
'isMain' => $image->getFile() == $product->getImage(),
];
}
}
foreach ($this->getAllowAttributes($currentProduct) as $attribute) {
$productAttribute = $attribute->getProductAttribute();
$productAttributeId = $productAttribute->getId();
$attributeValue = $product->getData($productAttribute->getAttributeCode());

$options[$productAttributeId][$attributeValue] = $productId;
$options['index'][$productId][$productAttributeId] = $attributeValue;
}
}
return $options;
}

/**
* Get allowed attributes
*
* @param MagentoCatalogModelProduct $product
* @return array
*/
public function getAllowAttributes($product)
{
return $product->getTypeInstance()->getConfigurableAttributes($product);
}
}



Vendor/ConfigurableProduct/Model/Rewrite/ConfigurableAttributeData.php




<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

namespace VendorConfigurableProductModelRewrite;

use MagentoCatalogModelProduct;
use MagentoConfigurableProductModelProductTypeConfigurableAttribute;

class ConfigurableAttributeData extends MagentoConfigurableProductModelConfigurableAttributeData
{
protected $eavConfig;

public function __construct(MagentoEavModelConfig $eavConfig)
{
$this->eavConfig = $eavConfig;
}

/**
* Get product attributes
*
* @param Product $product
* @param array $options
* @return array
*/
public function getAttributesData(Product $product, array $options = )
{

$defaultValues = ;
$attributes = ;

$attrs = $product->getTypeInstance()->getConfigurableAttributes($product);


foreach ($attrs as $attribute) {
$attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
if ($attributeOptionsData) {
$productAttribute = $attribute->getProductAttribute();
$attributeId = $productAttribute->getId();
$attributes[$attributeId] = [
'id' => $attributeId,
'code' => $productAttribute->getAttributeCode(),
'label' => $productAttribute->getStoreLabel($product->getStoreId()),
'options' => $attributeOptionsData,
'position' => $attribute->getPosition(),
];
$defaultValues[$attributeId] = $this->getAttributeConfigValue($attributeId, $product);
}
}
return [
'attributes' => $attributes,
'defaultValues' => $defaultValues,
];
}

public function getAttributeOptionsData($attribute, $config)
{

$attributeOptionsData = ;

$attributeId = $attribute->getAttributeId();

$objectManager = MagentoFrameworkAppObjectManager::getInstance();
$eavModel = $objectManager->create('MagentoCatalogModelResourceModelEavAttribute');
$attr = $eavModel->load($attributeId);
$attributeCode=$eavModel->getAttributeCode();


$attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
$options = $attribute->getSource()->getAllOptions();


foreach ($options as $attributeOption) {
$optionId = $attributeOption['value'];
$attributeOptionsData = [
'id' => $optionId,
'label' => $attributeOption['label'],
'products' => isset($config[$attribute->getAttributeId()][$optionId])
? $config[$attribute->getAttributeId()][$optionId]
: ,
];
}


return $attributeOptionsData;
}

/**
* Retrieve configurable attributes data
*
* @param MagentoCatalogModelProduct $product
* @return MagentoConfigurableProductModelProductTypeConfigurableAttribute
*/
public function getConfigurableAttributes($product)
{
MagentoFrameworkProfiler::start(
'CONFIGURABLE:' . __METHOD__,
['group' => 'CONFIGURABLE', 'method' => __METHOD__]
);
if (!$product->hasData($this->_configurableAttributes)) {
$configurableAttributes = $this->getConfigurableAttributeCollection($product);
$this->extensionAttributesJoinProcessor->process($configurableAttributes);
$configurableAttributes->orderByPosition()->load();
$product->setData($this->_configurableAttributes, $configurableAttributes);
}
MagentoFrameworkProfiler::stop('CONFIGURABLE:' . __METHOD__);
return $product->getData($this->_configurableAttributes);
}

}



Vendor/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml




<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info.options.wrapper">
<action method='setTemplate'>
<argument name="template" xsi:type="string">Vendor_ConfigurableProduct::configurable.phtml</argument>
</action>
<!--<argument name="class" xsi:type="string">VendorConfigurableProductBlockProductViewTypeConfigurable</argument>-->
</referenceBlock>
</body>
</page>



Vendor/ConfigurableProduct/view/frontend/templates/configurable.phtml




<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/

// @codingStandardsIgnoreFile

?>

<?php
/** @var $block VendorConfigurableProductBlockProductViewTypeConfigurable */
$_product = $block->getProduct();
$_attributes = $block->decorateArray($block->getAllowAttributes());
?>
<!-- TODO: custom layout -->
<?php if ($_product->isSaleable() && count($_attributes)):?>
<?php foreach ($_attributes as $_attribute): ?>
<div class="field configurable required">
<label class="label" for="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>">
<span><?= $block->escapeHtml($_attribute->getProductAttribute()->getStoreLabel()) ?></span>
</label>
<div class="control">
<select name="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
data-selector="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
data-validate="{required:true}"
id="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>"
class="super-attribute-select">
<option value=""><?= /* @escapeNotVerified */ __('Choose an Option...') ?></option>
</select>
</div>
</div>
<?php endforeach; ?>
<script type="text/x-magento-init">
{
"#product_addtocart_form": {
"configurable": {
"spConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>,
"gallerySwitchStrategy": "<?php /* @escapeNotVerified */ echo $block->getVar('gallery_switch_strategy',
'Magento_ConfigurableProduct') ?: 'replace'; ?>"
}
}
}
</script>
<?php endif;?>



And my system log ever shows:




[2019-01-16 13:02:01] main.CRITICAL: Invalid method MagentoCatalogBlockProductViewInterceptor::decorateArray  


So, I can't override the configurable.phtml file, because the Magento Interceptors can't load the decorateArray method.



And before, I need get the configurable products out of stock in my select, like this image:
example



But I don't know where the method to override this and get all product attributes










share|improve this question







New contributor




Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    0















    I want to show the all attributes from my configurable product on my select. I followed this tutorial: Magento 2.2 How to show out of stock in configurable product, with some changes and fixes.



    Well, my module is like this now:




    Vendor/ConfigurableProduct/etc/di.xml




    <?xml version="1.0"?>
    <!--
    /**
    * Copyright © 2015 Magento. All rights reserved.
    * See COPYING.txt for license details.
    */
    -->
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

    <preference for="MagentoSwatchesBlockProductRendererConfigurable" type="VendorConfigurableProductBlockProductViewTypeConfigurable" />

    <preference for="MagentoConfigurableProductModelConfigurableAttributeData" type="VendorConfigurableProductModelRewriteConfigurableAttributeData" />

    <preference for="MagentoConfigurableProductHelperData" type="VendorConfigurableProductHelperData" />
    </config>



    Vendor/ConfigurableProduct/Block/ConfigurableProduct.php




    <?php
    /**
    * Copyright © 2015 Magento. All rights reserved.
    * See COPYING.txt for license details.
    */
    namespace VendorConfigurableProductBlock;

    use MagentoFrameworkViewElementTemplate;

    class ConfigurableProduct extends Template
    {
    protected $_storeManager;

    public function __construct(
    MagentoFrameworkViewElementTemplateContext $context,
    array $data =
    ){
    parent::__construct($context, $data);
    $this->_storeManager = $context->getStoreManager();
    }
    }



    Vendor/ConfigurableProduct/Block/Product/View/Type/Configurable.php




    <?php

    namespace VendorConfigurableProductBlockProductViewType;

    uses...

    class Configurable extends MagentoSwatchesBlockProductRendererConfigurable
    {
    public function beforeSetTemplate(
    MagentoSwatchesBlockProductRendererConfigurable $subject,
    $template
    ) {
    return ['Vendor_ConfigurableProduct::configurable.phtml'];
    }

    public function beforeSetName(MagentoCatalogModelProduct $subject, $name)
    {
    return ['(' . $name . ')'];
    }

    public function __construct(
    Context $context,
    ArrayUtils $arrayUtils,
    EncoderInterface $jsonEncoder,
    Data $helper,
    CatalogProduct $catalogProduct,
    CurrentCustomer $currentCustomer,
    PriceCurrencyInterface $priceCurrency,
    ConfigurableAttributeData $configurableAttributeData,
    SwatchData $swatchHelper,
    Media $swatchMediaHelper,
    array $data =
    ){
    $this->swatchHelper = $swatchHelper;
    $this->swatchMediaHelper = $swatchMediaHelper;
    parent::__construct(
    $context,
    $arrayUtils,
    $jsonEncoder,
    $helper,
    $catalogProduct,
    $currentCustomer,
    $priceCurrency,
    $configurableAttributeData,
    $swatchHelper,
    $swatchMediaHelper,
    $data
    );
    }

    public function getJsonConfig()
    {
    $store = $this->getCurrentStore();
    $currentProduct = $this->getProduct();

    $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price');
    $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price');

    $options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
    $attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

    $config = [
    'attributes' => $attributesData['attributes'],
    'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
    'optionPrices' => $this->getOptionPrices(),
    'optionStock' => $this->getOptionStocks(),
    'prices' => [
    'oldPrice' => [
    'amount' => $this->_registerJsPrice($regularPrice->getAmount()->getValue()),
    ],
    'basePrice' => [
    'amount' => $this->_registerJsPrice(
    $finalPrice->getAmount()->getBaseAmount()
    ),
    ],
    'finalPrice' => [
    'amount' => $this->_registerJsPrice($finalPrice->getAmount()->getValue()),

    ],
    ],

    'productId' => $currentProduct->getId(),
    'chooseText' => __('Choose an Option...'),
    'images' => isset($options['images']) ? $options['images'] : ,
    'index' => isset($options['index']) ? $options['index'] : ,
    ];

    if ($currentProduct->hasPreconfiguredValues() && !empty($attributesData['defaultValues'])) {
    $config['defaultValues'] = $attributesData['defaultValues'];
    }

    $config = array_merge($config, $this->_getAdditionalConfig());

    return $this->jsonEncoder->encode($config);
    }


    /*-----------------------custom code----------------------*/

    protected function getOptionStocks()
    {


    $stocks = ;
    $objectManager = MagentoFrameworkAppObjectManager::getInstance();
    $stockObject=$objectManager->get('MagentoCatalogInventoryApiStockRegistryInterface');

    foreach ($this->getAllowProducts() as $product) {

    $productStockObj = $stockObject->getStockItem($product->getId());
    $isInStock = $productStockObj['is_in_stock'];
    $stocks[$product->getId()] = ['stockStatus' => $isInStock];
    }
    return $stocks;
    }

    public function getAllowProducts()
    {
    if (!$this->hasAllowProducts()){
    $skipSaleableCheck = 1;
    $products = $skipSaleableCheck ?
    $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null) :
    $this->getProduct()->getTypeInstance()->getSalableUsedProducts($this->getProduct(), null);
    $this->setAllowProducts($products);
    }
    return $this->getData('allow_products');
    }

    public function getAllowAttributes()
    {
    return $this->getProduct()->getTypeInstance()->getConfigurableAttributes($this->getProduct());
    }

    }

    > Vendor/ConfigurableProduct/Helper/Data.php

    <?php
    /**
    * Copyright © 2015 Magento. All rights reserved.
    * See COPYING.txt for license details.
    */

    namespace VendorConfigurableProductHelper;

    use MagentoCatalogModelProduct;

    /**
    * Class Data
    * Helper class for getting options
    *
    */
    class Data extends MagentoConfigurableProductHelperData
    {
    /**
    * Get Options for Configurable Product Options
    *
    * @param MagentoCatalogModelProduct $currentProduct
    * @param array $allowedProducts
    * @return array
    */
    public function getOptions($currentProduct, $allowedProducts)
    {
    $options = ;
    foreach ($allowedProducts as $product) {
    $productId = $product->getId();
    $images = $this->getGalleryImages($product);
    if ($images) {
    foreach ($images as $image) {
    $options['images'][$productId] =
    [
    'thumb' => $image->getData('small_image_url'),
    'img' => $image->getData('medium_image_url'),
    'full' => $image->getData('large_image_url'),
    'caption' => $image->getLabel(),
    'position' => $image->getPosition(),
    'isMain' => $image->getFile() == $product->getImage(),
    ];
    }
    }
    foreach ($this->getAllowAttributes($currentProduct) as $attribute) {
    $productAttribute = $attribute->getProductAttribute();
    $productAttributeId = $productAttribute->getId();
    $attributeValue = $product->getData($productAttribute->getAttributeCode());

    $options[$productAttributeId][$attributeValue] = $productId;
    $options['index'][$productId][$productAttributeId] = $attributeValue;
    }
    }
    return $options;
    }

    /**
    * Get allowed attributes
    *
    * @param MagentoCatalogModelProduct $product
    * @return array
    */
    public function getAllowAttributes($product)
    {
    return $product->getTypeInstance()->getConfigurableAttributes($product);
    }
    }



    Vendor/ConfigurableProduct/Model/Rewrite/ConfigurableAttributeData.php




    <?php
    /**
    * Copyright © Magento, Inc. All rights reserved.
    * See COPYING.txt for license details.
    */

    namespace VendorConfigurableProductModelRewrite;

    use MagentoCatalogModelProduct;
    use MagentoConfigurableProductModelProductTypeConfigurableAttribute;

    class ConfigurableAttributeData extends MagentoConfigurableProductModelConfigurableAttributeData
    {
    protected $eavConfig;

    public function __construct(MagentoEavModelConfig $eavConfig)
    {
    $this->eavConfig = $eavConfig;
    }

    /**
    * Get product attributes
    *
    * @param Product $product
    * @param array $options
    * @return array
    */
    public function getAttributesData(Product $product, array $options = )
    {

    $defaultValues = ;
    $attributes = ;

    $attrs = $product->getTypeInstance()->getConfigurableAttributes($product);


    foreach ($attrs as $attribute) {
    $attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
    if ($attributeOptionsData) {
    $productAttribute = $attribute->getProductAttribute();
    $attributeId = $productAttribute->getId();
    $attributes[$attributeId] = [
    'id' => $attributeId,
    'code' => $productAttribute->getAttributeCode(),
    'label' => $productAttribute->getStoreLabel($product->getStoreId()),
    'options' => $attributeOptionsData,
    'position' => $attribute->getPosition(),
    ];
    $defaultValues[$attributeId] = $this->getAttributeConfigValue($attributeId, $product);
    }
    }
    return [
    'attributes' => $attributes,
    'defaultValues' => $defaultValues,
    ];
    }

    public function getAttributeOptionsData($attribute, $config)
    {

    $attributeOptionsData = ;

    $attributeId = $attribute->getAttributeId();

    $objectManager = MagentoFrameworkAppObjectManager::getInstance();
    $eavModel = $objectManager->create('MagentoCatalogModelResourceModelEavAttribute');
    $attr = $eavModel->load($attributeId);
    $attributeCode=$eavModel->getAttributeCode();


    $attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
    $options = $attribute->getSource()->getAllOptions();


    foreach ($options as $attributeOption) {
    $optionId = $attributeOption['value'];
    $attributeOptionsData = [
    'id' => $optionId,
    'label' => $attributeOption['label'],
    'products' => isset($config[$attribute->getAttributeId()][$optionId])
    ? $config[$attribute->getAttributeId()][$optionId]
    : ,
    ];
    }


    return $attributeOptionsData;
    }

    /**
    * Retrieve configurable attributes data
    *
    * @param MagentoCatalogModelProduct $product
    * @return MagentoConfigurableProductModelProductTypeConfigurableAttribute
    */
    public function getConfigurableAttributes($product)
    {
    MagentoFrameworkProfiler::start(
    'CONFIGURABLE:' . __METHOD__,
    ['group' => 'CONFIGURABLE', 'method' => __METHOD__]
    );
    if (!$product->hasData($this->_configurableAttributes)) {
    $configurableAttributes = $this->getConfigurableAttributeCollection($product);
    $this->extensionAttributesJoinProcessor->process($configurableAttributes);
    $configurableAttributes->orderByPosition()->load();
    $product->setData($this->_configurableAttributes, $configurableAttributes);
    }
    MagentoFrameworkProfiler::stop('CONFIGURABLE:' . __METHOD__);
    return $product->getData($this->_configurableAttributes);
    }

    }



    Vendor/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml




    <?xml version="1.0"?>
    <!--
    /**
    * Copyright © 2015 Magento. All rights reserved.
    * See COPYING.txt for license details.
    */
    -->
    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
    <referenceBlock name="product.info.options.wrapper">
    <action method='setTemplate'>
    <argument name="template" xsi:type="string">Vendor_ConfigurableProduct::configurable.phtml</argument>
    </action>
    <!--<argument name="class" xsi:type="string">VendorConfigurableProductBlockProductViewTypeConfigurable</argument>-->
    </referenceBlock>
    </body>
    </page>



    Vendor/ConfigurableProduct/view/frontend/templates/configurable.phtml




    <?php
    /**
    * Copyright © Magento, Inc. All rights reserved.
    * See COPYING.txt for license details.
    */

    // @codingStandardsIgnoreFile

    ?>

    <?php
    /** @var $block VendorConfigurableProductBlockProductViewTypeConfigurable */
    $_product = $block->getProduct();
    $_attributes = $block->decorateArray($block->getAllowAttributes());
    ?>
    <!-- TODO: custom layout -->
    <?php if ($_product->isSaleable() && count($_attributes)):?>
    <?php foreach ($_attributes as $_attribute): ?>
    <div class="field configurable required">
    <label class="label" for="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>">
    <span><?= $block->escapeHtml($_attribute->getProductAttribute()->getStoreLabel()) ?></span>
    </label>
    <div class="control">
    <select name="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
    data-selector="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
    data-validate="{required:true}"
    id="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>"
    class="super-attribute-select">
    <option value=""><?= /* @escapeNotVerified */ __('Choose an Option...') ?></option>
    </select>
    </div>
    </div>
    <?php endforeach; ?>
    <script type="text/x-magento-init">
    {
    "#product_addtocart_form": {
    "configurable": {
    "spConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>,
    "gallerySwitchStrategy": "<?php /* @escapeNotVerified */ echo $block->getVar('gallery_switch_strategy',
    'Magento_ConfigurableProduct') ?: 'replace'; ?>"
    }
    }
    }
    </script>
    <?php endif;?>



    And my system log ever shows:




    [2019-01-16 13:02:01] main.CRITICAL: Invalid method MagentoCatalogBlockProductViewInterceptor::decorateArray  


    So, I can't override the configurable.phtml file, because the Magento Interceptors can't load the decorateArray method.



    And before, I need get the configurable products out of stock in my select, like this image:
    example



    But I don't know where the method to override this and get all product attributes










    share|improve this question







    New contributor




    Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      0












      0








      0








      I want to show the all attributes from my configurable product on my select. I followed this tutorial: Magento 2.2 How to show out of stock in configurable product, with some changes and fixes.



      Well, my module is like this now:




      Vendor/ConfigurableProduct/etc/di.xml




      <?xml version="1.0"?>
      <!--
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      -->
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

      <preference for="MagentoSwatchesBlockProductRendererConfigurable" type="VendorConfigurableProductBlockProductViewTypeConfigurable" />

      <preference for="MagentoConfigurableProductModelConfigurableAttributeData" type="VendorConfigurableProductModelRewriteConfigurableAttributeData" />

      <preference for="MagentoConfigurableProductHelperData" type="VendorConfigurableProductHelperData" />
      </config>



      Vendor/ConfigurableProduct/Block/ConfigurableProduct.php




      <?php
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      namespace VendorConfigurableProductBlock;

      use MagentoFrameworkViewElementTemplate;

      class ConfigurableProduct extends Template
      {
      protected $_storeManager;

      public function __construct(
      MagentoFrameworkViewElementTemplateContext $context,
      array $data =
      ){
      parent::__construct($context, $data);
      $this->_storeManager = $context->getStoreManager();
      }
      }



      Vendor/ConfigurableProduct/Block/Product/View/Type/Configurable.php




      <?php

      namespace VendorConfigurableProductBlockProductViewType;

      uses...

      class Configurable extends MagentoSwatchesBlockProductRendererConfigurable
      {
      public function beforeSetTemplate(
      MagentoSwatchesBlockProductRendererConfigurable $subject,
      $template
      ) {
      return ['Vendor_ConfigurableProduct::configurable.phtml'];
      }

      public function beforeSetName(MagentoCatalogModelProduct $subject, $name)
      {
      return ['(' . $name . ')'];
      }

      public function __construct(
      Context $context,
      ArrayUtils $arrayUtils,
      EncoderInterface $jsonEncoder,
      Data $helper,
      CatalogProduct $catalogProduct,
      CurrentCustomer $currentCustomer,
      PriceCurrencyInterface $priceCurrency,
      ConfigurableAttributeData $configurableAttributeData,
      SwatchData $swatchHelper,
      Media $swatchMediaHelper,
      array $data =
      ){
      $this->swatchHelper = $swatchHelper;
      $this->swatchMediaHelper = $swatchMediaHelper;
      parent::__construct(
      $context,
      $arrayUtils,
      $jsonEncoder,
      $helper,
      $catalogProduct,
      $currentCustomer,
      $priceCurrency,
      $configurableAttributeData,
      $swatchHelper,
      $swatchMediaHelper,
      $data
      );
      }

      public function getJsonConfig()
      {
      $store = $this->getCurrentStore();
      $currentProduct = $this->getProduct();

      $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price');
      $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price');

      $options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
      $attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

      $config = [
      'attributes' => $attributesData['attributes'],
      'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
      'optionPrices' => $this->getOptionPrices(),
      'optionStock' => $this->getOptionStocks(),
      'prices' => [
      'oldPrice' => [
      'amount' => $this->_registerJsPrice($regularPrice->getAmount()->getValue()),
      ],
      'basePrice' => [
      'amount' => $this->_registerJsPrice(
      $finalPrice->getAmount()->getBaseAmount()
      ),
      ],
      'finalPrice' => [
      'amount' => $this->_registerJsPrice($finalPrice->getAmount()->getValue()),

      ],
      ],

      'productId' => $currentProduct->getId(),
      'chooseText' => __('Choose an Option...'),
      'images' => isset($options['images']) ? $options['images'] : ,
      'index' => isset($options['index']) ? $options['index'] : ,
      ];

      if ($currentProduct->hasPreconfiguredValues() && !empty($attributesData['defaultValues'])) {
      $config['defaultValues'] = $attributesData['defaultValues'];
      }

      $config = array_merge($config, $this->_getAdditionalConfig());

      return $this->jsonEncoder->encode($config);
      }


      /*-----------------------custom code----------------------*/

      protected function getOptionStocks()
      {


      $stocks = ;
      $objectManager = MagentoFrameworkAppObjectManager::getInstance();
      $stockObject=$objectManager->get('MagentoCatalogInventoryApiStockRegistryInterface');

      foreach ($this->getAllowProducts() as $product) {

      $productStockObj = $stockObject->getStockItem($product->getId());
      $isInStock = $productStockObj['is_in_stock'];
      $stocks[$product->getId()] = ['stockStatus' => $isInStock];
      }
      return $stocks;
      }

      public function getAllowProducts()
      {
      if (!$this->hasAllowProducts()){
      $skipSaleableCheck = 1;
      $products = $skipSaleableCheck ?
      $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null) :
      $this->getProduct()->getTypeInstance()->getSalableUsedProducts($this->getProduct(), null);
      $this->setAllowProducts($products);
      }
      return $this->getData('allow_products');
      }

      public function getAllowAttributes()
      {
      return $this->getProduct()->getTypeInstance()->getConfigurableAttributes($this->getProduct());
      }

      }

      > Vendor/ConfigurableProduct/Helper/Data.php

      <?php
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */

      namespace VendorConfigurableProductHelper;

      use MagentoCatalogModelProduct;

      /**
      * Class Data
      * Helper class for getting options
      *
      */
      class Data extends MagentoConfigurableProductHelperData
      {
      /**
      * Get Options for Configurable Product Options
      *
      * @param MagentoCatalogModelProduct $currentProduct
      * @param array $allowedProducts
      * @return array
      */
      public function getOptions($currentProduct, $allowedProducts)
      {
      $options = ;
      foreach ($allowedProducts as $product) {
      $productId = $product->getId();
      $images = $this->getGalleryImages($product);
      if ($images) {
      foreach ($images as $image) {
      $options['images'][$productId] =
      [
      'thumb' => $image->getData('small_image_url'),
      'img' => $image->getData('medium_image_url'),
      'full' => $image->getData('large_image_url'),
      'caption' => $image->getLabel(),
      'position' => $image->getPosition(),
      'isMain' => $image->getFile() == $product->getImage(),
      ];
      }
      }
      foreach ($this->getAllowAttributes($currentProduct) as $attribute) {
      $productAttribute = $attribute->getProductAttribute();
      $productAttributeId = $productAttribute->getId();
      $attributeValue = $product->getData($productAttribute->getAttributeCode());

      $options[$productAttributeId][$attributeValue] = $productId;
      $options['index'][$productId][$productAttributeId] = $attributeValue;
      }
      }
      return $options;
      }

      /**
      * Get allowed attributes
      *
      * @param MagentoCatalogModelProduct $product
      * @return array
      */
      public function getAllowAttributes($product)
      {
      return $product->getTypeInstance()->getConfigurableAttributes($product);
      }
      }



      Vendor/ConfigurableProduct/Model/Rewrite/ConfigurableAttributeData.php




      <?php
      /**
      * Copyright © Magento, Inc. All rights reserved.
      * See COPYING.txt for license details.
      */

      namespace VendorConfigurableProductModelRewrite;

      use MagentoCatalogModelProduct;
      use MagentoConfigurableProductModelProductTypeConfigurableAttribute;

      class ConfigurableAttributeData extends MagentoConfigurableProductModelConfigurableAttributeData
      {
      protected $eavConfig;

      public function __construct(MagentoEavModelConfig $eavConfig)
      {
      $this->eavConfig = $eavConfig;
      }

      /**
      * Get product attributes
      *
      * @param Product $product
      * @param array $options
      * @return array
      */
      public function getAttributesData(Product $product, array $options = )
      {

      $defaultValues = ;
      $attributes = ;

      $attrs = $product->getTypeInstance()->getConfigurableAttributes($product);


      foreach ($attrs as $attribute) {
      $attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
      if ($attributeOptionsData) {
      $productAttribute = $attribute->getProductAttribute();
      $attributeId = $productAttribute->getId();
      $attributes[$attributeId] = [
      'id' => $attributeId,
      'code' => $productAttribute->getAttributeCode(),
      'label' => $productAttribute->getStoreLabel($product->getStoreId()),
      'options' => $attributeOptionsData,
      'position' => $attribute->getPosition(),
      ];
      $defaultValues[$attributeId] = $this->getAttributeConfigValue($attributeId, $product);
      }
      }
      return [
      'attributes' => $attributes,
      'defaultValues' => $defaultValues,
      ];
      }

      public function getAttributeOptionsData($attribute, $config)
      {

      $attributeOptionsData = ;

      $attributeId = $attribute->getAttributeId();

      $objectManager = MagentoFrameworkAppObjectManager::getInstance();
      $eavModel = $objectManager->create('MagentoCatalogModelResourceModelEavAttribute');
      $attr = $eavModel->load($attributeId);
      $attributeCode=$eavModel->getAttributeCode();


      $attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
      $options = $attribute->getSource()->getAllOptions();


      foreach ($options as $attributeOption) {
      $optionId = $attributeOption['value'];
      $attributeOptionsData = [
      'id' => $optionId,
      'label' => $attributeOption['label'],
      'products' => isset($config[$attribute->getAttributeId()][$optionId])
      ? $config[$attribute->getAttributeId()][$optionId]
      : ,
      ];
      }


      return $attributeOptionsData;
      }

      /**
      * Retrieve configurable attributes data
      *
      * @param MagentoCatalogModelProduct $product
      * @return MagentoConfigurableProductModelProductTypeConfigurableAttribute
      */
      public function getConfigurableAttributes($product)
      {
      MagentoFrameworkProfiler::start(
      'CONFIGURABLE:' . __METHOD__,
      ['group' => 'CONFIGURABLE', 'method' => __METHOD__]
      );
      if (!$product->hasData($this->_configurableAttributes)) {
      $configurableAttributes = $this->getConfigurableAttributeCollection($product);
      $this->extensionAttributesJoinProcessor->process($configurableAttributes);
      $configurableAttributes->orderByPosition()->load();
      $product->setData($this->_configurableAttributes, $configurableAttributes);
      }
      MagentoFrameworkProfiler::stop('CONFIGURABLE:' . __METHOD__);
      return $product->getData($this->_configurableAttributes);
      }

      }



      Vendor/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml




      <?xml version="1.0"?>
      <!--
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      -->
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <body>
      <referenceBlock name="product.info.options.wrapper">
      <action method='setTemplate'>
      <argument name="template" xsi:type="string">Vendor_ConfigurableProduct::configurable.phtml</argument>
      </action>
      <!--<argument name="class" xsi:type="string">VendorConfigurableProductBlockProductViewTypeConfigurable</argument>-->
      </referenceBlock>
      </body>
      </page>



      Vendor/ConfigurableProduct/view/frontend/templates/configurable.phtml




      <?php
      /**
      * Copyright © Magento, Inc. All rights reserved.
      * See COPYING.txt for license details.
      */

      // @codingStandardsIgnoreFile

      ?>

      <?php
      /** @var $block VendorConfigurableProductBlockProductViewTypeConfigurable */
      $_product = $block->getProduct();
      $_attributes = $block->decorateArray($block->getAllowAttributes());
      ?>
      <!-- TODO: custom layout -->
      <?php if ($_product->isSaleable() && count($_attributes)):?>
      <?php foreach ($_attributes as $_attribute): ?>
      <div class="field configurable required">
      <label class="label" for="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>">
      <span><?= $block->escapeHtml($_attribute->getProductAttribute()->getStoreLabel()) ?></span>
      </label>
      <div class="control">
      <select name="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
      data-selector="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
      data-validate="{required:true}"
      id="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>"
      class="super-attribute-select">
      <option value=""><?= /* @escapeNotVerified */ __('Choose an Option...') ?></option>
      </select>
      </div>
      </div>
      <?php endforeach; ?>
      <script type="text/x-magento-init">
      {
      "#product_addtocart_form": {
      "configurable": {
      "spConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>,
      "gallerySwitchStrategy": "<?php /* @escapeNotVerified */ echo $block->getVar('gallery_switch_strategy',
      'Magento_ConfigurableProduct') ?: 'replace'; ?>"
      }
      }
      }
      </script>
      <?php endif;?>



      And my system log ever shows:




      [2019-01-16 13:02:01] main.CRITICAL: Invalid method MagentoCatalogBlockProductViewInterceptor::decorateArray  


      So, I can't override the configurable.phtml file, because the Magento Interceptors can't load the decorateArray method.



      And before, I need get the configurable products out of stock in my select, like this image:
      example



      But I don't know where the method to override this and get all product attributes










      share|improve this question







      New contributor




      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.












      I want to show the all attributes from my configurable product on my select. I followed this tutorial: Magento 2.2 How to show out of stock in configurable product, with some changes and fixes.



      Well, my module is like this now:




      Vendor/ConfigurableProduct/etc/di.xml




      <?xml version="1.0"?>
      <!--
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      -->
      <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

      <preference for="MagentoSwatchesBlockProductRendererConfigurable" type="VendorConfigurableProductBlockProductViewTypeConfigurable" />

      <preference for="MagentoConfigurableProductModelConfigurableAttributeData" type="VendorConfigurableProductModelRewriteConfigurableAttributeData" />

      <preference for="MagentoConfigurableProductHelperData" type="VendorConfigurableProductHelperData" />
      </config>



      Vendor/ConfigurableProduct/Block/ConfigurableProduct.php




      <?php
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      namespace VendorConfigurableProductBlock;

      use MagentoFrameworkViewElementTemplate;

      class ConfigurableProduct extends Template
      {
      protected $_storeManager;

      public function __construct(
      MagentoFrameworkViewElementTemplateContext $context,
      array $data =
      ){
      parent::__construct($context, $data);
      $this->_storeManager = $context->getStoreManager();
      }
      }



      Vendor/ConfigurableProduct/Block/Product/View/Type/Configurable.php




      <?php

      namespace VendorConfigurableProductBlockProductViewType;

      uses...

      class Configurable extends MagentoSwatchesBlockProductRendererConfigurable
      {
      public function beforeSetTemplate(
      MagentoSwatchesBlockProductRendererConfigurable $subject,
      $template
      ) {
      return ['Vendor_ConfigurableProduct::configurable.phtml'];
      }

      public function beforeSetName(MagentoCatalogModelProduct $subject, $name)
      {
      return ['(' . $name . ')'];
      }

      public function __construct(
      Context $context,
      ArrayUtils $arrayUtils,
      EncoderInterface $jsonEncoder,
      Data $helper,
      CatalogProduct $catalogProduct,
      CurrentCustomer $currentCustomer,
      PriceCurrencyInterface $priceCurrency,
      ConfigurableAttributeData $configurableAttributeData,
      SwatchData $swatchHelper,
      Media $swatchMediaHelper,
      array $data =
      ){
      $this->swatchHelper = $swatchHelper;
      $this->swatchMediaHelper = $swatchMediaHelper;
      parent::__construct(
      $context,
      $arrayUtils,
      $jsonEncoder,
      $helper,
      $catalogProduct,
      $currentCustomer,
      $priceCurrency,
      $configurableAttributeData,
      $swatchHelper,
      $swatchMediaHelper,
      $data
      );
      }

      public function getJsonConfig()
      {
      $store = $this->getCurrentStore();
      $currentProduct = $this->getProduct();

      $regularPrice = $currentProduct->getPriceInfo()->getPrice('regular_price');
      $finalPrice = $currentProduct->getPriceInfo()->getPrice('final_price');

      $options = $this->helper->getOptions($currentProduct, $this->getAllowProducts());
      $attributesData = $this->configurableAttributeData->getAttributesData($currentProduct, $options);

      $config = [
      'attributes' => $attributesData['attributes'],
      'template' => str_replace('%s', '<%- data.price %>', $store->getCurrentCurrency()->getOutputFormat()),
      'optionPrices' => $this->getOptionPrices(),
      'optionStock' => $this->getOptionStocks(),
      'prices' => [
      'oldPrice' => [
      'amount' => $this->_registerJsPrice($regularPrice->getAmount()->getValue()),
      ],
      'basePrice' => [
      'amount' => $this->_registerJsPrice(
      $finalPrice->getAmount()->getBaseAmount()
      ),
      ],
      'finalPrice' => [
      'amount' => $this->_registerJsPrice($finalPrice->getAmount()->getValue()),

      ],
      ],

      'productId' => $currentProduct->getId(),
      'chooseText' => __('Choose an Option...'),
      'images' => isset($options['images']) ? $options['images'] : ,
      'index' => isset($options['index']) ? $options['index'] : ,
      ];

      if ($currentProduct->hasPreconfiguredValues() && !empty($attributesData['defaultValues'])) {
      $config['defaultValues'] = $attributesData['defaultValues'];
      }

      $config = array_merge($config, $this->_getAdditionalConfig());

      return $this->jsonEncoder->encode($config);
      }


      /*-----------------------custom code----------------------*/

      protected function getOptionStocks()
      {


      $stocks = ;
      $objectManager = MagentoFrameworkAppObjectManager::getInstance();
      $stockObject=$objectManager->get('MagentoCatalogInventoryApiStockRegistryInterface');

      foreach ($this->getAllowProducts() as $product) {

      $productStockObj = $stockObject->getStockItem($product->getId());
      $isInStock = $productStockObj['is_in_stock'];
      $stocks[$product->getId()] = ['stockStatus' => $isInStock];
      }
      return $stocks;
      }

      public function getAllowProducts()
      {
      if (!$this->hasAllowProducts()){
      $skipSaleableCheck = 1;
      $products = $skipSaleableCheck ?
      $this->getProduct()->getTypeInstance()->getUsedProducts($this->getProduct(), null) :
      $this->getProduct()->getTypeInstance()->getSalableUsedProducts($this->getProduct(), null);
      $this->setAllowProducts($products);
      }
      return $this->getData('allow_products');
      }

      public function getAllowAttributes()
      {
      return $this->getProduct()->getTypeInstance()->getConfigurableAttributes($this->getProduct());
      }

      }

      > Vendor/ConfigurableProduct/Helper/Data.php

      <?php
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */

      namespace VendorConfigurableProductHelper;

      use MagentoCatalogModelProduct;

      /**
      * Class Data
      * Helper class for getting options
      *
      */
      class Data extends MagentoConfigurableProductHelperData
      {
      /**
      * Get Options for Configurable Product Options
      *
      * @param MagentoCatalogModelProduct $currentProduct
      * @param array $allowedProducts
      * @return array
      */
      public function getOptions($currentProduct, $allowedProducts)
      {
      $options = ;
      foreach ($allowedProducts as $product) {
      $productId = $product->getId();
      $images = $this->getGalleryImages($product);
      if ($images) {
      foreach ($images as $image) {
      $options['images'][$productId] =
      [
      'thumb' => $image->getData('small_image_url'),
      'img' => $image->getData('medium_image_url'),
      'full' => $image->getData('large_image_url'),
      'caption' => $image->getLabel(),
      'position' => $image->getPosition(),
      'isMain' => $image->getFile() == $product->getImage(),
      ];
      }
      }
      foreach ($this->getAllowAttributes($currentProduct) as $attribute) {
      $productAttribute = $attribute->getProductAttribute();
      $productAttributeId = $productAttribute->getId();
      $attributeValue = $product->getData($productAttribute->getAttributeCode());

      $options[$productAttributeId][$attributeValue] = $productId;
      $options['index'][$productId][$productAttributeId] = $attributeValue;
      }
      }
      return $options;
      }

      /**
      * Get allowed attributes
      *
      * @param MagentoCatalogModelProduct $product
      * @return array
      */
      public function getAllowAttributes($product)
      {
      return $product->getTypeInstance()->getConfigurableAttributes($product);
      }
      }



      Vendor/ConfigurableProduct/Model/Rewrite/ConfigurableAttributeData.php




      <?php
      /**
      * Copyright © Magento, Inc. All rights reserved.
      * See COPYING.txt for license details.
      */

      namespace VendorConfigurableProductModelRewrite;

      use MagentoCatalogModelProduct;
      use MagentoConfigurableProductModelProductTypeConfigurableAttribute;

      class ConfigurableAttributeData extends MagentoConfigurableProductModelConfigurableAttributeData
      {
      protected $eavConfig;

      public function __construct(MagentoEavModelConfig $eavConfig)
      {
      $this->eavConfig = $eavConfig;
      }

      /**
      * Get product attributes
      *
      * @param Product $product
      * @param array $options
      * @return array
      */
      public function getAttributesData(Product $product, array $options = )
      {

      $defaultValues = ;
      $attributes = ;

      $attrs = $product->getTypeInstance()->getConfigurableAttributes($product);


      foreach ($attrs as $attribute) {
      $attributeOptionsData = $this->getAttributeOptionsData($attribute, $options);
      if ($attributeOptionsData) {
      $productAttribute = $attribute->getProductAttribute();
      $attributeId = $productAttribute->getId();
      $attributes[$attributeId] = [
      'id' => $attributeId,
      'code' => $productAttribute->getAttributeCode(),
      'label' => $productAttribute->getStoreLabel($product->getStoreId()),
      'options' => $attributeOptionsData,
      'position' => $attribute->getPosition(),
      ];
      $defaultValues[$attributeId] = $this->getAttributeConfigValue($attributeId, $product);
      }
      }
      return [
      'attributes' => $attributes,
      'defaultValues' => $defaultValues,
      ];
      }

      public function getAttributeOptionsData($attribute, $config)
      {

      $attributeOptionsData = ;

      $attributeId = $attribute->getAttributeId();

      $objectManager = MagentoFrameworkAppObjectManager::getInstance();
      $eavModel = $objectManager->create('MagentoCatalogModelResourceModelEavAttribute');
      $attr = $eavModel->load($attributeId);
      $attributeCode=$eavModel->getAttributeCode();


      $attribute = $this->eavConfig->getAttribute('catalog_product', $attributeCode);
      $options = $attribute->getSource()->getAllOptions();


      foreach ($options as $attributeOption) {
      $optionId = $attributeOption['value'];
      $attributeOptionsData = [
      'id' => $optionId,
      'label' => $attributeOption['label'],
      'products' => isset($config[$attribute->getAttributeId()][$optionId])
      ? $config[$attribute->getAttributeId()][$optionId]
      : ,
      ];
      }


      return $attributeOptionsData;
      }

      /**
      * Retrieve configurable attributes data
      *
      * @param MagentoCatalogModelProduct $product
      * @return MagentoConfigurableProductModelProductTypeConfigurableAttribute
      */
      public function getConfigurableAttributes($product)
      {
      MagentoFrameworkProfiler::start(
      'CONFIGURABLE:' . __METHOD__,
      ['group' => 'CONFIGURABLE', 'method' => __METHOD__]
      );
      if (!$product->hasData($this->_configurableAttributes)) {
      $configurableAttributes = $this->getConfigurableAttributeCollection($product);
      $this->extensionAttributesJoinProcessor->process($configurableAttributes);
      $configurableAttributes->orderByPosition()->load();
      $product->setData($this->_configurableAttributes, $configurableAttributes);
      }
      MagentoFrameworkProfiler::stop('CONFIGURABLE:' . __METHOD__);
      return $product->getData($this->_configurableAttributes);
      }

      }



      Vendor/ConfigurableProduct/view/frontend/layout/catalog_product_view_type_configurable.xml




      <?xml version="1.0"?>
      <!--
      /**
      * Copyright © 2015 Magento. All rights reserved.
      * See COPYING.txt for license details.
      */
      -->
      <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
      <body>
      <referenceBlock name="product.info.options.wrapper">
      <action method='setTemplate'>
      <argument name="template" xsi:type="string">Vendor_ConfigurableProduct::configurable.phtml</argument>
      </action>
      <!--<argument name="class" xsi:type="string">VendorConfigurableProductBlockProductViewTypeConfigurable</argument>-->
      </referenceBlock>
      </body>
      </page>



      Vendor/ConfigurableProduct/view/frontend/templates/configurable.phtml




      <?php
      /**
      * Copyright © Magento, Inc. All rights reserved.
      * See COPYING.txt for license details.
      */

      // @codingStandardsIgnoreFile

      ?>

      <?php
      /** @var $block VendorConfigurableProductBlockProductViewTypeConfigurable */
      $_product = $block->getProduct();
      $_attributes = $block->decorateArray($block->getAllowAttributes());
      ?>
      <!-- TODO: custom layout -->
      <?php if ($_product->isSaleable() && count($_attributes)):?>
      <?php foreach ($_attributes as $_attribute): ?>
      <div class="field configurable required">
      <label class="label" for="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>">
      <span><?= $block->escapeHtml($_attribute->getProductAttribute()->getStoreLabel()) ?></span>
      </label>
      <div class="control">
      <select name="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
      data-selector="super_attribute[<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>]"
      data-validate="{required:true}"
      id="attribute<?= /* @escapeNotVerified */ $_attribute->getAttributeId() ?>"
      class="super-attribute-select">
      <option value=""><?= /* @escapeNotVerified */ __('Choose an Option...') ?></option>
      </select>
      </div>
      </div>
      <?php endforeach; ?>
      <script type="text/x-magento-init">
      {
      "#product_addtocart_form": {
      "configurable": {
      "spConfig": <?= /* @escapeNotVerified */ $block->getJsonConfig() ?>,
      "gallerySwitchStrategy": "<?php /* @escapeNotVerified */ echo $block->getVar('gallery_switch_strategy',
      'Magento_ConfigurableProduct') ?: 'replace'; ?>"
      }
      }
      }
      </script>
      <?php endif;?>



      And my system log ever shows:




      [2019-01-16 13:02:01] main.CRITICAL: Invalid method MagentoCatalogBlockProductViewInterceptor::decorateArray  


      So, I can't override the configurable.phtml file, because the Magento Interceptors can't load the decorateArray method.



      And before, I need get the configurable products out of stock in my select, like this image:
      example



      But I don't know where the method to override this and get all product attributes







      magento2 module configurable-product overrides






      share|improve this question







      New contributor




      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question







      New contributor




      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question






      New contributor




      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked 19 mins ago









      Bruno RoboredoBruno Roboredo

      1




      1




      New contributor




      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Bruno Roboredo is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          0






          active

          oldest

          votes











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "479"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Bruno Roboredo is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f258032%2fconfigurableproduct-how-to-get-the-configurable-products-out-of-stock%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          0






          active

          oldest

          votes








          0






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Bruno Roboredo is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Bruno Roboredo is a new contributor. Be nice, and check out our Code of Conduct.













          Bruno Roboredo is a new contributor. Be nice, and check out our Code of Conduct.












          Bruno Roboredo is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Magento Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fmagento.stackexchange.com%2fquestions%2f258032%2fconfigurableproduct-how-to-get-the-configurable-products-out-of-stock%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Polycentropodidae

          Magento 2 Error message: Invalid state change requested

          Paulmy