15

One of the functions I'm using in my plugin is polluting the global scope with a name that could collide with another function (used in another plugin). So, I guess I should deprecate it. But how should I go about that?

function foo() {
    echo 'bar';
}

I'm aware of _deprecate_function() but would be grateful for an example showing all the steps I should take in order to remove the function from my plugin's core.

Ref: https://developer.wordpress.org/reference/functions/_deprecated_function/

  • Good question, but is it maybe time to namespace your plugin? You can still call the new namespace from your deprecated function... – brianlmerritt Dec 22 '15 at 14:40
  • Namespacing is an option I want to explore but not quite decided if I am to drop support for PHP 5.2 yet. – henrywright Dec 22 '15 at 14:41
  • Loading the deprecated alternative if php version is too low but namespacing otherwise might give you a transition path. Your deprecated message can then be "your hosting provider is not supporting PHP 5.3+ blah blah etc" – brianlmerritt Dec 22 '15 at 14:55
9

In addition to the answer by @Welcher:

There are some good "graveyard" examples in the core, where "functions come to die".

You could use them as guidelines, e.g. regarding the documentation.

Here's one such example for the permalink_link() under the wp-includes/deprecated.php

/**
 * Print the permalink of the current post in the loop.
 *
 * @since 0.71
 * @deprecated 1.2.0 Use the_permalink()
 * @see the_permalink()
 */
function permalink_link() {
        _deprecated_function( __FUNCTION__, '1.2', 'the_permalink()' );
        the_permalink();
}

Here's the inline documentation for the _deprecated_function function that explains the input arguments:

/**
 * Mark a function as deprecated and inform when it has been used.
 *
 * There is a hook deprecated_function_run that will be called that can be used
 * to get the backtrace up to what file and function called the deprecated
 * function.
 *
 * The current behavior is to trigger a user error if WP_DEBUG is true.
 *
 * This function is to be used in every function that is deprecated.
 *
 * @since 2.5.0
 * @access private
 *
 * @param string $function    The function that was called.
 * @param string $version     The version of WordPress that deprecated the function.
 * @param string $replacement Optional. The function that should have been called. 
 *                            Default null.
 */
  • 1
    Thanks for this. I didn't think to look at the approach taken by core! So I'm assuming these are the steps I'd need to take? 1) remove all of the original content from my function 2) add a call to _deprecated_function() 3) add a call to my new function which replaces the old one – henrywright Dec 22 '15 at 14:28
  • 1
    This sounds like a two sided problem discussed here - deprecation and possible name collision. I've only addressed the first part here according to the title of the question. – birgire Dec 22 '15 at 14:43
  • 1
    @MarkKaplun I agree that there are 2 issues going on. The question was how to deprecate the function and that's what my answer was based on. The __doing_it_wrong notice is for the developers who are calling this method in their themes etc to allow them to react to the changes in the API rather than just whitescreening the site. Log Deprecated Notices is a great dev plugin that allows you to keep up to date with core changes and would help in this case as well. – Welcher Dec 22 '15 at 18:24
  • 1
    @MarkKaplun I see your point. I would argue however that part of deprecation is to maintain backwards compatibility until the item is removed from the API. The point of the notice (no matter which method is used to generate it ) is to inform developers using the method that it will be removed and give them time to act accordingly. The way to deprecate something is to highlight and delete it, the proper way is to give users a heads up first :) – Welcher Dec 22 '15 at 20:26
  • 2
    @MarkKaplun I'm not sure what you are arguing against ( or for? ). The question was how to deprecate a method and it's clear by the fact that the OP says "my plugin" knows what deprecation means that he is a developer. The imaginary user you are talking about doesn't have anything to do with this specific question. If you're worried about getting a million notices in the log, the methods in question only output if WP_DEBUG is enabled and, to your point, that wouldn't be enabled by non-developers and certainly not in production. I'm going to respectfully just agree to disagree an move on :) – Welcher Dec 22 '15 at 21:11
7

Deprecation does not always equal being removed, it usually means that the item is marked for EVENTUAL removal from the API. Is this a method that will be called externally - as in by other plugins or developers? If this method is only ever used by the plugin internally, you can probably safely remove replace it with a better name function.

If not, I'd create the better named function and have the badly named one call it with a __doing_it_wrong call - read about it in the codex This will give other developers time to update their references to the method and you can safely remove the method in a later version.

function badly_named() {

    __doing_it_wrong( 'badly_named', 'This method has been deprecated in favor of better_named_function' );

    /**
     * Call the better named method
     */
     better_named_function();
}

Hope this helps!

  • Thanks for this but I'm thinking I should copy how core does it. Take a look at the answer by @birgire for an example – henrywright Dec 22 '15 at 18:49
  • Sounds good to me :) – Welcher Dec 22 '15 at 19:08
1

You create a new plugin and advice your users to migrate to it as the current one is EOL.

There is nothing more annoying than plugin and theme authors changing their public APIs and try to treat it as "just another small upgrade". There is no reason to break sites because of a problem your users are actually not being affected by.

  • My users would be totally affected by this if another plugin has a function with the exact same name (and isn't using namespaces). – henrywright Dec 22 '15 at 14:16
  • No, the plugin activation will fail and they will complain to you or the author of the other plugin. Total disruption time about zero. If they do need both plugins upgrading to a new one should take no more then 15 min with no interruption to the functioning of the site. What you want is that some of your users will upgrade and discover that some functionality is not working any longer without any notice. Time to fix? do you think that they have a backup at all and can fix it? – Mark Kaplun Dec 22 '15 at 14:29
  • Once you created an API you have to keep support it forever or at least untill it is totally irelevant, wordpress for example didn't actually remove any of the deprecated API since 3.4, and just adding a notice will not do you any good. – Mark Kaplun Dec 22 '15 at 14:30
  • 1
    +1 because I respect your opinion and what I enjoy about this site are the different views, approaches and solutions to problems, because usually there's not a one size that fits all. – birgire Dec 23 '15 at 9:59
1

I would suggest something like:

/**
 * @deprecated Please use good_function_name() instead
 * @since x.y.z Marked deprecated in favor of good_function_name()
 * @see good_function_name()
 */
function bad_function_name() {
    trigger_error(
        'The ' . __FUNCTION__ . ' function is deprecated. ' .
        'Please use good_function_name() instead.',
        defined( 'E_USER_DEPRECATED' ) ? E_USER_DEPRECATED : E_USER_WARNING
    );

    return good_function_name();
}

This has the effect of showing a deprecation warning in the logs along with a stack trace. Naturally this will only work if logging is enabled in WordPress.

The ternary operator is there because the E_USER_DEPRECATED constant was only introduced in PHP 5.3.0. In older versions we can fall back to a simple user warning instead.

From the PHP manual on error constants:

E_DEPRECATED Run-time notices. Enable this to receive warnings about code that will not work in future versions.

The reason I do not like to use _doing_it_wrong or __deprecated_function is that these functions are intended only for WordPress core. From the code reference on those functions:

This function’s access is marked private. This means it is not intended for use by plugin or theme developers, only in other core functions. It is listed here for completeness.

  • 1
    That's a totally valid point +1 - we can though see that plugins like Woocommerce use both functions. regardless. – birgire Jul 6 '17 at 10:09

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.