¿Cómo hacer que se requiera un complemento en un tema de wp sin usar declaraciones condicionales de php cuando se llama a una función individual desde ese complemento?

9

Uno de mis temas de Wordpress requiere algunos complementos de terceros para ejecutarse correctamente.

La mayoría de las veces solía llamar a funciones desde complementos de terceros usando declaraciones condicionales como

    if(function_exist('plugin_function')) {
             plugin_function() // do something
    }

aunque supongo que necesito usar mucho un complemento a través de muchos archivos de mi tema ... Me gustaría evitar el uso de muchas condiciones IF ... ¿hay una manera adecuada de requerir que se instale cierto complemento específico en WP o incluso mejor instalarlos? si faltan antes de activar el tema?

Gracias

unfulvio
fuente

Respuestas:

7

is_plugin_active()es bastante frágil: se romperá cuando el autor del complemento cambie el nombre del archivo principal o cuando el usuario cambie el nombre del directorio del complemento o el archivo principal. Es mejor verificar si existe cierta función pública.

Para evitar tener que hacer esa verificación cada vez que necesite algo de la funcionalidad del complemento, puede mostrar un mensaje en el área de administración:

add_action( 'admin_notices', 'my_theme_dependencies' );

function my_theme_dependencies() {
  if( ! function_exists('plugin_function') )
    echo '<div class="error"><p>' . __( 'Warning: The theme needs Plugin X to function', 'my-theme' ) . '</p></div>';
}

Otra alternativa es usar algo como http://tgmpluginactivation.com/

scribu
fuente
Si el autor del complemento cambia el nombre de una función con la que cuestiona function_exists, entonces un usuario normal simplemente recibirá el mensaje de que no ha instalado el complemento en el que se basa otro complemento. El problema es que el usuario realmente tendrá el complemento instalado y luego se preguntará por qué no funciona . Ah, y no voy a rechazarte por eso.
kaiser
Si te interesan los votos, entonces debes votar la Q en sí, ya que es buena.
Kaiser
Si el autor del complemento cambia el nombre de la función, recibirá quejas de muchos más usuarios que si cambiara el nombre del archivo.
scribu
Y rechacé su respuesta porque no abordaba la pregunta, OMI. ¿O preferiría que votara en secreto, sin ninguna explicación ofrecida?
scribu
Estaba hablando del voto negativo, no del comentario. El comentario en sí está bien, ya que este tema es algo que necesita discusión. Agregaré otra respuesta ya que mis pensamientos detrás de eso excederán la longitud de los comentarios. Simplemente edite la respuesta, para que podamos mantener los resultados de la discusión en las revisiones para que todos los sigan. Gracias.
Kaiser
1

Si bien esto no evitaría que el tema se rompa cuando el complemento esté deshabilitado, miraría este elegante artículo sobre el complemento "Cómo mostrar un aviso de administrador para temas requeridos" . Nunca me he sentido cómodo con la idea de un tema que obligue a instalar un complemento, por lo que esta parece ser la siguiente mejor opción.

Otro pensamiento rápido: nunca he intentado esto, pero me pregunto si podrías encontrar una forma inteligente de alojar múltiples ganchos en un solo condicional. Tal vez podría separar todas las funciones condicionales en un archivo diferente y solo requerirlo si se if( function_exists( 'plugin_function' ) )devuelve true(con el entendimiento de que esta es una verificación imperfecta.

mrwweb
fuente
0

Si solo necesita una página de complemento, entonces hay is_plugin_active(). Si lo necesita fuera, es mejor que copie / pegue la función principal en su tema y luego vuelva a usarlo:

if ( ! is_admin() )
{
/**
 * Check whether the plugin is active by checking the active_plugins list.
 *
 * @since 2.5.0
 *
 * @param string $plugin Base plugin path from plugins directory.
 * @return bool True, if in the active plugins list. False, not in the list.
 */
function is_plugin_active( $plugin ) {
    return in_array( $plugin, (array) get_option( 'active_plugins', array() ) ) || is_plugin_active_for_network( $plugin );
}
}

El condicional evita cualquier error con doble definición de la función.

emperador
fuente
Eso realmente no responde la pregunta. Simplemente reemplaza if(function_exist('plugin_function'))conif(is_plugin_active('plugin-file.php'))
scribu
0

Nota: Esta respuesta está aquí solo para facilitar la discusión entre @scribu y @kaiser. Mods: por favor no elimines. Usuarios / lectores: por favor no vote. Si desea seguir la discusión, eche un vistazo al registro de revisión / edición. Si desea unirse a la discusión, edite la Respuesta. Si la discusión tiene un resultado, se marcará como tal. Gracias.


Escenarios

También hay diferentes escenarios que tienen un peso diferente, donde podría tener una dependencia de complemento. (Los ejemplos son solo ficticios). La palabra "Plugin (principal)" se puede intercambiar con "Tema" desde el punto de vista principal.

  1. (hard) Un complemento secundario que solo extiende la funcionalidad o altera la visualización (y similar) de un complemento existente y, por lo tanto, no puede existir sin el principal. Ejemplo: BuddyPress »BuddyPress-FunkyCommentDisplay
  2. (normal) Un complemento que tiene una funcionalidad extendida cuando se activa un complemento secundario. Ejemplo: jQueryAttachmentCarousel »jQuerySlideDeck
  3. (suave) Un complemento que solo agrega una función. Ejemplo: DisneyWonderlandTheme »MickeysSocialLinks

A continuación, trato de esbozar lo que sucede cuando actualizas el complemento "otro" y la comprobación ya no funciona.

  • Anuncio 1) El complemento no podría existir sin BuddyPress activado »Las cosas están completamente rotas.
  • Anuncio 2) El complemento no podía ofrecer la opción de cambiar de Carrusel a SlideDeck »Pantallas cableadas (supongo que los estilos se modifican a SlideDeck).
  • Anuncio 3) MickeysSocialLinks desaparecen.

