14

I decided to namespace my plugin, and I got it all to work, except in my main plugin file.

I added two actions in that plugin, before calling the init method of the plugin.

<?php
namespace myPlugin;

add_action( 'admin_init', 'add_activation_notice' );

function add_activation_notice() {
    add_action( 'admin_notices', 'activation_notice' );
}

function activation_notice() {
    echo 'Notice!';
}

But this throws error

Uncaught Error: Undefined constant 'myPlugin\myPlugin\add_activation_notice'

I'm rather new to namespacing, so I don't know why this happens.

The two functions add_activation_notice and activation_notice are in the myPlugin namespace. Most of the code I found online reference methods inside classes, but I need these to be outside of a class so that I can have plugin activation notice.

EDIT:

When I try with

add_action( 'admin_init', \add_activation_notice() );

I get

Fatal error: Uncaught Error: Call to undefined function add_activation_notice()

2 Answers 2

29

Before going too far down this path I would suggest that you familiarize yourself with PHP name resolution rules.

To answer your actual question -

When you namespace functions, the fully qualified name of those functions includes the namespace.

In your example, you have defined two functions: \myPlugin\add_activation_notice and \myPlugin\activation_notice.

When calling either of these from within the myPlugin namespace, you can use the unqualified name (i.e. activation_notice()) but outside of the myPlugin namespace you have to follow the name resolution rules linked above.

In the case of add_action() - while this is called from within your myPlugin namespace, you are not passing the actual function but rather the function name as a string. WordPress later attempts to call that function from the global namespace.

The solution to your problem should be to include the myPlugin namespace in the function name passed to add_action (pay special attention to the escaped backslash):

add_action( 'admin_init', 'myPlugin\\add_activation_notice' );
add_action( 'admin_notice', 'myPlugin\\activation_notice' );

My preferred method of doing this would be by concatenating the __NAMESPACE__ magic constant which simplifies things slightly if you should you ever decide to change your namespaces:

add_action( 'admin_init', __NAMESPACE__ . '\\add_activation_notice' );
add_action( 'admin_notice', __NAMESPACE__ . '\\activation_notice' );
2
  • In my updated answer I've used your suggested __NAMESPACE__ method. Commented Nov 3, 2017 at 17:02
  • 1
    I'll try this, I didn't try with escaped backshlash. Thanks
    – dingo_d
    Commented Nov 3, 2017 at 18:33
3

The easiest way would be to enclose your code in curly brackets:

namespace myPlugin {

    add_action( 'admin_init', __NAMESPACE__ . '\\add_activation_notice' );

    function add_activation_notice() {
        add_action( 'admin_notice', __NAMESPACE__ . '\\activation_notice' );
    }

    function activation_notice() {
        echo 'Notice!';
    }
}

Otherwise, your action will look for activation_notice function in a global namespace.

Update

There is no admin_notice hook. Use admin_notices instead. Try:

namespace myPlugin {
    add_action( 'admin_init', __NAMESPACE__ . '\\add_activation_notice');

    function add_activation_notice() {
        add_action( 'admin_notices', __NAMESPACE__ . '\\activation_notice' );
    }

    function activation_notice() {
    ?>
        <div class="notice notice-info is-dismissible">
            <p><?php echo 'Done!'; ?></p>
        </div>
    <?php
    }
}
3
  • With this I get: ` Warning: call_user_func_array() expects parameter 1 to be a valid callback, function 'add_activation_notice' not found or invalid function name`
    – dingo_d
    Commented Nov 3, 2017 at 15:17
  • Read my updated answer. Commented Nov 3, 2017 at 16:57
  • admin_notice was probably a typo :D I had the code without namespacing and it worked, so it's 99% a typo :)
    – dingo_d
    Commented Nov 3, 2017 at 18:34

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.