{"id":230985,"date":"2022-12-24T18:29:00","date_gmt":"2022-12-24T15:29:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230985"},"modified":"2022-12-24T18:31:24","modified_gmt":"2022-12-24T15:31:24","slug":"ett-allmaent-exempel-paa-foervarsmoenstret-i-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/ett-allmaent-exempel-paa-foervarsmoenstret-i-wordpress\/","title":{"rendered":"Ett allm\u00e4nt exempel p\u00e5 f\u00f6rvarsm\u00f6nstret i WordPress"},"content":{"rendered":"\n<p>Enligt min erfarenhet p\u00e5verkar s\u00e4ttet vi f\u00f6rst interagerar med f\u00f6rvarsdesignm\u00f6nstret ofta hur vi t\u00e4nker om m\u00f6nstret. (Hela f\u00f6rsta intrycken \u00e4r best\u00e5ende intryck, eller hur?)<\/p>\n<p>Syftet med det h\u00e4r inl\u00e4gget \u00e4r att visa hur det kan implementeras i WordPress specifikt n\u00e4r man skriver objektorienterade plugins f\u00f6r att l\u00e4sa data (skrivdata kan t\u00e4ckas i ett annat inl\u00e4gg), men innan jag gjorde det f\u00f6rs\u00f6kte jag t\u00e4nka p\u00e5 n\u00e5gra konsistenser bland de varianter av m\u00f6nstret som jag har sett.<\/p>\n<p>Generellt sett \u00e4r detta vad jag tycker att ett f\u00f6rvarsm\u00f6nster b\u00f6r g\u00f6ra:<\/p>\n<ul>\n<li>tillhandah\u00e5lla en enda plats att l\u00e4sa data,<\/li>\n<li>abstrahera detaljerna om hur data n\u00e5s,<\/li>\n<li>och har ett konsekvent gr\u00e4nssnitt f\u00f6r att g\u00f6ra det.<\/li>\n<\/ul>\n<p>Det betyder att vad du \u00e4n beh\u00f6ver h\u00e4mta fr\u00e5n applikationen kan h\u00e4mtas fr\u00e5n databasen. Men hur det h\u00e4mtas kan betraktas som en svart l\u00e5da. Det \u00e4r upp till utvecklaren som implementerar m\u00f6nstret.<\/p>\n<p>Och i fallet f\u00f6r dem som l\u00e4ser det h\u00e4r inl\u00e4gget s\u00e5 \u00e4r det med st\u00f6rsta sannolikhet vi.<\/p>\n<h2>F\u00f6rvarsm\u00f6nstret i WordPress<\/h2>\n<p>F\u00f6r ett par \u00e5r sedan skrev <a href=\"https:\/\/wordpress.mediadoma.com\/sv\/repository-pattern-primer\/\" title=\"jag om f\u00f6rvarsm\u00f6nstret och\">jag om f\u00f6rvarsm\u00f6nstret och<\/a> gav ett konkret exempel. Det \u00e4r fortfarande relevant, men syftet med det jag vill ta upp i det h\u00e4r inl\u00e4gget \u00e4r lite annorlunda.<\/p>\n<p>Ist\u00e4llet f\u00f6r att visa en viss implementering med r\u00f6tter i ett verkligt exempel vill jag hellre argumentera f\u00f6r hur vi kan anv\u00e4nda detta m\u00f6nster i v\u00e5rt dagliga arbete.<\/p>\n<p>De tv\u00e5 sakerna att t\u00e4nka p\u00e5 n\u00e4r du l\u00e4ser detta \u00e4r:<\/p>\n<ol>\n<li>ur anv\u00e4ndarens perspektiv spelar den underliggande datalagringen ingen roll,<\/li>\n<li>ur utvecklarens perspektiv till\u00e5ter m\u00f6nstret oss att arbeta med flera datak\u00e4llor och \u00e4ven h\u00e5na ett exempeldatalager s\u00e5 att vi kan enhetstesta data.<\/li>\n<\/ol>\n<p>N\u00e4r du implementerar m\u00f6nstret spelar det ingen roll var data kommer ifr\u00e5n. \u00c5tminstone s\u00e5 l\u00e4nge som du \u00e4r utvecklaren eller klientobjektet som anropar det. Datalagret kan vara en databas, en upps\u00e4ttning API-funktioner eller en kombination av b\u00e5da.<\/p>\n<p>Anta d\u00e5 att du arbetar med en anpassad inl\u00e4ggstyp f\u00f6r Events och att du ocks\u00e5 arbetar med inl\u00e4ggsmetadata och alternativ relaterade till n\u00e5got som h\u00e4ndelser.<\/p>\n<p>Du kan g\u00f6ra n\u00e5got som:<\/p>\n<ul>\n<li>f\u00e5 namnet p\u00e5 h\u00e4ndelsen,<\/li>\n<li>hitta information om platsen f\u00f6r evenemanget,<\/li>\n<li>h\u00e4mta den f\u00f6rsta posttypen och statusen sorterad efter dess ID<\/li>\n<\/ul>\n<p>All denna information kan vara spridd p\u00e5 olika platser och hur den h\u00e4mtas kan variera.<\/p>\n<h3>1 H\u00e4mta h\u00e4ndelsenamnet<\/h3>\n<p>Om vi \u200b\u200barbetar med en anpassad inl\u00e4ggstyp och vi beh\u00f6ver f\u00e5 h\u00e4ndelsenamnet kan vi anv\u00e4nda ett inl\u00e4ggs ID och <a href=\"https:\/\/gist.github.com\/tommcfarlin\/24e5bae859863d39512abc2af2169fbb#file-00-get-event-name-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">en av WordPress API-funktioner f\u00f6r att g\u00f6ra det<\/a>.<\/p>\n<pre><code>&lt;?php\n\n\/**\n * Retrieves the title of the Event, a custom post type.\n *\n * @param  int    $eventId the ID of the event post type\n * @return string          the title of the post.\n *\/\npublic function getName(int $eventId): string\n{\n  return get_the_title($eventId);\n}<\/code><\/pre>\n<p>Detta \u00e4r ett fall d\u00e4r datalagret fortfarande \u00e4r abstraherat fr\u00e5n oss och ist\u00e4llet utnyttjar det befintliga WordPress API.<\/p>\n<h3>2 H\u00e4mta h\u00e4ndelseplatsen<\/h3>\n<p>I det h\u00e4r fallet kan vi anta att h\u00e4ndelseplatsen har angetts manuellt eller kanske har h\u00e4mtats av ett tredje parts API. Och eftersom platsen \u00e4r associerad med en specifik h\u00e4ndelse kan den finnas i postmetadatatabellen.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160195-61e7073d3924f.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-160195-61e7073d3924f.png\" alt=\"Ett allm\u00e4nt exempel p\u00e5 f\u00f6rvarsm\u00f6nstret i WordPress\"><\/a><\/p>\n<p>\u00c5terigen, vi kan h\u00e4mta det med hj\u00e4lp av redan existerande API-funktioner; Men i s\u00e5dana h\u00e4r situationer \u00e4r det vettigt att ha en hj\u00e4lpfunktion eftersom vi sannolikt ocks\u00e5 kommer \u00e5t annan metadata.<\/p>\n<p>S\u00e5 f\u00f6rst, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/24e5bae859863d39512abc2af2169fbb#file-01-get-the-event-location-helper-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">hj\u00e4lparen<\/a> :<\/p>\n<pre><code>&lt;?php \n\/**\n * A helper function for easily retrieving post meta data for a given Event.\n *\n * @param int    $id  the ID of the event\n * @param string $key the key for the post meta data for which we're retrieveing the data\n *\n * @return string the result of retrieiving the meta data\n *\/\nprivate function get(int $id, string $key): string\n{\n    return get_post_meta($id, $key, true);\n}<\/code><\/pre>\n<p>Och sedan funktionen som anv\u00e4nder hj\u00e4lparen f\u00f6r att <a href=\"https:\/\/gist.github.com\/tommcfarlin\/24e5bae859863d39512abc2af2169fbb#file-02-get-the-event-location-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">f\u00e5 platsen<\/a> :<\/p>\n<pre><code>&lt;?php\n\/**\n * @param  int    $eventID the ID of the event\n * @return string          the name of the event of an empty string\n *\/\npublic function getLocationName($eventId): string\n{\n    return $this-&gt;get($eventId, 'ymc-event-location-name');\n}<\/code><\/pre>\n<p>Men i dessa tv\u00e5 exempel anv\u00e4nder vi fortfarande befintliga API-funktioner. Hur \u00e4r det med fallet d\u00e4r vi beh\u00f6ver prata med databasen?<\/p>\n<h3>3 H\u00e4mta en URL f\u00f6r ett inl\u00e4gg<\/h3>\n<p>I det h\u00e4r fallet kommer vi att kommunicera direkt med WordPress-databasen. Om du \u00e4r bekant med <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">$wpdb-<\/a> objektet och SQL kommer detta inte att vara en stor sak.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-160195-61e70741367bc.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-160195-61e70741367bc.png\" alt=\"Ett allm\u00e4nt exempel p\u00e5 f\u00f6rvarsm\u00f6nstret i WordPress\"><\/a><\/p>\n<p>Om du inte \u00e4r det rekommenderar jag att du l\u00e4ser om funktionen <a href=\"https:\/\/codex.wordpress.org\/Data_Validation#Database\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">f\u00f6rbereda<\/a> s\u00e5v\u00e4l som funktionen <a href=\"https:\/\/codex.wordpress.org\/Class_Reference\/wpdb#Talking_to_the_Database:_The_wpdb_Class\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_results<\/a>.<\/p>\n<p>Med tanke p\u00e5 detta kan vi skriva en fr\u00e5ga som g\u00f6r f\u00f6ljande:<\/p>\n<ol>\n<li>ta tag i alla inl\u00e4gg d\u00e4r ID matchar ett visst v\u00e4rde, inl\u00e4ggstyp och inl\u00e4ggsstatus \u00e4r ett visst v\u00e4rde, s\u00e5 ordnar vi resultaten efter stigande v\u00e4rde p\u00e5 ID,<\/li>\n<li>sedan anv\u00e4nder vi resultaten av den fr\u00e5gan f\u00f6r att f\u00e5 ett enda v\u00e4rde.<\/li>\n<\/ol>\n<p>Och <a href=\"https:\/\/gist.github.com\/tommcfarlin\/24e5bae859863d39512abc2af2169fbb#file-03-get-single-post-url-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">vi kan g\u00f6ra detta<\/a> genom att b\u00e5de komma \u00e5t databasen och skriva en kapslad fr\u00e5ga:<\/p>\n<pre><code>&lt;?php\n\n\/**\n * @return string the URL to the event next to the current event.\n *\/\npublic function getNextEventUrl()\n{\n    global $wpdb;\n    $results = $wpdb-&gt;get_results(\n        $wpdb-&gt;prepare(\n            \"\n            SELECT *\n            FROM $wpdb-&gt;posts\n            WHERE ID &gt; (SELECT ID\n                FROM $wpdb-&gt;posts\n                WHERE ID = %d\n                AND post_type = '%s'\n                AND post_status = '%s'\n                ORDER BY ID ASC) AND post_type = '%s'\n            AND post_status = '%s'\n            ORDER BY ID ASC\n            LIMIT 1\n        \",\n            get_the_ID(),\n            'ymc-events',\n            'publish',\n            'ymc-events',\n            'publish') );\n\n  $result = (isset($result[0]))? $result[0]: '';\n\n  return $result;\n}<\/code><\/pre>\n<p>Och sedan kan allt detta inkapslas i en enda klass som skulle vara, s\u00e4g, Event Repository (eller <strong>EventRepository<\/strong> ).<\/p>\n<p>Jag kommer dock att ha mer om detta i ett uppf\u00f6ljande inl\u00e4gg. N\u00e4mligen, hur man hanterar best\u00e4mmer vilka funktioner som h\u00f6r hemma var, namnkonventionerna och hur man hanterar persistens om du ocks\u00e5 vill introducera det i ditt arkiv.<\/p>\n<h2>Lagringsplats definierad<\/h2>\n<p>Ha framf\u00f6r allt detta i \u00e5tanke:<\/p>\n<p>F\u00f6rvarsm\u00f6nstret maskerar hur data h\u00e4mtas men ger ett konsekvent s\u00e4tt f\u00f6r hur data som den \u00e4r relaterad till kan h\u00e4mtas.<\/p>\n<p>Vissa kanske ocks\u00e5 l\u00e4gger till hur det kan h\u00e4mtas <strong>och<\/strong> hur det kan skrivas, men det kanske jag tar upp i ett annat inl\u00e4gg.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Inspelningsk\u00e4lla:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>F\u00f6rvarsm\u00f6nstret ger ett konsekvent s\u00e4tt f\u00f6r hur data kan h\u00e4mtas. S\u00e5 h\u00e4r kan det implementeras i ett WordPress-plugin.<\/p>\n","protected":false},"author":1,"featured_media":236255,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[901,724,868],"tags":[1173],"class_list":["post-230985","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-koda","category-utvecklaren","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/230985","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/comments?post=230985"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/230985\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/236255"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=230985"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=230985"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=230985"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}