จะใช้คลาสที่ประกาศในปลั๊กอินอื่นได้อย่างไร?


10

ฉันกำลังพัฒนาปลั๊กอิน Wordpress Woocommerce ในสภาพแวดล้อมท้องถิ่นของฉันมันทำงานได้ดี แต่ฉันมีปัญหาเมื่อเพิ่มปลั๊กอินลงในแบบจำลองของสภาพแวดล้อมการผลิต ฉันใหม่กับเวิร์ดเพรสและไม่คุ้นเคยกับการพัฒนาเว็บมาก (ฉันเป็นโปรแกรมเมอร์ 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

ดังนั้นวิธีที่เหมาะสมในการใช้คลาสที่ประกาศในปลั๊กอินอื่นคืออะไร?

หมายเหตุ: การอัพเกรดไม่ได้เป็นตัวเลือกในขณะนี้

คำตอบ:


10

คุณต้องตรวจสอบว่ามีคลาสอยู่หรือไม่ แต่ก่อนหน้านี้คุณต้องรอว่าปลั๊กอินทั้งหมดถูกโหลดหรือไม่: ไม่มีใครรับประกันได้ว่าปลั๊กอินของคุณถูกโหลดหลังจาก WooCommerce

สำหรับรันโค้ดจากปลั๊กอินเมื่อปลั๊กอินทั้งหมดถูกโหลดลงในplugins_loadedhook

ระวังว่าคุณไม่สามารถใช้ hook นี้ในธีมได้เพราะเมื่อ theme โหลด hook นั้นถูกใช้งานแล้ว

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')
    );
}

ไม่แน่ใจว่าในกรณีนี้plugins_loadedเป็นเบ็ดที่เหมาะสมหรือไม่ หนึ่งจะต้องค้นหาเมื่อชั้นที่มีอยู่และขอหลังจากนั้น อย่างไรก็ตาม +1
kaiser

register_deactivation_hook( __FILE__, 'deactivate');ในกรณีนี้โดยเฉพาะอย่างยิ่งฉันกำลังตะขอเบ็ดปิดการทำางาน ดังนั้นฉันรอไม่ไหว ฉันขอให้เวิร์ดเพรสโหลดคลาสได้หรือไม่ถ้ายังไม่โหลด?
znat

2
ขอบคุณ @kaiser WC_Couponถูกโหลดโดย__constructในหลักWooCommerceชั้น (จริงๆโดยincludes()วิธีการที่เรียกว่าโดยตรง__construct) และWooCommerceชั้น instanziate (เป็นเดี่ยว) เร็วที่สุดเท่าที่มีการโหลดปลั๊กอิน ดังนั้นplugins_loadedเป็นเบ็ดที่เหมาะสมในกรณีนี้;)
gmazzap

ไม่ระบุชื่อก่อนที่จะโหลดแกน? ทำได้ดีมากวูทำได้ดีมาก
ไกเซอร์

@NathanZ class_exists( 'WC_Coupon' )ตรวจสอบ โปรดระบุด้วยว่าคุณกำลังใช้สิ่งนี้ในระหว่างปิดการใช้งาน ... อาจช่วยประหยัดเวลาในการตอบคำถามได้เป็นจำนวนมาก ...
kaiser

6

มันสายเกินไป แต่ฉันต้องการแบ่งปันวิธีใช้ woocommerce และคลาสของมันโดยไม่พบคลาสข้อผิดพลาด

ขั้นแรกคือการตรวจสอบว่ามีการติดตั้ง woocommerceและใช้woocommerce_loadedaction hook หรือไม่

/**
 * 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 คุณควรหาเอกสารในการจัดการงานที่ดีกว่า


1
หากคุณขยายคลาสของคุณผ่านทาง hook คลาสใหม่จะไม่อยู่ในขอบเขตของ hook ฟังก์ชั่นเท่านั้นหรือ
alexg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.