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

10

Я разрабатываю плагин для Wordpress Woocommerce. В моем локальном окружении все работает нормально, но у меня возникают проблемы при добавлении плагина в реплику среды prod. Я новичок в 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

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

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

znat
источник

Ответы:

10

Вы должны проверить, существует ли класс, но перед этим вы должны дождаться загрузки всех плагинов: никто не может гарантировать, что ваш плагин загружен после 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);
    // some code here
  } else {
    add_action('admin_notices', 'wc_not_loaded');
  }
}

function wc_not_loaded() {
    printf(
      '<div class="error"><p>%s</p></div>',
      __('Sorry cannot create coupon because WooCommerce is not loaded')
    );
}
Gmazzap
источник
Не уверен, что в этом случае plugins_loadedправильный крюк. Нужно будет искать, когда именно этот класс будет доступен, и подключиться после этого. В любом случае +1
кайзер
В этом конкретном случае я цепляюсь за крючок деактивации register_deactivation_hook( __FILE__, 'deactivate');. Так что я не могу ждать. Могу ли я попросить WordPress загрузить класс, если он еще не загружен?
Знат
2
Спасибо @kaiser. WC_CouponЗагружаются __constructиз основного WooCommerceкласса ( на самом деле по includes()методе непосредственно наречено __construct) и WooCommerceклассом instanziate (как одноточечные) , как только загружается плагин. Так что plugins_loadedэто правильный крючок в этом случае;)
gmazzap
Аноним перед загрузкой ядра? Молодцы Ву, молодцы.
Кайзер
@NathanZ Проверить class_exists( 'WC_Coupon' ). Также, пожалуйста, укажите, что вы используете это во время деактивации ... могли бы сэкономить на
ответных толпах кучу
6

Это слишком поздно, но я хотел бы поделиться тем, как использовать woocommerce и его классы, не найдя класс ошибок.

Сначала нужно проверить, установлен ли woocommerce, и использовать woocommerce_loadedловушку действий.

/**
 * Check if WooCommerce is active
 **/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
    // Put your plugin code here

    add_action('woocommerce_loaded' , function (){
         //Put your code here that needs any woocommerce class 
         //You can also Instantiate your main plugin file here 
    });

}

Я надеюсь, что это помогает кому-то.

Джеймсварт Лопес
источник
3

Правильный путь будет:

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

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

Вы не можете переопределить класс, который не разрешен в PHP.

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

class My_WC_Coupon extends WC_Coupon {
   //some code
   //some hook
}

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

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