2

I need to add a new function to the configurable.php block, located in Magento\ConfigurableProduct\Block\Product\View\Type\Configurable. It's a function similar to $block->getJsonConfig() except it gets some different values.

Can I do this (add a new method/function) through a plugin or do I have to override the original block? I'm not changing or removing any of the original functionality, just need to be able to call another function from the phtml file. If I override, does that mean I need to copy all the original methods from the original block php or can I just define the new function I need in my override file?

Edit: I have followed Aaron's advice for extending the original class. Here is my di.xml file:

<?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\ConfigurableProduct\Block\Product\View\Type\Configurable"
        type="zzTest\zzModule\Block\Product\View\Type\Configurable" />
</config>

Here is what zzTest\zzModule\Block\Product\View\Type\Configurable.php looks like:

<?php 

namespace zzTest\zzModule\Block\Product\View\Type;
use Magento\ConfigurableProduct\Block\Product\View\Type\Configurable;
class Configurable extends \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable
{
    public function getXPPackCounts()
    {
        return 'good';
    }
}

Finally, I attempt to call this function from configurable.phtml in design/frontend/my/theme/Magento_ConfigurableProduct/templates/product/view/type/options/configurable.phtml . My calling code looks like this:

<?php /* @escapeNotVerified */ echo $block->getXPPackCounts() ?>

I know this phtml file is being called okay because I have other stuff on it that shows up. But I don't receive any output from my call. What have I setup incorrectly?

4

Plugins are not used for adding a method, they are for altering the input/output of an existing public method.

You'll need to replace the block with one that reuses the template but has a class which extends Magento\ConfigurableProduct\Block\Product\View\Type\Configurable and contains your method.

In {module_dir}/view/frontend/layout/catalog_product_view_type_configurable.xml :

<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.configurable" remove="true"/>
        <referenceBlock name="product.info.options.wrapper">
            <block class="Your\Module\Block\Product\View\Type\Configurable" name="my.product.info.options.configurable" before="-" template="Magento_ConfigurableProduct::product/view/type/options/configurable.phtml"/>
        </referenceBlock>
    </body>
</page>
  • Aaron, I have taken the steps you suggest, however I am not able to call the functions from the configurable.phtml file. I have added the contents of my di.xml and class extension file to the O.P. , as well as the php code I use to call the new method of the extending class. – Todd Sep 14 '16 at 13:25
  • I guess dependency injection won't work in this case because the block is being called from a layout xml and not a php constructor. Regardless, you should be able to replace the block in layout. I'll change the answer to reflect this. – Aaron Allen Sep 14 '16 at 18:35
  • When I did as you suggested, and added the xml file, I got some interesting results. The remove directive is ignored, but a second version of the block appears on the page - in one of the blocks I get the output from the special class (a string containing "good") and the other one still doesn't work. Also, I had to leave the preference in the di.xml or magento breaks. Pretty confusing! – Todd Sep 14 '16 at 20:42
  • It's a mystery as to why the remove directive doesn't work in this case. This is a bit of a hack, but to get rid of that block you could create an 'afterGetHtml' plugin for the Magento\ConfigurableProduct\Block\Product\View\Type\Configurable class that just returns an empty string. As for the offending preference in di.xml, try deleting the var/generation directory. – Aaron Allen Sep 16 '16 at 20:34
  • This statement is incorrect: Plugins are not used for adding a method, they are for altering the input/output of an existing public method....there is an around listener that can be used to modify content of that function – Stevie G Jan 5 '17 at 13:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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