{"id":231405,"date":"2022-12-20T12:25:00","date_gmt":"2022-12-20T09:25:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=231405"},"modified":"2022-12-20T12:25:09","modified_gmt":"2022-12-20T09:25:09","slug":"wordpress-widgetit-refaktorointi-osa-10","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/fi\/wordpress-widgetit-refaktorointi-osa-10\/","title":{"rendered":"WordPress-widgetit: Refaktorointi, osa 10"},"content":{"rendered":"\n<p>Mit\u00e4 tulee WordPress Widget Boilerplaten uudelleenj\u00e4rjestelyyn, olemme hyv\u00e4ss\u00e4 paikassa. Paljon ty\u00f6t\u00e4 on tehty niin, ett\u00e4 uusien luokkien, ominaisuuksien ja toimintojen k\u00e4ytt\u00f6\u00f6noton pit\u00e4isi olla paljon helpompaa.<\/p>\n<p>Eik\u00e4 vain sit\u00e4: Sen pit\u00e4isi olla helpompi seurata.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/fi\/wordpress-widgetit-refaktorointi-osa-9\/\" title=\"Kiitos edellisen postauksen ty\u00f6st\u00e4\">Kiitos edellisen postauksen ty\u00f6st\u00e4<\/a>, meill\u00e4 on paljon teht\u00e4v\u00e4\u00e4 &#8211; nimitt\u00e4in perushallinnollinen k\u00e4ytt\u00f6liittym\u00e4.<\/p>\n<p>Lopuksi viimeisess\u00e4 viestiss\u00e4 sanottiin:<\/p>\n<blockquote>\n<p>Muutaman seuraavan artikkelin aikana t\u00e4m\u00e4 kehittyy edelleen, mutta kuten n\u00e4et, varmistamme, ett\u00e4 meill\u00e4 on yksi perustoimintoluokka WordPressin kanssa keskustelua varten ja luokka erityisesti hallinnollisen lomakkeen render\u00f6inti\u00e4 varten.<\/p>\n<\/blockquote>\n<p>Ja siit\u00e4 aiomme poimia t\u00e4ss\u00e4 artikkelissa. Tarkastelemme erityisesti tietojen puhdistamista ja sarjoittamista sek\u00e4 widgetiin tallennettujen tietojen hakemista.<\/p>\n<h2>WordPress Widget Boilerplate: Refactoring osa 10<\/h2>\n<h3>K\u00e4ytt\u00f6liittym\u00e4n refaktorointi<\/h3>\n<p>Ennen kuin aloitamme serialisoinnin, meid\u00e4n on teht\u00e4v\u00e4 joitain pieni\u00e4 t\u00f6it\u00e4 hallinnollisen n\u00e4kym\u00e4mme suhteen. Muista sarjan aiemmista viesteist\u00e4, ett\u00e4 olemme rakentaneet lomakkeen, joka hyv\u00e4ksyy:<\/p>\n<ul>\n<li>titteli,<\/li>\n<li>jotain sis\u00e4lt\u00f6\u00e4,<\/li>\n<li>ja valintaruutu.<\/li>\n<\/ul>\n<p>T\u00e4m\u00e4 n\u00e4kyy hienosti, mutta se ei sis\u00e4ll\u00e4 joitakin <a href=\"https:\/\/codex.wordpress.org\/Widgets_API#Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Widgets API<\/a> :n t\u00e4rkeimpi\u00e4 ominaisuuksia. Meid\u00e4n on nimitt\u00e4in varmistettava, ett\u00e4 nime\u00e4mme elementit oikein seuraavilla funktioilla:<\/p>\n<ul>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/get_field_id\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get_field_id<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/reference\/classes\/wp_widget\/get_field_name\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">hanki_kent\u00e4n_nimi<\/a><\/li>\n<\/ul>\n<p>Ja sitten kirjoitamme funktiomme nimelt\u00e4 <a href=\"https:\/\/codex.wordpress.org\/Widgets_API#Widgets_API\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">get<\/a>, jonka selit\u00e4n hetken.<\/p>\n<p>Yll\u00e4 olevat toiminnot ovat v\u00e4ltt\u00e4m\u00e4tt\u00f6mi\u00e4, koska ne auttavat WordPressi\u00e4 seuraamaan kuinka monta widgetin esiintym\u00e4\u00e4 on k\u00e4yt\u00f6ss\u00e4 ja mit\u00e4 k\u00e4ytt\u00e4j\u00e4 muokkaa. Toisin sanoen, saamme paljon toimintoja ilmaiseksi.<\/p>\n<p>Ennen kuin n\u00e4yt\u00e4n sinulle koodin, haluan keskustella lyhyesti\u00a0 esittelem\u00e4n <strong>get<\/strong> &#8211; toiminnon tarkoituksesta. Lyhyesti sanottuna se on tapa, jolla voimme v\u00e4litt\u00e4\u00e4 avain (kuten avain\/arvo-parin avaimessa) funktioon ja saada se sitten helposti hakemaan arvon, jotta se pit\u00e4\u00e4 k\u00e4ytt\u00f6liittym\u00e4mme mahdollisimman puhtaana.<\/p>\n<p>Joten ensin <a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-00-get-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">hakumenetelm\u00e4<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/**\n * If the value for the key exists in the current instance of the widget, then it will\n * retrieve it. Otherwise, it will return an empty value.\n *\n * @param string $key the used to identify the value of the widget.\n * @param array $instance the options for the instance of this widget\n *\/\nprotected function get($key, $instance)\n{\n    return empty($instance[$key])? '': $instance[$key];\n}<\/code><\/pre>\n<p>T\u00e4rke\u00e4\u00e4 on huomata, ett\u00e4 t\u00e4m\u00e4 menetelm\u00e4 ei hyv\u00e4ksy ainoastaan \u200b\u200blukemamme arvon avainta, vaan my\u00f6s taulukon esiintym\u00e4\u00e4n viittaavan taulukon.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-01-admin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Ja nyt, uudelleen muotoiltu k\u00e4ytt\u00f6liittym\u00e4<\/a> :<\/p>\n<pre><code>&lt;?php\n\/*\n * This file is part of WordPress Widget Boilerplate\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?&gt;\n\n&lt;div class=\"widget-content\"&gt;\n    &lt;p&gt;\n        &lt;input\n            type=\"text\"\n            id=\"&lt;?php echo esc_attr($this-&gt;get_field_id('title')); ?&gt;\"\n            name=\"&lt;?php echo esc_attr($this-&gt;get_field_name('title')); ?&gt;\"\n            value=\"&lt;?php echo $this-&gt;get('title', $instance) ?&gt;\"\n            placeholder=\"Widget Title\"\n            class=\"widefat\"\n        \/&gt;\n    &lt;\/p&gt;\n\n    &lt;p&gt;\n        &lt;textarea\n            id=\"&lt;?php echo esc_attr($this-&gt;get_field_id('content')); ?&gt;\"\n            name=\"&lt;?php echo esc_attr($this-&gt;get_field_name('content')); ?&gt;\"\n            placeholder=\"Widget Content\"\n            style=\"width:100%;\"&gt;&lt;?php echo $this-&gt;get('content', $instance) ?&gt;&lt;\/textarea&gt;\n    &lt;\/p&gt;\n\n    &lt;p&gt;\n        &lt;input\n            type=\"checkbox\"\n            value=\"on\"\n            name=\"&lt;?php echo esc_attr($this-&gt;get_field_name('display-title')); ?&gt;\"\n            id=\"&lt;?php echo esc_attr($this-&gt;get_field_id('display-title')); ?&gt;\"\n            &lt;?php checked('on', $this-&gt;get('display-title', $instance), true); ?&gt;\n            class=\"checkbox\"\n        \/&gt;\n        &lt;label for=\"&lt;?php echo esc_attr($this-&gt;get_field_id('display-title')); ?&gt;\"&gt;Display Title?&lt;\/label&gt;\n    &lt;\/p&gt;\n&lt;\/div&gt;&lt;!-- .widget-content --&gt;\n<\/code><\/pre>\n<p>Mutta t\u00e4m\u00e4 j\u00e4tt\u00e4\u00e4 silti toiminnallisuuden puutteen ja se j\u00e4tt\u00e4\u00e4 meille ty\u00f6t\u00e4. Meid\u00e4n on nimitt\u00e4in desinfioitava tiedot ja l\u00e4hetett\u00e4v\u00e4 ne takaisin WordPressille, jotta se tallentaa tiedot.<\/p>\n<h3>Puhdistus ja serialisointi<\/h3>\n<p>Esimerkkimme tarkoituksia varten aiomme olla hyvin tiukkoja siin\u00e4, mit\u00e4 sallimme. Nimitt\u00e4in tuemme vain perusteksti\u00e4 ja poistamme kaiken aggressiivisesti.<\/p>\n<p>T\u00e4m\u00e4 tarkoittaa, ett\u00e4 emme salli merkint\u00f6j\u00e4 tai muuta vastaavaa. Sen sijaan poistamme kaiken, mik\u00e4 ei ole perusteksti\u00e4. Voimme koristella sit\u00e4 hieman, kun on aika laittaa se esille, mutta j\u00e4t\u00e4mme sen sopivaan postaukseen.<\/p>\n<p>T\u00e4t\u00e4 varten k\u00e4yt\u00e4mme seuraavia toimintoja:<\/p>\n<ul>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.strip-tags.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">strip_tags<\/a><\/li>\n<li><a href=\"https:\/\/php.net\/manual\/en\/function.stripslashes.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">viiltoja<\/a><\/li>\n<\/ul>\n<p>Muista, ett\u00e4 widgetiss\u00e4mme on kaksi kentt\u00e4\u00e4 \u2013 otsikkokentt\u00e4 ja sis\u00e4lt\u00f6kentt\u00e4. Rakentamasi widgetin tyypist\u00e4 riippuen saatat tarvita vain yhden luokan tai funktion tietojen puhdistamiseen. Muissa tilanteissa saatat tarvita jotain monimutkaisempaa.<\/p>\n<p>Pid\u00e4 t\u00e4m\u00e4 mieless\u00e4, kun k\u00e4ymme l\u00e4pi t\u00e4t\u00e4 koodia, koska t\u00e4m\u00e4 ei tule olemaan yksi kokoinen ratkaisu. Sen sijaan se on nimenomaan t\u00e4t\u00e4 varten.<\/p>\n<p>Joka tapauksessa tietojen desinfioimiseksi kirjoitamme luokan erityisesti t\u00e4t\u00e4 tarkoitusta varten ja annamme sen sitten WidgetAdmin-luokkamme saataville.<\/p>\n<p><a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-02-widget-serializer-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">T\u00e4ss\u00e4 on luokka kokonaisuudessaan<\/a> seurattavalla kuvauksella:<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\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 WordPressWidgetBoilerplateWordPress;\n\n\/**\n * Santiizes and saves the data for the widget.\n *\/\nclass WidgetSerializer\n{\n    \/**\n     * Updates the values of the widget. Sanitizes the information before saving it.\n     *\n     * @param array $newInstance the array of new options to save\n     *\/\n    public function update($newInstance)\n    {\n        $instance = [];\n        foreach ($newInstance as $key =&gt; $value) {\n            $instance[$key] = strip_tags(\n                stripslashes($value)\n            );\n        }\n\n        return $instance;\n    }\n}\n<\/code><\/pre>\n<p>Luokan tulee olla suoraviivaista. Se ottaa vastaan \u200b\u200bwidgetin saapuvat arvot, puhdistaa ne ja palauttaa sitten uuden taulukon, joka palautetaan WordPressille.<\/p>\n<p>Siin\u00e4 on kuitenkin saalis. T\u00e4m\u00e4n luokan on oltava viimeisess\u00e4 viestiss\u00e4 n\u00e4ytetyn <strong>Widget -p\u00e4\u00e4luokan ominaisuus.<\/strong><\/p>\n<p>Toiseksi <strong>p\u00e4ivitysmenetelm\u00e4<\/strong>, joka on osa Widgets API:ta, kutsuu t\u00e4h\u00e4n luokkaan. <strong>$oldInstance-<\/strong> muuttujaa ei tarvitse v\u00e4litt\u00e4\u00e4 serialisaattoriin, mutta se on pakollinen p\u00e4ivitysmenetelm\u00e4ss\u00e4.<\/p>\n<p>T\u00e4ss\u00e4 on <strong>Widget<\/strong> &#8211; \u00a0luokka <a href=\"https:\/\/gist.github.com\/tommcfarlin\/392a2eda9ebc0b0a59cd4b364e427445#file-03-widget-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sellaisena kuin se t\u00e4ll\u00e4 hetkell\u00e4 on rakennettu<\/a> :<\/p>\n<pre><code>&lt;?php\n\n\/*\n * This file is part of WordPress Widget Boilerplate\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 WordPressWidgetBoilerplateWordPress;\n\nuse WP_Widget;\n\nclass Widget extends WP_Widget\n{\n    \/**\n     * @var string unique identifier for your widget\n     *\/\n    protected $widgetSlug;\n\n    \/**\n     * Initializes the plugin by setting its properties and calling the parent class with the description.\n     *\n     * @param string           $widgetSlug       unique identifier for your widget\n     * @param WidgetSerializer $widgetSerializer the class responsible for saving widget options\n     *\/\n    public function __construct($widgetSlug)\n    {\n        $this-&gt;widgetSlug = $widgetSlug;\n\n        parent::__construct(\n            $this-&gt;getWidgetSlug(),\n            __('Widget Name', $this-&gt;getWidgetSlug()),\n            [\n                'classname' =&gt; $this-&gt;getWidgetSlug().'-class',\n                'description' =&gt; __('Short description of the widget goes here.', $this-&gt;getWidgetSlug()),\n            ]\n        );\n    }\n\n    \/**\n     * Return the widget slug.\n     *\n     * @return string slug variable\n     *\/\n    public function getWidgetSlug()\n    {\n        return $this-&gt;widgetSlug;\n    }\n\n    \/**\n     * Displays the administrative view of the form and includes the options\n     * for the instance of the widget as arguments passed into the function.\n     *\n     * @param array $instance the options for the instance of this widget\n     *\/\n    public function form($instance)\n    {\n        include plugin_dir_path(__FILE__).'Views\/Admin.php';\n    }\n\n    \/**\n     * Updates the values of the widget. Uses the serialization class to sanitize the\n     * information before saving it.\n     *\n     * @param array $newInstance the values to be sanitized and saved\n     * @param array $oldInstance the values that were originally saved\n     *\/\n    public function update($newInstance, $oldInstance)\n    {\n        return $this-&gt;widgetSerializer-&gt;update($newInstance, $oldInstance);\n    }\n\n    \/**\n     * If the value for the key exists in the current instance of the widget, then it will\n     * retrieve it. Otherwise, it will return an empty value.\n     *\n     * @param string $key      the used to identify the value of the widget\n     * @param array  $instance the options for the instance of this widget\n     *\/\n    protected function get($key, $instance)\n    {\n        return empty($instance[$key])? '': $instance[$key];\n    }\n}\n<\/code><\/pre>\n<p>Mutta jos p\u00e4ivit\u00e4t sivun, saatat huomata, ett\u00e4 desinfiointi ja serialisointi eiv\u00e4t n\u00e4yt\u00e4 toimivan tietoja haettaessa. Ja sit\u00e4 aiomme tarkastella seuraavassa postauksessa.<\/p>\n<h2>Haetaan tietoja<\/h2>\n<p>Huomaa, ett\u00e4 vaikka toiminnot vaikuttavat ep\u00e4t\u00e4ydelliselt\u00e4 t\u00e4ss\u00e4 (koska puhdistamattomat tiedot n\u00e4kyv\u00e4t edelleen), olemme keskittyneet varmistamaan, ett\u00e4 kirjoitamme luokkia johdonmukaisesti, vastuullisesti ja jotka eiv\u00e4t ole tiukasti kytkettyj\u00e4.<\/p>\n<p>Aiomme toistaa t\u00e4t\u00e4 hieman enemm\u00e4n seuraavassa postauksessa. Joten tutki yll\u00e4 olevaa koodia, ota se k\u00e4ytt\u00f6\u00f6n, jos olet tehnyt niin, ja jatkamme siit\u00e4 seuraavassa viestiss\u00e4.<\/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>Ja nyt alamme lis\u00e4t\u00e4 desinfiointi- ja serialisointitoimintoja WordPress Widget Boilerplateen.<\/p>\n","protected":false},"author":1,"featured_media":234958,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[719,843],"tags":[1166],"class_list":["post-231405","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-kehittaejae","category-opetusohjelmia","tag-affiai-fi"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/231405","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=231405"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/posts\/231405\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media\/234958"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/media?parent=231405"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/categories?post=231405"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/fi\/wp-json\/wp\/v2\/tags?post=231405"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}