0

I am trying to add a new function into the Magento\Catalog\Block\Product\View by extending the class. I tried to use that function in the template which is getHelloWorld() but I can't seem to get the function to work

etc/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" type="My\Module\Block\Catalog\Product\View" />
</config>

My/Module/Block/Catalog/Product/View.php

<?php

namespace My\Module\Block\Catalog\Product;

class View extends \Magento\Catalog\Block\Product\View
{
     public function getHelloWorld()
     {
         return 'Hello World';
     }
}

design/frontend/theme/folder/Magento_Catalog/templates/product/view/type/default.phtml

<?php $_product = $block->getProduct() ?>

//-----added it here this
<?php echo $block->getHelloWorld() ?>


<?php if ($block->displayProductStockStatus()): ?>
    <strong>Availability</strong>: 
    <?php if ($_product->isAvailable()): ?>
        <span class="stock available" title="<?= /* @escapeNotVerified */ __('Availability') ?>">
            <span><?= /* @escapeNotVerified */ __('In stock') ?></span>
        </span>
    <?php else: ?>
        <span class="stock unavailable" title="<?= /* @escapeNotVerified */ __('Availability') ?>">
            <span><?= /* @escapeNotVerified */ __('Out of stock') ?></span>
        </span>
    <?php endif; ?>
<?php endif; ?>
2

You really don't need to overwrite the class just to add some data. You would only want to overwrite that class for major changes. Otherwise, observers and plugins are available to you.

To modify block or model data or behavior, here is my order of preference, from least intrusive to "OMG you better have a good reason for doing this".

  1. Plugin: before, around, or after. Alan Storm does an excellent plugin tutorial here.
  2. Observer: There are several observers available which will allow you to change the data or behavior of the block in question.
  3. Argument Replacement: More Magento awesomeness where you can replace a single instance of the class instead of EVERY usage of the class which is what happens when you use 'preference'.
  4. Preference: This is a class rewrite. Unless you have major changes, you should really ask yourself "what's so special about my changes that I need to take full ownership of this class when the Magento core team lovingly created all of these other fantastic and more efficient ways to achieve my goal?".

The block you mentioned uses magic methods. If you create a plugin or observer and do $block->setHelloWorld('some text here'), and then in the actual template do echo $block->getHelloWorld(), 'some text here' will be printed out in the template even though the 'getHelloWord' method doesn't actually exist.


A little more explanation.

Any class that inherits from \Magento\Framework\DataObject has access to the magic methods. In that class, the __call method checks to see if the function being called begins with get, set, uns, or has. If it does and there is a concrete method that matches, that method will be called. Otherwise, depending on what three letters the function begins with, it will convert your function name as per the example below:

getHelloWorld will become $this->getData('hello_world')
setHelloWorld('some value') will become $this->setData('hello_world', 'some value')
unsHelloWorld will become $this->unsetData('hello_world')
hasHelloWorld will do a check to see if any element with the key hello_world exists in the class's $this->_data array.

I hope this helps you out!

  • I only plan to add a new function into \Magento\Catalog\Block\Product\View, I will be changing the 'some value' to will auto generated text. I tried doing this with a plugin public function afterGetProduct(\Magento\Catalog\Block\Product\View $subject, $result) { $this->setData('hello world', 'some value'); return $result; } and with the phtml $block->getHelloWorld() does not work – JustBigBoy12345 May 4 '18 at 0:01
  • I seen this on magento.stackexchange.com/a/160900/67225 but their solution is almost the same as what I want to do, but it doesn't work – JustBigBoy12345 May 4 '18 at 0:03
  • @JustBigBoy12345 can you clarify a little more about how the function should work? I mean I can show you how to easily override and extend the class but it goes against Magento's best practices so I am trying to make the effort to push you in the right direction. – Shawn Abramson May 4 '18 at 0:10
  • Also, when overriding a class to add one function only, that's usually an indicator that you're thinking about it in the wrong way. Explain a little bit and I'll do my best to get you going. – Shawn Abramson May 4 '18 at 0:12
  • I am trying to display the last quantity of the product bought by the logged in customer and have a button as a shortcut to add the same amount into the cart. – JustBigBoy12345 May 4 '18 at 2:30

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