So, I am not completely new to developing plugins in WordPress but this is something I’ve been bumping onto.
I am making a plugin using the Object Oriented style. This, however, is completely new to me.
I am trying to make an admin menu icon to display in the backend. This is quite easy when just using function. But somehow, in OOP, I get this error:
Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'ssp_build_hook' not found or invalid function name in /home/example/domains/example.com/public_html/test/wp-includes/plugin.php on line 503
Now, I have no clue how to fix this. I have thought about WordPress not fully loaded when trying to call that function.
This is my main file, test-plugin.php:
<?php
namespace SSP;
spl_autoload_register(__NAMESPACE__ . '\autoload');
function autoload($cls)
{
$cls = ltrim($cls, '');
if(strpos($cls, __NAMESPACE__) !== 0)
return;
$cls = str_replace(__NAMESPACE__, '', $cls);
$path = plugin_dir_path(__FILE__) . 'inc' . str_replace('', DIRECTORY_SEPARATOR, $cls) . '.php';
require_once($path);
}
class CSSP_Prepare {
function __construct() {
global $wpdb;
$this->tablename = $wpdb->prefix . 'example_table';
$this->fssp_register_hooks();
}
function fssp_register_hooks() {
register_activation_hook(__FILE__, array(&$this, 'fssp_activate'));
register_deactivation_hook(__FILE__, array(&$this, 'fssp_deactivate'));
//register_uninstall_hook(__FILE__, array(&$this, 'fssp_uninstall'));
}
function fssp_activate($wpdb) {
global $wpdb;
if($wpdb->get_var("SHOW TABLES LIKE '" . $this->tablename . "'") != $this->tablename) {
$this->sql = 'CREATE TABLE ' . $this->tablename . ' (id bigint(21) NOT NULL AUTO_INCREMENT, text text, UNIQUE KEY id (id)) ';
require_once(ABSPATH.'wp-admin/includes/upgrade.php');
dbDelta( $this->sql );
}
}
function fssp_deactivate() {
}
function fssp_uninstall() {
$this->sql = 'DROP TABLE ' . $this->tablename . '';
require_once(ABSPATH.'wp-admin/includes/upgrade.php');
dbDelta( $this->sql );
}
}
new CSSP_Prepare();
class CSSP_Construct {
function __construct() {
$this->build = new CBuild();
}
function fssp_construct() {
$this->build->ssp_init();
}
}
$page_constructor = new CSSP_Construct();
$page_constructor->fssp_construct();
?>
So as you can see, I am trying to call $this->build->ssp_init()
from the CBuild
class.
CBuild code is as follows CBuild.php:
<?php
namespace SSP;
class CBuild {
function __construct() {
require_once( ABSPATH . '/wp-load.php' );
}
function ssp_init() {
add_action('wp_loaded', 'ssp_build_hook');
}
public function ssp_build_hook() {
add_action('admin_menu', 'ssp_buildpage_hooks');
}
function ssp_buildpage_hooks() {
add_menu_page('SSP Options', 'SSP Options', 'manage_options', 'example_plugin_options', 'ssp_build_options_page', 'dashicons-art');
add_menu_page('SSP Orders', 'SSP Orders', 'manage_options', 'example_plugin_orders', 'ssp_build_orders_page', 'dashicons-cart');
}
function ssp_build_options_page() {
?>
<div class="wrapper">
<form action="options.php" method="post">
<?php settings_fields('ssp_options'); ?>
<?php do_settings_sections('ssp_options_input'); ?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
function ssp_build_orders_page() {
?>
<div class="wrapper">
<form action="options.php" method="post">
<?php settings_fields('ssp_orders'); ?>
<?php do_settings_sections('ssp_orders_input'); ?>
<?php submit_button(); ?>
</form>
</div>
<?php
}
}
?>
So you can see, I am calling $this->build->ssp_init();
in test-plugin.php
and this function is located in CBuild.php
.
This function contains a WordPress action hook, add_action('wp_loaded', 'ssp_build_hook');
.
But it can’t find ssp_build_hook
.
So my question is, why can’t it find ssp_build_hook
?
Any advice, tutorials, coding improvements or question improvements would be greatly appreciated!
Try like
add_action('wp_loaded', array( $this, 'ssp_build_hook'));
oradd_action('wp_loaded', array( __CLASS__, 'ssp_build_hook'));
to add action in class, we need to pass in array,$this
and thenfunction_name
. Hope this will help. Applies to all hooks in a class.