Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Magento2 removed code pool . So what component is used to substituted the customization way? #450

Closed
guoguolong opened this issue Dec 25, 2013 · 8 comments

Comments

@guoguolong
Copy link

As we've known, Magento2 removed 'code pool' . Is there a better way to substitute it in Magento2 ?

I try to use 'rewrite' to customize classes. But sometimes it doesn't work. For example,
It doesn't work when the class to be customized has one more derived classes and it's not called directly($objmgr->create('ClassNameToBeCustomized'))

See below the living sample. I Added a line to di.xml in my module's

The Magento\Customer\Model\Address\AbstractAddress class is a basic class which haven't been called directly. Means:
There are fews classes
Magento\Customer\Model\Address
Magento\Sales\Model\Order\Address
Magento\Sales\Model\Quote\Address
extend Magento\Customer\Model\Address\AbstractAddress.It's called when call above one of 3 classes. I found the rewrite doesn't work at all, Is there anybody can give some suggestions ?

@kandy
Copy link
Contributor

kandy commented Dec 25, 2013

The main reason of removing of the class rewrites and code pool is conflict of modules and version updates.
Best practices are use Plugins for extend base functionality. Also interface preferences can be used in some cases.

But if you think that it real need for you then you can use autoloading to load your classes instead of magento. Just add to index.php code like:

\Magento\Autoload\IncludePath::addIncludePath(array(
    BP . '/mycode',
), false);

@guoguolong
Copy link
Author

Thanks for your answer. Looks Plugins is what I want. But I still got some errors.
I created one class Haw\Basic\Model\Customer\Address\A to be intercept then create the configuration in etc/di.xml as below.
<type name="Haw\Basic\Model\Customer\Address\A">
<plugin name="customer_address_r" type="Haw\Basic\Model\Customer\Address\R"/>
</type>
It works. Now I want to intercept the public method 'getRegion' of magento internal class Magento\Customer\Model\Address\AbstractAddress . I create the configuration as below:
<type name="Magento\Customer\Model\Address\AbstractAddress">
<plugin name="customer_address_r" type="Haw\Basic\Model\Customer\Address\R"/>
</type>
The only change is the type name . I also added 'beforeGetRegion' method to Haw\Basic\Model\Customer\Address\R. But it doesn't work at all. Nothing happen when I run the page. Can you give me more suggestions?

@guoguolong
Copy link
Author

I just tried below the calling:
$objManager = \Magento\App\ObjectManager::getInstance();
$obj = $objManager->create('Magento\Customer\Model\Address');
$obj->getRegion();
The interceptor works. But I want all AbstractAddress calling in internal Magento code are intercepted. Actually it didn't . I saw the Plugin document in wiki which mentioned the limitation of Plugin as below:

The plugin feature is not available for:

  1. Classes created without dependency injection, that is, created with operator new directly
  2. Classes containing the final methods
  3. Final classes
  4. Non-public calls, that is, internal calls of a method, disregarding a method's visibility

Am I sinking into the limitation of Plugin?. Is there perfect solution for it?

@guoguolong
Copy link
Author

I found the line
$address = $customer->getAddressItemById($addressId);
in Magento\Customer\Service\Customer. At this time, the $address instance getRegion calling won't be intercepted by decalred Plugin in di.xml. Any suggestion?

@sshymko
Copy link

sshymko commented Jan 2, 2014

@guoguolong
You have noticed probably the most significant limitation of plugins - inability to intercept internal calls. The limitation is a side-effect of the current implementation of interceptors, i.e. wrapping an original instance like a decorator. Certain changes to the implementation of interception mechanism would allow to overcome the limitation. Corresponding improvement ticket has already been filed in the internal bug tracker. We'll keep you posted about its status, although it's not scheduled for implementation yet.

@guoguolong
Copy link
Author

thanks @sshymko . Is below the solution for base calsses extending/overrite possible?
Suppose I just want to rewrite Magento class Magento\Customer\Model\Address\AbstractAddress. It owns 3 derived classes at least :

Magento\Customer\Model\Address
Magento\Sales\Model\Order\Address
Magento\Sales\Model\Quote\Address

Then we simply declare the rewrite in di.xml as below:

<preference for="Magento\Customer\Model\Address\AbstractAddress" type="Haw\Basic\Model\Customer\Address\AbstractAddress" />

Then run any magento page, at this time the compiler recompile out all derived calsses of \AbstractAddress into var/generation folder.

class Magento\Customer\Model\Address extends Haw\Basic\Model\Customer\Address\AbstractAddress
class Magento\Sales\Model\Order\Address extends Haw\Basic\Model\Customer\Address\AbstractAddress
class Magento\Sales\Model\Quote\Address extends Haw\Basic\Model\Customer\Address\AbstractAddress

When call these derived classes, php loader load them in var/generation first , load the same classes in app/code if not found in var/generation

@sshymko
Copy link

sshymko commented Mar 6, 2014

@guoguolong Sorry for the delay in response.

DI Preferences

Descendant classes are not going to be affected by the DI preference directive for the abstract class they inherit. Directory var/generation is used only for two kinds of auto-generated classes: factories, proxies. None of those is used for the preference directive.

Plugins

Good news, the mechanism of plugins has been significantly enhanced recently. It no longer has the limitations, described above: inability to intercept internal calls, lack of access to the pluginized object, etc. It's recommended to use plugins for cross-cutting customization, rather than class rewrites.

@verklov
Copy link
Contributor

verklov commented Apr 23, 2014

@guoguolong, as we see, the response given by @sshymko is complete and correct. Please follow the provided recommendations. We are closing this issue.

@verklov verklov closed this as completed Apr 23, 2014
magento-team pushed a commit that referenced this issue Mar 18, 2016
mmansoor-magento pushed a commit that referenced this issue Sep 30, 2016
magento-engcom-team added a commit that referenced this issue Mar 13, 2019
 - Merge Pull Request magento/graphql-ce#450 from magento/graphql-ce:420-test-coverage-getAvailablePaymentMethods-guest
 - Merged commits:
   1. 9b2be29
   2. 9395e76
   3. 8ab0ab3
   4. 2bd07f7
   5. e24a4c8
magento-devops-reposync-svc pushed a commit that referenced this issue May 24, 2022
CABPI-397: Fix Failed Functional Tests CE Tests
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants