1

I'm trying to figure out how to redeclare a theme's function from within a plugin. The problem is that I'm getting a "Fatal error: Cannot redeclare" when trying to activate the plugin. But if I add the code to already activated plugin - everything is working as expected. Is there something obvious that I'm missing?

Here's a simplified example of the code I'm using:

// In my theme I use function_exists check
if ( ! function_exists( 'my_awesome_function' ) ) {
    function my_awesome_function() {
        return "theme";
    }
}

// Now I want to override 'my_awesome_function' output in a plugin
function my_awesome_function() {
    return "plugin";
}

EDIT:

In the given example I need my_awesome_function() to return plugin if the plugin is active and theme otherwise. So I need to keep the original function in the theme.

Basically, I thought that if such approach works for child themes, it should work for plugins too. But obviously, I was wrong.

1

You can only declare a function once.

My reccomendation is that you put the functions in the plugin, then use filters to override in the theme, e.g.

In the plugins:

function my_awesome_function() {
    return apply_filters( 'my_awesome_function', "plugin" );
}

In your theme:

add_filter( 'my_awesome_function', function( $value ) {
    return "theme";
} );

Now every call to my_awesome_function(); will return "theme" not "plugin"

  • Ah, so that appears to be a completely different problem than what you asked about, your edit completely changes the question, you should have asked "How can I tell if a plugin is loaded?" and I'd recommend you do exactly that – Tom J Nowell Oct 19 '16 at 11:57
  • This doesn't solve a problem with a plugin (unlike child theme's functions.php) being unable to override pluggable function from theme. Imagine you are a plugin author who wants to replace pluggable function and can't modify someone else's theme. – Ryszard Jędraszyk May 28 at 16:26
1

1) if you write a theme don't eve use function_exists, use proper filter instead.

2) Your problem comes from different order of execution when activating a plugin. Usually the plugin is included before the theme, but in that case it is included after the theme

The proper way to write your plugin code is

if ( ! function_exists( 'my_awesome_function' ) ) {
    function my_awesome_function() {
        return "plugin";
    }
}
  • Very clear explanation, exactly what OP asked for and works in 2019 :) – Ryszard Jędraszyk May 28 at 16:34
0

When the function is loading, the second function is not yet called. So the function_exist check for a function that has not been registered yet. When the second one is loading the first one has been already called and then exist and create the fatal error.

If your awesome function without the function_exists is in a child theme or a plugin file, I think you better invert function_exists check for the second one.

0

I think you should wrap it in a hook. There are different execution times for different things in themes and plugins. If you hook into the right hook your code get executed before the functions of the theme is loaded. For a list of the hooks, check the codex:

https://codex.wordpress.org/Plugin_API/Action_Reference

Find the appropiate one that works for you. If the theme has it all wrapped in "function_exists" then that should work.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.