Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Autoloader fails to load dependency classes #236

Closed
rawtaz opened this Issue · 1 comment

2 participants

@rawtaz

Example plugin name: Api
Example plugin file: plugin/Api.php
Plugin has dependency class with name: Phergie_Plugin_Api_HtmlSourceFinder
That dependency class is in file: plugins/Api/HtmlSourceFinder.php

In the config file (which is located in the same folder as the plugin/ folder is), I've added the following, because this plugin and its related classes are in a totally different folder than Phergie's default Plugins/ folder:

'plugins.paths' => array(
    __DIR__ . '/plugin' => 'Phergie_Plugin_',  // This key evaluates to the full path of the 'plugin' folder listed below.
),

Some file listings:

% ls -l plugin 
drwxr-xr-x  33 rawtaz  _www   1122 Sep  1 00:43 Api
-rw-r--r--   1 rawtaz  _www  13674 Sep  5 23:40 Api.php

% ls -l plugin/Api
<snip>
drwxr-xr-x   3 rawtaz  _www    102 Jul 29 01:59 HtmlSourceFinder  <-- this folder contains even more child classes of Phergie_Plugin_Api_HtmlSourceFinder
-rw-r--r--   1 rawtaz  _www   2385 Jul 30 00:32 HtmlSourceFinder.php
<snip>

Problem:

The plugin is loaded fine, but when the code in it requests the Phergie_Plugin_Api_HtmlSourceFinder class, the following happens:

PHP Fatal error:  Class 'Phergie_Plugin_Api_HtmlSourceFinder' not found in /Users/rawtaz/Sites/yii/Bot/plugin/Api.php on line 129
PHP Stack trace:
PHP   1. {main}() /Users/rawtaz/Sites/yii/Bot/phergie-phergie-40673a6/phergie.php:0
PHP   2. Phergie_Bot->run() /Users/rawtaz/Sites/yii/Bot/phergie-phergie-40673a6/phergie.php:54
PHP   3. Phergie_Bot->loadPlugins() /Users/rawtaz/Sites/yii/Bot/phergie-phergie-40673a6/Phergie/Bot.php:389
PHP   4. Phergie_Plugin_Handler->addPlugin() /Users/rawtaz/Sites/yii/Bot/phergie-phergie-40673a6/Phergie/Bot.php:338
PHP   5. Phergie_Plugin_Api->onLoad() /Users/rawtaz/Sites/yii/Bot/phergie-phergie-40673a6/Phergie/Plugin/Handler.php:242

If i debug the autoloader in Phergie a bit, I see that when the class is requested, the following paths are tried as $fileName:

/Users/rawtaz/Sites/yii/Bot/phergie-phergie-40673a6/Phergie/Plugin/Api/HtmlSourceFinder.php
./Phergie/Plugin/Api/HtmlSourceFinder.php
/usr/pkg/lib/php/Phergie/Plugin/Api/HtmlSourceFinder.php

Adding Phergie_Autoload::addPath(__DIR__); in the plugin code doesn't help either, it just makes the autoloader try /Users/rawtaz/Sites/yii/Bot/plugin/Phergie/Plugin/Api/HtmlSourceFinder.php.
If the autoloader took the prefix from the plugins.paths setting into account, and tried /Users/rawtaz/Sites/yii/Bot/plugin/Api/HtmlSourceFinder.php instead, it would probably have worked.
It would need to do that individually for all the entries in 'plugins.paths' though, since there could potentially be multiple entries and with different prefixes.

I'm not sure that just making Phergie/Plugin/Handler.php call Phergie_Autoload::addPath() (as suggested in #Phergie on freenode) solves the problem, for the reasons outlined in the previous paragraph. The autoloader would still try to find /Users/rawtaz/Sites/yii/Bot/plugin/Phergie/Plugin/Api/HtmlSourceFinder.php, instead of the correct /Users/rawtaz/Sites/yii/Bot/plugin/Api/HtmlSourceFinder.php.

@rawtaz

The PR I just filed fixes this problem, and I believe it also maintains BC (in terms of not breaking it – it does indeed add one optional parameter to Autoload::addPath()).

It don't think it's ideal to keep the prefixes stored in a static variable in Autoload, but to store them in a property we'd have to either make Autoload keep a reference to an instance of itself, which isn't much better, or we could inject an Autoload instance into Phergie instead, gaining less coupling/dependencies. The latter is better, but I didn't want to suggest too much change as I haven't spent much time with Phergie's internals. For now I wanted to solve this problem in an acceptible way.

@elazar elazar closed this issue from a commit
@rawtaz rawtaz Fix #236: Add support for class name prefixes when autoloading classe…
…s. With this, one can have class A_B_Class loaded from the file 'folder/Class.php' (using prefix 'A_B_') instead of as previously only 'folder/A/B/Class.php'.
92b489f
@elazar elazar closed this in 92b489f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.