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.
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.
Share Improve this question edited Oct 24, 2018 at 17:09 Amirition asked Oct 23, 2018 at 22:19 AmiritionAmirition 3555 silver badges20 bronze badges1 Answer
Reset to default 1The 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.