✅ WEB- und WordPress-Nachrichten, Themen, Plugins. Hier teilen wir Tipps und beste Website-Lösungen.

WordPress-Widgets: Refactoring, Teil 2

40

Nach all den vorläufigen Inhalten sind wir endlich an einem Punkt angelangt, an dem wir bereit sind, mit der Lösung der Codierungsstandardprobleme zu beginnen, die von unserer IDE und unseren Codequalitätstools ausgelöst werden.

Dabei werde ich den Inhalt in zwei Beiträge aufteilen:

  • Der erste Beitrag konzentriert sich ausschließlich auf das Refactoring des vorhandenen Codes.
  • Im nächsten Beitrag werden wir uns mit dem Refactoring der Struktur des Plugins befassen, um die Organisation und Architektur zu verbessern.

Lassen Sie uns zunächst einen Blick auf die Fehler werfen, die der Code-Sniffer auslöst, und sehen, ob wir ihn nicht auf modernere Standards bringen können.

Das WordPress-Widget Boilerplate: Refactoring, Teil 2

Beachten Sie, dass ich mich immer noch im Entwicklungszweig befinde, da wir noch nicht bereit sind, dies mit dem Master zusammenzuführen. Und wenn Sie Ihre Code-Sniffer und andere Tools richtig eingerichtet haben, sollten Sie Folgendes sehen:

Warning: Uncaught ErrorException: require_once(/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/vendor/autoload.php): failed to open stream: No such file or directory in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer:62
Stack trace:
#0 /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer(62): {closure}(2, 'require_once(/U...', '/Users/tommcfar...', 62, Array)
#1 /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer(62): require_once()
#2 {main}
  thrown in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer on line 62

Call Stack:
    0.0041     365448   1. {main}() /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer:0

Fatal error: main(): Failed opening required '/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/vendor/autoload.php' (include_path='.:/usr/local/Cellar/php@7.1/7.1.19/share/php@7.1/pear') in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer on line 62

Call Stack:
    0.0041     365448   1. {main}() /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer:0

You can fix all errors by running following commands:
'/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer' '--allow-risky=yes' '--config=.php_cs.dist' '--using-cache=yes' '--verbose' 'fix'
ERROR: Ruleset /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/phpcs.xml is not valid

Run "phpcs --help" for usage information

Warning: require(/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint.php): failed to open stream: No such file or directory in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint on line 4

Call Stack:
    0.0035     352864   1. {main}() /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint:0

Fatal error: require(): Failed opening required '/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint.php' (include_path='.:/usr/local/Cellar/php@7.1/7.1.19/share/php@7.1/pear') in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint on line 4

Call Stack:
    0.0035     352864   1. {main}() /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint:0

PHP Warning:  require(/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint.php): failed to open stream: No such file or directory in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint on line 4
PHP Stack trace:
PHP   1. {main}() /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint:0
PHP Fatal error:  require(): Failed opening required '/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint.php' (include_path='.:/usr/local/Cellar/php@7.1/7.1.19/share/php@7.1/pear') in /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint on line 4
PHP Stack trace:
PHP   1. {main}() /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/parallel-lint:0
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:33     The class Widget_Name has 12 public methods. Consider refactoring Widget_Name to keep number of public methods under 10.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:33     The class Widget_Name is not named in CamelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:33     The property$widget_slug is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:97     The method get_widget_slug is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$widget_string is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$before_widget is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$widget_string is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$widget_string is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$after_widget is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$widget_string is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    The variable$widget_string is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:111    Avoid unusedparameters such as '$instance'.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:131    Avoid unusedlocal variables such as '$before_widget'.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:137    Avoid unusedlocal variables such as '$after_widget'.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:149    The method flush_widget_cache is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:159    The parameter $new_instance is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:159    The parameter $old_instance is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:159    The variable$old_instance is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:159    Avoid unusedparameters such as '$new_instance'.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:195    The method widget_textdomain is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:207    The parameter $network_wide is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:207    Avoid unusedparameters such as '$network_wide'.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:216    The parameter $network_wide is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:216    Avoid unusedparameters such as '$network_wide'.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:223    The method register_admin_styles is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:232    The method register_admin_scripts is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:241    The method register_widget_styles is not named in camelCase.
/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/src/Plugin.php:250    The method register_widget_scripts is not named in camelCase.
[FATAL] /Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/phpcs.xml: Premature end of data in tag ruleset line 2
 (77) on line 28,12

