¿Cómo desaprobar una función utilizada en un complemento?

17

Una de las funciones que estoy usando en mi complemento es contaminar el alcance global con un nombre que podría colisionar con otra función (utilizada en otro complemento). Entonces, supongo que debería desaprobarlo. Pero, ¿cómo debo hacer eso?

function foo() {
    echo 'bar';
}

Estoy al tanto, _deprecate_function()pero agradecería un ejemplo que muestre todos los pasos que debo seguir para eliminar la función del núcleo de mi complemento.

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

henrywright
fuente
Buena pregunta, pero ¿quizás es hora de poner un espacio de nombres a su complemento? Todavía puede llamar al nuevo espacio de nombres desde su función obsoleta ...
brianlmerritt
El espacio de nombres es una opción que quiero explorar, pero aún no estoy decidido si dejo de admitir PHP 5.2.
henrywright
Cargar la alternativa obsoleta si la versión de php es demasiado baja, pero el espacio de nombres de lo contrario podría darle una ruta de transición. Su mensaje en desuso puede ser "su proveedor de alojamiento no es compatible con PHP 5.3+ bla, bla, etc."
brianlmerritt

Respuestas:

11

Además de la respuesta de @Welcher:

Hay algunos buenos ejemplos de " cementerio " en el núcleo, donde "las funciones vienen a morir ".

Puede usarlos como pautas, por ejemplo, con respecto a la documentación.

Aquí hay un ejemplo de esto permalink_link()debajo dewp-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();
}

Aquí está la documentación en línea para la _deprecated_functionfunción que explica los argumentos de entrada:

/**
 * 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.
 */
Birgire
fuente
1
Gracias por esto. ¡No pensé en mirar el enfoque adoptado por core! ¿Así que supongo que estos son los pasos que debería seguir? 1) eliminar todo el contenido original de mi función 2) agregar una llamada a _deprecated_function()3) agregar una llamada a mi nueva función que reemplaza la anterior
henrywright
1
Esto suena como un problema de dos lados discutido aquí: desaprobación y posible colisión de nombres. Solo he abordado la primera parte aquí según el título de la pregunta.
Birgire
1
@ MarkKaplun Estoy de acuerdo en que hay 2 problemas en curso. La pregunta era cómo desaprobar la función y en eso se basaba mi respuesta. El aviso __doing_it_wrong es para los desarrolladores que llaman a este método en sus temas, etc., para permitirles reaccionar a los cambios en la API en lugar de simplemente analizar el sitio. Los avisos obsoletos de registro son un excelente complemento de desarrollo que le permite mantenerse al día con los cambios principales y también ayudaría en este caso.
Welcher
1
@ MarkKaplun veo tu punto. Sin embargo, argumentaría que parte de la degradación es mantener la compatibilidad con versiones anteriores hasta que el elemento se elimine de la API. El objetivo del aviso (sin importar qué método se use para generarlo) es informar a los desarrolladores que usan el método que se eliminará y darles tiempo para actuar en consecuencia. La forma de desaprobar algo es resaltarlo y eliminarlo, la forma correcta es darles a los usuarios un aviso primero :)
Welcher
2
@ MarkKaplun No estoy seguro de lo que estás argumentando (¿o por qué?). La pregunta era cómo desaprobar un método y está claro por el hecho de que el OP dice "mi plugin" sabe qué desaprobación significa que él es un desarrollador. El usuario imaginario del que estás hablando no tiene nada que ver con esta pregunta específica. Si le preocupa recibir un millón de avisos en el registro, los métodos en cuestión solo se mostrarán si WP_DEBUG está habilitado y, hasta su punto, eso no lo habilitarían los que no son desarrolladores y ciertamente no están en producción. Respetuosamente solo estaré de acuerdo en no estar de acuerdo con seguir adelante :)
Welcher
7

La desaprobación no siempre equivale a ser eliminado, por lo general significa que el elemento está marcado para su eliminación EVENTUAL de la API. ¿Es este un método que se llamará externamente, como lo hacen otros complementos o desarrolladores? Si este método solo es utilizado internamente por el complemento, probablemente pueda eliminarlo con seguridad y reemplazarlo con una mejor función de nombre.

De lo contrario, crearía la función mejor nombrada y la llamaría mal con una __doing_it_wrongllamada; lea sobre esto en el códice Esto les dará tiempo a otros desarrolladores para actualizar sus referencias al método y puede eliminarlo de manera segura en Una versión posterior.

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

¡Espero que esto ayude!

Welcher
fuente
Gracias por esto, pero estoy pensando que debería copiar cómo lo hace Core. Eche un vistazo a la respuesta de @birgire para ver un ejemplo
henrywright
Suena bien para mí :)
Welcher
1

Crea un nuevo complemento y aconseja a sus usuarios que migren a él, ya que el actual es EOL.

No hay nada más molesto que los autores de plugins y temas que cambian sus API públicas e intentan tratarlo como "solo otra pequeña actualización". No hay razón para romper sitios debido a un problema por el cual sus usuarios no se ven afectados.

Mark Kaplun
fuente
Esto afectaría totalmente a mis usuarios si otro plugin tiene una función con el mismo nombre (y no usa espacios de nombres).
henrywright
No, la activación del complemento fallará y se quejarán ante usted o el autor del otro complemento. Tiempo total de interrupción de aproximadamente cero. Si necesitan que ambos complementos se actualicen a uno nuevo, no debería llevar más de 15 minutos sin interrumpir el funcionamiento del sitio. Lo que desea es que algunos de sus usuarios se actualicen y descubran que algunas funcionalidades ya no funcionan sin previo aviso. ¿Hora de arreglar? ¿Crees que tienen una copia de seguridad y pueden solucionarlo?
Mark Kaplun
Una vez que haya creado una API, debe mantener su soporte para siempre o al menos hasta que sea totalmente irrelevante, por ejemplo, WordPress no eliminó ninguna de las API obsoletas desde 3.4, y solo agregar un aviso no le servirá de nada.
Mark Kaplun
1
+1 porque respeto tu opinión y lo que disfruto de este sitio son las diferentes opiniones, enfoques y soluciones a los problemas, porque generalmente no hay una talla única para todos.
Birgire
1

Sugeriría algo como:

/**
 * @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();
}

Esto tiene el efecto de mostrar una advertencia de desuso en los registros junto con un seguimiento de la pila. Naturalmente, esto solo funcionará si el registro está habilitado en WordPress.

El operador ternario está allí porque la constante E_USER_DEPRECATED solo se introdujo en PHP 5.3.0. En versiones anteriores, podemos recurrir a una simple advertencia de usuario.

Del manual de PHP sobre constantes de error :

E_DEPRECATED Avisos de tiempo de ejecución. Habilite esto para recibir advertencias sobre el código que no funcionará en futuras versiones.

La razón por la que no me gusta usar _doing_it_wrong o __deprecated_function es que estas funciones están destinadas solo al núcleo de WordPress. De la referencia del código en esas funciones:

El acceso de esta función está marcado como privado. Esto significa que no está destinado a ser utilizado por desarrolladores de plugins o temas, solo en otras funciones principales. Se enumera aquí para completar.

alexg
fuente
1
Ese es un punto totalmente válido +1, aunque podemos ver que los complementos como Woocommerce usan ambas funciones . independientemente.
birgire