0

I am having a weird issue with the autoloader class I built in PHP to use in WordPress.

The core concept is that it should load class regardless of if you are a child theme, parent theme or a plugin. It should find the class based on the name (coreesponding to the folder structure: CoreTheme_Folder_SubFolder_ClassName(){} = CoreTheme/Folder/SubFolder/ClassName.php

This works fine in child themes and parent themes, In child themes I include the parent themes function.php and from there it loads the autoloader so that I can call parent theme classes in child themes and not have a bunch of require_once() every where.

The problem comes, when I am doing the same concept in a plugin. The Autoloader is apart of a framework (think of zend) that you include at the root of your theme. If that theme is active and I set up the autoloader in a plugin, it spazzes out saying "there are two instances of this autoloader, what are you doing?" If I deactivate said theme then instantiate the autoloader in the plugin, it cant find any class I create using the pear naming standards.

So My question to those who understand both WordPress and PHP on a deeper level, How do I create my autoloader such that, regardless of weather your theme, child theme or plugin it will always find the class you are looking for.

the code below is the autloader class. If you take out: plugin_dir_path(__FILE__) then what will happen is the autoloader will load any class in the theme and corresponding child theme.

class AisisCore_Loader_AutoLoader{

    protected static $_instance;

    protected static $_directories;

    public function get_instance(){
        if(null == self::$_instance){
            self::$_instance = new self();
        }

        self::$_directories = array(
            get_template_directory(),
            get_stylesheet_directory(),
            plugin_dir_path(__FILE__),
        );

        return self::$_instance;
    }

    public function reset_instance(){
        self::$_instance = null;
    }

    public function register_auto_loader(){
        spl_autoload_register(array($this, 'load_class'));
    }

    public function load_class($class){
        $path = str_replace('_', '/', $class);
        foreach(self::$_directories as $directories){
            if(file_exists($directories . '/' . $path . '.php')){
                require_once($directories . '/' . $path . '.php');
            }
        }
    }   
}

The class is instantiated in your parent functions.php via:

// Load the autoloader.
require_once(get_template_directory() . '/AisisCore/Loader/AutoLoader.php');

// Setup the autoloader.
$auto_loader = AisisCore_Loader_AutoLoader::get_instance();
$auto_loader->register_auto_loader();

And then in the child theme all you have to do is:

require_once(TEMPLATEPATH . '/functions.php');

This allows the autoloader to work in both child and parent theme. The main issue is that when you create a plugin you place a copy of the framework in your plugin's Name root directory: plugins/myplugin/AisisCore/ and one in your theme (parent) Themes/MyTheme/AisisCore

So I can see why it would freak out - sort of, how ever is there a way around it?

TheWebs
  • 12,470
  • 30
  • 107
  • 211
  • `plugin_dir_path(__FILE__)` is likely wrong. Also you don't need a singleton, just allow to add directories, you then can register new plugin or theme direcotries on the run. Use an abstract class instead, that works better in Wordpress. Like @hakre suggested you in [your previous question](http://stackoverflow.com/q/15534211/2261774). – M8R-1jmw5r Apr 13 '13 at 21:10
  • Actually the function is correct as stated in WordPress, if it wasn't the whole app would crash, my implementation of the class is correct as it works - I cannot see the advantage of an abstract class but thanks for that ;). The issue here is that It freaks out if any theme active has AisisCore library in it. the issue here: http://wordpress.stackexchange.com/questions/95742/am-i-not-understanding-plugins is about the autloader not seeing anything in the plugin directory of your plugin. – TheWebs Apr 13 '13 at 21:15
  • Check conditionally if the autoloader is initialized inside a plugin or a theme. You need to troubleshoot this a little (you will also learn useful stuff while doing so). And `plugin_dir_path(__FILE__)` is a faker. Watch out what `__FILE__` is. See source: http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/plugin.php#L577 – M8R-1jmw5r Apr 13 '13 at 21:18
  • I understand that `__File__` points to the root of the file to which the code gets called in. so for me, I am calling `plugin_dir_path(__FILE__)` at the root of my file. This should in theory see AisisCore/ which is also at the root of my plugin directory much like how `get_template_directory` sees it in the folder. – TheWebs Apr 13 '13 at 21:22

1 Answers1

0

I think you want to only load one class, so use return; like this

public function load_class($class){
    $path = str_replace('_', '/', $class);
    foreach(self::$_directories as $directories){
        if(file_exists($directories . '/' . $path . '.php')){
            require_once($directories . '/' . $path . '.php');
            return;
        }
    }
}

or else you will load multiple classes. Check this out: http://php.net/return