{"id":229423,"date":"2022-11-01T10:15:00","date_gmt":"2022-11-01T07:15:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229423"},"modified":"2022-11-09T06:59:19","modified_gmt":"2022-11-09T03:59:19","slug":"wordpress-koukkujen-rekisteroeinti-toisella-luokalla","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/wordpress-koukkujen-rekisteroeinti-toisella-luokalla\/","title":{"rendered":"WordPress-koukkujen rekister\u00f6inti toisella luokalla"},"content":{"rendered":"\n<p>Eilisess\u00e4 <a href=\"https:\/\/wordpress.mediadoma.com\/fi\/wordpress-laajennusten-rakentajien-ei-pitaeisi-maeaeritellae-koukkuja\/\" title=\"postauksessa\" >postauksessa<\/a> puhuin WordPress-laajennuksen rakentajista ja perusteluista sille, miksi koukkujen ei pit\u00e4isi olla rakentajassa.<\/p>\n<p>Vaikka mainitsinkin useita tapoja k\u00e4sitell\u00e4 koukun rekister\u00f6inti\u00e4, en vaivautunut menem\u00e4\u00e4n yksityiskohtiin kunkin strategian osalta. Minun mielest\u00e4ni he ansaitsevat oman artikkelinsa tarjotakseen mahdollisimman paljon yksityiskohtia siit\u00e4, miten jotain asetetaan.<\/p>\n<p>Esimerkiksi yksi jakamistani tavoista sanoi:<\/p>\n<ul>\n<li>WordPressill\u00e4 on mahdollista luoda luokka, joka yll\u00e4pit\u00e4\u00e4 rekisteri\u00e4 objekteista ja koukuista.<\/li>\n<\/ul>\n<p>Toisin sanoen kyse on WordPress-koukkujen rekister\u00f6innist\u00e4 k\u00e4ytt\u00e4m\u00e4ll\u00e4 oliol\u00e4ht\u00f6ist\u00e4 l\u00e4hestymistapaa kytkenn\u00e4n v\u00e4hent\u00e4miseksi ja yhteenkuuluvuuden lis\u00e4\u00e4miseksi laajennuksen komponenttien v\u00e4lill\u00e4.<\/p>\n<p>Mutta mit\u00e4 se edes tarkoittaa? Mit\u00e4 hy\u00f6ty\u00e4 siit\u00e4 on, miten se asennetaan ja miten sit\u00e4 k\u00e4ytet\u00e4\u00e4n?<\/p>\n<h2>WordPress-koukkujen rekister\u00f6inti<\/h2>\n<p>Jos luet t\u00e4t\u00e4, olet todenn\u00e4k\u00f6isesti perehtynyt WordPress- <a href=\"https:\/\/codex.wordpress.org\/Plugin_API#Hooks:_Actions_and_Filters\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">hook-j\u00e4rjestelm\u00e4\u00e4n<\/a>, niiden k\u00e4ynnistysj\u00e4rjestykseen ja siihen, kuinka funktio tai luokka voi rekister\u00f6id\u00e4 funktionsa WordPressiin, jotta ne voivat suorittaa mit\u00e4 tahansa tarvitsemaansa ty\u00f6t\u00e4.<\/p>\n<p>Ja n\u00e4emme usein luokkien tekev\u00e4n t\u00e4m\u00e4n yksin. Projektista riippuen teen sen itse. Niille, jotka eiv\u00e4t ole tuttuja, se n\u00e4ytt\u00e4\u00e4 yleens\u00e4 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-00-plugins-loaded-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e4lt\u00e4<\/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>Mutta kaikki t\u00e4m\u00e4 voidaan jakaa yhten\u00e4isemmiksi luokiksi, jotta niille annetaan lopulta viel\u00e4 v\u00e4hemm\u00e4n vastuuta (hyv\u00e4 asia) ja v\u00e4hennet\u00e4\u00e4n luokan tai luokkajoukon v\u00e4list\u00e4 yhteytt\u00e4 WordPressin kanssa.<\/p>\n<p>Esimerkki mallista, jonka aion purkaa t\u00e4ss\u00e4 viestiss\u00e4.<\/p>\n<p>T\u00e4m\u00e4n intuitiivisen vastakohtana on kuitenkin se, ett\u00e4 se vaatii ainakin toisen luokan. Mutta n\u00e4in se toimii.<\/p>\n<h2>K\u00e4ytt\u00f6\u00f6notto<\/h2>\n<p>T\u00e4ss\u00e4 esimerkiss\u00e4 k\u00e4yt\u00e4mme vain yksinkertaista luokkaa, joka rekister\u00f6i tietyn tyyppisen toiminnon WordPressiin. Idea arkkitehtuurista toimii jotakuinkin n\u00e4in:<\/p>\n<ol>\n<li>Siell\u00e4 on p\u00e4\u00e4luokka, jolla on toiminto, jonka haluamme liitt\u00e4\u00e4 WordPressiin.<\/li>\n<li>Siell\u00e4 on luokka, joka vastaa luokan funktion liitt\u00e4misest\u00e4 WordPressiin.<\/li>\n<\/ol>\n<p>Tarpeeksi helppoa, eik\u00f6? Mutta t\u00e4ss\u00e4 on saalis: luokka, joka vastaa tietyn luokan funktioiden rekister\u00f6imisest\u00e4 WordPressiin, on se kohta, joka vaatii suunnittelup\u00e4\u00e4t\u00f6ksen.<\/p>\n<p>Kutsutaan ensin luokkaa <strong>HookRegistry<\/strong>, jotta voimme viitata siihen oikein. Kutsutaan seuraavaksi luokkaa funktioineen, joihin haluamme liitt\u00e4\u00e4 <strong>AcmeColumn<\/strong> yksinkertaisesti edustamaan luokkaa, joka lis\u00e4\u00e4 uuden sarakkeen, sivun hallintapaneeliksi WordPressin hallinta-alueella.<\/p>\n<p>Kun se on paikallaan, suunnittelup\u00e4\u00e4t\u00f6s tulee t\u00e4h\u00e4n:<\/p>\n<ol>\n<li>Pit\u00e4isik\u00f6 <strong>HookRegisteryn<\/strong> tiet\u00e4\u00e4 <strong>AcmeColumnista?<\/strong><\/li>\n<li>Pit\u00e4isik\u00f6 <strong>AcmeColumn<\/strong> tiet\u00e4\u00e4 <strong>HookRegistryst\u00e4<\/strong>? <\/li>\n<\/ol>\n<p>Tied\u00e4n, ett\u00e4 on olemassa muitakin tapoja j\u00e4rjest\u00e4\u00e4 t\u00e4m\u00e4 ja on olemassa my\u00f6s strategioita t\u00e4m\u00e4n k\u00e4sittelemiseksi (kuten <a href=\"https:\/\/carlalexander.ca\/dependency-inversion-principle-wordpress\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">ohjauksen k\u00e4\u00e4nt\u00e4minen p\u00e4invastaiseksi<\/a> ), ja n\u00e4m\u00e4 ovat aiheita, joihin kannattaa tutustua, mutta jotta t\u00e4m\u00e4 alkuper\u00e4inen idea pysyisi mahdollisimman suoraviivaisena, esit\u00e4n sen tuleva postaus.<\/p>\n<h3>Luokan k\u00e4ytt\u00e4minen<\/h3>\n<p>Yll\u00e4 olevat vaihtoehdot huomioiden v\u00e4lit\u00e4mme AcmeColumnin esiintym\u00e4n <strong>HookRegistryyn<\/strong><strong>,<\/strong> kun luokat instantoidaan WordPress-laajennuksen ensimm\u00e4isen k\u00e4ynnistysprosessin aikana. T\u00e4m\u00e4 voi n\u00e4ytt\u00e4\u00e4 <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-startup-process-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">t\u00e4lt\u00e4<\/a> :<a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-startup-process-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external\"><\/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>Seuraavaksi aina kun on aika pyyt\u00e4\u00e4 <strong>AcmeColumn\u00a0<\/strong> rekister\u00f6im\u00e4\u00e4n toimintonsa WordPressiin, soitamme <strong>HookRegistrylle<\/strong> ja opastamme sit\u00e4 tekem\u00e4\u00e4n niin.<\/p>\n<p>Ensinn\u00e4kin <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>Sitten <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>Valinnaisesti voimme my\u00f6s yll\u00e4pit\u00e4\u00e4 luetteloa eri luokista ja koukuista, jotka on rekister\u00f6ity. T\u00e4m\u00e4 voi olla hy\u00f6dyllinen tai ei ehk\u00e4 hy\u00f6dyllinen toteutuksestasi riippuen, joten jaan puhtaasti &quot;t\u00e4ss\u00e4 on jotain, mit\u00e4 saatat haluta tehd\u00e4&quot;.<\/p>\n<p>Ja se voisi <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-03-hook-registry-improved-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">n\u00e4ytt\u00e4\u00e4 t\u00e4lt\u00e4<\/a> (k\u00e4ytt\u00e4m\u00e4ll\u00e4 yksinkertaista assosiatiivista taulukkoa):<\/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>Huomaa, ett\u00e4 yll\u00e4 olevassa luokassa se hyv\u00e4ksyy nyt <strong>$id<\/strong> :n parametrina. Voit tunnistaa rekisteriin menev\u00e4t tiedot useilla tavoilla, joista helpoin on luoda tunnus itse.<\/p>\n<p>Kuitenkin, jos haluat k\u00e4ytt\u00e4\u00e4 jotain, kuten koukun tai luokan nime\u00e4, sekin toimisi. Huomaa vain, ett\u00e4 koska se on assosiatiivinen matriisi, se voi s\u00e4ilytt\u00e4\u00e4 vain yhden arvon avainta kohden, joten voit p\u00e4\u00e4ty\u00e4 roskakoriin aiemman tiedon, jos et ole varovainen.<\/p>\n<p>T\u00e4st\u00e4 huolimatta pid\u00e4n t\u00e4t\u00e4 valinnaisena, mutta jos se on otettu k\u00e4ytt\u00f6\u00f6n, on t\u00e4rke\u00e4\u00e4 varmistaa, ett\u00e4 sinulla on oikeat toiminnot objektin esiintym\u00e4n hakemiseen avaimella.<\/p>\n<h2>Yksi monista<\/h2>\n<p>Kuten kaiken t\u00e4m\u00e4ntyyppiseen ty\u00f6h\u00f6n liittyv\u00e4n, t\u00e4m\u00e4nkin on mahdollista suunnitella tai suunnitella uudelleen tavalla, joka toimii eri tavalla tai sopii tarpeisiisi. Tarkoituksena ei ole n\u00e4ytt\u00e4\u00e4 lopullista kaavaa, miten jotain tehd\u00e4\u00e4n, vaan tapa l\u00e4hesty\u00e4 ja mukauttaa sit\u00e4 (kuten mik\u00e4 tahansa suunnittelumalli).<\/p>\n<p>Lis\u00e4ksi sen tarkoituksena on varmistaa, ett\u00e4 luokkamme s\u00e4ilytt\u00e4v\u00e4t vastuut, joita varten ne on luotu, samalla kun he voivat rekister\u00f6ity\u00e4 WordPressiin tarpeen mukaan. T\u00e4ll\u00e4 kertaa luokan ei kuitenkaan tarvitse tehd\u00e4 sit\u00e4 itse.<\/p>\n<p>Sen sijaan se siirt\u00e4\u00e4 vastuun luokalle, joka on yksin vastuussa mainittujen koukkujen rekister\u00f6imisest\u00e4. Joten vaikka se tuo lis\u00e4\u00e4 luokkia, se lis\u00e4\u00e4 koheesiota ja v\u00e4hent\u00e4\u00e4 kytkent\u00e4\u00e4.<\/p>\n<p>T\u00e4m\u00e4 tarjoaa etuja yll\u00e4pidossa, testauksessa ja yleisess\u00e4 suunnittelussa.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Kyse on WordPress-koukkujen rekister\u00f6innist\u00e4 k\u00e4ytt\u00e4m\u00e4ll\u00e4 oliol\u00e4ht\u00f6ist\u00e4 l\u00e4hestymistapaa kytkenn\u00e4n v\u00e4hent\u00e4miseksi ja laajennuksen koheesion lis\u00e4\u00e4miseksi.<\/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":[719,895,813,917,864],"tags":[1166],"class_list":["post-229423","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kehittaejae","category-koodi","category-laajennuksia","category-muut","category-wordpress-5","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/229423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/comments?post=229423"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/229423\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/223973"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=229423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=229423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=229423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}