Und Sie sollten nach dem Laufen zumindest all dies sehen:

$ vendor/bin/grumphp run

Bevor wir fortfahren, müssen wir einige geringfügige Änderungen an der Organisation der Dateien vornehmen. Das heißt, wir müssen die Kern-Plugin-Datei (die wir als Plugin.php haben) in zwei Dateien aufteilen.

Insbesondere benötigen wir eine Plugin-Bootstrap-Datei, und dann müssen wir die Kern-Plugin-Datei verwalten. Lassen Sie uns also zuerst einen Plugin-Bootstrap erstellen.

Erstellen Sie den Bootstrap

Erstellen Sie im Stammverzeichnis des Plugins eine Datei mit dem Namen wordpress-widget-boilerplate.php. Fügen Sie dann Folgendes hinzu :

<?php
/**
 * WordPress Widget Boilerplate
 *
 * The WordPress Widget Boilerplate is an organized, maintainable boilerplate for building widgets using WordPress best practices.
 *
 * @package   Widget_Name
 * @author    Your Name <email@example.com>
 * @license   GPL-2.0+
 * @link      http://example.com
 * @copyright 2018 Your Name or Company Name
 *
 * @wordpress-plugin
 * Plugin Name:       @TODO
 * Plugin URI:        @TODO
 * Description:       @TODO
 * Version:           1.0.0
 * Author:            @TODO
 * Author URI:        @TODO
 * Text Domain:       widget-name
 * License:           GPL-3.0+
 * License URI:       http://www.gnu.org/licenses/gpl-3.0.txt
 * Domain Path:       /lang
 * GitHub Plugin URI: https://github.com/<owner>/<repo>
 */

// Prevent this file from being called directly.
defined('WPINC') || die;

// Include the autoloader.
require_once __DIR__. '/inc/autoload.php';

Hinweis in der Datei oben; Wir haben den Plugin-Header, die Bedingung, um festzustellen, ob auf die Datei zugegriffen werden kann, und laden dann den Composer-Autoloader.

Bearbeiten Sie das Core-Plugin

Sobald dies erledigt ist, wird die Kerndatei Plugin.php so geändert, dass sie wie folgt aussieht :

<?php

// TODO: change 'Widget_Name' to the name of your plugin
class Widget_Name extends WP_Widget {

    /**
     * @TODO - Rename "widget-name" to the name your your widget
     *
     * Unique identifier for your widget.
     *
     *
     * The variable name is used as the text domain when internationalizing strings
     * of text. Its value should match the Text Domain file header in the main
     * widget file.
     *
     * @since    1.0.0
     *
     * @var      string
     */
    protected $widget_slug = 'widget-name';

    /*--------------------------------------------------*/
    /* Constructor
    /*--------------------------------------------------*/

    /**
     * Specifies the classname and description, instantiates the widget,
     * loads localization files, and includes necessary stylesheets and JavaScript.
     */
    public function __construct() {

        // load plugin text domain
        add_action( 'init', array( $this, 'widget_textdomain') );

        // TODO: update description
        parent::__construct(
            $this->get_widget_slug(),
            __( 'Widget Name', $this->get_widget_slug() ),
            array(
                'classname'  => $this->get_widget_slug().'-class',
                'description' => __( 'Short description of the widget goes here.', $this->get_widget_slug())) );

        // Register admin styles and scripts
        add_action( 'admin_print_styles', array( $this, 'register_admin_styles') );
        add_action( 'admin_enqueue_scripts', array( $this, 'register_admin_scripts') );

        // Register site styles and scripts
        add_action( 'wp_enqueue_scripts', array( $this, 'register_widget_styles') );
        add_action( 'wp_enqueue_scripts', array( $this, 'register_widget_scripts') );

        // Refreshing the widget's cached output with each new post
        add_action( 'save_post',    array( $this, 'flush_widget_cache') );
        add_action( 'deleted_post', array( $this, 'flush_widget_cache') );
        add_action( 'switch_theme', array( $this, 'flush_widget_cache') );

    } // end constructor

    /**
     * Return the widget slug.
     *
     * @since    1.0.0
     *
     * @return    Plugin slug variable.
     */
    public function get_widget_slug() {
        return $this->widget_slug;
    }

