13

Like this thread said: Override abstract class in Magento 2 in Magento 1, I can just create a full new class. In Magento 2, we should use plugins instead, but plugins only allow me to modified existent methods. What if I need to add a new method? Example: this class vendor/magento/module-ui/Component/AbstractComponent.php, has an array of components: $components, there is no function to unset/delete elements for that array. So how can I create that function?

0

I don't see how you can do that without completely overriding the class. In the case of your example, you can disable individual components by setting the "disabled" item to the "data" argument in the XML. For instance:

<?xml version="1.0" encoding="UTF-8"?>

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="general">
        <field name="title">
            <argument name="data" xsi:type="array">
                <item name="disabled" xsi:type="boolean">true</item>
            </argument>
        </field>
    </fieldset>
</form>

This effectively removes 'title' from the $components array.

This is due to the createChildComponent method in the Magento\Framework\View\Element\UiComponentFactory class:

 protected function createChildComponent(
        array $bundleComponents,
        ContextInterface $renderContext,
        $identifier
    ) {
        list($className, $arguments) = $this->argumentsResolver($identifier, $bundleComponents);
        if (isset($arguments['data']['disabled']) && (int)$arguments['data']['disabled']) {
            return null;
        }
        $components = [];
        foreach ($bundleComponents['children'] as $childrenIdentifier => $childrenData) {
            $children = $this->createChildComponent(
                $childrenData,
                $renderContext,
                $childrenIdentifier
            );
            $components[$childrenIdentifier] = $children;
        }
        $components = array_filter($components);
        $arguments['components'] = $components;
        if (!isset($arguments['context'])) {
            $arguments['context'] = $renderContext;
        }

        return $this->objectManager->create($className, $arguments);
    }
  • This is not what I'm looking for... I want a way to add new methods to an Abstract class... this is just an example... for example, what if I want to remove the elements dynamically? In your comment you mention "complete overriding" how you do that?? – Matias Aug 23 '16 at 20:48
  • Then you'll need to define your new methods in a class that extends the abstract class and then create classes for the abstract class's subclasses that instead inherit from your class and set preferences in di.xml. That's what I mean by 'completely overriding the class.' I was trying to show an example of how to avoid doing that. – Aaron Allen Aug 23 '16 at 21:05
  • Yes, I understand you... but the solution is not scalable at all... I cannot believe that M2 removed the possibility of overriding abstract classes... I thought that they were going to improve it, instead of removing it... – Matias Aug 24 '16 at 12:25
0

You can use class preference ,using before, around and after in the required method . Please check the docs for further details http://devdocs.magento.com/guides/v2.1/extension-dev-guide/plugins.html

0

overloading a class in M1 in the autoloader via community or local directory (like suggested in the question you linked) was considered bad practice in M1 for very good reasons.

Mostly you lose the ability to upgrade your Magento instance if the original class is changed in places, you did not consider in your overloaded class.

Actually, I cannot think of any usecase, where you really need to add methods to an abstract class, since you always can add your own logic to an own class an integrate it in a plugin / observer / viewModel / xml config

The best way would be, introducing a new class that extends the abstract class for your specific use case and then use your class where needed.

If you need to remove elements from a Ui Component, there is also likely a better way to do it via layout / a plugin on the layout processor / changing the js file that requires it.

So if you describe your specific usecase there might be a better answer to this.

  • I know, that doing that is a bad practice, but at least, you have one way to do it. For instance, consider the case you want to add a cache for every single model you load. This could be done by modifying the load method in the abstract class and then this change will be propagated to all the classes. If you don't have this you have to modify each model you have, and that's absolutely not scalable at all. – Matias Jan 29 at 21:56
  • A second use case, could be if you want to do what I say in the ticket, unset/delete elements from that array (consider as an example), you can think on whatever other thing... you need to create a new function in the abstract class, otherwise, you will be forced to create the same function in each class that extends, and that again is not scalable at all... And worst, because variables in Magento core are private instead of being protected, so the only way to do it is to add a method in the abstract class... – Matias Jan 29 at 21:56
  • the first example is absolutely easy by just adding an around plugin to the abstract model and cache the result of load per model. Which would be much better then overloading the abstract class which would break every future update where the abstract model is changed. You second "example" I cannot tell you much about, because your basically asking exactly for adding a method to the abstract class, instead of stating your actual use case – David Verholen Jan 30 at 5:37
  • btw it's still possible in Magento2 because you can manipulate the composer autoloader, but highly discouraged because you will have problems with updates magento.stackexchange.com/questions/164455/… – David Verholen Jan 30 at 5:40
  • That´s not an option – Matias Jan 30 at 18:40

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.