Bölüm 7 – WordPress ve Nesne Yönelimli Programlama: Bir WordPress Örneği – Uygulama: WordPress Kancalarını Yönetme

Yayınlanan: 2022-02-04

Bu noktaya kadar, Plugin API ile etkileşim, her sınıfın yapıcısında add_action() ve add_filters() öğesini çağırmak anlamına geliyordu.

Şimdiye kadar bu yaklaşım yeterince iyiydi, çünkü işleri basitleştirdi ve WordPress ile nesne yönelimli programlama hakkında daha fazla şey öğrenmeye odaklanmamıza izin verdi. Ancak, ideal değil.

Bir nesne oluşturulduğunda tüm kancalarını kaydederse, birim testi gibi şeyler zorlaşır.

NOT: Birim testleri, her bir "birimi" ayrı ayrı test etmelidir. Şu anda birim testleri yazmıyor olsanız bile, test edilebilir kod yazmak, testler yazmaya karar verirseniz, daha sonra yeniden düzenleme yapmak için size çok zaman kazandıracaktır.

Kanca Yöneticisi

Bunu bir adım daha ileri götürelim ve kancalarımızı yönetmek için yeni bir sınıf tanıtalım, buna Hooks_Manager . Bu sınıf, tüm kancalarımızın kayıtlarından sorumlu olacak. Böylece register() metodu ile yeni bir sınıf oluşturacağız.

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

Uygulamak için kancaları kaydetmesi gereken her sınıf için bir arayüze ihtiyacımız var.

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

Bir arabirimi, bu arabirimi uygulayan bir sınıfın, o arabirimde tanımlanan tüm yöntemleri uygulamak için "sözleşmeyle bağlı" olduğu bir sözleşme olarak düşünebilirsiniz.

Örneğin, login_head eylemine bağlanan bir Login_Error sınıfı, Hooks arabirimimizin get_actions() yöntemini uygulamalıdır.

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

Hooks_Manager register() yöntemi bir nesneyi kabul eder, onun get_actions() yöntemini çağırır ve tüm eylemlerini kaydeder.

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

Arayüzümüze bir get_filters() yöntemi ekleyelim, böylece hem eylemleri hem de filtreleri kaydedebiliriz.

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

Login_Error sınıfımıza geri dönersek, bu yeni get_filters() yöntemini uygulamamız gerekiyor.

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

Hooks_Manager register_actions() register() yöntemini register_actions() olarak yeniden adlandıracağız. Ayrıca bir register_filters() yöntemi ekleyeceğiz. Bu iki yöntem, sırasıyla eylemleri ve filtreleri kaydetmekten sorumlu olacaktır.

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

Şimdi, hem register_actions() hem de register_filters() () öğesini çağıracak olan bir register() yöntemini tekrar ekleyebiliriz.

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

Bir sınıfın hem eylemleri hem de filtreleri kaydetmesi gerekmiyorsa ne olur? Hooks arabirimi iki yöntem içerir: get_actions() ve get_filters() . Bu arabirimi uygulayan tüm sınıflar, her iki yöntemi de uygulamak zorunda kalacak.

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

Örneğin, Cookie_Login sınıfının yalnızca eylemleri kaydetmesi gerekir, ancak şimdi yalnızca boş bir dizi döndürmek için get_filters() yöntemini uygulamak zorunda kalır.

SOLID'deki "I" olan Arayüz Ayrımı İlkesi (ISP) şunları belirtir:

"Hiçbir müşteri, kullanmadığı yöntemlere bağlı kalmaya zorlanmamalıdır."

Yani şu anda yaptığımız şey tam olarak yapmamamız gereken şey.

Arayüz Ayrımı

Arayüzümüzü daha küçük, daha spesifik olanlara bölerek bunu düzeltebiliriz, böylece sınıflarımız yalnızca kendilerini ilgilendiren yöntemleri bilmek zorunda kalacak.

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

Artık hem get_actions() hem de get_filters( get_filters() 'a ihtiyacımız yok, sadece Actions arabirimini uygulayabilir ve get_filters() 'dan kurtulabiliriz

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

Öte yandan, eylemlere ve filtrelere ihtiyaç duyan Login_Error , her iki arabirimi de uygulamak zorundadır. Sınıflar, virgülle ayırarak birden fazla interface uygulayabilir.

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

Arayüzümüzü ayırdığımıza göre, değişikliklerimizi yansıtmak için Hooks_Manager register() yöntemini güncellememiz yeterli.

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

Bu şekilde, belirtilen nesnenin uyguladığı arabirim(ler)e bağlı olarak koşullu olarak yalnızca register_actions() , yalnızca register_filters() veya her ikisini çağırırız.

Kanca yöneticisini gerçekten kullanmak için:

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

Bu kadar! Artık bu nesneyi, tüm kod tabanındaki kancaları yönetmek için kullanabiliriz.

Çözüm

Elbette, kancalarınızı nesne yönelimli bir şekilde yönetmenin birkaç yolu vardır, size bunlardan birini gösterdik. Denemeli ve ihtiyaçlarınıza uygun olanı bulmalısınız.

Seçenekleri nesne yönelimli bir şekilde nasıl ele alacağınızı göreceğimiz, kapsülleme, soyutlama hakkında konuşacağımız ve genişletilmesi kolay esnek bir eklenti oluşturmak için sınıflarınızı nasıl ayrıştıracağınız hakkında konuşacağımız bu serinin son bölümünde bizimle kalın!

Nesneye Yönelik Programlama Dizimizin 8. Bölümünü okumak için buraya tıklayın

Ayrıca bakınız

  • WordPress ve Nesne Yönelimli Programlama – Genel Bakış
  • Bölüm 2 – WordPress ve Nesne Yönelimli Programlama: Gerçek Bir Dünya Örneği
  • Bölüm 3 – WordPress ve Nesne Yönelimli Programlama: Α WordPress Örneği – Kapsamın Tanımlanması
  • Bölüm 4 – WordPress ve Nesne Yönelimli Programlama: Bir WordPress Örneği – Tasarım
  • Bölüm 5 – WordPress ve Nesne Yönelimli Programlama: Bir WordPress Örneği – Uygulama: Yönetim Menüsü
  • Bölüm 6 – WordPress ve Nesne Yönelimli Programlama: Bir WordPress Örneği – Uygulama: Bölümlerin Kaydedilmesi