Jak korzystać z klas zadeklarowanych w innej wtyczce?

10

Tworzę wtyczkę Wordpress Woocommerce. W moim lokalnym środowisku działa dobrze, ale mam problemy z dodaniem wtyczki do repliki środowiska prod. Jestem nowym użytkownikiem wordpress i nie znam się na web dev (jestem programistą Java).

W pliku wtyczki tworzę instancję klasy z pakietu wtyczek Woocommerce w następujący sposób:

$coupon = new WC_Coupon($some_code);

W środowisku lokalnym (php 5.4.10, Woocommerce 2.0.13, Wordpress 3.6) jest w porządku. W środowisku produkcyjnym (php 5.4.10, Woocommerce 1.6.5.2, Wordpress 3.4.2) mam następujący błąd:

Fatal error: Class 'WC_Coupon' not found

Próbowałem dołączyć plik, w którym zdefiniowano klasę WC_Coupon, ale wtedy pojawia się błąd

Fatal error: Cannot redeclare class WC_Coupon

Jaki jest właściwy sposób używania klas zadeklarowanych w innej wtyczce?

Uwaga: aktualizacja nie jest obecnie opcją.

znat
źródło

Odpowiedzi:

10

Musisz sprawdzić, czy klasa istnieje, ale wcześniej musisz poczekać , wszystkie wtyczki zostaną załadowane: nikt nie może zagwarantować, że wtyczka zostanie załadowana po WooCommerce.

Do uruchomienia kodu z wtyczki, gdy wszystkie wtyczki są załadowane zaczep do plugins_loadedzaczepu.

Należy pamiętać, że nie można użyć tego haka w motywie, ponieważ podczas ładowania motywu ten hak był już uruchomiony.

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
źródło
Nie jestem pewien, czy w takim przypadku plugins_loadedjest odpowiedni hak. Trzeba będzie sprawdzić, kiedy dokładnie ta klasa jest dostępna, i po niej podłączyć . W każdym razie +1
kaiser
W tym konkretnym przypadku zaczepiam się o hak dezaktywacyjny register_deactivation_hook( __FILE__, 'deactivate');. Więc nie mogę się doczekać. Czy mogę poprosić wordpress o załadowanie klasy, jeśli jeszcze nie jest załadowana?
znat
2
Dzięki @kaiser. WC_CouponJest ładowany przez __constructgłównego WooCommerceklasy (naprawdę przez includes()metody bezpośrednio wzywano __construct) i WooCommerceklasy jest instanziate (jako pojedyncza) tak szybko, jak wtyczka jest załadowany. Tak plugins_loadedjest w tym przypadku właściwy hak;)
gmazzap
Anonimowy przed ładowaniem rdzenia? Dobra robota Woo, dobra robota.
kaiser
@NathanZ Check class_exists( 'WC_Coupon' ). Proszę również powiedzieć, że używasz tego podczas dezaktywacji ... mógł zaoszczędzić mnóstwo czasu na odpowiadanie tłumowi ...
Kaiser
6

Jest już za późno, ale chciałbym podzielić się tym, jak korzystać z woocommerce i jego klas bez znalezienia klasy błędu.

Najpierw sprawdź, czy woocommerce jest zainstalowany i użyj woocommerce_loadedhaka akcji.

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

}

Mam nadzieję, że to komuś pomoże.

Jameshwart Lopez
źródło
3

Właściwy sposób to:

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

Lepiej sprawdzić, czy klasa istnieje przed jej użyciem, pozwala uniknąć błędu krytycznego, jeśli wtyczka jest wyłączona.

Nie można zmienić klasy, co nie jest dozwolone w PHP.

Możesz także przedłużyć klasę:

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

Ale przez większość czasu, w tym przypadku z WooCommerce, lepiej znaleźć hak w dokumentacji , która poradzi sobie z zadaniem.

JMau
źródło
1
Jeśli rozszerzysz swoją klasę za pomocą haka, czy nowa klasa nie będzie istnieć tylko w zakresie funkcji hook?
alexg