Pregunta

Estoy tratando de anular el module-catalog/Block/Product/View/Options/Type/Select.php class con una nueva versión que incluye algunos otros bits de php personalizado (agregando clases HTML e ID a los DIV que los contienen).Estoy intentando lograr esto creando un nuevo módulo.Desafortunadamente, cuando este nuevo módulo está habilitado, las opciones de selección no se muestran en la página del producto.El resto de la página está bien, solo que sin las opciones de selección (casillas de verificación y botones de opción).Creo que todo se ve bien y debería funcionar, así que no puedo entender por qué Select.php no devuelve las opciones seleccionadas.

Estructura de directorios:

app/
├── Mike/
│   ├── Newselect/
│   │   ├── Block/
│   │   │   ├── Product/
│   │   │   │   ├── View/
│   │   │   │   │   ├── Options/
│   │   │   │   │   │   ├── Type/
│   │   │   │   │   │   │   ├── Select.php
│   │   ├── etc/
│   │   │   ├── di.xml
│   │   │   ├── module.xml
│   │   ├── registration.php
│   │   ├── composer.json

di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\View\Options\Type\Select" type="Mike\Newselect\Block\Product\View\Options\Type\Select" />
</config>

module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Mike_Newselect" setup_version="1.0.0"/>
</config>

registration.php

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Mike_Newselect',
    __DIR__    
);

composer.json

{
    "name": "Mike/Newselect",
    "description": "Update the Select module to add HTML classes and IDs",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",
        "magento/module-store": "100.0.*",
        "magento/module-eav": "100.0.*",
        "magento/module-cms": "100.0.*",
        "magento/module-indexer": "100.0.*",
        "magento/module-customer": "100.0.*",
        "magento/module-theme": "100.0.*",
        "magento/module-checkout": "100.0.*",
        "magento/module-backend": "100.0.*",
        "magento/module-widget": "100.0.*",
        "magento/module-wishlist": "100.0.*",
        "magento/module-tax": "100.0.*",
        "magento/module-msrp": "100.0.*",
        "magento/module-catalog-inventory": "100.0.*",
        "magento/module-directory": "100.0.*",
        "magento/module-catalog-rule": "100.0.*",
        "magento/module-product-alert": "100.0.*",
        "magento/module-url-rewrite": "100.0.*",
        "magento/module-catalog-url-rewrite": "100.0.*",
        "magento/module-page-cache": "100.0.*",
        "magento/module-quote": "100.0.*",
        "magento/module-config": "100.0.*",
        "magento/module-media-storage": "100.0.*",
        "magento/framework": "100.0.*",
        "magento/module-configurable-product": "100.0.*",
        "magento/module-ui": "100.0.*"
    },
    "suggest": {
        "magento/module-cookie": "100.0.*",
        "magento/module-catalog-sample-data": "Sample Data version:100.0.*"
    },
    "type": "magento2-module",
    "version": "100.0.5",
    "license": [
        "OSL-3.0",
        "AFL-3.0"
    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Magento\\Catalog\\": ""
        }
    }
}

Select.php (Esto es solo una copia del archivo principal Select.php, aún no actualizado, aparte del espacio de nombres y la extensión de la clase principal)

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

/**
 * Product options text type block
 *
 * @author     Magento Core Team <core@magentocommerce.com>
 */

namespace Mike\Newselect\Block\Product\View\Options\Type;

