2
"autoload": {
        "psr-4": {
            "Magento\\Framework\\": "lib/internal/Magento/Framework/",
            "Magento\\Setup\\": "setup/src/Magento/Setup/",
            "Magento\\": "app/code/Magento/"
        },
        "psr-0": {
            "": "app/code/"
        },
        "files": [
            "app/etc/NonComposerComponentRegistration.php"
        ]
    },

This is composer autoload part from composer.json on magento2 root

as per this i have successfully overirde

vendor/magento/framework/View/Element/Html/Link.php

by replacing this file in

lib/internal/Magento/Framework/View/Element/Html/Links.php

Now i have tried same for

vendor/magento/module-catalog-import-export/Model/Import/Product/Validator/Media.php

By replacing this file in

app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php

above override method is not working.can anyone point me in right direction ?

PS : i want to change const URL_REGEXP = '|^http(s)?://[a-z0-9-_]+(.[a-z0-9-_]+)*(:[0-9]+)?(/.*)?$|i'; of above class as it cause issue in product import which has double underscore in image url

Can i override using psr-4 or not ? I do not want to go for "preference" if above solution fix my issue.

6
  • 2
    @TejabhagavanKollepara No. Please read it again.this is different one Mar 15, 2017 at 11:23
  • @MineshPatel: You're trying to do it wrong. The link Teja gave explains the correct (and working) way of overriding a given class.
    – Ryan Hoerr
    Mar 15, 2017 at 13:05
  • @RyanHoerr i know that. i want to confirm the way i have selected is possible or not ? Mar 15, 2017 at 13:29
  • @RyanHoerr is it possible to put class directly in app/code/Magento like magento1.x in app/code/local ? Mar 16, 2017 at 7:09

2 Answers 2

4
+50

As described here, you can override single classes by (ab)using composer autoload definitions like this:

  "files": ["app/code/Magento/CatalogImportExport/Model/Import/Product/Validator/Media.php"]

But just because you can, does not mean you should. Always prefer plugins if possible, and fall back to DI preferences if not. There are very rare cases where a hack like this is really necessary.

Regarding your concrete issue: while you cannot override a constant using preferences, you can override its usages. In Magento 2.1 this constant is only used once, in Magento\CatalogImportExport\Model\Import\Product\Validator\Media::checkValidUrl(). Since it is a protected method, you cannot write a plugin for it, but you can replace the class using preferences with:

class MediaValidator extends Magento\CatalogImportExport\Model\Import\Product\Validator\Media
{
    const URL_REGEXP = '|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i'; // <-- change this line

    protected function checkValidUrl($string)
    {
        return preg_match(self::URL_REGEXP, $string);
    }
}

Here, self refers to the new class instead of the parent class.

And just for your info, in Magento 2.2 this method is not used anymore and marked as deprecated:

 * @deprecated As this method doesn't give a guarantee of correct URL validation.
 * @see \Magento\Framework\Url\Validator::isValid() It provides better URL validation.
3
  • Thanks Fabian this is what i wanted. this trick is useful for quick core bug fix. Jul 20, 2017 at 4:51
  • do we need to put this line in composer.json on root OR can we add this in our own module ? Jul 20, 2017 at 4:56
  • This also works in a module Jul 20, 2017 at 6:06
2

TL;DR: You can't use PSR-4 autoload in composer.json file. Every modules in Magento 2 have their own autoload, that's useless unless you are using the source code from Magento 2 Github repo.

magento/framework ("lib/internal/Magento/Framework/") and magento/magento2-base ("app/code/Magento"), actually, have their autoload.

The reason why Git repository (magento/magento2) is that it includes whole Magento and so does not download components (such as Framework) via Composer. That's why composer.json of the Git repository includes duplicated information to let Composer read and process it.

2
  • i have installed magento using composer so all core files are under vendor. so it is not possible to override by placing core files in app/code/Magento/Module-Name OR in lib/internal/Magento/Module-Name ? i am asking this because in some case i found internal bug and wanted to fix that by putting in separate code pool same like magento1.x another way is i need to override using DI for bug fix Jul 14, 2017 at 5:25
  • @MineshPatel That's not possible. M2 structure is too different to M1. M1 is worser in this situation, believe me. DI might be strange at the very first steps, but when you used it. You will see the benefits it brings to you in managing the code. Jul 14, 2017 at 6:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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