Cheque

En mi opinión, existen tres posibilidades de verificación, si desea saber si un complemento está activo:

  • A. ¿Existe la carpeta?
  • B. ¿Existe el archivo principal - opción 'active_plugins'-?
  • C. ¿Existe una función particular?

Si ahora tomo mi complemento de Comprobador de enlaces internos como un ejemplo, que no ofrece API pública y no está destinado a extenderse, entonces no vería ninguna razón (como autor) para no cambiar el nombre de la función interna a pedido o solo por voluntad . Entonces, si alguien intentara aprovechar este complemento, entonces las cosas simplemente se romperían (dependiendo de la funcionalidad y la rigidez de la agrupación) en la actualización. Lo mismo ocurre con los nombres de archivo. No tendría ninguna razón real (aparte de eso, el complemento se desactivaría en la actualización) para no cambiar el nombre del archivo. Lo único que me detendría de cambiar el nombre de la carpeta es que la verificación y notificación de actualización se ejecuta contra el nombre del archivo, si está alojado en el repositorio oficial.

Entonces, diría que la parte más débil (fácil de cambiar) a la más difícil (se habla mucho de cambiar) de un complemento (principal) sería:

función »nombre del archivo principal» carpeta


Cuando dije que una verificación de función es menos frágil que usar is_plugin_active(), supuse que la función en cuestión es una que el autor del complemento alienta explícitamente. El último ejemplo de esto sería la wp_pagenavi()etiqueta de plantilla que ofrece el complemento WP-PageNavi.

La dificultad para definir dependencias es que no hay una forma estándar de identificar de manera exclusiva los complementos que no involucran nombres de archivos.

Más pensamientos sobre el tema:

http://wordpress.org/support/topic/plugin-plugin-dependencies-unreliable-plugin-namingidentifying-scheme


Creo que hasta ahora podemos resumirlo en tres puntos:

  • Hemos hablado de temas ligeramente diferentes.
  • Estamos de acuerdo en que no hay una forma a prueba de balas para evitar lo que pensé que sería el tema
  • Desde su comprensión de la pregunta, ofreció un camino válido

La forma (hasta ahora) más inteligente que puedo pensar, que ya he visto en algunos complementos (mucho menos):

// inside the plugin file:
add_action( 'plugin_custom_hook', 'plugin_trigger' );
// inside some template:
do_action( 'plugin_custom_hook' );

Sin pensarlo demasiado en detalle, pero supongo que podría conectar su aviso a una verificación en el filtro 'todos' y verificar dentro del filtro actual si se activó cuando está en el shutdowngancho ...?


Usar ganchos funcionaría bien para dependencias 'normales' y 'débiles'. El único inconveniente es que aún necesitaría usar function_exists()o is_plugin_active()si desea detener si no se cumple la dependencia. Usar el filtro 'todos' para eso sería una OMI demasiado costosa.

@scibu Esto estaba dirigido a "su" tema. (Ya dejé de hablar sobre el mío). :)

Básicamente, si necesita una dependencia, y tiene un buen autor, entonces podría ofrecerle un gancho en lugar de una etiqueta de plantilla. Porque el complemento solo se engancharía si el gancho estuviera presente, o simplemente no haría nada. Y, por otro lado, no tendría un error, cuando los complementos no están presentes.

Aquí está la parte difícil (o más de una Q): Para escribir un aviso de administrador para informar al usuario sobre la dependencia "Debe instalar» DisneyWonderLinks «", puede verificar el array_keys( $GLOBALS['wp_filter']['template_tag_like_hook'] ). No estoy seguro de si esto funcionaría, pero afaik la matriz debería ser accesible en ambos lados (público / administrador).


Eso no funcionaría. El hecho de que una devolución de llamada esté registrada en un enlace no significa que el enlace se activará cuando se espera. Lo único que sería una especie de tipo de trabajo es usar el gancho de "apagado", que mencionó antes:

add_action( 'shutdown', function() {
  if ( !did_action( 'template_tag_like_hook' ) )
    echo 'Problem.';
} );

Por supuesto, esto se imprimiría en la parte inferior, después de la </html>etiqueta, en la parte frontal (ya que allí es donde normalmente se usan las etiquetas de plantilla), lo que no es de mucha utilidad.

Podría intentar almacenar el mensaje en wp_options y luego mostrarlo en el área de administración, pero eso abriría una nueva lata de gusanos: invalidación, almacenamiento en caché de complementos, etc.

emperador
fuente
Para el registro, esta es una forma poco ortodoxa de usar la funcionalidad del sitio. Me recuerda a c2.com/cgi/wiki
scribu
Sí lo es. Pero no tenía idea de cómo podríamos continuar la discusión sin ocultarlo a los lectores posteriores.
kaiser
No me daría cuenta de que publicar la pregunta habría generado una gran discusión :) Pero es realmente interesante y les agradezco a ambos por su esfuerzo y tiempo para dar consejos y proporcionar un debate reflexivo. Creo que el consejo de scribu (uno de los muchos que hay) para usar la clase de activación TGM podría ofrecer una solución a mi respuesta, al menos desde un punto de vista meramente práctico, lo investigaré. Sin embargo, todavía estoy pendiente de toda la discusión porque también otros métodos propuestos tienen sentido en ciertos escenarios y es muy interesante para mí leerlos, ¡gracias!
unfulvio