{"id":231354,"date":"2023-01-04T13:46:00","date_gmt":"2023-01-04T10:46:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231354"},"modified":"2023-01-04T13:49:38","modified_gmt":"2023-01-04T10:49:38","slug":"odlaczanie-logiki-domeny-w-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/odlaczanie-logiki-domeny-w-wordpress\/","title":{"rendered":"Od\u0142\u0105czanie logiki domeny w WordPress"},"content":{"rendered":"\n<p>Pami\u0119taj, \u017ce WordPress u\u017cywa <a href=\"https:\/\/en.wikipedia.org\/wiki\/Event-driven_architecture\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">wzorca projektowego opartego na zdarzeniach<\/a> i chocia\u017c cz\u0119sto odwo\u0142ujemy si\u0119 do dzia\u0142a\u0144 i filtr\u00f3w, koncepcja sprowadza si\u0119 do hook\u00f3w. Przep\u0142yw kontroli przez program wygl\u0105da mniej wi\u0119cej tak:<\/p>\n<ol>\n<li>Wykonaj program,<\/li>\n<li>Za ka\u017cdym razem, gdy program natrafi na hak (w WordPressie zobaczymy <code>do_action<\/code>lub <code>apply_filters<\/code>), przeprowad\u017a iteracj\u0119 wszystkich zarejestrowanych hak\u00f3w,<\/li>\n<li>Przywr\u00f3\u0107 sterowanie z powrotem do programu,<\/li>\n<li>Wykona\u0107 do ko\u0144ca.<\/li>\n<\/ol>\n<p>Nie r\u00f3\u017cni si\u0119 to ca\u0142kowicie od wzorca wydawcy\/subskrybenta (lub w <a href=\"https:\/\/en.wikipedia.org\/wiki\/Publish%E2%80%93subscribe_pattern\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">skr\u00f3cie PubSub<\/a> ), ale jest kluczowa r\u00f3\u017cnica: wzorzec oparty na zdarzeniach po prostu sygnalizuje, \u017ce co\u015b si\u0119 wydarzy\u0142o, a je\u015bli s\u0105 zaczepy, zostan\u0105 uruchomione. Wzorzec PubSub poinformuje zarejestrowanego subskrybenta, aby co\u015b zrobi\u0142.<\/p>\n<p>W ka\u017cdym razie wr\u00f3\u0107 do hook\u00f3w w WordPressie. Zachowanie dw\u00f3ch koncepcji hak\u00f3w, kt\u00f3re mamy, mo\u017cna naj\u0142atwiej zrobi\u0107, my\u015bl\u0105c o nich w ten spos\u00f3b:<\/p>\n<ul>\n<li>Akcje s\u0142u\u017c\u0105 do robienia czego\u015b,<\/li>\n<li>Filtry s\u0142u\u017c\u0105 do przetwarzania danych.<\/li>\n<\/ul>\n<p>Je\u015bli chcesz podej\u015b\u0107 do programowania WordPress w spos\u00f3b zorientowany obiektowo, \u015bcis\u0142e \u0142\u0105czenie kodu z rdzeniem WordPressa poprzez rejestrowanie klas za pomoc\u0105 zaczep\u00f3w do aplikacji rdzenia nie jest dobrym pomys\u0142em.<\/p>\n<p>Innymi s\u0142owy, nie rejestruj swojej logiki biznesowej w WordPressie. Trzymaj je osobno. Oto papierek lakmusowy sprawdzaj\u0105cy, czy Twoja praca jest \u015bci\u015ble powi\u0105zana z WordPress: Je\u015bli nie mo\u017cesz przeprowadzi\u0107 testu jednostkowego na swojej klasie bez za\u0142adowania WordPressa, jest to \u015bci\u015ble powi\u0105zane.<\/p>\n<p>Wi\u0119c jakie jest rozwi\u0105zanie? Delegacja.<\/p>\n<h2>Logika domeny w WordPress<\/h2>\n<p>Logika domeny i logika biznesowa s\u0105 dla mnie wymienne, wi\u0119c je\u015bli czyta\u0142e\u015b poprzednie posty na ten temat i m\u00f3wi\u0142em o nich na r\u00f3\u017cne sposoby, wiesz dlaczego.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-158738-61e6e493ec777.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-158738-61e6e493ec777.png\" alt=\"Od\u0142\u0105czanie logiki domeny w WordPress\"><\/a><\/p>\n<p><a href=\"https:\/\/unsplash.com\/photos\/guiQYiRxkZY\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Kredyt<\/a><\/p>\n<p>Nast\u0119pnie pomys\u0142 delegowania logiki z WordPressa do klasy logiki domeny w WordPressie jest realizowany przez klas\u0119 po\u015brednicz\u0105c\u0105, kt\u00f3ra jest odpowiedzialna za:<\/p>\n<ol>\n<li>Zapisuj\u0105c si\u0119 na hak,<\/li>\n<li>Delegowanie pracy do klasy.<\/li>\n<\/ol>\n<p>Wiem, \u017ce zaj\u0119cia maj\u0105 robi\u0107 \u201ejedn\u0105 rzecz dobrze&quot;, ale co, je\u015bli t\u0105 jedn\u0105 rzecz\u0105 jest delegowanie?<\/p>\n<blockquote>\n<p>zobowi\u0105za\u0107 si\u0119 (uprawnienia, funkcje itp.) do innego jako agenta<\/p>\n<p><a href=\"https:\/\/www.dictionary.com\/browse\/delegate\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">s\u0142ownik<\/a><\/p>\n<\/blockquote>\n<p>Aby w\u0142a\u015bciwie przekaza\u0107 funkcjonalno\u015b\u0107 innemu agentowi lub, w naszym przypadku, klasie, musisz wiedzie\u0107, co delegujesz. Czasami, aby zrobi\u0107 jedn\u0105 rzecz, musisz zna\u0107 kilka informacji.<\/p>\n<p>Wi\u0119c jak to wygl\u0105da w praktyce? Wyobra\u017a sobie, \u017ce masz <code>[AbstractSubscriber](https:\/\/github.com\/tommcfarlin\/remove-empty-shortcodes\/blob\/master\/src\/Subscriber\/AbstractSubscriber.php)<\/code>do przejmie nazw\u0119 haka do swojego konstruktora:<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of Remove Empty Shortcodes.\n *\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 TomMcFarlinRESCSubscriber;\n\nuse TomMcFarlinUtilitiesRegistry;\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     * @var Registry a reference to the simple container used to maintain plugin objects\n     *\/\n    protected $registry;\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        $this-&gt;registry = apply_filters('rescRegistry', null);\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    abstract public function load();\n}<\/code><\/pre>\n<p>A gdy to si\u0119 stanie, <code>load<\/code>funkcja prze\u015ble prac\u0119 do klasy odpowiedzialnej za faktyczne przetwarzanie.<\/p>\n<p>We\u017amy na przyk\u0142ad <a href=\"https:\/\/github.com\/tommcfarlin\/remove-empty-shortcodes\/blob\/master\/src\/WordPress\/PostContentProcessor.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ten kod<\/a> z <a href=\"https:\/\/github.com\/tommcfarlin\/remove-empty-shortcodes\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Remove Empty Shortcodes<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of Remove Empty Shortcodes.\n *\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 TomMcFarlinRESCWordPress;\n\n\/**\n * Processes the post content by looking to see if any orphaned shortcode\n * exists and then removes it from displaying it from the user.\n *\/\nclass PostContentProcessor\n{\n    \/**\n     * A reference to the Shortcode Manager for processing orphaned shortcodes.\n     *\/\n    private $shortcodeManager;\n\n    \/**\n     * Initializes the class by setting up a reference to the Registry and the\n     * Shortcode Manager.\n     *\/\n    public function __construct()\n    {\n        $registry = apply_filters('rescRegistry', null);\n        $this-&gt;shortcodeManager = $registry-&gt;get('shortcodeManager');\n    }\n\n    \/**\n     * @param string $content the filtered post content\n     *\n     * @return string $content the filtered post content without the shortcode\n     *\/\n    public function run(string $content): string\n    {\n        return $this-&gt;shortcodeManager-&gt;processShortcodes($content);\n    }\n}<\/code><\/pre>\n<p>Klasa subskrybuje okre\u015blone zdarzenie, takie jak <code>[the_content](https:\/\/developer.wordpress.org\/reference\/functions\/the_content\/)<\/code>, a nast\u0119pnie deleguje prac\u0119 do klasy przetwarzania tre\u015bci postu.<\/p>\n<p>To ca\u0142kiem dos\u0142ownie pozwala plikowi startowemu wtyczki na utworzenie instancji delegata. Nast\u0119pnie delegat \u0142\u0105czy si\u0119 z WordPressem i kiedy WordPress dociera do w\u0142a\u015bciwego punktu wykonania, delegat wysy\u0142a odpowiedzialno\u015b\u0107 do klasy odpowiedzialnej za jej przetwarzanie.<\/p>\n<p>Ca\u0142a ta architektura jest nie tylko ca\u0142kowicie wielokrotnego u\u017cytku (patrz u\u017cycie klasy abstrakcyjnej powy\u017cej), ale pozwala nam oddzieli\u0107 logik\u0119 domeny od WordPressa i przetestowa\u0107 j\u0105 w izolacji.<\/p>\n<h2>Wi\u0119cej o separacji obaw<\/h2>\n<p>Napisa\u0142em kilka innych post\u00f3w na temat oddzielania obaw:<\/p>\n<ul>\n<li><a href=\"https:\/\/tommcfarlin.com\/separation-of-concerns-with-wordpress-templates\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Separacja obaw za pomoc\u0105 szablon\u00f3w WordPress<\/a><\/li>\n<li><a href=\"https:\/\/tommcfarlin.com\/separation-of-concerns-with-queries-and-helper-functions\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Rozdzielanie w\u0105tpliwo\u015bci za pomoc\u0105 zapyta\u0144 i funkcji pomocniczych<\/a><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/pl\/programowanie-wordpress-oddzielanie-obaw\/\" title=\"Programowanie WordPress: oddzielanie obaw\">Programowanie WordPress: oddzielanie obaw<\/a><\/li>\n<\/ul>\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>Pami\u0119taj, \u017ce WordPress u\u017cywa wzorca projektowego opartego na zdarzeniach i chocia\u017c cz\u0119sto odwo\u0142ujemy si\u0119 do dzia\u0142a\u0144 i filtr\u00f3w, koncepcja sprowadza si\u0119 do hook\u00f3w. Przep\u0142yw kontroli przez program idzie co\u015b\u2026<\/p>\n","protected":false},"author":1,"featured_media":158739,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,919,897,836,845,866],"tags":[1169],"class_list":["post-231354","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-kod","category-przewodnik-dla-poczatkujacych","category-samouczki","category-wordpress-7","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/231354","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=231354"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/231354\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/158739"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=231354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=231354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=231354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}