{"id":228754,"date":"2022-11-01T09:30:00","date_gmt":"2022-11-01T06:30:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=228754"},"modified":"2022-11-09T04:09:31","modified_gmt":"2022-11-09T01:09:31","slug":"registrera-wordpress-hooks-med-en-annan-klass","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/sv\/registrera-wordpress-hooks-med-en-annan-klass\/","title":{"rendered":"Registrera WordPress Hooks med en annan klass"},"content":{"rendered":"\n<p>I <a href=\"https:\/\/wordpress.mediadoma.com\/sv\/wordpress-plugin-konstruktoerer-borde-inte-definiera-krokar\/\" title=\"g\u00e5rdagens inl\u00e4gg\" >g\u00e5rdagens inl\u00e4gg<\/a> pratade jag om ett WordPress-plugin-konstrukt\u00f6rer och sk\u00e4len till varf\u00f6r krokar inte borde finnas i konstrukt\u00f6ren.<\/p>\n<p>\u00c4ven om jag n\u00e4mnde ett antal s\u00e4tt att hantera krokregistrering, brydde jag mig inte om att g\u00e5 in p\u00e5 detaljer f\u00f6r var och en av dessa strategier. F\u00f6r mig \u00e4r de v\u00e4rda en egen artikel f\u00f6r att ge s\u00e5 mycket detaljer som m\u00f6jligt f\u00f6r hur man st\u00e4ller upp n\u00e5got.<\/p>\n<p>Till exempel, en av metoderna jag delade sa:<\/p>\n<ul>\n<li>Det \u00e4r m\u00f6jligt att skapa en klass som uppr\u00e4tth\u00e5ller ett register \u00f6ver objekt och krokar med WordPress.<\/li>\n<\/ul>\n<p>Det handlar med andra ord om att registrera WordPress-hooks med hj\u00e4lp av ett objektorienterat tillv\u00e4gag\u00e5ngss\u00e4tt f\u00f6r att minska kopplingen och \u00f6ka sammanh\u00e5llningen mellan komponenterna i plugin.<\/p>\n<p>Men vad betyder det ens? Vilka \u00e4r f\u00f6rdelarna med det, hur \u00e4r det konfigurerat och hur anv\u00e4nds det?<\/p>\n<h2>Registrera WordPress Hooks<\/h2>\n<p>Om du l\u00e4ser det h\u00e4r \u00e4r du f\u00f6rmodligen bekant med WordPress <a href=\"https:\/\/codex.wordpress.org\/Plugin_API#Hooks:_Actions_and_Filters\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">hook-systemet<\/a>, ordningen p\u00e5 hur de aktiveras och hur en funktion eller klass kan registrera sina funktioner med WordPress s\u00e5 att de kan utf\u00f6ra det arbete de beh\u00f6ver hantera.<\/p>\n<p>Och vi ser ofta klasser som g\u00f6r detta p\u00e5 egen hand. Beroende p\u00e5 projekt g\u00f6r jag det sj\u00e4lv. F\u00f6r de som inte \u00e4r bekanta ser det vanligtvis ut <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-00-plugins-loaded-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ungef\u00e4r s\u00e5 h\u00e4r<\/a> :<\/p>\n<pre><code>&lt;?php\n\nadd_action( 'plugins_loaded', 'acme_start' );\n\/**\n * Start the machine.\n * https:\/\/www.youtube.com\/watch?v=ysoMOefPyRs\n *\/\nfunction acme_start() {\n    $plugin = new AcmeColumn();\n}\n<\/code><\/pre>\n<p>Men allt detta kan delas upp i mer sammanh\u00e5llna klasser f\u00f6r att i slut\u00e4ndan ge dem klasser \u00e4nnu mindre ansvar (en bra sak) och f\u00f6r att minska kopplingen mellan en klass eller upps\u00e4ttning klasser med WordPress.<\/p>\n<p>Ett exempel p\u00e5 en design som jag ska bryta ner i det h\u00e4r inl\u00e4gget.<\/p>\n<p>Den kontraintuitiva karakt\u00e4ren av detta \u00e4r dock att det kommer att kr\u00e4va \u00e5tminstone en annan klass. Men s\u00e5 h\u00e4r fungerar det.<\/p>\n<h2>Konfigurera det<\/h2>\n<p>F\u00f6r detta exempel kommer vi bara att anv\u00e4nda en enkel klass som kommer att registrera n\u00e5gon typ av \u00e5tg\u00e4rd med WordPress. Id\u00e9n till arkitekturen fungerar ungef\u00e4r s\u00e5 h\u00e4r:<\/p>\n<ol>\n<li>Det finns huvudklassen som har funktionen vi vill koppla till WordPress.<\/li>\n<li>Det finns en klass som ansvarar f\u00f6r att orkestrera kopplingen av klassens funktion till WordPress.<\/li>\n<\/ol>\n<p>L\u00e4tt nog, eller hur? Men h\u00e4r \u00e4r haken: Klassen som ansvarar f\u00f6r att registrera en given klass funktioner med WordPress \u00e4r punkten som kr\u00e4ver ett designbeslut.<\/p>\n<p>L\u00e5t oss f\u00f6rst kalla klassen <strong>HookRegistry<\/strong> s\u00e5 att vi kan referera till den ordentligt. L\u00e5t oss sedan kalla klassen med funktionerna som vi vill koppla <strong>AcmeColumn<\/strong> helt enkelt f\u00f6r att representera en klass som l\u00e4gger till en ny kolumn p\u00e5 sidans instrumentpanel i adminomr\u00e5det i WordPress.<\/p>\n<p>Med det p\u00e5 plats kommer designbeslutet ner p\u00e5 detta:<\/p>\n<ol>\n<li>B\u00f6r <strong>HookRegistery<\/strong> veta om <strong>AcmeColumn?<\/strong><\/li>\n<li>B\u00f6r <strong>AcmeColumn<\/strong> k\u00e4nna till <strong>HookRegistry<\/strong>? <\/li>\n<\/ol>\n<p>Jag vet att det finns andra s\u00e4tt att organisera detta och det finns ocks\u00e5 strategier f\u00f6r hur man hanterar detta (som <a href=\"https:\/\/carlalexander.ca\/dependency-inversion-principle-wordpress\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">inversion av kontroll<\/a>) och det h\u00e4r \u00e4r \u00e4mnen som \u00e4r v\u00e4rda att utforska, men f\u00f6r att h\u00e5lla den h\u00e4r f\u00f6rsta id\u00e9n s\u00e5 enkel som m\u00f6jligt, ska jag l\u00e4gga upp det f\u00f6r ett framtida inl\u00e4gg.<\/p>\n<h3>Anv\u00e4nder klassen<\/h3>\n<p>Med tanke p\u00e5 alternativen ovan kommer vi att skicka en instans av <strong>AcmeColumn<\/strong> till <strong>HookRegistry<\/strong> n\u00e4r klasserna instansieras under den f\u00f6rsta WordPress-pluginstartprocessen. Det h\u00e4r kan se ut ungef\u00e4r <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-startup-process-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">s\u00e5 h\u00e4r<\/a> :<\/p>\n<pre><code>&lt;?php\n\nadd_action( 'plugins_loaded', 'acme_start' );\n\/**\n * Start the machine.\n * https:\/\/www.youtube.com\/watch?v=ysoMOefPyRs\n *\/\nfunction acme_start() {\n\n  $registry    = new HookRegistry();\n\n  $acme_column = new AcmeColumn( $registry );\n  $acme_column-&gt;start();\n}\n<\/code><\/pre>\n<p>D\u00e4refter, n\u00e4r det \u00e4r dags att l\u00e5ta <strong>AcmeColumn\u00a0<\/strong> registrera sin funktion med WordPress, ringer vi <strong>HookRegistry<\/strong> och instruerar det att g\u00f6ra det.<\/p>\n<p>F\u00f6rst, <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-acme-column-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">AcmeColumn<\/a> :<\/p>\n<pre><code>&lt;?php\n\nclass AcmeColumn {\n\n    private $registry;\n\n    public function __construct( $registry) {\n        $this-&gt;registry = $registry;\n    }\n\n    public function start() {\n        $registry-&gt;add_hook( 'filter', 'manage_edit-page_columns', $this, 'add_page_column' );\n    }\n\n    public function add_page_column( $page_columns) {\n\n        $page_columns['template'] = 'Acme Column';\n        return $page_columns;\n    } \n}\n<\/code><\/pre>\n<p>Sedan <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-02-hook-registry-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">HookRegistry<\/a> :<\/strong><\/p>\n<pre><code>&lt;?php\n\nclass HookRegistry {\n\n  public add_hook( $type, $name, $object, $method) {\n\n    $type = strtolower( $type );\n    if ('filter' !== $type || 'action' !== $type) {\n      return new WP_Error( '1', 'No proper hook type defined.' );\n    }\n  }\n\n  private function add_filter( $name, $object, $method) {\n    add_filter( $name, array( $object, $method) );\n  }\n\n  private function add_action( $name, $object, $method) {\n    add_action( $name, array( $object, $method) );\n  }\n}\n<\/code><\/pre>\n<p>Valfritt kan vi \u00e4ven f\u00f6ra en lista \u00f6ver de olika klasser och krokar som har registrerats. Detta kan eller kanske inte \u00e4r anv\u00e4ndbart beroende p\u00e5 din implementering s\u00e5 jag delar bara som ett &quot;h\u00e4r \u00e4r n\u00e5got som du kanske vill g\u00f6ra.&quot;<\/p>\n<p>Och det kan <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-03-hook-registry-improved-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">se ut s\u00e5 h\u00e4r<\/a> (med en enkel associativ array):<\/p>\n<pre><code>&lt;?php\n\nclass HookRegistry {\n\n  private $registry;\n\n  public function __construct() {\n    $this-&gt;registery = array(); \n  }\n\n  public add_hook( $id, $type, $name, $object, $method) {\n\n    $type = strtolower( $type );\n    if ('filter' !== $type || 'action' !== $type) {\n      return new WP_Error( '1', 'No proper hook type defined.' );\n    }\n\n    if ('filter' === $type) {\n      $this-&gt;add_filter( $name, $object, $method );\n    } else {\n      $this-&gt;add_action( $name, $object, $method );\n    }\n\n    $hook_info = array(\n      $type,\n      $name,\n      $object,\n      $method,\n    );\n    $this-&gt;registry[ $id ] = $hook_info;\n  }\n\n  private function add_filter( $name, $object, $method) {\n    add_filter( $name, array( $object, $method) );\n  }\n\n  private function add_action( $name, $object, $method) {\n    add_action( $name, array( $object, $method) );\n  }\n}\n<\/code><\/pre>\n<p>L\u00e4gg m\u00e4rke till att i klassen ovan accepterar den nu ett <strong>$id<\/strong> som en parameter. Det finns flera s\u00e4tt att identifiera informationen som kommer in i ett register, det enklaste \u00e4r att skapa ID sj\u00e4lv.<\/p>\n<p>Men om du vill anv\u00e4nda n\u00e5got som namnet p\u00e5 kroken eller namnet p\u00e5 klassen, skulle det ocks\u00e5 fungera. Observera bara att eftersom det \u00e4r en associativ array, kan den bara beh\u00e5lla ett enda v\u00e4rde per nyckel, s\u00e5 du kan hamna i att kasta tidigare data om du inte \u00e4r f\u00f6rsiktig.<\/p>\n<p>Oavsett vilket \u00e4r detta n\u00e5got som jag anser vara valfritt, men om det \u00e4r implementerat \u00e4r det viktigt att se till att du har r\u00e4tt funktioner f\u00f6r att h\u00e4mta en instans av objektet med en nyckel.<\/p>\n<h2>En av m\u00e5nga<\/h2>\n<p>Som med allt som har med den h\u00e4r typen av arbete att g\u00f6ra, \u00e4r det m\u00f6jligt att omarbeta eller omorientera detta p\u00e5 ett s\u00e4tt som fungerar annorlunda eller som passar dina behov. Syftet \u00e4r inte att visa det definitiva m\u00f6nstret f\u00f6r hur man g\u00f6r n\u00e5got, utan ett s\u00e4tt att n\u00e4rma sig och anpassa det (ungef\u00e4r som vilket designm\u00f6nster som helst).<\/p>\n<p>Vidare \u00e4r det menat att se till att v\u00e5ra klasser uppr\u00e4tth\u00e5ller det ansvar som de skapas f\u00f6r samtidigt som de l\u00e5ter dem registrera sig sj\u00e4lva med WordPress efter behov. Den h\u00e4r g\u00e5ngen beh\u00f6ver klassen dock inte g\u00f6ra det sj\u00e4lv.<\/p>\n<p>Ist\u00e4llet \u00f6verl\u00e4mnar den ansvaret till en klass som har det ensamma ansvaret f\u00f6r att registrera n\u00e4mnda krokar. S\u00e5 \u00e4ven om det introducerar fler klasser, \u00f6kar det sammanh\u00e5llningen och minskar kopplingen.<\/p>\n<p>Detta ger f\u00f6rdelar i underh\u00e5ll, testning och \u00f6vergripande design.<\/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>Det handlar om att registrera WordPress-hooks med ett objektorienterat tillv\u00e4gag\u00e5ngss\u00e4tt f\u00f6r att minska kopplingen och \u00f6ka sammanh\u00e5llningen i pluginet.<\/p>\n","protected":false},"author":1,"featured_media":223973,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[901,922,818,724,868],"tags":[1173],"class_list":["post-228754","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-koda","category-oevrig","category-plugins-3","category-utvecklaren","category-wordpress-9","tag-affiai-sv"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228754","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=228754"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/posts\/228754\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media\/223973"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/media?parent=228754"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/categories?post=228754"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/sv\/wp-json\/wp\/v2\/tags?post=228754"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}