{"id":231071,"date":"2022-12-27T11:48:00","date_gmt":"2022-12-27T08:48:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231071"},"modified":"2022-12-27T12:49:56","modified_gmt":"2022-12-27T09:49:56","slug":"zapytania-do-bazy-danych-w-celu-szybkiej-aktualizacji-danych-czesc-2","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/pl\/zapytania-do-bazy-danych-w-celu-szybkiej-aktualizacji-danych-czesc-2\/","title":{"rendered":"Zapytania do bazy danych w celu szybkiej aktualizacji danych, cz\u0119\u015b\u0107 2"},"content":{"rendered":"\n<p>To druga i ostatnia cz\u0119\u015b\u0107 z cyklu o \u2013 jak sugeruje tytu\u0142 \u2013 bezpo\u015brednich zapytaniach do bazy danych. W szczeg\u00f3lno\u015bci chodzi o zmian\u0119 status\u00f3w post\u00f3w (ale ma to znaczenie nie tylko).<\/p>\n<p>Zdj\u0119cie: Ross Findon na Unsplash<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/pl\/zapytania-do-bazy-danych-w-celu-szybkiej-aktualizacji-danych-czesc-1\/\" title=\"Z poprzedniego posta:\">Z poprzedniego posta:<\/a><\/p>\n<blockquote>\n<p>To kolejny post, kt\u00f3ry b\u0119dzie ilustracj\u0105 tego, jak u\u017cywa\u0107 $wpdb do szybkiego aktualizowania informacji na podstawie metadanych.<\/p>\n<\/blockquote>\n<p>Kod podany w tym po\u015bcie dzia\u0142a, ale je\u015bli chcesz uczyni\u0107 go bardziej zorientowanym obiektowo, to jest wi\u0119cej pracy do wykonania.<\/p>\n<p>Zanim jednak przejdziemy do w\u0142a\u015bciwego posta, nale\u017cy zauwa\u017cy\u0107, \u017ce je\u015bli chodzi o programowanie obiektowe, jest du\u017co pracy, kt\u00f3r\u0105 mo\u017cna po\u015bwi\u0119ci\u0107 na projektowanie klas i tworzenie poziom\u00f3w abstrakcji.<\/p>\n<p>W pewnym momencie musisz narysowa\u0107 przys\u0142owiow\u0105 granic\u0119 mi\u0119dzy tym, kiedy zamierzasz u\u017cywa\u0107 interfejs\u00f3w, a tym, jak szczeg\u00f3\u0142owe b\u0119d\u0105 twoje klasy pod wzgl\u0119dem tego, co abstrahuj\u0105, i tym podobne.<\/p>\n<p>Celem tego posta jest pomoc w zapewnieniu lepszego projektowania zorientowanego obiektowo, ale nie jest to \u0107wiczenie, aby uczyni\u0107 go tak optymalnym, jak to tylko mo\u017cliwe. Tematy takie jak ten omawiam w <a href=\"https:\/\/tommcfarlin.com\/tag\/object-oriented-programming-in-wordpress\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">innej serii post\u00f3w<\/a>.<\/p>\n<p>Ale miej to na uwadze, czytaj\u0105c kod w dalszej cz\u0119\u015bci postu.<\/p>\n<h2>Zapytania do bazy danych w celu szybkiej aktualizacji danych, cz\u0119\u015b\u0107 2<\/h2>\n<p>Bior\u0105c pod uwag\u0119, gdzie sko\u0144czyli\u015bmy, mamy jedn\u0105 funkcj\u0119 wykonuj\u0105c\u0105 nast\u0119puj\u0105ce czynno\u015bci:<\/p>\n<ol>\n<li>pobra\u0107 wszystkie posty powi\u0105zane z okre\u015blonym kluczem meta,<\/li>\n<li>okre\u015bli\u0107, czy musimy wyj\u015b\u0107 wcze\u015bniej,<\/li>\n<li>aktualizowa\u0107 status post\u00f3w istniej\u0105cych post\u00f3w.<\/li>\n<\/ol>\n<p>Pierwsz\u0105 rzecz\u0105, na kt\u00f3r\u0105 nale\u017cy zwr\u00f3ci\u0107 uwag\u0119, jest to, \u017ce pojedyncza funkcja to za du\u017co, wi\u0119c nale\u017cy j\u0105 podzieli\u0107 na kilka innych funkcji. A poniewa\u017c jest zorientowany obiektowo, musimy upewni\u0107 si\u0119, \u017ce to, co robi funkcja, niekoniecznie jest oparte na poprzednich krokach \u2013 na tym w\u0142a\u015bnie polega programowanie proceduralne.<\/p>\n<p>Zamiast tego wykorzystamy t\u0119 okazj\u0119 do skonfigurowania funkcji, aby dzia\u0142a\u0142y na wszelkich przekazywanych im danych, niezale\u017cnie od tego, w jaki spos\u00f3b si\u0119 tam dosta\u0142y.<\/p>\n<p>Wreszcie, do Ciebie, jako dewelopera, nale\u017cy okre\u015blenie, czy chcesz mie\u0107 do tego jedn\u0105 klas\u0119, wi\u0119cej ni\u017c jedn\u0105, czy te\u017c zestaw klas powi\u0105zanych, kt\u00f3re dziedzicz\u0105 po klasie nadrz\u0119dnej.<\/p>\n<p>Ponownie, chodzi o to, jak abstrakcyjny chcesz zrobi\u0107 kod.<\/p>\n<p>Na razie jednak przejd\u017amy do przodu z rozbijaniem rzeczy.<\/p>\n<h3>1 Chwy\u0107 identyfikatory post\u00f3w za pomoc\u0105 powi\u0105zanego klucza meta<\/h3>\n<p>Podobnie jak w pierwszym po\u015bcie, chcemy si\u0119 upewni\u0107, \u017ce pobieramy identyfikatory wpis\u00f3w, kt\u00f3re s\u0105 powi\u0105zane z okre\u015blonym kluczem meta.<\/p>\n<p>Aby ta funkcja by\u0142a jak najbardziej elastyczna, skonfigurujemy j\u0105 tak, aby:<\/p>\n<ul>\n<li>zaakceptuj meta klucz jako ci\u0105g,<\/li>\n<li>zwr\u00f3\u0107 tablic\u0119<\/li>\n<\/ul>\n<p>Funkcja b\u0119dzie wtedy wygl\u0105da\u0107 mniej wi\u0119cej <a href=\"https:\/\/gist.github.com\/tommcfarlin\/233a98350aa5ad4765e2a3c84691b0c1#file-00-get-inactive-post-ids-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">tak:<\/a><\/p>\n<pre><code>&lt;?php\n\n\/**\n * Locates all of the post IDs that are associated with an empty meta key (which\n * is specified as an argument for the function).\n *\n * @param string $metaKey The meta key used to retrieve the set of post IDs.\n * @return array $results The set of product IDs associated with the specified meta key.\n *\/\npublic function getInactivePostIds(string $metaKey): array\n{\n    global $wpdb;\n\n    $results = $wpdb-&gt;get_results(\n        $wpdb-&gt;prepare(\n            \"\n            SELECT post_id\n            FROM $wpdb-&gt;postmeta\n            WHERE meta_key = %s\n            AND meta_value = ''\n            \",\n            $metaKey) );\n\n    return $results;\n}<\/code><\/pre>\n<p>W pierwszym po\u015bcie podzielili\u015bmy to na trzy kroki (kt\u00f3re r\u00f3wnie\u017c zosta\u0142y opisane powy\u017cej). Tutaj jednak mo\u017cemy po\u0142\u0105czy\u0107 drugi i trzeci krok w jedn\u0105 funkcj\u0119.<\/p>\n<h3>2 Zaktualizuj status postu<\/h3>\n<p>Jak wspomnia\u0142em, jednym aspektem programowania obiektowego jest upewnienie si\u0119, \u017ce funkcje, kt\u00f3rych u\u017cywamy, s\u0105 niezale\u017cne od sposobu generowania danych, kt\u00f3re otrzymuj\u0105.<\/p>\n<p>Zamiast tego maj\u0105 pojedynczy algorytm do uruchomienia, aby skupi\u0107 si\u0119 na danych przekazywanych do funkcji. W takim przypadku chcemy pobra\u0107 zestaw wynik\u00f3w \u2014 kt\u00f3re s\u0105 identyfikatorami post\u00f3w \u2014 i zaktualizowa\u0107 ich status posta, tak aby by\u0142 ustawiony na <strong>wersj\u0119 robocz\u0105<\/strong>.<\/p>\n<p>Oznacza to, \u017ce funkcja zaakceptuje tablic\u0119, ale niczego nie zwr\u00f3ci. Potencjalnie m\u00f3g\u0142by\u015b \u015bledzi\u0107 wiele post\u00f3w, kt\u00f3re zaktualizowa\u0142 (lub je\u015bli w og\u00f3le co\u015b zaktualizowa\u0142), ale ja skupiam si\u0119 tylko na refaktoryzacji kodu, kt\u00f3ry ju\u017c mamy.<\/p>\n<p>Wi\u0119c to w\u0142a\u015bnie zamierzamy zrobi\u0107. Pierwsz\u0105 rzecz\u0105 jest upewnienie si\u0119, \u017ce istniej\u0105 rzeczywiste dane, z kt\u00f3rymi mo\u017cna pracowa\u0107. A je\u015bli tak, to przeprowad\u017a iteracj\u0119 listy identyfikator\u00f3w post\u00f3w i <a href=\"https:\/\/gist.github.com\/tommcfarlin\/233a98350aa5ad4765e2a3c84691b0c1#file-01-set-posts-to-draft-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">zmie\u0144 ich status post\u00f3w:<\/a><\/p>\n<pre><code>&lt;?php\n\n\/**\n * Updates incoming posts by setting their post status to 'draft.'\n *\n * @param array $postData the set of post IDs associated with the specific meta key.\n *\/\npublic function setPostsToDraft(array $postData)\n{\n    \/\/ If the post data is empty, there's nothing to do.\n    if (0 === count($postData)) {\n        return;\n    }\n\n    \/\/ Otherwise, set the post_status of the specified post IDs to 'draft'.\n    global $wpdb;\n    foreach ($postData as $post) {\n        $wpdb-&gt;get_results(\n            $wpdb-&gt;prepare(\n                \"\n                UPDATE $wpdb-&gt;posts\n                SET post_status = %s\n                WHERE ID = %d\n                \",\n                'draft',\n                (int) ($post-&gt;post_id)) );\n    }\n}<\/code><\/pre>\n<p>Wida\u0107, \u017ce nie r\u00f3\u017cni si\u0119 to zbytnio od pracy wykonanej w pierwszym po\u015bcie, ale teraz rodzi kilka pyta\u0144.<\/p>\n<h3>3 Rozwa\u017cania zorientowane na obiekt<\/h3>\n<p>Podczas pracy z takim kodem:<\/p>\n<ul>\n<li>Czy to wszystko nale\u017cy do tej samej klasy, czy do oddzielnych klas?<\/li>\n<li>Czy powinna istnie\u0107 klasa bazowa, a je\u015bli tak, to dlaczego lub dlaczego nie?<\/li>\n<li>Czy powinna by\u0107 wywo\u0142ywana pojedyncza funkcja publiczna, kt\u00f3ra wywo\u0142uje te metody (i oznacza je jako prywatne)?<\/li>\n<li>Czy powinni\u015bmy pozostawi\u0107 funkcje publiczne?<\/li>\n<\/ul>\n<p>W tym po\u015bcie zrobi\u0119 co nast\u0119puje:<\/p>\n<ul>\n<li><strong>Ujawnij ka\u017cd\u0105 funkcj\u0119 jako metod\u0119 publiczn\u0105<\/strong>. Dzieje si\u0119 tak, \u017ce je\u015bli istniej\u0105 dane zwr\u00f3cone z pierwszej metody, mo\u017cesz potencjalnie zrobi\u0107 z ni\u0105 co\u015b innego.<\/li>\n<li><strong>Trzymaj to w jednej klasie<\/strong>. W ten spos\u00f3b mo\u017cemy utworzy\u0107 instancj\u0119 pojedynczej klasy, a nast\u0119pnie u\u017cy\u0107 jej do wykonania dowolnej pracy, kt\u00f3r\u0105 musimy wykona\u0107. Gdyby istnia\u0142y inne metody, u\u017cyliby\u015bmy tych samych metod.<\/li>\n<li><strong>Zacznij od interfejsu<\/strong>. Nie zamierzam zawraca\u0107 sobie g\u0142owy pisaniem interfejsu tylko po to, aby pokaza\u0107 interfejs (zak\u0142adam, \u017ce \u0142atwo to wydedukowa\u0107, bior\u0105c pod uwag\u0119 funkcje, kt\u00f3re mamy w tej chwili), ale zamierzam wzi\u0105\u0107 klas\u0119 i pokaza\u0107, jak mo\u017cemy wywo\u0142a\u0107 funkcje \u201eod zewn\u0105trz do wewn\u0105trz&quot;.<\/li>\n<\/ul>\n<p>Wi\u0119c zaczn\u0119 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/233a98350aa5ad4765e2a3c84691b0c1#file-02-invoking-the-class-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">od ostatniego punktu<\/a> i b\u0119d\u0119 pracowa\u0142 wstecz. Oto jeden ze sposob\u00f3w pracy z kodem:<\/p>\n<pre><code>&lt;?php\n\n$postStatusModifier = new PostStatusModifier();\n$inactivePost = $postStatusModifier-&gt;getInactivePostIds('acme-status');\n$postStatusModifier-&gt;setPostsToDraft($inactivePosts);<\/code><\/pre>\n<p>A oto jak wygl\u0105da <a href=\"https:\/\/gist.github.com\/tommcfarlin\/233a98350aa5ad4765e2a3c84691b0c1#file-03-post-status-modifier-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ca\u0142a klasa :<\/a><\/p>\n<pre><code>&lt;?php\n\nclass PostStatusModifier\n{\n    \/**\n     * Locates all of the post IDs that are associated with an empty meta key (which\n     * is specified as an argument for the function).\n     *\n     * @param string $metaKey The meta key used to retrieve the set of post IDs.\n     * @return array $results The set of product IDs associated with the specified meta key.\n     *\/\n    public function getInactivePostIds(string $metaKey): array\n    {\n        global $wpdb;\n\n        $results = $wpdb-&gt;get_results(\n            $wpdb-&gt;prepare(\n                \"\n                SELECT post_id\n                FROM $wpdb-&gt;postmeta\n                WHERE meta_key = %s\n                AND meta_value = ''\n                \",\n                $metaKey) );\n\n        return $results;\n    }\n\n    \/**\n     * Updates incoming posts by setting their post status to 'draft.'\n     *\n     * @param array $postData the set of post IDs associated with the specific meta key.\n     *\/\n    public function setPostsToDraft(array $postData)\n    {\n        \/\/ If the post data is empty, there's nothing to do.\n        if (0 === count($postData)) {\n            return;\n        }\n\n        \/\/ Otherwise, set the post_status of the specified post IDs to 'draft'.\n        global $wpdb;\n        foreach ($postData as $post) {\n            $wpdb-&gt;get_results(\n                $wpdb-&gt;prepare(\n                    \"\n                    UPDATE $wpdb-&gt;posts\n                    SET post_status = %s\n                    WHERE ID = %d\n                    \",\n                    'draft',\n                    (int) ($post-&gt;post_id)) );\n        }\n    }\n}<\/code><\/pre>\n<p>Og\u00f3lnie rzecz bior\u0105c, b\u0119dzie to s\u0142u\u017cy\u0142o tym samym celom, co pierwsze, ale w spos\u00f3b bardziej zorientowany obiektowo.<\/p>\n<h2>To nie jest droga<\/h2>\n<p>Jak wielokrotnie pr\u00f3bowa\u0142em powt\u00f3rzy\u0107 w tym po\u015bcie, nie jest to ostateczny spos\u00f3b na wykonanie tej pracy. Zamiast tego jest to jeden ze sposob\u00f3w wykonywania pracy.<\/p>\n<p>Mo\u017cesz ponownie zaprojektowa\u0107, ponownie uwzgl\u0119dni\u0107 lub ponownie wykorzysta\u0107 to, jak uznasz za stosowne. Celem jest jednak pokazanie, jak oddzieli\u0107 logik\u0119, kt\u00f3r\u0105 zwykle postrzegamy jako proceduraln\u0105, w co\u015b, co jest nieco mniej zale\u017cne od siebie i pozostawia miejsce na dodatkow\u0105 prac\u0119.<\/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>Korzystanie z zasad zorientowanych obiektowo w celu ulepszenia projektowania klas do pisania zapyta\u0144 do bazy danych w celu szybkiej aktualizacji danych.<\/p>\n","protected":false},"author":1,"featured_media":237043,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[721,919,897,836,845],"tags":[1169],"class_list":["post-231071","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-deweloper","category-inny","category-kod","category-przewodnik-dla-poczatkujacych","category-samouczki","tag-affiai-pl"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/231071","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=231071"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/posts\/231071\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media\/237043"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/media?parent=231071"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/categories?post=231071"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/pl\/wp-json\/wp\/v2\/tags?post=231071"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}