{"id":228735,"date":"2022-11-01T09:51:00","date_gmt":"2022-11-01T06:51:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228735"},"modified":"2022-11-09T04:04:50","modified_gmt":"2022-11-09T01:04:50","slug":"rejestrowanie-hakow-wordpress-przy-uzyciu-innej-klasy","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/rejestrowanie-hakow-wordpress-przy-uzyciu-innej-klasy\/","title":{"rendered":"Rejestrowanie hak\u00f3w WordPress przy u\u017cyciu innej klasy"},"content":{"rendered":"\n<p>We <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/konstruktorzy-wtyczek-wordpress-nie-powinni-definiowac-hookow\/\" title=\"wczorajszym po\u015bcie\" >wczorajszym po\u015bcie<\/a> m\u00f3wi\u0142em o konstruktorach wtyczek WordPress i uzasadnieniu, dlaczego hooki nie powinny znajdowa\u0107 si\u0119 w konstruktorze.<\/p>\n<p>Chocia\u017c wspomnia\u0142em o wielu sposobach obs\u0142ugi rejestracji haka, nie zawraca\u0142em sobie g\u0142owy wchodzeniem w szczeg\u00f3\u0142y dla ka\u017cdej z tych strategii. Je\u015bli o mnie chodzi, zas\u0142uguj\u0105 na sw\u00f3j w\u0142asny artyku\u0142, aby poda\u0107 jak najwi\u0119cej szczeg\u00f3\u0142\u00f3w na temat tego, jak co\u015b skonfigurowa\u0107.<\/p>\n<p>Na przyk\u0142ad jedna z udost\u0119pnionych przeze mnie metod m\u00f3wi\u0142a:<\/p>\n<ul>\n<li>Za pomoc\u0105 WordPressa mo\u017cna stworzy\u0107 klas\u0119, kt\u00f3ra prowadzi rejestr obiekt\u00f3w i hook\u00f3w.<\/li>\n<\/ul>\n<p>Innymi s\u0142owy, chodzi o rejestrowanie hook\u00f3w WordPressa przy u\u017cyciu podej\u015bcia obiektowego, aby zmniejszy\u0107 sprz\u0119\u017cenie i zwi\u0119kszy\u0107 sp\u00f3jno\u015b\u0107 mi\u0119dzy komponentami wtyczki.<\/p>\n<p>Ale co to w og\u00f3le oznacza? Jakie korzy\u015bci przynosi, jak jest skonfigurowany i jak jest u\u017cywany?<\/p>\n<h2>Rejestrowanie hak\u00f3w WordPress<\/h2>\n<p>Je\u015bli to czytasz, prawdopodobnie znasz <a href=\"https:\/\/codex.wordpress.org\/Plugin_API#Hooks:_Actions_and_Filters\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">system<\/a> zaczep\u00f3w WordPressa, kolejno\u015b\u0107 ich uruchamiania oraz spos\u00f3b, w jaki funkcja lub klasa mo\u017ce rejestrowa\u0107 swoje funkcje w WordPressie, aby mog\u0142y wykonywa\u0107 ka\u017cd\u0105 prac\u0119, kt\u00f3rej potrzebuj\u0105.<\/p>\n<p>Cz\u0119sto widzimy, jak klasy robi\u0105 to samodzielnie. W zale\u017cno\u015bci od projektu robi\u0119 to sam. Dla tych, kt\u00f3rzy nie s\u0105 zaznajomieni, og\u00f3lnie wygl\u0105da to mniej wi\u0119cej <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-00-plugins-loaded-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a> :<\/p>\n<pre><code>&lt;?php\n\nadd_action( 'plugins_loaded', 'acme_start' );\n\/**\n * Start the machine.\n * https:\/\/www.youtube.com\/watch?v=ysoMOefPyRs\n *\/\nfunction acme_start() {\n    $plugin = new AcmeColumn();\n}\n<\/code><\/pre>\n<p>Ale wszystko to mo\u017cna podzieli\u0107 na bardziej sp\u00f3jne klasy, aby ostatecznie da\u0107 im jeszcze mniej odpowiedzialno\u015bci (to dobrze) i zmniejszy\u0107 sprz\u0119\u017cenie mi\u0119dzy klas\u0105 lub zestawem klas z WordPress.<\/p>\n<p>Przyk\u0142adowy projekt, kt\u00f3ry opisz\u0119 w tym po\u015bcie.<\/p>\n<p>Jednak sprzeczny z intuicj\u0105 charakter tego jest taki, \u017ce b\u0119dzie to wymaga\u0142o co najmniej jednej innej klasy. Ale oto jak to dzia\u0142a.<\/p>\n<h2>Konfigurowanie go<\/h2>\n<p>Na potrzeby tego przyk\u0142adu u\u017cyjemy po prostu prostej klasy, kt\u00f3ra zarejestruje pewien rodzaj akcji w WordPressie. Pomys\u0142 na architektur\u0119 dzia\u0142a mniej wi\u0119cej tak:<\/p>\n<ol>\n<li>Istnieje g\u0142\u00f3wna klasa, kt\u00f3ra ma funkcj\u0119, kt\u00f3r\u0105 chcemy pod\u0142\u0105czy\u0107 do WordPressa.<\/li>\n<li>Istnieje klasa odpowiedzialna za orkiestracj\u0119 podpinania funkcji klasy do WordPressa.<\/li>\n<\/ol>\n<p>Wystarczaj\u0105co \u0142atwe, prawda? Ale tu jest haczyk: klasa odpowiedzialna za rejestracj\u0119 funkcji danej klasy w WordPressie to punkt, kt\u00f3ry wymaga decyzji projektowej.<\/p>\n<p>Najpierw nazwijmy klas\u0119 <strong>HookRegistry<\/strong>, aby\u015bmy mogli si\u0119 do niej w\u0142a\u015bciwie odwo\u0142ywa\u0107. Nast\u0119pnie wywo\u0142ajmy klas\u0119 z funkcjami, kt\u00f3re chcemy podpi\u0105\u0107 <strong>AcmeColumn<\/strong>, aby po prostu reprezentowa\u0107 klas\u0119, kt\u00f3ra dodaje now\u0105 kolumn\u0119 do pulpitu nawigacyjnego strony w obszarze administracyjnym WordPressa.<\/p>\n<p>Maj\u0105c to na uwadze, decyzja projektowa sprowadza si\u0119 do tego:<\/p>\n<ol>\n<li>Czy <strong>HookRegistery<\/strong> powinien wiedzie\u0107 o <strong>AcmeColumn?<\/strong><\/li>\n<li>Czy <strong>AcmeColumn<\/strong> powinien wiedzie\u0107 o <strong>HookRegistry<\/strong>? <\/li>\n<\/ol>\n<p>Wiem, \u017ce istniej\u0105 inne sposoby na zorganizowanie tego i istniej\u0105 r\u00f3wnie\u017c strategie, jak sobie z tym poradzi\u0107 (jak <a href=\"https:\/\/carlalexander.ca\/dependency-inversion-principle-wordpress\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">odwr\u00f3cenie kontroli<\/a>) i s\u0105 to tematy, kt\u00f3re warto zbada\u0107, ale aby zachowa\u0107 ten pocz\u0105tkowy pomys\u0142 jak najprostszy, przedstawi\u0119 to dla przysz\u0142y post.<\/p>\n<h3>Korzystanie z klasy<\/h3>\n<p>Bior\u0105c pod uwag\u0119 powy\u017csze opcje, przeka\u017cemy instancj\u0119 <strong>AcmeColumn<\/strong> do <strong>HookRegistry<\/strong> podczas tworzenia instancji klas podczas pocz\u0105tkowego procesu uruchamiania wtyczki WordPress. To mo\u017ce wygl\u0105da\u0107 mniej wi\u0119cej <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-startup-process-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a> :<\/p>\n<pre><code>&lt;?php\n\nadd_action( 'plugins_loaded', 'acme_start' );\n\/**\n * Start the machine.\n * https:\/\/www.youtube.com\/watch?v=ysoMOefPyRs\n *\/\nfunction acme_start() {\n\n  $registry    = new HookRegistry();\n\n  $acme_column = new AcmeColumn( $registry );\n  $acme_column-&gt;start();\n}\n<\/code><\/pre>\n<p>Nast\u0119pnie, gdy nadejdzie czas, aby <strong>AcmeColumn\u00a0<\/strong> zarejestrowa\u0142 swoj\u0105 funkcj\u0119 w WordPressie, <strong>wywo\u0142amy HookRegistry<\/strong> i poinstruujemy go, aby to zrobi\u0142.<\/p>\n<p>Po pierwsze, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-acme-column-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">AcmeColumn<\/a> :<\/p>\n<pre><code>&lt;?php\n\nclass AcmeColumn {\n\n    private $registry;\n\n    public function __construct( $registry) {\n        $this-&gt;registry = $registry;\n    }\n\n    public function start() {\n        $registry-&gt;add_hook( 'filter', 'manage_edit-page_columns', $this, 'add_page_column' );\n    }\n\n    public function add_page_column( $page_columns) {\n\n        $page_columns['template'] = 'Acme Column';\n        return $page_columns;\n    } \n}\n<\/code><\/pre>\n<p>Nast\u0119pnie <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-02-hook-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">rejestr hak\u00f3w<\/a> :<\/strong><\/p>\n<pre><code>&lt;?php\n\nclass HookRegistry {\n\n  public add_hook( $type, $name, $object, $method) {\n\n    $type = strtolower( $type );\n    if ('filter' !== $type || 'action' !== $type) {\n      return new WP_Error( '1', 'No proper hook type defined.' );\n    }\n  }\n\n  private function add_filter( $name, $object, $method) {\n    add_filter( $name, array( $object, $method) );\n  }\n\n  private function add_action( $name, $object, $method) {\n    add_action( $name, array( $object, $method) );\n  }\n}\n<\/code><\/pre>\n<p>Opcjonalnie mo\u017cemy r\u00f3wnie\u017c prowadzi\u0107 list\u0119 r\u00f3\u017cnych klas i hook\u00f3w, kt\u00f3re zosta\u0142y zarejestrowane. Mo\u017ce to by\u0107 przydatne, ale nie musi, w zale\u017cno\u015bci od implementacji, wi\u0119c udost\u0119pniam wy\u0142\u0105cznie jako \u201eoto co\u015b, co mo\u017cesz chcie\u0107 zrobi\u0107&quot;.<\/p>\n<p>A to mog\u0142oby <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-03-hook-registry-improved-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wygl\u0105da\u0107 tak<\/a> (przy u\u017cyciu prostej tablicy asocjacyjnej):<\/p>\n<pre><code>&lt;?php\n\nclass HookRegistry {\n\n  private $registry;\n\n  public function __construct() {\n    $this-&gt;registery = array(); \n  }\n\n  public add_hook( $id, $type, $name, $object, $method) {\n\n    $type = strtolower( $type );\n    if ('filter' !== $type || 'action' !== $type) {\n      return new WP_Error( '1', 'No proper hook type defined.' );\n    }\n\n    if ('filter' === $type) {\n      $this-&gt;add_filter( $name, $object, $method );\n    } else {\n      $this-&gt;add_action( $name, $object, $method );\n    }\n\n    $hook_info = array(\n      $type,\n      $name,\n      $object,\n      $method,\n    );\n    $this-&gt;registry[ $id ] = $hook_info;\n  }\n\n  private function add_filter( $name, $object, $method) {\n    add_filter( $name, array( $object, $method) );\n  }\n\n  private function add_action( $name, $object, $method) {\n    add_action( $name, array( $object, $method) );\n  }\n}\n<\/code><\/pre>\n<p>Zauwa\u017c, \u017ce w powy\u017cszej klasie, teraz akceptuje <strong>$id<\/strong> jako parametr. Istnieje wiele sposob\u00f3w identyfikowania informacji trafiaj\u0105cych do rejestru, z kt\u00f3rych naj\u0142atwiejszym jest samodzielne utworzenie identyfikatora.<\/p>\n<p>Je\u015bli jednak chcia\u0142by\u015b u\u017cy\u0107 czego\u015b takiego jak nazwa haka lub nazwa klasy, to te\u017c by zadzia\u0142a\u0142o. Pami\u0119taj tylko, \u017ce poniewa\u017c jest to tablica asocjacyjna, mo\u017ce utrzymywa\u0107 tylko jedn\u0105 warto\u015b\u0107 na klucz, wi\u0119c mo\u017cesz sko\u0144czy\u0107 z wyrzuceniem poprzednich danych, je\u015bli nie b\u0119dziesz ostro\u017cny.<\/p>\n<p>Niezale\u017cnie od tego jest to co\u015b, co uwa\u017cam za opcjonalne, ale je\u015bli jest zaimplementowane, wa\u017cne jest, aby upewni\u0107 si\u0119, \u017ce masz odpowiednie funkcje do pobrania instancji obiektu za pomoc\u0105 klucza.<\/p>\n<h2>Jeden z wielu<\/h2>\n<p>Podobnie jak w przypadku wszystkiego, co dotyczy tego rodzaju pracy, mo\u017cliwe jest przeprojektowanie lub przeorientowanie tego w spos\u00f3b, kt\u00f3ry dzia\u0142a inaczej lub odpowiada Twoim potrzebom. Celem nie jest pokazanie ostatecznego wzorca, jak co\u015b zrobi\u0107, ale spos\u00f3b podej\u015bcia i dostosowania go (podobnie jak ka\u017cdy wzorzec projektowy).<\/p>\n<p>Co wi\u0119cej, ma to na celu upewnienie si\u0119, \u017ce nasze klasy zachowuj\u0105 obowi\u0105zki, do kt\u00f3rych zosta\u0142y stworzone, jednocze\u015bnie umo\u017cliwiaj\u0105c im zarejestrowanie si\u0119 w WordPressie w razie potrzeby. Tym razem jednak klasa nie musi tego robi\u0107 sama.<\/p>\n<p>Zamiast tego przekazuje odpowiedzialno\u015b\u0107 klasie, kt\u00f3ra ma wy\u0142\u0105czn\u0105 odpowiedzialno\u015b\u0107 za rejestracj\u0119 wspomnianych podpi\u0119\u0107. Wi\u0119c chocia\u017c wprowadza wi\u0119cej klas, zwi\u0119ksza sp\u00f3jno\u015b\u0107 i zmniejsza sprz\u0119\u017cenie.<\/p>\n<p>Zapewnia to korzy\u015bci w zakresie konserwacji, testowania i og\u00f3lnego projektowania.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">\u0179r\u00f3d\u0142o nagrywania:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chodzi o rejestrowanie hook\u00f3w WordPressa przy u\u017cyciu podej\u015bcia obiektowego, aby zmniejszy\u0107 sprz\u0119\u017cenie i zwi\u0119kszy\u0107 sp\u00f3jno\u015b\u0107 wtyczki.<\/p>\n","protected":false},"author":1,"featured_media":223973,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,919,897,866,815],"tags":[1169],"class_list":["post-228735","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-kod","category-wordpress-7","category-wtyczki","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228735","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/comments?post=228735"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228735\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/223973"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=228735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=228735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=228735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}