    /*--------------------------------------------------*/
    /* Widget API Functions
    /*--------------------------------------------------*/

    /**
     * Outputs the content of the widget.
     *
     * @param array args  The array of form elements
     * @param array instance The current instance of the widget
     */
    public function widget( $args, $instance) {

        // Check if there is a cached output
        $cache = wp_cache_get( $this->get_widget_slug(), 'widget' );

        if (!is_array( $cache)) $cache = array();

        if (! isset ($args['widget_id'])) $args['widget_id'] = $this->id;

        if (isset ($cache[ $args['widget_id'] ])) return print $cache[ $args['widget_id'] ];

        // go on with your widget logic, put everything into a string and …

        extract( $args, EXTR_SKIP );

        $widget_string = $before_widget;

        // TODO: Here is where you manipulate your widget's values based on their input fields
        ob_start();
        include( plugin_dir_path( __FILE__ ). 'views/widget.php' );
        $widget_string .= ob_get_clean();
        $widget_string .= $after_widget;

        $cache[ $args['widget_id'] ] = $widget_string;

        wp_cache_set( $this->get_widget_slug(), $cache, 'widget' );

        print $widget_string;

    } // end widget

    public function flush_widget_cache()
    {
        wp_cache_delete( $this->get_widget_slug(), 'widget' );
    }
    /**
     * Processes the widget's options to be saved.
     *
     * @param array new_instance The new instance of values to be generated via the update.
     * @param array old_instance The previous instance of values before the update.
     */
    public function update( $new_instance, $old_instance) {

        $instance = $old_instance;

        // TODO: Here is where you update your widget's old values with the new, incoming values

        return $instance;

    } // end update

    /**
     * Generates the administration form for the widget.
     *
     * @param array instance The array of keys and values for the widget.
     */
    public function form( $instance) {

        // TODO: Define default values for your variables
        $instance = wp_parse_args(
            (array) $instance
        );

        // TODO: Store the values of the widget in their own variable

        // Display the admin form
        include( plugin_dir_path(__FILE__). 'views/admin.php' );

    } // end form

    /*--------------------------------------------------*/
    /* Public Functions
    /*--------------------------------------------------*/

    /**
     * Loads the Widget's text domain for localization and translation.
     */
    public function widget_textdomain() {

        // TODO be sure to change 'widget-name' to the name of *your* plugin
        load_plugin_textdomain( $this->get_widget_slug(), false, dirname( plugin_basename( __FILE__) ). 'lang/' );

    } // end widget_textdomain

    /**
     * Fired when the plugin is activated.
     *
     * @param  boolean $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog.
     */
    public static function activate( $network_wide) {
        // TODO define activation functionality here
    } // end activate

    /**
     * Fired when the plugin is deactivated.
     *
     * @param boolean $network_wide True if WPMU superadmin uses "Network Activate" action, false if WPMU is disabled or plugin is activated on an individual blog
     */
    public static function deactivate( $network_wide) {
        // TODO define deactivation functionality here
    } // end deactivate

    /**
     * Registers and enqueues admin-specific styles.
     */
    public function register_admin_styles() {

        wp_enqueue_style( $this->get_widget_slug().'-admin-styles', plugins_url( 'css/admin.css', __FILE__) );

    } // end register_admin_styles

    /**
     * Registers and enqueues admin-specific JavaScript.
     */
    public function register_admin_scripts() {

        wp_enqueue_script( $this->get_widget_slug().'-admin-script', plugins_url( 'js/admin.js', __FILE__ ), array('jquery') );

    } // end register_admin_scripts

    /**
     * Registers and enqueues widget-specific styles.
     */
    public function register_widget_styles() {

        wp_enqueue_style( $this->get_widget_slug().'-widget-styles', plugins_url( 'css/widget.css', __FILE__) );

    } // end register_widget_styles

    /**
     * Registers and enqueues widget-specific scripts.
     */
    public function register_widget_scripts() {

        wp_enqueue_script( $this->get_widget_slug().'-script', plugins_url( 'js/widget.js', __FILE__ ), array('jquery') );

    } // end register_widget_scripts

} // end class

// TODO: Remember to change 'Widget_Name' to match the class name definition
add_action( 'widgets_init', create_function( '', 'register_widget("Widget_Name");') );

