Question

To get with the time and improve my coding practices, I'm starting to implementing namespaces in my own plugins moving forward since there are some advantages, such as eliminating ambiguity.

I found a similar question to help me set up my plugin template which worked for me. However, I've since modified it slightly. This is my setup:

In wp-plugin-template/wp-plugin-template.php:

<?php
/**
 * Plugin Name: WP Plugin Template
 */
# If accessed directly, exit
if ( ! defined( 'ABSPATH' ) ) exit;
# Call the autoloader
require_once( 'autoloader.php' );

use PluginTemplate\admin\Plugin_Meta;
new Plugin_Meta;

In wp-plugin-template/autoloader.php:

<?php
spl_autoload_register( 'autoload_function' );
function autoload_function( $classname ) {
    $class = str_replace( '\\', DIRECTORY_SEPARATOR, str_replace( '_', '-', strtolower($classname) ) );
    # Create the actual file-path
    $path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $class . '.php';
    # Check if the file exists
    if ( file_exists( $path ) ) {
        # Require once on the file
        require_once $path;
    }
}

In wp-plugin-template/admin/plugin-meta.php:

<?php
namespace PluginTemplate\admin;
class Plugin_Meta {
    public function __construct() {
        add_action( 'plugins_loaded', array($this, 'test' ) );
    }

    public function test() {
        echo 'It works!';
    }
}

When I try to activate the plugin template for testing, I get the following error:

Fatal error: Class PluginTemplate\admin\Plugin_Meta not found in wp-content/plugins/wp-plugin-template/wp-plugin-template.php on line 11

In this case, line 11 is:

new Plugin_Meta;

I think this is due to me having the namespace named PluginTemplate? What am I doing wrong? Just to reiterate, the previous question that I mentioned worked for me before I started to rename my files and directories.

Was it helpful?

Solution

The problem is with your Autoloader set-up. You need to convert your Camelcase namespacese to dashes for locating files as per your current folder structure.

I have added convert function and updated your autoloader function.

In wp-plugin-template/autoloader.php:

<?php
spl_autoload_register( 'autoload_function' );
function autoload_function( $classname ) {
    $class = str_replace( '\\', DIRECTORY_SEPARATOR, str_replace( '_', '-', strtolower(convert($classname)) ) );
    # Create the actual file-path
    $path = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $class . '.php';
    # Check if the file exists
    if ( file_exists( $path ) ) {
        # Require once on the file
        require_once $path;
    }
}

function convert($class){
    $class = preg_replace('#([A-Z\d]+)([A-Z][a-z])#','\1_\2', $class);
    $class = preg_replace('#([a-z\d])([A-Z])#', '\1_\2', $class);
    return $class;
}

Also you have to update your top level namespace to WpPluginTemplate in both wp-plugin-template.php and admin/plugin-meta.php as you are using wp-plugin-template as your plugin folder name.

UPDATE:

When autoloader tries to find Plugin_Meta class, it will look into YOUR_PLUGIN_DIR/wp-plugin-template/admin/plugin-meta.php

In wp-plugin-template.php

<?php
/**
 * Plugin Name: WP Plugin Template
 */
# If accessed directly, exit
if ( ! defined( 'ABSPATH' ) ) exit;
# Call the autoloader
require_once( 'autoloader.php' );

use WpPluginTemplate\admin\Plugin_Meta;
new Plugin_Meta;

In wp-plugin-template/admin/plugin-meta.php

<?php
namespace WpPluginTemplate\admin;
class Plugin_Meta {
    public function __construct() {
        add_action( 'plugins_loaded', array($this, 'test' ) );
    }

    public function test() {
        echo 'It works!';
    }
}

OTHER TIPS

Just some additional note about your autoloader:

If the $classname input is PluginTemplate\admin\Plugin_Meta then the $path becomes

/full/path/to/wp-content/plugins/plugintemplate/admin/plugin-meta.php

and this file doesn't exists and the Plugin_Meta class definition isn't loaded.

It's also not recommended to use the WP_PLUGIN_DIR constant directly, there are alternatives, like plugin_dir_path( __FILE__ ).

There are more complete autoloaders out there, e.g. the generated autoloader in Composer.

Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top