3

I'm building a custom theme and I want to create a helper class for handling creation of metaboxes in admin panel. I have my class declared like this:

namespace ci\wp;

Metaboxes::init();

class Metaboxes {

    private static $instance;
    private static $post;

    private static $metaboxesPath = TEMPLATEPATH . "/config/metaboxes/";

    static function init() {
        global $post;
        self::$post = &$post;
        add_action( 'add_meta_boxes', [ __CLASS__, 'addMetabox' ], 10, 5 );
    }

    // ADD METABOX
    static function addMetabox($id, $title, $post_type, $position, $priority) {
        if (file_exists(self::$metaboxesPath.$id.'.php')) {
            require_once(self::$metaboxesPath.$id.'.php');
            add_meta_box($id, $title, 'do_'.$id, $post_type, $position, $priority);
        }
    }

[...]

The problem is that when I want to use the addMetabox method, by writing \ci\wp\Metaboxes::addMetabox('front_page_slide_settings', 'Slide settings', 'page', 'normal', 'high'); I get the following error:

Fatal error: Uncaught Error: Call to undefined function ci\wp\add_meta_box() in [...]

I tried several different methods of using add_action inside the class but no matter if it's a static class, singleton with add_action run at instantiation or a normal class with add_action in constructor, it always results in the said error.

Is there a way to make it work? What am I doing wrong?

1
  • 1
    As @birgire said you are calling the function before it's defined. Every add_meta_box function call should be hooked to the add_meta_boxes hook. You can either have an array with all desired metabox settings and then run a loop through the array, inside addMetabox that is hook to add_meta_boxes hook, and call add_meta_box with the settings as input or every time you call addMetabox you add an action.
    – Laxmana
    Apr 13, 2017 at 10:56

2 Answers 2

4

You're actually calling the add_meta_box() function before it's defined, when you run this directly:

\ci\wp\Metaboxes::addMetabox(
    'front_page_slide_settings', 
    'Slide settings', 
    'page', 
    'normal', 
    'high'
);

You don't mention where you run it, but it's too early or you run it in the front-end, where add_meta_box() is not defined.

The add_meta_box() function is defined within this file:

/** WordPress Template Administration API */
require_once(ABSPATH . 'wp-admin/includes/template.php');

Make sure to run your problematic snippet afterwards, e.g. within the add_meta_boxes action, like you do within the Metaboxes::init() call.

The core init action, as an example, fires before that Template Administration API is loaded.

0

Thank you for help. I figure out exactly what I missed.

I simply forgot to wrap all calls to the addMetabox static method inside a function that is hooked to admin_init. After I did that, everything work as expected. I don't even need to hook to add_meta_boxes inside the Metaboxes class.


UPDATE: after spending some time figuring out how to quickly make other things like saving new post meta, it turned out that trying to simplify things like that using methods like that actually makes them more complicated. Adding metaboxes on admin_init hook makes it impossible to check edited post ID as at that moment the post var has no data. Lesson learned.

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.