{"id":228725,"date":"2022-11-01T12:20:00","date_gmt":"2022-11-01T09:20:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228725"},"modified":"2022-11-09T04:02:25","modified_gmt":"2022-11-09T01:02:25","slug":"konstruktorzy-wtyczek-wordpress-nie-powinni-definiowac-hookow","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/konstruktorzy-wtyczek-wordpress-nie-powinni-definiowac-hookow\/","title":{"rendered":"Konstruktorzy wtyczek WordPress nie powinni definiowa\u0107 hook\u00f3w"},"content":{"rendered":"\n<p>Konstruktory wtyczek WordPress wydaj\u0105 si\u0119 by\u0107 coraz bardziej przedmiotem dyskusji, je\u015bli chodzi o to, co nale\u017cy zdefiniowa\u0107. M\u00f3wi\u0142em o tym wcze\u015bniej, ale mo\u017cna od czasu do czasu wraca\u0107 do takiego tematu, prawda?<\/p>\n<p>W ko\u0144cu s\u0105 rzeczy, kt\u00f3rych si\u0119 uczymy i kt\u00f3re zmieniamy w miar\u0119 zdobywania do\u015bwiadczenia.<\/p>\n<p>Nie jest niczym niezwyk\u0142ym, \u017ce wtyczki definiuj\u0105 hooki i inne zachowania, ale nie jestem fanem tego podej\u015bcia. Zamiast tego my\u015bl\u0119, \u017ce obs\u0142uga rejestracji hak\u00f3w powinna by\u0107 wykonywana w jej w\u0142asnej funkcji lub, jeszcze bardziej drastycznie, obs\u0142ugiwana przez zestaw klas.<\/p>\n<p>Ale zanim zajm\u0119 si\u0119 tym, chc\u0119 wyja\u015bni\u0107, co powinno znale\u017a\u0107 si\u0119 w konstruktorze wtyczek WordPress, dlaczego powinno si\u0119 znale\u017a\u0107 w konstruktorze i jak mo\u017cna to obs\u0142u\u017cy\u0107 podczas pracy nad wtyczkami.<\/p>\n<h2>Konstruktorzy wtyczek WordPress<\/h2>\n<p>Od pocz\u0105tku uwa\u017cam, \u017ce konstruktor\u00f3w nale\u017cy u\u017cywa\u0107 do jednego:<\/p>\n<ul>\n<li>Inicjowanie stanu obiektu.<\/li>\n<\/ul>\n<p>To, co definiuje stan pocz\u0105tkowy obiektu, mo\u017ce zale\u017ce\u0107 od tego, czy zosta\u0142 on utworzony \u201eod zera&quot;, czy te\u017c jest \u0142adowany informacjami z poprzedniego zestawu (np. serializowana sesja). Spos\u00f3b, w jaki to widz\u0119:<\/p>\n<ul>\n<li>atrybuty to rzeczowniki opisuj\u0105ce obiekt,<\/li>\n<li>funkcje to czasowniki opisuj\u0105ce, co obiekt mo\u017ce zrobi\u0107.<\/li>\n<\/ul>\n<p>Funkcje oczywi\u015bcie wykonuj\u0105 prac\u0119, kt\u00f3r\u0105 obiekt jest w stanie wykona\u0107. Mog\u0105 modyfikowa\u0107 stan obiektu po wywo\u0142aniu lub mog\u0105 pracowa\u0107 na argumentach przekazanych do funkcji.<\/p>\n<h3>Co powinno znale\u017a\u0107 si\u0119 w konstruktorze?<\/h3>\n<p>Kiedy obiekt jest konstruowany, nale\u017cy go po prostu ustawi\u0107 w taki spos\u00f3b, aby jego atrybuty by\u0142y ustawione, a jego funkcje by\u0142y gotowe do pracy.<\/p>\n<p>Je\u015bli w konstruktorze jest co\u015b, co nie wp\u0142ywa na stan pocz\u0105tkowy obiektu, nie powinno tego tam by\u0107.<\/p>\n<h3>Dlaczego atrybuty powinny znajdowa\u0107 si\u0119 w konstruktorze?<\/h3>\n<p>By\u0107 mo\u017ce lepszym sposobem na zadanie tego pytania jest:<\/p>\n<p>Dlaczego hooki nie powinny by\u0107 definiowane w konstruktorze?<\/p>\n<p>System hook\u00f3w WordPressa jest cz\u0119\u015bci\u0105 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Event-driven_programming\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wzorca projektowania sterowanego zdarzeniami<\/a> (kt\u00f3rego jestem fanem), ale rejestracja hook\u00f3w nie opisuje stanu obiektu. Zamiast tego, na najbardziej podstawowym poziomie, jest to co\u015b, co tworzy relacj\u0119 z obiektem i WordPressem.<\/p>\n<p>Pocz\u0105tkowy stan obiektu nie musi wiedzie\u0107 o WordPressie, nie musi mie\u0107 \u017cadnej z jego funkcji po\u0142\u0105czonych z WordPress ani nie musi wykonywa\u0107 \u017cadnych operacji za pomoc\u0105 WordPress.<\/p>\n<p>Pami\u0119taj, atrybuty s\u0105 inicjowane w konstruktorze. WordPress nie jest atrybutem. To zale\u017cno\u015b\u0107. Stworzenie zale\u017cno\u015bci to podj\u0119cie dzia\u0142ania, kt\u00f3re jest definicj\u0105 czasownika.<\/p>\n<p>Dlatego wszystkie rejestracje podpi\u0119\u0107 powinny by\u0107 wykonywane w funkcji.<\/p>\n<h3>Jak mo\u017cemy obs\u0142u\u017cy\u0107 rejestracj\u0119 haka?<\/h3>\n<p>To jeden z tych temat\u00f3w, kt\u00f3re mog\u0105 by\u0107 samodzielnym postem lub seri\u0105 post\u00f3w.<\/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<li>Mo\u017cliwe jest r\u00f3wnie\u017c zdefiniowanie rejestracji podpi\u0119cia w funkcji w klasie.<\/li>\n<li>Mo\u017cemy r\u00f3wnie\u017c zrobi\u0107 wiele rzeczy z <a href=\"https:\/\/carlalexander.ca\/dependency-inversion-principle-wordpress\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">odwr\u00f3ceniem zale\u017cno\u015bci<\/a>.<\/li>\n<\/ul>\n<p>Wszystkie powy\u017csze s\u0105 rzeczami, kt\u00f3re wykraczaj\u0105 poza zakres tego postu, ale dla uproszczenia poka\u017c\u0119 przyk\u0142ad, jak klasa mo\u017ce zarejestrowa\u0107 swoje funkcje w WordPressie <a href=\"https:\/\/gist.github.com\/tommcfarlin\/30521dcf0c493283327bf9162c7b9a35#file-01-javascript-asset-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">w funkcji init<\/a> :<\/p>\n<pre><code>&lt;?php\n\nnamespace AcmeAdmin;\nuse AcmeAdminInterfaces;\n\nclass JavaScript_Assets implements InterfacesAsset {\n\n    private $assets_dir;\n\n    private $js_dir;\n\n    public function __construct() {\n\n        $this-&gt;assets_dir = trailingslashit(\n            plugin_dir_url( __FILE__ ). 'assets'\n        );\n\n        $this-&gt;js_dir = trailingslashit( $this-&gt;assets_dir. 'js' );\n    }\n\n    public function init() {\n\n        add_action(\n            'admin_enqueue_scripts',\n            array( $this, 'enqueue') );\n    }\n\n    public function enqueue() {\n\n        wp_enqueue_script(\n            'toggle-admin-notices',\n            $this-&gt;js_dir. 'admin.js',\n            array( 'jquery' ),\n            false\n        );\n    }\n}\n<\/code><\/pre>\n<p>W ten spos\u00f3b jeste\u015bmy w stanie utworzy\u0107 instancj\u0119 obiektu, przetestowa\u0107 go, u\u017cy\u0107 itd., ale nie musimy zajmowa\u0107 si\u0119 niczym zwi\u0105zanym z WordPressem bez jawnego wywo\u0142ania\u00a0 funkcji <strong>init<\/strong>.<\/p>\n<p>Po wywo\u0142aniu tworzona jest zale\u017cno\u015b\u0107, potrzebny jest WordPress i sprawy staj\u0105 si\u0119 bardziej skomplikowane.<\/p>\n<h2>Och, i ta rzecz testuj\u0105ca<\/h2>\n<p>Chc\u0119 wspomnie\u0107 o jeszcze jednym punkcie, kt\u00f3ry jest nieco poza zakresem i punktem tego postu, ale nadal jest istotny: je\u015bli chodzi o testowanie klasy, powinni\u015bmy by\u0107 w stanie:<\/p>\n<ol>\n<li>utworzy\u0107 instancj\u0119 klasy,<\/li>\n<li>testowanie jego logiki przez wywo\u0142ywanie funkcji,<\/li>\n<li>przekazywanie jej parametr\u00f3w i ocenianie jego zwracanych warto\u015bci.<\/li>\n<\/ol>\n<p>I powinni\u015bmy by\u0107 w stanie zrobi\u0107 jak najwi\u0119cej w odosobnieniu. Je\u015bli hooki s\u0105 zdefiniowane w konstruktorze, tworzy to natychmiastow\u0105 zale\u017cno\u015b\u0107 od WordPressa, kt\u00f3ra nie powinna by\u0107 potrzebna.<\/p>\n<p>WordPress nie opisuje stanu obiektu. To zale\u017cno\u015b\u0107 obiektu.<\/p>\n<p>W ka\u017cdym razie chodzi mi o to, \u017ce konstruktory wtyczek do WordPressa nie powinny zajmowa\u0107 si\u0119 rejestracj\u0105 hook\u00f3w, poniewa\u017c hooki nie opisuj\u0105 ich stanu. S\u0105 one powi\u0105zane z czym\u015b, co robi klasa i uniemo\u017cliwiaj\u0105 nam testowanie obiektu w izolacji.<\/p>\n<p>Maj\u0105 wi\u0119c swoje miejsce, ale nie w konstruktorze.<\/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>Konstruktorzy wtyczek WordPress nie powinni zajmowa\u0107 si\u0119 rejestracj\u0105 hook\u00f3w, poniewa\u017c hooki nie opisuj\u0105 ich stanu.<\/p>\n","protected":false},"author":1,"featured_media":223852,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,897,805,845,866,815],"tags":[1169],"class_list":["post-228725","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-kod","category-php-7","category-samouczki","category-wordpress-7","category-wtyczki","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228725","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=228725"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/228725\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/223852"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=228725"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=228725"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=228725"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}