3

So, I'm facing the almighty "Class Bla not found" error on one of my website.

The class file sits in the vendor folder and I'm using an event observer for the autoload:

<events>
    <resource_get_tablename>
        <observers>
            <composer_autoloader>
                <type>singleton</type>
                <class>module/observer</class>
                <method>addComposerAutoloader</method>
            </composer_autoloader>
        </observers>
    </resource_get_tablename>
</events>

Here's my observer:

class Vendor_Module_Model_Observer
{
    /**
     * @var bool
     */
    protected static $added = false;
    /**
     * Register the Composer autoloader
     * @param Varien_Event_Observer $observer
     */
    public function addComposerAutoloader(Varien_Event_Observer $observer)
    {
        if (self::$added === false) {
            /** @var $helper Vendor_Module_Helper_Data */
            $helper = Mage::helper('module');
            $helper->registerAutoloader();
            self::$added = true;
        }
    }
}

And here's my helper method:

public function registerAutoloader($path = null, $filename = null)
{
    if ($path === null) {
        $path = $this->getVendorDirectoryPath();
    }
    if ($filename === null) {
        $filename = self::AUTOLOAD_FILENAME;
    }
    if (file_exists($path . DS . $filename)) {
        require_once($path . DS . $filename);
    }
}

According to my tests using xDebug, the observer is properly triggered and the require_once leading to my vendor/autoload.php is called.

I've checked the namespace I use to call my custom class and I'm 100% sure there's no typo.

NB: please note that if I get rid of this composer code and if I patch the app/Mage.php directly with the following code, it does not work either:

/** AUTOLOADER PATCH **/
if (file_exists($autoloaderPath = BP . DS . '../vendor/autoload.php') ||
    file_exists($autoloaderPath = BP . DS . 'vendor/autoload.php')
) {
    require $autoloaderPath;
}
/** AUTOLOADER PATCH **/

So my question is: how do I debug that error ? Any usual suspects ?

2 Answers 2

1

So my question is: how do I debug that error ? Any usual suspects ?

Breakpoints in lib/Varien/Autoload.php and vendor/autoload.php. Or in a new Here_Your_Class_Name line to see in which order the autoloaders are registered.


That's a typical problem: the Varien Autoloader is called first and it has this bug that it does not verify if the resolved file path can be included (i.e. the file exists), then fails instead of letting other autoloaders try1.

spl_autoload_register() has a prepend parameter, that you must use if you register your autoloader anytime after Varien_Autoload.

But I just checked, the composer autoloader uses $prepend = true, so not a problem in your case.


Another thing that comes to mind: Make sure the composer autoloader is up to date by running composer dump-autoload.


1) can be easily fixed using stream_resolve_include_path()

0

Ok so here is how I ended up fixing my issue.

First I created a super simple script in my root folder to test the autoload without going through the entire Magento stack:

<?php

include 'vendor/autoload.php';
$foo = new \My\Class\Located\In\Vendor();
$test = get_class($foo);
echo $test;

Then I used xDebug in vendor/composer/ClassLoader.php by adding breakpoints in the following methods:

  • loadFile()
  • findFile()
  • findFileWithExtension()

Thanks to this, I have found out that the generated path of the file in the end of the findFileWithExtension method was totally wrong and it wasn't looking for the file in the right folder.

I tried composer dumpautoload by didn't fix my issue.

Did you try turning it off and on ?

That's pretty much what I did to fix my issue. I have ended up reinstalling the library by running the composer install again. On top of that I have installed this module but I don't think that's what fixed my issue (it's still an helpful module though) : https://github.com/magento-hackathon/Magento-PSR-0-Autoloader

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.