{"id":230734,"date":"2022-12-19T17:25:00","date_gmt":"2022-12-19T14:25:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230734"},"modified":"2022-12-19T17:25:59","modified_gmt":"2022-12-19T14:25:59","slug":"widzety-wordpress-refaktoryzacja-czesc-8","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/widzety-wordpress-refaktoryzacja-czesc-8\/","title":{"rendered":"Wid\u017cety WordPress: Refaktoryzacja, cz\u0119\u015b\u0107 8"},"content":{"rendered":"\n<p>Je\u015bli chodzi o refaktoryzacj\u0119 WordPress Widget Boilerplate, wykonali\u015bmy du\u017co pracy, aby dostosowa\u0107 baz\u0119 kodu do standardu bardziej zorientowanego obiektowo. Ponadto wprowadzili\u015bmy wiele innych narz\u0119dzi, kt\u00f3re pozwalaj\u0105 nam dostosowa\u0107 nasz kod do bardziej nowoczesnych standard\u00f3w<\/p>\n<p>Teraz, gdy sp\u0119dzili\u015bmy na tym troch\u0119 czasu, nadszed\u0142 czas, aby wr\u00f3ci\u0107 do kodu i rozpocz\u0105\u0107 jego refaktoryzacj\u0119 w taki spos\u00f3b, aby umo\u017cliwi\u0107 korzystanie z <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/klasy-abstrakcyjne-czesc-1-zachowanie-abstrakcji\/\" title=\"klas abstrakcyjnych\">klas abstrakcyjnych<\/a> i subskrybent\u00f3w (dzia\u0142aj\u0105cych jako cz\u0119\u015b\u0107 <a href=\"https:\/\/wordpress.mediadoma.com\/pl\/podstawy-dzialania-hookow-w-wordpressie\/\" title=\"wzorca projektowania sterowanego zdarzeniami\">wzorca projektowania sterowanego zdarzeniami<\/a> ).<\/p>\n<p>Pod koniec poprzedniego posta napisa\u0142em:<\/p>\n<blockquote>\n<p>W nadchodz\u0105cych postach przyjrzymy si\u0119, jak mo\u017cemy zaimplementowa\u0107 subskrybent\u00f3w dla publicznej strony witryny (czyli tam, gdzie wy\u015bwietlana jest tre\u015b\u0107 wid\u017cetu). I zrobimy to samo dla obszaru administracyjnego witryny.<\/p>\n<\/blockquote>\n<p>W tym po\u015bcie zrobimy dok\u0142adnie to. Konkretnie, zaczniemy od pracy nad subskrybentem wid\u017cetu, a nast\u0119pnie wy\u015bwietleniem podstawowego wid\u017cetu po stronie administracyjnej witryny.<\/p>\n<h2>WordPress Widget Boilerplate: Refaktoryzacja, cz\u0119\u015b\u0107 8<\/h2>\n<p>Powodem, dla kt\u00f3rego interesuje mnie przede wszystkim skupienie si\u0119 na stronie administracyjnej witryny, jest to, \u017ce pozwala nam ona:<\/p>\n<ul>\n<li>zapoznaj si\u0119 z prac\u0105 subskrybent\u00f3w,<\/li>\n<li>zobacz jak trzeba b\u0119dzie uporz\u0105dkowa\u0107 baz\u0119 kod\u00f3w,<\/li>\n<li>zakodowa\u0107 pewne informacje przed rozpocz\u0119ciem pracy z serializacj\u0105.<\/li>\n<\/ul>\n<p>Gdy to wszystko b\u0119dzie na miejscu, b\u0119dziemy w dobrej pozycji, aby zwr\u00f3ci\u0107 nasz\u0105 uwag\u0119 na bardziej zaawansowane rzeczy. Mianowicie, b\u0119dziemy mogli wprowadzi\u0107 subskrybent\u00f3w do wy\u015bwietlania informacji w obszarze administracyjnym oraz subskrybent\u00f3w do czyszczenia, serializacji, pobierania, sprawdzania i wy\u015bwietlania danych.<\/p>\n<p>Ale najpierw wykonajmy prac\u0119 niezb\u0119dn\u0105 do ustawienia nowej klasy, skonfigurowania autoloadera i wy\u015bwietlenia tre\u015bci w obszarze administracyjnym witryny.<\/p>\n<h3>1 Abstrakcyjny subskrybent<\/h3>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-00-abstract-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Przyjrzyjmy<\/a> si\u0119 najpierw subskrybentowi abstraktu, poniewa\u017c to w\u0142a\u015bnie zaimplementuj\u0105 wszyscy subskrybenci.<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\n\/**\n * An abstract implementation of a subscriber that requires a hook and the ability to\n * start the class.\n *\/\nabstract class AbstractSubscriber\n{\n    \/**\n     * @var string a reference to the hook to which the subscriber should be registered\n     *\/\n    protected $hook;\n\n    \/**\n     * @param string $hook the hook to which the subscriber is registered\n     *\/\n    public function __construct(string $hook)\n    {\n        $this-&gt;hook = $hook;\n    }\n\n    \/**\n     * @return string the hook to which the subscriber is registered\n     *\/\n    public function getHook(): string\n    {\n        return $this-&gt;hook;\n    }\n\n    \/**\n     * Implements the domain logic for the concrete class implementating this subcriber.\n     *\/\n    abstract public function load();\n}\n<\/code><\/pre>\n<p>Zauwa\u017c, \u017ce ma dwie publiczne funkcje \u2014 konstrukcj\u0119, kt\u00f3ra ustawia zaczep i funkcj\u0119 do pobierania zaczepu. Posiada r\u00f3wnie\u017c abstrakcyjn\u0105 funkcj\u0119 \u0142adowania, w kt\u00f3rej ka\u017cda klasa, kt\u00f3ra rozszerza t\u0119 klas\u0119, implementuje swoj\u0105 specyficzn\u0105 funkcjonalno\u015b\u0107.<\/p>\n<p>Przypomnij sobie, \u017ce ze wzgl\u0119du na spos\u00f3b, w jaki WordPress obs\u0142uguje akcje i filtry, wszystko jest do\u0142\u0105czone do okre\u015blonego haka (albo tych <a href=\"https:\/\/codex.wordpress.org\/Plugin_API\/Hooks\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">, kt\u00f3re WordPress definiuje,<\/a> albo niestandardowych hak\u00f3w).<\/p>\n<h3>2 Przestrze\u0144 nazw WordPress<\/h3>\n<p>Za ka\u017cdym razem, gdy pracuj\u0119 nad funkcjonalno\u015bci\u0105 \u015bci\u015ble powi\u0105zan\u0105 z WordPress, staram si\u0119 umie\u015bci\u0107 j\u0105 w przestrzeni nazw WordPressa. Wskazuje to dla mnie, jak r\u00f3wnie\u017c dla innych programist\u00f3w, \u017ce wszystko, co znajduje si\u0119 w tej przestrzeni nazw, nie mo\u017ce by\u0107 oddzielone od podstawowej aplikacji.<\/p>\n<p>Tak wi\u0119c w\u00a0 katalogu <strong>src<\/strong> utw\u00f3rz\u00a0 katalog <strong>WordPress<\/strong>. To tutaj b\u0119dzie znajdowa\u0107 si\u0119 podstawowa klasa Widget\u00f3w wraz z innymi klasami wprowadzonymi w tej serii.<\/p>\n<p>Oznacza to, \u017ce nie potrzebujemy ju\u017c klasy w katalogu API. Dlatego upewnij si\u0119, \u017ce przenosisz klas\u0119, aktualizujesz jej przestrze\u0144 nazw i usuwasz katalog. Troch\u0119 p\u00f3\u017aniej zrobi\u0119 zrzut ekranu i troch\u0119 kodu.<\/p>\n<p>Dodatkowo, przypomnijmy, wcze\u015bniej w serii umie\u015bcili\u015bmy\u00a0 katalog <strong>Views<\/strong> w katalogu g\u0142\u00f3wnym\u00a0 katalogu <strong>src<\/strong>, ale teraz mo\u017cemy go przenie\u015b\u0107 do\u00a0 katalogu <strong>WordPress<\/strong>. Wi\u0119c \u015bmia\u0142o zr\u00f3b to teraz.<\/p>\n<p>Ostateczny wynik powinien wygl\u0105da\u0107 mniej wi\u0119cej tak:<\/p>\n<p>Teraz mo\u017cemy zwr\u00f3ci\u0107 uwag\u0119 na kod.<\/p>\n<h3>3 Spojrzenie na klas\u0119 wid\u017cet\u00f3w<\/h3>\n<p>W tym po\u015bcie zamierzamy nieco upro\u015bci\u0107 podstawow\u0105 klas\u0119 wid\u017cet\u00f3w. To cofnie cz\u0119\u015b\u0107 naszej pracy, ale potrzebowali\u015bmy tej poprzedniej pracy, aby doprowadzi\u0107 nas do tego punktu.<\/p>\n<p>Na razie skupiamy si\u0119 na konstruktorze i funkcji pobierania informacji o wid\u017cecie. To w\u0142a\u015bnie ostatecznie pozwoli nam zobaczy\u0107 co\u015b w obszarze administracyjnym WordPressa.<\/p>\n<p>Wi\u0119c najpierw upewnij si\u0119, \u017ce Twoja klasa Widget wygl\u0105da <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-01-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\n * (c) Tom McFarlin &lt;tom@tommcfarlin.com&gt;\n *\n * This source file is subject to the GPL license that is bundled\n * with this source code in the file LICENSE.\n *\/\n\nnamespace WordPressWidgetBoilerplateWordPress;\n\nuse WP_Widget;\n\nclass Widget extends WP_Widget\n{\n    \/**\n     * @var string unique identifier for your widget\n     *\/\n    protected $widgetSlug;\n\n    \/**\n     * Initializes the plugin by setting its properties and calling the parent class with the description.\n     *\n     * @param mixed $widgetSlug\n     *\/\n    public function __construct($widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n\n        parent::__construct(\n            $this-&gt;getWidgetSlug(),\n            __('Widget Name', $this-&gt;getWidgetSlug()),\n            [\n                'classname' =&gt; $this-&gt;getWidgetSlug().'-class',\n                'description' =&gt; __('Short description of the widget goes here.', $this-&gt;getWidgetSlug()),\n            ]\n        );\n    }\n\n    \/**\n     * Return the widget slug.\n     *\n     * @return string slug variable\n     *\/\n    public function getWidgetSlug()\n    {\n        return $this-&gt;widgetSlug;\n    }\n}<\/code><\/pre>\n<p>Nast\u0119pnie, poniewa\u017c przenie\u015bli\u015bmy ten plik do\u00a0 przestrzeni nazw <strong>WordPress<\/strong>, musimy zaktualizowa\u0107 sekcj\u0119 autoload <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-02-composer-json\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">naszego pliku konfiguracyjnego Composera<\/a> :<\/p>\n<pre><code>\"autoload\": {\n    \"psr-4\": {\n        \"WordPressWidgetBoilerplate\": \"src\/\",\n        \"WordPressWidgetBoilerplateUtilities\": \"src\/Utilities\/\",\n        \"WordPressWidgetBoilerplateSubscriber\": \"src\/Subscriber\/\",\n        \"WordPressWidgetBoilerplateWordPress\": \"src\/WordPress\/\"\n    }\n},<\/code><\/pre>\n<p>Nast\u0119pnie musimy wprowadzi\u0107 subskrybenta.<\/p>\n<h3>4 Przedstawiamy subskrybenta wid\u017cetu<\/h3>\n<p>Za ka\u017cdym razem, gdy mam jak\u0105\u015b klas\u0119 podstawow\u0105, zazwyczaj staram si\u0119 stworzy\u0107 prostego subskrybenta, kt\u00f3ry tworzy instancj\u0119 klasy podstawowej i pozwala jej wykonywa\u0107 swoj\u0105 prac\u0119.<\/p>\n<p>Robi\u0119 to, poniewa\u017c WordPress, jak wspomniano, u\u017cywa wzorca projektowego opartego na zdarzeniach, co oznacza, \u017ce \u200b\u200bwszystko musi by\u0107 zarejestrowane w jakim\u015b typie haka. I nie lubi\u0119 miesza\u0107 logiki domeny z t\u0105 sam\u0105 klas\u0105, kt\u00f3ra \u0142\u0105czy si\u0119 z WordPressem. Wi\u0119c je rozdzielam.<\/p>\n<p>I to w\u0142a\u015bnie robi subskrybent. Rejestruje si\u0119 w WordPressie, a nast\u0119pnie wywo\u0142uje klas\u0119 odpowiedzialn\u0105 za faktyczne wykonanie pracy.<\/p>\n<p>Powiedziawszy to, zwr\u00f3\u0107 uwag\u0119 na\u00a0 katalog <strong>Subscriber<\/strong> i dodaj klas\u0119 o nazwie <strong>WidgetSubscriber<\/strong>. W tej klasie <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-03-widget-subscriber-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">dodaj nast\u0119puj\u0105cy kod<\/a> :<\/p>\n<pre><code>&lt;?php\n\n&lt;?php\n\nnamespace WordPressWidgetBoilerplateSubscriber;\n\nuse WordPressWidgetBoilerplateWordPressWidget;\n\n\/**\n * Initializes the core Widget class that's used by WordPress to instantiate the widget,\n * renders the administrative area, provide serialization functionality, and displays the\n * public-facing view.\n *\/\nclass WidgetSubscriber extends AbstractSubscriber\n{\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function __construct(string $hook)\n    {\n        parent::__construct($hook);\n    }\n\n    \/**\n     * Registers the core Widget class using the WordPress APIs.\n     *\/\n    public function load()\n    {\n        register_widget(new Widget('widget-name'));\n    }\n}\n<\/code><\/pre>\n<p>Konstruktor zarejestruje klas\u0119 z konkretnym hakiem, kt\u00f3ry za chwil\u0119 przyjrzymy; nast\u0119pnie u\u017cyje API WordPressa do utworzenia instancji naszego wid\u017cetu (co dzieje si\u0119 w\u00a0 funkcji <strong>\u0142adowania<\/strong> ).<\/p>\n<h3>5 Zapasy<\/h3>\n<p>Na koniec musimy zaktualizowa\u0107 bootstrap, aby:<\/p>\n<ul>\n<li>rejestruje <strong>WidgetSubscriber<\/strong> z odpowiednim hakiem,<\/li>\n<li>dodaje subskrybenta do <strong>Rejestru<\/strong> ,<\/li>\n<li>i uruchamia wtyczk\u0119 (co robili\u015bmy).<\/li>\n<\/ul>\n<p>Po tym wszystkim bootstrap powinien wygl\u0105da\u0107 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/f2e397e634ed2422d4840e6402a59fb9#file-04-bootstrap-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak<\/a> :<\/p>\n<pre><code>&lt;?php\n\nnamespace WordPressWidgetBoilerplate;\n\nuse WordPressWidgetBoilerplateUtilitiesRegistry;\nuse WordPressWidgetBoilerplatePlugin;\nuse WordPressWidgetBoilerplateSubscriberWidgetSubscriber;\n\n\/\/ Prevent this file from being called directly.\ndefined('WPINC') || die;\n\n\/\/ Include the autoloader.\nrequire_once __DIR__. '\/vendor\/autoload.php';\n\n\/\/ Setup a filter so we can retrieve the registry throughout the plugin.\n$registry = new Registry();\nadd_filter('wpwBoilerplateRegistry', function() use ($registry) {\n    return $registry;\n});\n\n\/\/ Add the Widget base class to the Registry.\n$registry-&gt;add('widgetSubscriber', new WidgetSubscriber('widgets_init'));\n\n\/\/ Start the machine.\n(new Plugin($registry))-&gt;start();<\/code><\/pre>\n<p>Nast\u0119pnie powiniene\u015b by\u0107 w stanie zalogowa\u0107 si\u0119 do WordPressa i aktywowa\u0107 wtyczk\u0119.<\/p>\n<h2>Spojrzenie na obszar administracyjny<\/h2>\n<p>W tym momencie nie ma na co patrze\u0107, ale do tego dochodzimy. Po pierwsze, powiniene\u015b zauwa\u017cy\u0107, \u017ce wid\u017cet pojawia si\u0119 teraz w obszarze zawieraj\u0105cym dost\u0119pne wid\u017cety:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160941-61e7175c46bcc.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160941-61e7175c46bcc.png\" alt=\"Wid\u017cety WordPress: Refaktoryzacja, cz\u0119\u015b\u0107 8\"><\/a><\/p>\n<p>Powiniene\u015b tak\u017ce zauwa\u017cy\u0107, \u017ce po przeci\u0105gni\u0119ciu wid\u017cetu do obszaru wid\u017cet\u00f3w (lub dowolnego paska bocznego), nie ma on dost\u0119pnych opcji.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160941-61e7175f91557.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160941-61e7175f91557.png\" alt=\"Wid\u017cety WordPress: Refaktoryzacja, cz\u0119\u015b\u0107 8\"><\/a><\/p>\n<p>To powiedziawszy, jeste\u015bmy w dobrym miejscu, aby dalej budowa\u0107 na tym, co mamy. Zawsze mo\u017cesz nadal \u015bledzi\u0107 rozw\u00f3j boilerplate&#8217;u <a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">w serwisie GitHub<\/a>.<\/p>\n<h2>Kontynuacja w\u0142.<\/h2>\n<p>Nast\u0119pnie b\u0119dziemy kontynuowa\u0107 tworzenie funkcjonalno\u015bci obszaru administracyjnego wid\u017cetu. Nast\u0119pnie zwr\u00f3cimy uwag\u0119 na publiczn\u0105 stron\u0119 wid\u017cetu oraz na funkcj\u0119 serializacji.<\/p>\n<p>Powiniene\u015b by\u0107 w stanie zobaczy\u0107, jak rzeczy zaczynaj\u0105 nabiera\u0107 kszta\u0142tu, gdy zaczynamy rozdziela\u0107 logik\u0119 na jej r\u00f3\u017cne elementy. Je\u015bli nie, nie martw si\u0119 \u2013 przed nami jeszcze wiele.<\/p>\n<p>A ostateczna wersja Boilerplate b\u0119dzie oczywi\u015bcie zademonstrowa\u0107 wszystkie zasady, na kt\u00f3rych opieramy si\u0119 w tej serii post\u00f3w.<\/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>Zaczniemy rozdziela\u0107 r\u00f3\u017cne komponenty, kt\u00f3re sk\u0142adaj\u0105 si\u0119 na wid\u017cety WordPress, zaczynaj\u0105c od obszaru administracyjnego.<\/p>\n","protected":false},"author":1,"featured_media":234945,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,845,866],"tags":[1169],"class_list":["post-230734","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230734","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=230734"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/230734\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/234945"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=230734"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=230734"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=230734"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}