{"id":230877,"date":"2022-12-16T14:26:00","date_gmt":"2022-12-16T11:26:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230877"},"modified":"2022-12-16T14:26:20","modified_gmt":"2022-12-16T11:26:20","slug":"widgets-de-wordpress-refactorizacion-parte-2","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-refactorizacion-parte-2\/","title":{"rendered":"Widgets de WordPress: Refactorizaci\u00f3n, Parte 2"},"content":{"rendered":"\n<p><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/widgets-de-wordpress-refactorizacion-parte-1\/\" title=\"Despu\u00e9s de todo el contenido preliminar\">Despu\u00e9s de todo el contenido preliminar<\/a><\/strong>, finalmente estamos en un lugar donde estamos listos para comenzar a resolver los problemas de est\u00e1ndares de codificaci\u00f3n generados por nuestro IDE y por nuestras herramientas de calidad de c\u00f3digo.<\/p>\n<p>Al hacer esto, voy a dividir el contenido en dos publicaciones:<\/p>\n<ul>\n<li>la primera publicaci\u00f3n se centrar\u00e1 \u00fanicamente en refactorizar el c\u00f3digo existente,<\/li>\n<li>en la pr\u00f3xima publicaci\u00f3n, veremos la refactorizaci\u00f3n de la estructura del complemento para mejorar la organizaci\u00f3n y la arquitectura.<\/li>\n<\/ul>\n<p>Por ahora, sin embargo, echemos un vistazo a los errores que arroja el rastreador de c\u00f3digo y veamos si podemos actualizarlo a est\u00e1ndares m\u00e1s modernos.<\/p>\n<h2>El modelo de widget de WordPress: refactorizaci\u00f3n, parte 2<\/h2>\n<p>Tenga en cuenta que todav\u00eda estoy en la rama de <strong>desarrollo<\/strong> ya que a\u00fan no estamos listos para fusionar esto en maestro. Y si tiene sus rastreadores de c\u00f3digo y otras herramientas configuradas correctamente, deber\u00eda ver <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/dce6bda0d104192a21cb06dc7d3ca23c#file-00-regex-results-txt\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">lo siguiente:<\/a><\/strong><\/p>\n<pre><code>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\nStack trace:\n#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)\n#1 \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/php-cs-fixer(62): require_once()\n#2 {main}\n  thrown in \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/php-cs-fixer on line 62\n\nCall Stack:\n    0.0041     365448   1. {main}() \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/php-cs-fixer:0\n\nFatal 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\n\nCall Stack:\n    0.0041     365448   1. {main}() \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/php-cs-fixer:0\n\nYou can fix all errors by running following commands:\n'\/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'\nERROR: Ruleset \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/phpcs.xml is not valid\n\nRun \"phpcs --help\" for usage information\n\nWarning: 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\n\nCall Stack:\n    0.0035     352864   1. {main}() \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/parallel-lint:0\n\nFatal 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\n\nCall Stack:\n    0.0035     352864   1. {main}() \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/parallel-lint:0\n\nPHP 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\nPHP Stack trace:\nPHP   1. {main}() \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/parallel-lint:0\nPHP 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\nPHP Stack trace:\nPHP   1. {main}() \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/vendor\/bin\/parallel-lint:0\n\/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.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:33     The class Widget_Name is not named in CamelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:33     The property$widget_slug is not named in camelCase.\n\/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.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$widget_string is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$before_widget is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$widget_string is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$widget_string is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$after_widget is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$widget_string is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    The variable$widget_string is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:111    Avoid unusedparameters such as '$instance'.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:131    Avoid unusedlocal variables such as '$before_widget'.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:137    Avoid unusedlocal variables such as '$after_widget'.\n\/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.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:159    The parameter $new_instance is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:159    The parameter $old_instance is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:159    The variable$old_instance is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:159    Avoid unusedparameters such as '$new_instance'.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:195    The method widget_textdomain is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:207    The parameter $network_wide is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:207    Avoid unusedparameters such as '$network_wide'.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:216    The parameter $network_wide is not named in camelCase.\n\/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/src\/Plugin.php:216    Avoid unusedparameters such as '$network_wide'.\n\/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.\n\/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.\n\/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.\n\/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.\n[FATAL] \/Users\/tommcfarlin\/Dropbox\/Projects\/trunk\/wp-content\/plugins\/WordPress-Widget-Boilerplate\/phpcs.xml: Premature end of data in tag ruleset line 2\n (77) on line 28,12<\/code><\/pre>\n<p>Y deber\u00eda ver al menos todo esto despu\u00e9s de ejecutar:<\/p>\n<pre><code>$ vendor\/bin\/grumphp run<\/code><\/pre>\n<p>Antes de seguir adelante, debemos realizar algunos cambios menores en la forma en que se organizan los archivos. Es decir, necesitamos separar el archivo del complemento principal (que lo tenemos como <strong>Plugin.php<\/strong>) en dos archivos.<\/p>\n<p>Espec\u00edficamente, necesitamos tener un archivo de arranque del complemento, y luego debemos mantener el archivo del complemento principal. Entonces, primero, creemos un arranque de complemento.<\/p>\n<h3>Crear el Bootstrap<\/h3>\n<p>En la ra\u00edz del complemento, cree un archivo llamado <strong>wordpress-widget-boilerplate.php.<\/strong> Luego <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/dce6bda0d104192a21cb06dc7d3ca23c#file-01-wordpress-widget-boilerplate-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">a\u00f1\u00e1dele lo siguiente<\/a><\/strong> :<\/p>\n<pre><code>&lt;?php\n\/**\n * WordPress Widget Boilerplate\n *\n * The WordPress Widget Boilerplate is an organized, maintainable boilerplate for building widgets using WordPress best practices.\n *\n * @package   Widget_Name\n * @author    Your Name &lt;email@example.com&gt;\n * @license   GPL-2.0+\n * @link      http:\/\/example.com\n * @copyright 2018 Your Name or Company Name\n *\n * @wordpress-plugin\n * Plugin Name:       @TODO\n * Plugin URI:        @TODO\n * Description:       @TODO\n * Version:           1.0.0\n * Author:            @TODO\n * Author URI:        @TODO\n * Text Domain:       widget-name\n * License:           GPL-3.0+\n * License URI:       http:\/\/www.gnu.org\/licenses\/gpl-3.0.txt\n * Domain Path:       \/lang\n * GitHub Plugin URI: https:\/\/github.com\/&lt;owner&gt;\/&lt;repo&gt;\n *\/\n\n\/\/ Prevent this file from being called directly.\ndefined('WPINC') || die;\n\n\/\/ Include the autoloader.\nrequire_once __DIR__. '\/inc\/autoload.php';\n<\/code><\/pre>\n<p>Nota en el archivo de arriba; tenemos el encabezado del complemento, el condicional para determinar si se puede acceder al archivo y luego cargar el cargador autom\u00e1tico Composer.<\/p>\n<h3>Edite el complemento principal<\/h3>\n<p>Una vez hecho esto, esto cambiar\u00e1 el archivo principal <strong>Plugin.php<\/strong> para que se vea <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/dce6bda0d104192a21cb06dc7d3ca23c#file-02-plugin-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\n\/\/ TODO: change 'Widget_Name' to the name of your plugin\nclass Widget_Name extends WP_Widget {\n\n    \/**\n     * @TODO - Rename \"widget-name\" to the name your your widget\n     *\n     * Unique identifier for your widget.\n     *\n     *\n     * The variable name is used as the text domain when internationalizing strings\n     * of text. Its value should match the Text Domain file header in the main\n     * widget file.\n     *\n     * @since    1.0.0\n     *\n     * @var      string\n     *\/\n    protected $widget_slug = 'widget-name';\n\n    \/*--------------------------------------------------*\/\n    \/* Constructor\n    \/*--------------------------------------------------*\/\n\n    \/**\n     * Specifies the classname and description, instantiates the widget,\n     * loads localization files, and includes necessary stylesheets and JavaScript.\n     *\/\n    public function __construct() {\n\n        \/\/ load plugin text domain\n        add_action( 'init', array( $this, 'widget_textdomain') );\n\n        \/\/ TODO: update description\n        parent::__construct(\n            $this-&gt;get_widget_slug(),\n            __( 'Widget Name', $this-&gt;get_widget_slug() ),\n            array(\n                'classname'  =&gt; $this-&gt;get_widget_slug().'-class',\n                'description' =&gt; __( 'Short description of the widget goes here.', $this-&gt;get_widget_slug())) );\n\n        \/\/ Register admin styles and scripts\n        add_action( 'admin_print_styles', array( $this, 'register_admin_styles') );\n        add_action( 'admin_enqueue_scripts', array( $this, 'register_admin_scripts') );\n\n        \/\/ Register site styles and scripts\n        add_action( 'wp_enqueue_scripts', array( $this, 'register_widget_styles') );\n        add_action( 'wp_enqueue_scripts', array( $this, 'register_widget_scripts') );\n\n        \/\/ Refreshing the widget's cached output with each new post\n        add_action( 'save_post',    array( $this, 'flush_widget_cache') );\n        add_action( 'deleted_post', array( $this, 'flush_widget_cache') );\n        add_action( 'switch_theme', array( $this, 'flush_widget_cache') );\n\n    } \/\/ end constructor\n\n    \/**\n     * Return the widget slug.\n     *\n     * @since    1.0.0\n     *\n     * @return    Plugin slug variable.\n     *\/\n    public function get_widget_slug() {\n        return $this-&gt;widget_slug;\n    }\n\n    \/*--------------------------------------------------*\/\n    \/* Widget API Functions\n    \/*--------------------------------------------------*\/\n\n    \/**\n     * Outputs the content of the widget.\n     *\n     * @param array args  The array of form elements\n     * @param array instance The current instance of the widget\n     *\/\n    public function widget( $args, $instance) {\n\n        \/\/ Check if there is a cached output\n        $cache = wp_cache_get( $this-&gt;get_widget_slug(), 'widget' );\n\n        if (!is_array( $cache)) $cache = array();\n\n        if (! isset ($args['widget_id'])) $args['widget_id'] = $this-&gt;id;\n\n        if (isset ($cache[ $args['widget_id'] ])) return print $cache[ $args['widget_id'] ];\n\n        \/\/ go on with your widget logic, put everything into a string and \u2026\n\n        extract( $args, EXTR_SKIP );\n\n        $widget_string = $before_widget;\n\n        \/\/ TODO: Here is where you manipulate your widget's values based on their input fields\n        ob_start();\n        include( plugin_dir_path( __FILE__ ). 'views\/widget.php' );\n        $widget_string .= ob_get_clean();\n        $widget_string .= $after_widget;\n\n        $cache[ $args['widget_id'] ] = $widget_string;\n\n        wp_cache_set( $this-&gt;get_widget_slug(), $cache, 'widget' );\n\n        print $widget_string;\n\n    } \/\/ end widget\n\n    public function flush_widget_cache()\n    {\n        wp_cache_delete( $this-&gt;get_widget_slug(), 'widget' );\n    }\n    \/**\n     * Processes the widget's options to be saved.\n     *\n     * @param array new_instance The new instance of values to be generated via the update.\n     * @param array old_instance The previous instance of values before the update.\n     *\/\n    public function update( $new_instance, $old_instance) {\n\n        $instance = $old_instance;\n\n        \/\/ TODO: Here is where you update your widget's old values with the new, incoming values\n\n        return $instance;\n\n    } \/\/ end update\n\n    \/**\n     * Generates the administration form for the widget.\n     *\n     * @param array instance The array of keys and values for the widget.\n     *\/\n    public function form( $instance) {\n\n        \/\/ TODO: Define default values for your variables\n        $instance = wp_parse_args(\n            (array) $instance\n        );\n\n        \/\/ TODO: Store the values of the widget in their own variable\n\n        \/\/ Display the admin form\n        include( plugin_dir_path(__FILE__). 'views\/admin.php' );\n\n    } \/\/ end form\n\n    \/*--------------------------------------------------*\/\n    \/* Public Functions\n    \/*--------------------------------------------------*\/\n\n    \/**\n     * Loads the Widget's text domain for localization and translation.\n     *\/\n    public function widget_textdomain() {\n\n        \/\/ TODO be sure to change 'widget-name' to the name of *your* plugin\n        load_plugin_textdomain( $this-&gt;get_widget_slug(), false, dirname( plugin_basename( __FILE__) ). 'lang\/' );\n\n    } \/\/ end widget_textdomain\n\n    \/**\n     * Fired when the plugin is activated.\n     *\n     * @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.\n     *\/\n    public static function activate( $network_wide) {\n        \/\/ TODO define activation functionality here\n    } \/\/ end activate\n\n    \/**\n     * Fired when the plugin is deactivated.\n     *\n     * @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\n     *\/\n    public static function deactivate( $network_wide) {\n        \/\/ TODO define deactivation functionality here\n    } \/\/ end deactivate\n\n    \/**\n     * Registers and enqueues admin-specific styles.\n     *\/\n    public function register_admin_styles() {\n\n        wp_enqueue_style( $this-&gt;get_widget_slug().'-admin-styles', plugins_url( 'css\/admin.css', __FILE__) );\n\n    } \/\/ end register_admin_styles\n\n    \/**\n     * Registers and enqueues admin-specific JavaScript.\n     *\/\n    public function register_admin_scripts() {\n\n        wp_enqueue_script( $this-&gt;get_widget_slug().'-admin-script', plugins_url( 'js\/admin.js', __FILE__ ), array('jquery') );\n\n    } \/\/ end register_admin_scripts\n\n    \/**\n     * Registers and enqueues widget-specific styles.\n     *\/\n    public function register_widget_styles() {\n\n        wp_enqueue_style( $this-&gt;get_widget_slug().'-widget-styles', plugins_url( 'css\/widget.css', __FILE__) );\n\n    } \/\/ end register_widget_styles\n\n    \/**\n     * Registers and enqueues widget-specific scripts.\n     *\/\n    public function register_widget_scripts() {\n\n        wp_enqueue_script( $this-&gt;get_widget_slug().'-script', plugins_url( 'js\/widget.js', __FILE__ ), array('jquery') );\n\n    } \/\/ end register_widget_scripts\n\n} \/\/ end class\n\n\/\/ TODO: Remember to change 'Widget_Name' to match the class name definition\nadd_action( 'widgets_init', create_function( '', 'register_widget(\"Widget_Name\");') );\n\n\/\/ Hooks fired when the Widget is activated and deactivated\n\/\/ TODO: Remember to change 'Widget_Name' to match the class name definition\nregister_activation_hook( __FILE__, array( 'Widget_Name', 'activate') );\nregister_deactivation_hook( __FILE__, array( 'Widget_Name', 'deactivate') );\n<\/code><\/pre>\n<p>Recuerde, todav\u00eda hay mucho trabajo por hacer, pero lo primero que debemos hacer es comenzar a limpiar el c\u00f3digo base de su estado actual. Eventualmente, refactorizaremos esto de una manera mucho m\u00e1s orientada a objetos, pero necesitamos obtener la versi\u00f3n actual del complemento en un estado saludable.<\/p>\n<p>Ahora, sin embargo, podemos volver nuestra atenci\u00f3n a la salida original de GrumPHP. Si mira a trav\u00e9s, la salida ver\u00e1 una l\u00ednea como esta:<\/p>\n<pre><code>You can fix all errors by running following commands:\n'\/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'<\/code><\/pre>\n<p>Entonces, en este punto, echemos un vistazo a la ejecuci\u00f3n del comando recomendado y veamos qu\u00e9 sucede. Espec\u00edficamente, ingrese esto en su terminal:<\/p>\n<pre><code>'\/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'<\/code><\/pre>\n<p>Suponiendo que todo funcione correctamente, deber\u00eda ver algo como esto:<\/p>\n<h4>Una nota sobre los errores de salida<\/h4>\n<p>Si recibe alg\u00fan error cada vez que hace esto, es posible que deba actualizar el directorio de <strong>proveedores<\/strong> o incluso actualizar el directorio. Si este es el caso, primero intente esto:<\/p>\n<pre><code>$ composer update<\/code><\/pre>\n<p>Y si eso no resuelve su problema, intente:<\/p>\n<pre><code>$ rm -rf vendor\n$ composer update<\/code><\/pre>\n<p>Despu\u00e9s de eso, vuelva a ejecutar el comando.<\/p>\n<h3>Volver a la salida<\/h3>\n<p>A continuaci\u00f3n, deber\u00eda ver una salida como esta:<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161324-61e71fbbbfefa.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-161324-61e71fbbbfefa.png\" alt=\"Widgets de WordPress: Refactorizaci\u00f3n, Parte 2\"><\/a><\/p>\n<p>A continuaci\u00f3n, ejecute el siguiente comando en su terminal:<\/p>\n<pre><code>$ vendor\/grumphp\/run<\/code><\/pre>\n<p>Aqu\u00ed, ahora deber\u00eda ver problemas con los est\u00e1ndares de codificaci\u00f3n. La lista es demasiado larga para enumerarla aqu\u00ed, pero deber\u00eda ver una opci\u00f3n para hacer algo <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/dce6bda0d104192a21cb06dc7d3ca23c#file-03-coding-standards-txt\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">como esto:<\/a><\/strong><\/p>\n<pre><code>----------------------------------------------------------------------\nFOUND 9 ERRORS AFFECTING 8 LINES\n----------------------------------------------------------------------<\/code><\/pre>\n<p>Y en este punto, hay muchos cambios que debemos hacer si queremos actualizarlo a los est\u00e1ndares de PSR2. As\u00ed que hag\u00e1moslo ahora.<\/p>\n<h3>Refactorizaci\u00f3n del modelo de widget<\/h3>\n<p>Suponiendo que tiene todas las extensiones y complementos necesarios instalados en Visual Studio Code, es probable que vea una buena cantidad de rojo en su IDE.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-161324-61e71fbfb62de.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-161324-61e71fbfb62de.png\" alt=\"Widgets de WordPress: Refactorizaci\u00f3n, Parte 2\"><\/a><\/p>\n<p>Todos estos son problemas que deben solucionarse. As\u00ed que voy a revisar y actualizar el c\u00f3digo. Luego compartir\u00e9 el c\u00f3digo aqu\u00ed (sin comentarios para ahorrar espacio).<\/p>\n<p>Suponiendo que haya realizado todos los cambios adecuados, deber\u00eda tener algo <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/dce6bda0d104192a21cb06dc7d3ca23c#file-04-wordpress-widget-boilerplate-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">como esto:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace WordPressWidgetBoilerplate;\n\nclass Plugin extends WP_Widget\n{\n    protected $widgetSlug = 'widget-name';\n\n    public function __construct()\n    {\n        add_action('init', [$this, 'widgetTextdomain']);\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        add_action('admin_print_styles', [$this, 'registerAdminStyles']);\n        add_action('admin_enqueue_scripts', [$this, 'registerAdminScripts']);\n\n        add_action('wp_enqueue_scripts', [$this, 'registerWidgetStyles']);\n        add_action('wp_enqueue_scripts', [$this, 'registerWidgetScripts']);\n\n        add_action('save_post', [$this, 'flushWidgetCache']);\n        add_action('deleted_post', [$this, 'flushWidgetCache']);\n        add_action('switch_theme', [$this, 'flushWidgetCache']);\n    }\n\n    public function getWidgetSlug()\n    {\n        return $this-&gt;widgetSlug;\n    }\n\n    public function widget($args, $instance)\n    {\n        \/\/ Check if there is a cached output\n        $cache = wp_cache_get($this-&gt;getWidgetSlug(), 'widget');\n\n        if (!is_array($cache)) {\n            $cache = [];\n        }\n\n        if (!isset($args['widget_id'])) {\n            $args['widget_id'] = $this-&gt;id;\n        }\n\n        if (isset($cache[$args['widget_id']])) {\n            return print $cache[$args['widget_id']];\n        }\n\n        extract($args, EXTR_SKIP);\n\n        $widgetString = $beforeWidget;\n\n        ob_start();\n        include plugin_dir_path(__FILE__).'views\/widget.php';\n        $widgetString .= ob_get_clean();\n        $widgetString .= $afterWidget;\n\n        $cache[$args['widget_id']] = $widgetString;\n\n        wp_cache_set($this-&gt;getWidgetSlug(), $cache, 'widget');\n\n        echo $widgetString;\n    }\n\n    public function flushWidgetCache()\n    {\n        wp_cache_delete($this-&gt;getWidgetSlug(), 'widget');\n    }\n\n    public function update($newInstance, $oldInstance)\n    {\n        $instance = $oldInstance;\n\n        \/\/ TODO: Here is where you update your widget's old values with the new, incoming values\n\n        return $instance;\n    }\n\n    public function form($instance)\n    {\n        \/\/ TODO: Define default values for your variables\n        $instance = wp_parse_args(\n            (array) $instance\n        );\n\n        \/\/ TODO: Store the values of the widget in their own variable\n\n        \/\/ Display the admin form\n        include plugin_dir_path(__FILE__).'views\/admin.php';\n    }\n\n    public function widgetTextdomain()\n    {\n        \/\/ TODO: be sure to change 'widget-name' to the name of *your* plugin\n        load_plugin_textdomain($this-&gt;getWidgetSlug(), false, dirname(plugin_basename(__FILE__)).'lang\/');\n    }\n\n    public static function activate($networkWide)\n    {\n        \/\/ TODO: define activation functionality here\n    }\n\n    public static function deactivate($networkWide)\n    {\n        \/\/ TODO:define deactivation functionality here\n    }\n\n    public function registerAdminStyles()\n    {\n        wp_enqueue_style($this-&gt;getWidgetSlug().'-admin-styles', plugins_url('css\/admin.css', __FILE__));\n    }\n\n    public function registerAdminScripts()\n    {\n        wp_enqueue_script($this-&gt;getWidgetSlug().'-admin-script', plugins_url('js\/admin.js', __FILE__), ['jquery']);\n    }\n\n    public function registerWidgetStyles()\n    {\n        wp_enqueue_style($this-&gt;getWidgetSlug().'-widget-styles', plugins_url('css\/widget.css', __FILE__));\n    }\n\n    public function registerWidgetScripts()\n    {\n        wp_enqueue_script($this-&gt;getWidgetSlug().'-script', plugins_url('js\/widget.js', __FILE__), ['jquery']);\n    }\n}\n<\/code><\/pre>\n<p>Una vez m\u00e1s, ejecuta:<\/p>\n<pre><code>$ vendor\/bin\/grumphp run<\/code><\/pre>\n<p>Y mira qu\u00e9 salida obtienes. Todav\u00eda obtendr\u00e1 una variedad de errores, a saber, que dice algo en el tono de:<\/p>\n<blockquote>\n<p>Evite las variables locales no utilizadas como&#8230;<\/p>\n<\/blockquote>\n<p>Esto se debe a que las reglas de rastreo de c\u00f3digo no quieren que usemos variables que no se usan; sin embargo, en un modelo est\u00e1ndar, es probable que usemos estas variables antes de que finalice el proyecto.<\/p>\n<p>Entonces, con ese fin, no hay necesidad de preocuparse por eso en este momento. Lo manejaremos cuando llegue el momento.<\/p>\n<h2>Hasta PSR<\/h2>\n<p>En este punto, gran parte del complemento se ha comprado seg\u00fan los est\u00e1ndares de PSR y ha tenido un conjunto s\u00f3lido de herramientas que podemos usar para probar constantemente nuestro c\u00f3digo mientras lo escribimos.<\/p>\n<p>Si est\u00e1 siguiendo el repositorio, la rama de <strong><a href=\"https:\/\/github.com\/tommcfarlin\/WordPress-Widget-Boilerplate\/tree\/develop\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">desarrollo<\/a><\/strong> se actualiz\u00f3 para reflejar los cambios en esta publicaci\u00f3n, as\u00ed que si\u00e9ntase libre de extraerla y revisar el c\u00f3digo.<\/p>\n<p>En la pr\u00f3xima publicaci\u00f3n, comenzaremos a refactorizar el c\u00f3digo de una manera mucho m\u00e1s orientada a objetos.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Echemos un vistazo a los errores que arroja el rastreador de c\u00f3digo para WordPress Widget Boilerplate y veamos si podemos actualizarlo a est\u00e1ndares m\u00e1s modernos.<\/p>\n","protected":false},"author":1,"featured_media":236238,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[892,716,800,840,861],"tags":[1172],"class_list":["post-230877","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-desarrollador","category-php-2","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230877","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230877"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230877\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/236238"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230877"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230877"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230877"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}