Magento – Magento 2 override core Model class with psr-4 by replacing in app/code/Magento

composermagento2overrides

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

Best Answer

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.