// Hooks fired when the Widget is activated and deactivated
// TODO: Remember to change 'Widget_Name' to match the class name definition
register_activation_hook( __FILE__, array( 'Widget_Name', 'activate') );
register_deactivation_hook( __FILE__, array( 'Widget_Name', 'deactivate') );

Denken Sie daran, dass wir noch viel zu tun haben, aber als erstes müssen wir damit beginnen, die Codebasis von ihrem aktuellen Zustand zu bereinigen. Letztendlich werden wir dies in eine viel objektorientiertere Weise umgestalten, aber wir müssen die aktuelle Version des Plugins in einen gesunden Zustand bringen.

Jetzt können wir unsere Aufmerksamkeit jedoch wieder auf die ursprüngliche Ausgabe von GrumPHP richten. Wenn Sie durchsehen, sehen Sie in der Ausgabe eine Zeile wie diese:

You can fix all errors by running following commands:
'/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer' '--allow-risky=yes' '--config=.php_cs.dist' '--using-cache=yes' '--verbose' 'fix'

Sehen wir uns an dieser Stelle an, wie wir den empfohlenen Befehl ausführen und sehen, was passiert. Geben Sie dies insbesondere in Ihr Terminal ein:

'/Users/tommcfarlin/Dropbox/Projects/trunk/wp-content/plugins/WordPress-Widget-Boilerplate/vendor/bin/php-cs-fixer' '--allow-risky=yes' '--config=.php_cs.dist' '--using-cache=yes' '--verbose' 'fix'

Angenommen, alle Dinge funktionieren korrekt, dann sollten Sie so etwas sehen:

Ein Hinweis zu Ausgabefehlern

Wenn Sie dabei eine Fehlermeldung erhalten, müssen Sie möglicherweise das Herstellerverzeichnis aktualisieren oder sogar das Verzeichnis aktualisieren. Wenn dies der Fall ist, versuchen Sie zunächst Folgendes:

$ composer update

Und wenn das Ihr Problem nicht löst, versuchen Sie Folgendes:

$ rm -rf vendor
$ composer update

Führen Sie danach den Befehl erneut aus.

Zurück zur Ausgabe

Sie sollten dann eine Ausgabe wie diese sehen:

WordPress-Widgets: Refactoring, Teil 2

Führen Sie als Nächstes den folgenden Befehl auf Ihrem Terminal aus:

$ vendor/grumphp/run

Hier sollten Sie nun Probleme mit den Codierungsstandards sehen. Die Liste ist zu lang, um sie hier aufzulisten, aber Sie sollten eine Option sehen, um so etwas zu tun :

----------------------------------------------------------------------
FOUND 9 ERRORS AFFECTING 8 LINES
----------------------------------------------------------------------

Und an diesem Punkt gibt es viele Änderungen, die wir vornehmen müssen, wenn wir es auf PSR2-Standards bringen wollen. Also machen wir das jetzt.

Refactoring der Widget-Boilerplate

Angenommen, Sie haben alle erforderlichen Erweiterungen und Plug-ins in Visual Studio Code installiert, dann sehen Sie wahrscheinlich ziemlich viel Rot in Ihrer IDE.

WordPress-Widgets: Refactoring, Teil 2

Das sind alles Probleme, die behoben werden müssen. Also werde ich durchgehen und den Code aktualisieren. Dann teile ich den Code hier (aus Platzgründen ohne Kommentare).

Angenommen, Sie haben alle richtigen Änderungen vorgenommen, sollten Sie so etwas haben:

<?php

namespace WordPressWidgetBoilerplate;

class Plugin extends WP_Widget
{
    protected $widgetSlug = 'widget-name';

    public function __construct()
    {
        add_action('init', [$this, 'widgetTextdomain']);

        parent::__construct(
            $this->getWidgetSlug(),
            __('Widget Name', $this->getWidgetSlug()),
            [
                'classname' => $this->getWidgetSlug().'-class',
                'description' => __('Short description of the widget goes here.', $this->getWidgetSlug()),
            ]
        );

        add_action('admin_print_styles', [$this, 'registerAdminStyles']);
        add_action('admin_enqueue_scripts', [$this, 'registerAdminScripts']);

        add_action('wp_enqueue_scripts', [$this, 'registerWidgetStyles']);
        add_action('wp_enqueue_scripts', [$this, 'registerWidgetScripts']);

        add_action('save_post', [$this, 'flushWidgetCache']);
        add_action('deleted_post', [$this, 'flushWidgetCache']);
        add_action('switch_theme', [$this, 'flushWidgetCache']);
    }

