I am attempting to override the file lib/internal/Magento/Framework/Model/AbstractModel.php itself, since there is code within one of its public functions that I wish to modify.

If I specify a preference in my di.xml to specify that the class is overridden, it is never used. This "preference" mechanism seems to be the method for extending the class somehow. Since AbstractModel is an abstract class, all overrides/extensions of it are about actually making it a concrete class instead of an abstract. That isn't what I want to do - I want to actually replace the base AbstractModel class itself and then all other classes (concrete instances of it, implementing its virtual methods) can use my new class.

How can I do this?

eg. in my di.xml I have this: <preference for="Magento\Framework\Model\AbstractModel" type="My\Module\Model\AbstractModel"/>

....which is then never used.

Do I have to actually change the AbstractModel.php file itself? If so, this seems a Bad Idea as I am modifying the extremely fragile "core" code.

EDIT: To clarify, I do not want the original function to be called. The plugin system includes before, after and around calls (around = before + after) but in no circumstance does it exclude calling the original function. See https://devdocs.magento.com/guides/v2.3/extension-dev-guide/plugins.html where the sample scenarios for "replacing" Action::dispatch() always include the call to Action::dispatch() despite the before, after and around functionality.

In normal PHP with inheritance, if you override a base class method, the overridden method (and only the overridden method) will always be called. The child is under no obligation to call its parent, and therefore the parent overridden method may never be called. This is what I am trying to achieve - ordinary, sensible inheritance.

This Magento design seems to be contrary to this, where the base method is always called even if you "replace" it. This is different to every "inheritance" model in any OOP language I have ever encountered (C++, C#, Java, PHP etc. etc.). It appears to be a new definition of the word "replace"/"substitute" that doesn't exist in any language. It doesn't replace it at all - it simply calls functions around it. That isn't the same as substitution at all.

  • @PЯINCƏ Perhaps! Using plugins instead of preferences in the best way? – gibbotronic Feb 3 '20 at 14:07
  • Yes, plugin is preferable than preference, this allows you to update the logic without overriding the base file. – PЯINCƏ Feb 3 '20 at 14:16
  • @PЯINCƏ Thanks, is the type for this plugin the Magento/Framework/Model/AbstractModel or the class that AbstractModel inherits (\Magento\Framework\DataObject) ? The dev docs seem to indicate referring to an interface (which I suppose AbstractModel is in reality as it's an abstract class...) – gibbotronic Feb 3 '20 at 14:34
  • @PЯINCƏ I think plugins are not the solution because they get called before, after, or before and after ("around"). I want to get called INSTEAD, not before or after. I literally want to replace it. I do not want the original function to ever be called, ever. – gibbotronic Feb 3 '20 at 14:41

Your Answer

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

Browse other questions tagged or ask your own question.