Bagian 7 – WordPress dan Pemrograman Berorientasi Objek: Contoh WordPress – Implementasi: Mengelola Hooks WordPress

Diterbitkan: 2022-02-04

Sampai saat ini, berinteraksi dengan API Plugin berarti memanggil add_action() dan add_filters() di konstruktor setiap kelas.

Sejauh ini pendekatan itu cukup baik, karena membuat semuanya tetap sederhana dan memungkinkan kami untuk fokus belajar lebih banyak tentang pemrograman berorientasi objek dengan WordPress. Namun, itu tidak ideal.

Jika sebuah objek mendaftarkan semua kaitnya saat dibuat, hal-hal seperti pengujian unit menjadi rumit.

CATATAN: Pengujian unit harus menguji setiap "unit" secara terpisah. Bahkan jika Anda tidak sedang menulis tes unit saat ini, menulis kode yang dapat diuji akan menghemat banyak waktu untuk refactoring nanti, jika Anda memutuskan untuk menulis tes.

Manajer Kait

Mari kita selangkah lebih maju dan memperkenalkan kelas baru untuk mengelola hook kita, kita akan menyebutnya Hooks_Manager . Kelas ini akan bertanggung jawab untuk pendaftaran semua kait kami. Jadi, kita akan membuat kelas baru dengan metode register() .

 class Hooks_Manager { /** * Register the hooks of the given object. * * @param object $object */ public function register( $object ) { // Register the hooks the specified object needs } }

Kami membutuhkan antarmuka untuk setiap kelas yang perlu mendaftarkan kait untuk diimplementasikan.

 interface Hooks { /** * Return the actions to register. * * @return array */ public function get_actions(); }

Anda dapat menganggap antarmuka sebagai kontrak , di mana kelas yang mengimplementasikan antarmuka itu "terikat secara kontrak" untuk mengimplementasikan semua metode yang ditentukan dalam antarmuka itu.

Misalnya, kelas Login_Error yang terhubung ke tindakan login_head , harus mengimplementasikan metode get_actions() dari antarmuka Hooks kita.

 class Login_Error implements Hooks { public function get_actions() { return array( 'login_head' => array( 'add_errors', 10, 1 ), ); } }

Metode register() dari Hooks_Manager menerima objek, memanggil metode get_actions() dan mendaftarkan semua tindakannya.

 public function register( $object ) { $actions = $object->get_actions(); foreach ( $actions as $action_name => $action_details ) { $method = $action_details[0]; $priority = $action_details[1]; $accepted_args = $action_details[2]; add_action( $action_name, array( $object, $method ), $priority, $accepted_args ); } }

Mari tambahkan metode get_filters() ke antarmuka kita, sehingga kita dapat mendaftarkan tindakan dan filter.

 interface Hooks { /** * Return the actions to register. * * @return array */ public function get_actions(); /** * Return the filters to register. * * @return array */ public function get_filters(); }

Kembali ke kelas Login_Error kita, kita perlu mengimplementasikan metode get_filters() baru ini.

 class Login_Error implements Hooks { public function get_actions() { return array( 'login_head' => array( 'add_errors', 10, 1 ), ); } public function get_filters() { return array( 'authenticate' => array( 'track_credentials', 10, 3 ), 'shake_error_code' => array( 'add_error_code', 10, 1 ), 'login_errors' => array( 'format_error_message', 10, 1 ), ); } }

Kami akan mengganti nama metode register() dari Hooks_Manager kami menjadi register_actions() . Kami juga akan menambahkan metode register_filters() . Kedua metode ini akan bertanggung jawab untuk mendaftarkan tindakan dan filter masing-masing.

 class Hooks_Manager { /** * Register the actions of the given object. * * @param object $object */ private function register_actions( $object ) { $actions = $object->get_actions(); foreach ( $actions as $action_name => $action_details ) { $method = $action_details[0]; $priority = $action_details[1]; $accepted_args = $action_details[2]; add_action( $action_name, array( $object, $method ), $priority, $accepted_args ); } } /** * Register the filters of the given object. * * @param object $object */ private function register_filters( $object ) { $filters = $object->get_filters(); foreach ( $filters as $filter_name => $filter_details ) { $method = $filter_details[0]; $priority = $filter_details[1]; $accepted_args = $filter_details[2]; add_filter( $filter_name, array( $object, $method ), $priority, $accepted_args ); } } }

Sekarang kita dapat menambahkan metode register() lagi, yang hanya akan memanggil register_actions() dan register_filters() .

 class Hooks_Manager { /** * Register an object. * * @param object $object */ public function register( $object ) { $this->register_actions( $object ); $this->register_filters( $object ); } // ...

Bagaimana jika kelas tidak perlu mendaftarkan tindakan dan filter? Antarmuka Hooks berisi dua metode: get_actions() dan get_filters() . Semua kelas yang mengimplementasikan antarmuka itu akan dipaksa untuk mengimplementasikan kedua metode tersebut.

 class Cookie_Login implements Hooks { public function get_actions() { return array( 'auth_cookie_bad_username' => array( 'handle_bad_username', 10, 1 ), 'auth_cookie_bad_hash' => array( 'handle_bad_hash', 10, 1 ), 'auth_cookie_valid' => array( 'handle_valid', 10, 2 ), ); } public function get_filters() { return array(); } }

Misalnya, kelas Cookie_Login harus mendaftarkan tindakan saja, tetapi sekarang dipaksa untuk mengimplementasikan metode get_filters() hanya untuk mengembalikan array kosong.

Prinsip Pemisahan Antarmuka (ISP) , "I" di SOLID, menyatakan:

“Tidak ada klien yang harus dipaksa untuk bergantung pada metode yang tidak digunakannya.”

Artinya apa yang kita lakukan sekarang adalah persis apa yang seharusnya tidak kita lakukan.

Segregasi Antarmuka

Kita dapat memperbaikinya dengan membagi antarmuka kita menjadi yang lebih kecil, yang lebih spesifik sehingga kelas kita hanya perlu tahu tentang metode yang menarik bagi mereka.

 interface Actions { /** * Return the actions to register. * * @return array */ public function get_actions(); }
 interface Filters { /** * Return the filters to register. * * @return array */ public function get_filters(); }

Kami tidak membutuhkan get_actions() dan get_filters() lagi, kami hanya dapat mengimplementasikan antarmuka Actions dan menyingkirkan get_filters()

 class Cookie_Login implements Actions { public function get_actions() { return array( 'auth_cookie_bad_username' => array( 'handle_bad_username', 10, 1 ), 'auth_cookie_bad_hash' => array( 'handle_bad_hash', 10, 1 ), 'auth_cookie_valid' => array( 'handle_valid', 10, 2 ), ); } }

Di sisi lain, Login_Error , yang membutuhkan tindakan dan filter, hanya perlu mengimplementasikan kedua antarmuka. Kelas dapat mengimplementasikan lebih dari satu antarmuka dengan memisahkannya dengan koma.

 class Login_Error implements Actions, Filters { public function get_actions() { return array( 'login_head' => array( 'add_errors', 10, 1 ), ); } public function get_filters() { return array( 'authenticate' => array( 'track_credentials', 10, 3 ), 'shake_error_code' => array( 'add_error_code', 10, 1 ), 'login_errors' => array( 'format_error_message', 10, 1 ), ); } }

Sekarang kita telah memisahkan antarmuka kita, kita hanya perlu memperbarui metode register() dari Hooks_Manager untuk mencerminkan perubahan kita.

 class Hooks_Manager { /** * Register an object. * * @param object $object */ public function register( $object ) { if ( $object instanceof Actions ) { $this->register_actions( $object ); } if ( $object instanceof Filters ) { $this->register_filters( $object ); } } // ...

Dengan begitu, kita secara kondisional hanya memanggil register_actions() , hanya register_filters() , atau keduanya, berdasarkan antarmuka yang diimplementasikan objek yang ditentukan.

Untuk benar-benar menggunakan manajer kait:

 $hooks_manager = new Hooks_Manager(); $hooks_manager->register( $login_error ); $hooks_manager->register( $cookie_login );

Itu dia! Kita sekarang dapat menggunakan objek itu untuk mengelola kait di seluruh basis kode.

Kesimpulan

Tentu saja, ada beberapa cara untuk mengelola hook Anda dengan cara berorientasi objek, kami baru saja menunjukkan salah satunya. Anda harus bereksperimen dan menemukan satu yang sesuai dengan kebutuhan Anda.

Tetap bersama kami untuk bagian terakhir dari seri ini, di mana kita akan melihat cara menangani opsi dengan cara berorientasi objek, berbicara tentang enkapsulasi, abstraksi, dan cara memisahkan kelas Anda untuk membuat plugin fleksibel yang mudah diperluas!

Klik di sini untuk membaca Bagian 8 dalam Seri Pemrograman Berorientasi Objek kami

Lihat juga

  • WordPress dan Pemrograman Berorientasi Objek – Gambaran Umum
  • Bagian 2 – WordPress dan Pemrograman Berorientasi Objek: Contoh Dunia Nyata
  • Bagian 3 – WordPress dan Pemrograman Berorientasi Objek: Contoh WordPress – Mendefinisikan Ruang Lingkup
  • Bagian 4 – WordPress dan Pemrograman Berorientasi Objek: Contoh WordPress – Desain
  • Bagian 5 – WordPress dan Pemrograman Berorientasi Objek: Contoh WordPress – Implementasi: Menu Administrasi
  • Bagian 6 – WordPress dan Pemrograman Berorientasi Objek: Contoh WordPress – Implementasi: Mendaftarkan Bagian