1
<?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="Maxime\Helloworld\Block\Rewrite\Product\Selectoption" />
</config>


<?php
namespace Maxime\Helloworld\Block\Rewrite\Product;
use Magento\Framework\View\Element\Template;
class Selectoption extends \Magento\Catalog\Block\Product\View\Options\Type\Select
{

    public function getValuesHtml()
    {
        $_option = $this->getOption();
        $configValue = $this->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
        $store = $this->getProduct()->getStore();

        $this->setSkipJsReloadPrice(1);

        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('', __('fdhfgdhfghdfg'));
            } 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'),
                    ],
                    falsehh
                );
                $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()"';
            }
            $extraParams .= ' data-selector="' . $select->getName() . '"';
            $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() .
                            ']"' .
                            ' data-selector="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' : '';
                }

                $dataSelector = 'options[' . $_option->getId() . ']';
                if ($arraySign) {
                    $dataSelector .= '[' . $htmlValue . ']';
                }

                $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 .
                    ' data-selector="' . $dataSelector . '"' .
                    ' 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;
        }
    }
}
?>

3 Answers 3

1

If the main purpose is to change the html content of the output in \Magento\Catalog\Block\Product\View\Options\Type\Select.php, you can try via virtualType.

<virtualType name="customCheckable" type="Magento\Catalog\Block\Product\View\Options\Type\Select\CheckableFactory">
    <arguments>
        <argument name="instanceName" xsi:type="string">Vendor\Module\Block\Product\View\Options\Type\Select\Checkable</argument>
    </arguments>
</virtualType>
<type name="Magento\Catalog\Block\Product\View\Options\Type\Select">
    <arguments>
        <argument name="checkableFactory" xsi:type="object">customCheckable</argument>
    </arguments>
</type>

instanceName is the variable used in Magento\Catalog\Block\Product\View\Options\Type\Select\CheckableFactory

customCheckable can be any name

checkableFactory is the variable used in vendor/magento/module-catalog/Block/Product/View/Options/Type/Select.php

<?php
namespace Vendor\Module\Block\Product\View\Options\Type\Select;
use Magento\Framework\Pricing\Helper\Data;
use Magento\Framework\View\Element\Template\Context;

class Checkable extends \Magento\Catalog\Block\Product\View\Options\Type\Select\Checkable
{
    /**
     * Checkable constructor.
     * @param Context $context
     * @param Data $pricingHelper
     * @param \Magento\Catalog\Helper\Data $catalogData
     * @param array $data
     */
    public function __construct(
        Context $context,
        Data $pricingHelper,
        \Magento\Catalog\Helper\Data $catalogData,
        array $data = []
    ) {
        parent::__construct($context, $pricingHelper, $catalogData, $data);
    }

    /**
     * @var string
     */
    protected $_template = 'Vendor_Module::product/composite/fieldset/options/view/checkable.phtml';