class Select extends \Magento\Catalog\Block\Product\View\Options\Type\Select
{
    /**
     * Return html for control element
     *
     * @return string
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
     */
    public function getValuesHtml()
    {
        $_option = $this->getOption();
        $configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
        $store = $this->getProduct()->getStore();

        $this->setSkipJsReloadPrice(1);
        // Remove inline prototype onclick and onchange events

        if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_DROP_DOWN ||
            $_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE
        ) {
            $require = $_option->getIsRequire() ? ' required' : '';
            $extraParams = '';
            $select = $this->getLayout()->createBlock(
                'Magento\Framework\View\Element\Html\Select'
            )->setData(
                [
                    'id' => 'select_' . $_option->getId(),
                    'class' => $require . ' product-custom-option admin__control-select'
                ]
            );
            if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_DROP_DOWN) {
                $select->setName('options[' . $_option->getid() . ']')->addOption('', __('-- Please Select --'));
            } else {
                $select->setName('options[' . $_option->getid() . '][]');
                $select->setClass('multiselect admin__control-multiselect' . $require . ' product-custom-option');
            }
            foreach ($_option->getValues() as $_value) {
                $priceStr = $this->_formatPrice(
                    [
                        'is_percent' => $_value->getPriceType() == 'percent',
                        'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
                    ],
                    false
                );
                $select->addOption(
                    $_value->getOptionTypeId(),
                    $_value->getTitle() . ' ' . strip_tags($priceStr) . '',
                    ['price' => $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)]
                );
            }
            if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE) {
                $extraParams = ' multiple="multiple"';
            }
            if (!$this->getSkipJsReloadPrice()) {
                $extraParams .= ' onchange="opConfig.reloadPrice()"';
            }
            $select->setExtraParams($extraParams);

            if ($configValue) {
                $select->setValue($configValue);
            }

            return $select->getHtml();
        }

        if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_RADIO ||
            $_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_CHECKBOX
        ) {
            $selectHtml = '<div class="options-list nested" id="options-' . $_option->getId() . '-list">';
            $require = $_option->getIsRequire() ? ' required' : '';
            $arraySign = '';
            switch ($_option->getType()) {
                case \Magento\Catalog\Model\Product\Option::OPTION_TYPE_RADIO:
                    $type = 'radio';
                    $class = 'radio admin__control-radio';
                    if (!$_option->getIsRequire()) {
                        $selectHtml .= '<div class="field choice admin__field admin__field-option">' .
                            '<input type="radio" id="options_' .
                            $_option->getId() .
                            '" class="' .
                            $class .
                            ' product-custom-option" name="options[' .
                            $_option->getId() .
                            ']"' .
                            ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
                            ' value="" checked="checked" /><label class="label admin__field-label" for="options_' .
                            $_option->getId() .
                            '"><span>' .
                            __('None') . '</span></label></div>';
                    }
                    break;
                case \Magento\Catalog\Model\Product\Option::OPTION_TYPE_CHECKBOX:
                    $type = 'checkbox';
                    $class = 'checkbox admin__control-checkbox';
                    $arraySign = '[]';
                    break;
            }
            $count = 1;
            foreach ($_option->getValues() as $_value) {
                $count++;

                $priceStr = $this->_formatPrice(
                    [
                        'is_percent' => $_value->getPriceType() == 'percent',
                        'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
                    ]
                );

                $htmlValue = $_value->getOptionTypeId();
                if ($arraySign) {
                    $checked = is_array($configValue) && in_array($htmlValue, $configValue) ? 'checked' : '';
                } else {
                    $checked = $configValue == $htmlValue ? 'checked' : '';
                }

                $selectHtml .= '<div class="field choice admin__field admin__field-option' .
                    $require .
                    '">' .
                    '<input type="' .
                    $type .
                    '" class="' .
                    $class .
                    ' ' .
                    $require .
                    ' product-custom-option"' .
                    ($this->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
                    ' name="options[' .
                    $_option->getId() .
                    ']' .
                    $arraySign .
                    '" id="options_' .
                    $_option->getId() .
                    '_' .
                    $count .
                    '" value="' .
                    $htmlValue .
                    '" ' .
                    $checked .
                    ' price="' .
                    $this->pricingHelper->currencyByStore($_value->getPrice(true), $store, false) .
                    '" />' .
                    '<label class="label admin__field-label" for="options_' .
                    $_option->getId() .
                    '_' .
                    $count .
                    '"><span>' .
                    $_value->getTitle() .
                    '</span> ' .
                    $priceStr .
                    '</label>';
                $selectHtml .= '</div>';
            }
            $selectHtml .= '</div>';

            return $selectHtml;
        }
    }
}

catalog_product_view.xml

<block class="Magento\Catalog\Block\Product\View\Options\Type\Select" as="select" template="product/view/options/type/select.phtml"/>
¿Fue útil?

Solución

En primer lugar, Necesitamos agregar el método de inyección Constructor a nuestra clase de selección personalizada: (Editar:No necesitamos agregar Constructor injection, necesitamos agregar el módulo de secuencia.)

    <?php
    namespace Mike\Newselect\Block\Product\View\Options\Type;

    class Select extends \Magento\Catalog\Block\Product\View\Options\Type\Select
    {
        public function __construct(
            \Magento\Framework\View\Element\Template\Context $context,
            \Magento\Framework\Pricing\Helper\Data $pricingHelper,
            \Magento\Catalog\Helper\Data $catalogData,
            array $data = []
        )
        {
            parent::__construct($context, $pricingHelper, $catalogData, $data);
        }
        .....

Necesitamos agregar:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="Mike_Newselect" setup_version="1.0.0">
            <sequence>
                <module name="Magento_Catalog"/>
            </sequence>
        </module>
</config>

http://devdocs.magento.com/guides/v2.1/extension-dev-guide/build/module-load-order.html

Segundo, copiar vendor/magento/module-catalog/view/frontend/templates/product/view/options/type/select.phtml a nuestro módulo personalizado app/code/Mike/Newselect/view/frontend/templates/product/view/options/type/select.phtml

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top