Question

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()

Was it helpful?

Solution

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' );

OTHER TIPS

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
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top