    /**
     * @return bool|string
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getCustomMethod()
    {
        return 'Sample Value';
    }
}

in app/code/Vendor/Module/view/frontend/templates/product/composite/fieldset/options/view/checkable.phtml call the function getCustomMethod()

<?= $block->getCustomMethod()?>
0

You should create the plugin for this

Please follow then blog as plug in reference

http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html https://www.demacmedia.com/magento-commerce/create-a-magento-2-plugin/ https://webkul.com/blog/magento2-use-plugins/ https://www.mageplaza.com/magento-2-module-development/magento-2-plugin-interceptor.html

For You case

di.xml should contain below code:

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Block\Product\View\Options\Type\Select">
        <plugin disabled="false" name="Mageplaza_HelloWorld_Plugin_Post" sortOrder="10" 
            type="[Vendorname]\[Modulename]\Plugin\Block\Product\View\Options\Type\Select"/>
    </type>
</config>

And plugin class: [Vendorname][Modulename]\Plugin\Block\Product\View\Options\Type\Select

namespace [Vendorname]\[Modulename]\Plugin\Block\Product\View\Options\Type;

class Select {

    public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject, $result)
    {
        // modify code at $result
        return $result; 
    }
    public function beforeGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject, $result)
    {
        // modify code at $result
        return $result; 
    }
     public function aroundGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select  $subject, callable $proceed)
    {
       // change here
        $returnValue = $proceed();
        if ($returnValue) {
           //chnages
        }
        return $returnValue;
    }
}

use before, after and around method as per as your requirement

0


Above answers helped me but it did not work for me as it is.
This is what I did to override block \Magento\Catalog\Block\Product\View\Options\Type\Select.php

File - [Vendor][Module]\etc\di.xml

<type name="Magento\Catalog\Block\Product\View\Options\Type\Select">
    <plugin name="[Vendor]_[Module]_select" sortOrder="10"
            type="[Vendor]\[Module]\Block\Product\View\Options\Type\Select"/>
</type>

File - [Vendor][Module]\Block\Product\View\Options\Type\Select.php

<?php

namespace [Vendor]\[Module]\Block\Product\View\Options\Type;

class Select extends \Magento\Catalog\Block\Product\View\Options\AbstractOptions
{

 public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject, $result)
 {
    $_option = $subject->getOption();
    $configValue = $subject->getProduct()->getPreconfiguredValues()->getData('options/' . $_option->getId());
    $store = $subject->getProduct()->getStore();

    $subject->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 = $subject->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) {
            // Code changes start
            if($_option->getIsSize()){
                $select->setName('options[' . $_option->getid() . ']')->addOption('', __('Select a Size'));
            }
            else if($_option->getIsCut()){
                $select->setName('options[' . $_option->getid() . ']')->addOption('', __('Select a Cut'));
            }
            else{
                $select->setName('options[' . $_option->getid() . ']')->addOption('', __('Select an Option'));
            }
            // Code changes end
        } else {
            $select->setName('options[' . $_option->getid() . '][]');
            $select->setClass('multiselect admin__control-multiselect' . $require . ' product-custom-option');
        }
        foreach ($_option->getValues() as $_value) {
            $priceStr = $subject->_formatPrice(
                [
                    'is_percent' => $_value->getPriceType() == 'percent',
                    'pricing_value' => $_value->getPrice($_value->getPriceType() == 'percent'),
                ],
                false
            );
            $select->addOption(
                $_value->getOptionTypeId(),
                $_value->getTitle() . ' ' . strip_tags($priceStr) . '',
                ['price' => $subject->pricingHelper->currencyByStore($_value->getPrice(true), $store, false)]
            );
        }
        if ($_option->getType() == \Magento\Catalog\Model\Product\Option::OPTION_TYPE_MULTIPLE) {
            $extraParams = ' multiple="multiple"';
        }
        if (!$subject->getSkipJsReloadPrice()) {
            $extraParams .= ' onchange="opConfig.reloadPrice()"';
        }
        $extraParams .= ' data-selector="' . $select->getName() . '"';
        $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() .
                        ']"' .
                        ' data-selector="options[' . $_option->getId() . ']"' .
                        ($subject->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 = $subject->_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' : '';
            }

            $dataSelector = 'options[' . $_option->getId() . ']';
            if ($arraySign) {
                $dataSelector .= '[' . $htmlValue . ']';
            }

            $selectHtml .= '<div class="field choice admin__field admin__field-option' .
                $require .
                '">' .
                '<input type="' .
                $type .
                '" class="' .
                $class .
                ' ' .
                $require .
                ' product-custom-option"' .
                ($subject->getSkipJsReloadPrice() ? '' : ' onclick="opConfig.reloadPrice()"') .
                ' name="options[' .
                $_option->getId() .
                ']' .
                $arraySign .
                '" id="options_' .
                $_option->getId() .
                '_' .
                $count .
                '" value="' .
                $htmlValue .
                '" ' .
                $checked .
                ' data-selector="' . $dataSelector . '"' .
                ' price="' .
                $subject->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;
    }
 }
}

Important things to note here -

After copying `\Magento\Catalog\Block\Product\View\Options\Type\Select.php` to [`Vendor][Module]\Block\Product\View\Options\Type\Select.php`, you must do following.

1. Change the namespace to `[Vendor]\[Module]\Block\Product\View\Options\Type;`
2. Replace `public function getValuesHtml()` to `public function afterGetValuesHtml(\Magento\Catalog\Block\Product\View\Options\Type\Select $subject, $result)`
3. Replace `$this` to `$subject`

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.