1
"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.

  • 2
    @TejabhagavanKollepara No. Please read it again.this is different one – Minesh Patel Mar 15 '17 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 '17 at 13:05
  • @RyanHoerr i know that. i want to confirm the way i have selected is possible or not ? – Minesh Patel Mar 15 '17 at 13:29
  • @RyanHoerr is it possible to put class directly in app/code/Magento like magento1.x in app/code/local ? – Minesh Patel Mar 16 '17 at 7:09
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.
  • Thanks Fabian this is what i wanted. this trick is useful for quick core bug fix. – Minesh Patel Jul 20 '17 at 4:51
  • do we need to put this line in composer.json on root OR can we add this in our own module ? – Minesh Patel Jul 20 '17 at 4:56
  • This also works in a module – Fabian Schmengler Jul 20 '17 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.

  • 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 – Minesh Patel Jul 14 '17 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. – Toan Nguyen Jul 14 '17 at 6:29

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.