¿Cómo usar clases declaradas en otro plugin?
Estoy desarrollando un plugin para WordPress WooCommerce. En mi entorno local funciona bien pero tengo problemas al añadir el plugin a una réplica del entorno de producción. Soy nuevo en WordPress y no estoy muy familiarizado con el desarrollo web (soy programador Java).
En el archivo del plugin, instancio una clase del paquete del plugin WooCommerce de esta manera:
$coupon = new WC_Coupon($some_code);
En el entorno local (php 5.4.10, WooCommerce 2.0.13, WordPress 3.6) funciona bien. En el entorno de producción (php 5.4.10, WooCommerce 1.6.5.2, WordPress 3.4.2) tengo el siguiente error:
Fatal error: Class 'WC_Coupon' not found
// Error fatal: Clase 'WC_Coupon' no encontrada
He intentado incluir el archivo donde está definida la clase WC_Coupon pero entonces el error se convierte en:
Fatal error: Cannot redeclare class WC_Coupon
// Error fatal: No se puede redeclarar la clase WC_Coupon
Entonces, ¿cuál es la forma correcta de usar clases declaradas en otro plugin?
Nota: actualizar no es una opción en este momento.
Debes verificar si la clase existe, pero antes tienes que esperar a que todos los plugins estén cargados: nadie puede asegurar que tu plugin se cargue después de WooCommerce.
Para ejecutar código desde un plugin cuando todos los plugins estén cargados, engancha el hook plugins_loaded
.
Ten en cuenta que no puedes usar este hook en un tema, porque cuando el tema se carga, ese hook ya se ha ejecutado.
add_action('plugins_loaded', 'my_coupon_init');
function my_coupon_init() {
if ( class_exists('WC_Coupon') ) {
$coupon = new WC_Coupon($some_code);
// algún código aquí
} else {
add_action('admin_notices', 'wc_not_loaded');
}
}
function wc_not_loaded() {
printf(
'<div class="error"><p>%s</p></div>',
__('Lo siento, no se puede crear el cupón porque WooCommerce no está cargado')
);
}

No estoy seguro si en ese caso plugins_loaded
es el hook adecuado. Habría que buscar exactamente cuándo está disponible esa clase y engancharse después de eso. De cualquier forma +1

En este caso particular, me estoy enganchando al hook de desactivación register_deactivation_hook( __FILE__, 'deactivate');
. Así que no puedo esperar. ¿Puedo pedirle a WordPress que cargue la clase si aún no está cargada?

Gracias @kaiser. La clase WC_Coupon
es cargada por el __construct
de la clase principal WooCommerce
(realmente por el método includes()
llamado directamente por __construct
) y la clase WooCommerce
se instancia (como singleton) tan pronto como se carga el plugin. Así que plugins_loaded
es el hook adecuado en este caso ;)

Es demasiado tarde, pero me gustaría compartir cómo usar WooCommerce y sus clases sin tener el error de clase no encontrada.
Lo primero es verificar si WooCommerce está instalado y usar el hook de acción woocommerce_loaded
.
/**
* Verificar si WooCommerce está activo
**/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
// Coloca aquí el código de tu plugin
add_action('woocommerce_loaded' , function (){
//Coloca aquí tu código que necesite cualquier clase de WooCommerce
//También puedes instanciar tu archivo principal del plugin aquí
});
}
Espero que esto ayude a alguien.

La forma correcta sería:
if( class_exists('WC_Coupon') ) $coupon = new WC_Coupon($some_code);
Es mejor verificar si la clase existe antes de usarla, esto evita errores fatales si el plugin está desactivado.
No puedes redeclarar una clase, no está permitido en PHP.
También puedes extender la clase:
class My_WC_Coupon extends WC_Coupon {
//algún código
//algún hook
}
Pero la mayoría de las veces, y en este caso con WooCommerce, es mejor buscar un hook en la documentación que maneje el trabajo.

Un encabezado "Requires Plugins" fue añadido en 2024, Introduciendo Dependencias de Plugins en WordPress 6.5
/**
* Plugin Name: Pasarela de Pago Express para Tienda
* Requires Plugins: shop, payment-gateway
*/
Esto permite que un plugin dependa de otro plugin para ser activado. El orden de carga sigue siendo una preocupación, y otras respuestas tienen soluciones que esperan a que todos los plugins se carguen y verifican adicionalmente si las clases esperadas existen.
