Как использовать классы, объявленные в другом плагине?

19 авг. 2013 г., 15:46:14
Просмотры: 34.7K
Голосов: 12

Я разрабатываю плагин для WordPress Woocommerce. В локальной среде он работает нормально, но возникают проблемы при добавлении плагина в копию продакшн-среды. Я новичок в WordPress и не очень знаком с веб-разработкой (я Java программист).

В файле плагина я создаю экземпляр класса из пакета плагина Woocommerce следующим образом:

$coupon = new WC_Coupon($some_code);

В локальной среде (php 5.4.10, Woocommerce 2.0.13, Wordpress 3.6) всё работает нормально. В продакшн-среде (php 5.4.10, Woocommerce 1.6.5.2, Wordpress 3.4.2) возникает следующая ошибка:

Fatal error: Class 'WC_Coupon' not found

Я пытался подключить файл, где определен класс WC_Coupon, но тогда ошибка становится следующей:

Fatal error: Cannot redeclare class WC_Coupon

Так какой правильный способ использования классов, объявленных в другом плагине?

Примечание: обновление на данный момент не является возможным вариантом.

0
Все ответы на вопрос 4
5
11

Вам нужно проверить существование класса, но перед этим необходимо дождаться загрузки всех плагинов: никто не может гарантировать, что ваш плагин загрузится после WooCommerce.

Для выполнения кода из плагина после загрузки всех плагинов используйте хук plugins_loaded.

Обратите внимание, что этот хук нельзя использовать в теме, потому что к моменту загрузки темы этот хук уже сработал.

add_action('plugins_loaded', 'my_coupon_init');

function my_coupon_init() {
  if ( class_exists('WC_Coupon') ) {
    $coupon = new WC_Coupon($some_code);
    // какой-то код здесь
  } else {
    add_action('admin_notices', 'wc_not_loaded');
  }
}

function wc_not_loaded() {
    printf(
      '<div class="error"><p>%s</p></div>',
      __('Извините, невозможно создать купон, потому что WooCommerce не загружен')
    );
}
19 авг. 2013 г. 16:24:46
Комментарии

Не уверен, что в этом случае plugins_loaded - это правильный хук. Нужно выяснить, когда именно этот класс становится доступен, и подключиться после этого. В любом случае +1

kaiser kaiser
19 авг. 2013 г. 16:48:53

В данном конкретном случае я подключаюсь к хуку деактивации register_deactivation_hook( __FILE__, 'deactivate');. Так что ждать я не могу. Могу ли я попросить WordPress загрузить класс, если он ещё не загружен?

znat znat
19 авг. 2013 г. 17:01:04

Спасибо, @kaiser. Класс WC_Coupon загружается через __construct главного класса WooCommerce (фактически через метод includes(), вызываемый непосредственно из __construct), а класс WooCommerce создаётся (как синглтон) сразу после загрузки плагина. Так что plugins_loaded в этом случае действительно подходящий хук ;)

gmazzap gmazzap
19 авг. 2013 г. 17:28:31

Анонимность до загрузки ядра? Хорошая работа, Woo, хорошая работа.

kaiser kaiser
19 авг. 2013 г. 17:45:42

@NathanZ Проверьте class_exists( 'WC_Coupon' ). И укажите, пожалуйста, что вы используете это во время деактивации... могло бы сэкономить кучу времени отвечающим...

kaiser kaiser
19 авг. 2013 г. 17:46:31
0

Это уже поздно, но я хотел бы поделиться, как использовать WooCommerce и его классы без ошибки "class not found".

Первое - проверить, установлен ли WooCommerce, и использовать хук действия woocommerce_loaded.

/**
 * Проверяем, активен ли WooCommerce
 **/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
    // Поместите сюда код вашего плагина

    add_action('woocommerce_loaded' , function (){
         //Поместите сюда код, который требует каких-либо классов WooCommerce 
         //Вы также можете инициализировать здесь основной файл вашего плагина 
    });

}

Надеюсь, это кому-то поможет.

15 апр. 2016 г. 18:31:54
1

Правильный способ будет следующим:

if( class_exists('WC_Coupon') ) $coupon = new WC_Coupon($some_code);

Лучше проверять, существует ли класс, перед его использованием, это позволяет избежать фатальной ошибки, если плагин отключен.

Вы не можете переопределить класс - это запрещено в PHP.

Вы также можете расширить класс:

class My_WC_Coupon extends WC_Coupon {
   //код
   //хук
}

Но в большинстве случаев, и в данном случае с WooCommerce, лучше найти подходящий хук в документации, который выполнит нужную задачу.

19 авг. 2013 г. 16:06:58
Комментарии

Если вы расширяете свой класс через хук, разве новый класс не будет существовать только в области видимости функции хука?

alexg alexg
29 дек. 2015 г. 20:05:59
0

Заголовок "Requires Plugins" был добавлен в 2024 году, Введение зависимостей плагинов в WordPress 6.5

/**
 * Plugin Name: Экспресс-платежный шлюз для магазина
 * Requires Plugins: shop, payment-gateway
 */

Это позволяет плагину зависеть от другого плагина, который должен быть активирован. Порядок загрузки по-прежнему имеет значение, и другие ответы содержат решения, которые ожидают загрузки всех плагинов и дополнительно проверяют наличие ожидаемых классов.

15 сент. 2024 г. 08:05:58