    public function getWidgetSlug()
    {
        return $this->widgetSlug;
    }

    public function widget($args, $instance)
    {
        // Check if there is a cached output
        $cache = wp_cache_get($this->getWidgetSlug(), 'widget');

        if (!is_array($cache)) {
            $cache = [];
        }

        if (!isset($args['widget_id'])) {
            $args['widget_id'] = $this->id;
        }

        if (isset($cache[$args['widget_id']])) {
            return print $cache[$args['widget_id']];
        }

        extract($args, EXTR_SKIP);

        $widgetString = $beforeWidget;

        ob_start();
        include plugin_dir_path(__FILE__).'views/widget.php';
        $widgetString .= ob_get_clean();
        $widgetString .= $afterWidget;

        $cache[$args['widget_id']] = $widgetString;

        wp_cache_set($this->getWidgetSlug(), $cache, 'widget');

        echo $widgetString;
    }

    public function flushWidgetCache()
    {
        wp_cache_delete($this->getWidgetSlug(), 'widget');
    }

    public function update($newInstance, $oldInstance)
    {
        $instance = $oldInstance;

        // TODO: Here is where you update your widget's old values with the new, incoming values

        return $instance;
    }

    public function form($instance)
    {
        // TODO: Define default values for your variables
        $instance = wp_parse_args(
            (array) $instance
        );

        // TODO: Store the values of the widget in their own variable

        // Display the admin form
        include plugin_dir_path(__FILE__).'views/admin.php';
    }

    public function widgetTextdomain()
    {
        // TODO: be sure to change 'widget-name' to the name of *your* plugin
        load_plugin_textdomain($this->getWidgetSlug(), false, dirname(plugin_basename(__FILE__)).'lang/');
    }

    public static function activate($networkWide)
    {
        // TODO: define activation functionality here
    }

    public static function deactivate($networkWide)
    {
        // TODO:define deactivation functionality here
    }

    public function registerAdminStyles()
    {
        wp_enqueue_style($this->getWidgetSlug().'-admin-styles', plugins_url('css/admin.css', __FILE__));
    }

    public function registerAdminScripts()
    {
        wp_enqueue_script($this->getWidgetSlug().'-admin-script', plugins_url('js/admin.js', __FILE__), ['jquery']);
    }

    public function registerWidgetStyles()
    {
        wp_enqueue_style($this->getWidgetSlug().'-widget-styles', plugins_url('css/widget.css', __FILE__));
    }

    public function registerWidgetScripts()
    {
        wp_enqueue_script($this->getWidgetSlug().'-script', plugins_url('js/widget.js', __FILE__), ['jquery']);
    }
}

Führen Sie noch einmal aus:

$ vendor/bin/grumphp run

Und sehen Sie, welche Ausgabe Sie erhalten. Sie erhalten immer noch eine Vielzahl von Fehlern, die etwas zum Ton von sagen:

Vermeiden Sie ungenutzte lokale Variablen wie …

Dies liegt daran, dass die Code-Sniffing-Regeln nicht wollen, dass wir Variablen verwenden, die nicht verwendet werden. In einem Boilerplate werden wir diese Variablen jedoch wahrscheinlich vor dem Ende des Projekts verwenden.

Zu diesem Zweck müssen Sie sich an dieser Stelle also keine Sorgen machen. Wir kümmern uns, wenn es soweit ist.

Bis PSR

Zu diesem Zeitpunkt wurde ein Großteil des Plugins auf PSR-Standards aufgekauft und verfügt über eine solide Reihe von Tools, mit denen wir unseren Code während des Schreibens konsequent testen können.

Wenn Sie dem Repository folgen, wurde der Entwicklungszweig aktualisiert, um die Änderungen in diesem Beitrag widerzuspiegeln, also zögern Sie nicht, ihn zu ziehen und den Code zu überprüfen.

Im nächsten Beitrag werden wir damit beginnen, den Code viel objektorientierter umzugestalten.

Aufnahmequelle: tommcfarlin.com

Diese Website verwendet Cookies, um Ihre Erfahrung zu verbessern. Wir gehen davon aus, dass Sie damit einverstanden sind, Sie können sich jedoch abmelden, wenn Sie möchten. Annehmen Weiterlesen