0

I'm writing a simple plugin with oop and using namespaces and autoloading. Here is my main file:

add_action('plugins_loaded', array(My_Test_Plugin::get_instance(), 'plugin_setup'));

class My_Test_Plugin
{
    /**
     * Plugin instance.
     *
     * @see get_instance()
     * @type object
     */
    protected static $instance = NULL;
    /**
     * URL to this plugin's directory.
     *
     * @type string
     */
    public $plugin_url = '';
    /**
     * Path to this plugin's directory.
     *
     * @type string
     */
    public $plugin_path = '';

    /**
     * Access this plugin’s working instance
     *
     * @wp-hook plugins_loaded
     * @since   2012.09.13
     * @return  object of this class
     */
    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    /**
     * Used for regular plugin work.
     *
     * @wp-hook plugins_loaded
     * @return  void
     */
    public function plugin_setup()
    {
        $this->plugin_url = plugins_url('/', __FILE__);
        $this->plugin_path = plugin_dir_path(__FILE__);
        $this->load_language('vt-plugin');

        spl_autoload_register(array($this, 'autoload'));

    }
    /**
     * @param $class
     *
     */
    public function autoload($class)
    {
        $class = str_replace('\\', DIRECTORY_SEPARATOR, $class);

        if (!class_exists($class)) {
            $class_full_path = $this->plugin_path . 'includes/' . $class . '.php';
            if (file_exists($class_full_path)) {
                require $class_full_path;
            }
        }
    }
}

In includes/PostTypes directory there is a file called Book.php and it's containing this:

namespace Book;

class Book {
    public function vt_create_book_post_type() {
        $labels = array(
            'name'                  => _x( 'Books', 'vt-plugin' ),
            'singular_name'         => _x( 'Book', 'vt-plugin' ),
            'menu_name'             => _x( 'Books', 'vt-plugin' ),
            ),
        );

        register_post_type( 'book', $args );
    }
}

It just registers a simple post type. Now my question is Where I should use my init action to register post type?

I used this code in the plugin_setup function in my main file:

add_action( 'init', array('Book', 'vt_register_book_post_type') );

But it gave me this error:

Warning: call_user_func_array() expects parameter 1 to be a valid callback 

Update If I change my autoloader function to this:

public function autoload($class)
    {
        $class = str_replace('\\', DIRECTORY_SEPARATOR, $class);

        if (!class_exists($class)) {
            $class_full_path = $this->plugin_path . 'includes/' . $class . '.php';
            if (file_exists($class_full_path)) {
                require $class_full_path;
                echo $class_full_path; 
            }
        }
    }

And echo the full path inside the if statement, it does not echo anything and I think this means that files aren't included.

1 Answer 1

1

The callback [ 'Book', 'vt_register_book_post_type' ] is adding a hook to the static method vt_register_book_post_type in the Book class of the global namespace.

If you want to add a callback to a static class of the Book namespace, you need to use [ '\Book\Book\', 'vt_register_book_post_type' ] as a callback, but that will also cause a warning or error because your method is not static. You can declare your method static, but what I think you want to do is something like this:

namespace Book;
class book {
  public function vt_create_book_post_type() {
    $labels = [
      'name'                  => _x( 'Books', 'vt-plugin' ),
      'singular_name'         => _x( 'Book', 'vt-plugin' ),
      'menu_name'             => _x( 'Books', 'vt-plugin' ),
    ];
    register_post_type( 'book', $args );
  }
}
$book = new book();
\add_action( 'init', [ $book, 'vt_create_book_post_type' ] );

There's nothing wrong with your autoloader. Or at least that's not what's causing the error.

4
  • I corrected my code based on your answer, but still it doesn't create the post type. And also there is no error or warning.
    – Amirition
    Commented Oct 24, 2018 at 6:59
  • $book = new book(); and the add_action() need to be in a file that has already been included. It's hard for me to imagine how this could both not register the post type and not produce an error of some kind. Commented Oct 24, 2018 at 15:37
  • I updated the question with some more info about the autoloader function. I still think something is wrong with it.
    – Amirition
    Commented Oct 24, 2018 at 17:10
  • 1
    Is the autoloader being run at all? What's $class? What's $class_full_path? Commented Oct 24, 2018 at 19:59

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.