Magento 2:Anulación de la clase de bloque: no genera salida
-
29-09-2020 - |
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"/>
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