{"id":229010,"date":"2022-11-01T10:07:00","date_gmt":"2022-11-01T07:07:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=229010"},"modified":"2022-11-09T05:10:56","modified_gmt":"2022-11-09T02:10:56","slug":"registro-de-ganchos-de-wordpress-usando-otra-clase","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/registro-de-ganchos-de-wordpress-usando-otra-clase\/","title":{"rendered":"Registro de ganchos de WordPress usando otra clase"},"content":{"rendered":"\n<p>En <a href=\"https:\/\/wordpress.mediadoma.com\/es\/los-constructores-de-complementos-de-wordpress-no-deberian-definir-ganchos\/\" title=\"la publicaci\u00f3n de ayer\" >la publicaci\u00f3n de ayer<\/a>, habl\u00e9 sobre los constructores de complementos de WordPress y la raz\u00f3n de por qu\u00e9 los ganchos no deber\u00edan estar en el constructor.<\/p>\n<p>Aunque mencion\u00e9 varias formas de manejar el registro de anzuelos, no me molest\u00e9 en entrar en detalles para cada una de esas estrategias. En lo que a m\u00ed respecta, merecen su propio art\u00edculo para proporcionar tantos detalles como sea posible sobre c\u00f3mo configurar algo.<\/p>\n<p>Por ejemplo, uno de los m\u00e9todos que compart\u00ed dec\u00eda:<\/p>\n<ul>\n<li>Es posible crear una clase que mantenga un registro de objetos y los ganchos con WordPress.<\/li>\n<\/ul>\n<p>En otras palabras, se trata de registrar ganchos de WordPress utilizando un enfoque orientado a objetos para disminuir el acoplamiento y aumentar la cohesi\u00f3n entre los componentes del complemento.<\/p>\n<p>Pero, \u00bfqu\u00e9 significa eso? \u00bfCu\u00e1les son las ventajas que trae, c\u00f3mo se configura y c\u00f3mo se usa?<\/p>\n<h2>Registro de ganchos de WordPress<\/h2>\n<p>Si est\u00e1 leyendo esto, es probable que est\u00e9 familiarizado con el <a href=\"https:\/\/codex.wordpress.org\/Plugin_API#Hooks:_Actions_and_Filters\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">sistema<\/a> de enlace de WordPress, el orden en que se activan y c\u00f3mo una funci\u00f3n o clase puede registrar sus funciones con WordPress para que puedan realizar cualquier trabajo que necesiten manejar.<\/p>\n<p>Y a menudo vemos clases haciendo esto por su cuenta. Dependiendo del proyecto, lo hago yo mismo. Para aquellos que no est\u00e1n familiarizados, generalmente se ve <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-00-plugins-loaded-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed<\/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>Pero todo esto se puede dividir en clases m\u00e1s cohesivas para, en \u00faltima instancia, darles a las clases a\u00fan menos responsabilidad (algo bueno) y disminuir el acoplamiento entre una clase o un conjunto de clases con WordPress.<\/p>\n<p>Un ejemplo de un dise\u00f1o que desglosar\u00e9 en esta publicaci\u00f3n.<\/p>\n<p>Sin embargo, la naturaleza contraria a la intuici\u00f3n de esto es que requerir\u00e1 al menos otra clase. Pero as\u00ed es como funciona.<\/p>\n<h2>Configur\u00e1ndolo<\/h2>\n<p>Para los prop\u00f3sitos de este ejemplo, solo usaremos una clase simple que registrar\u00e1 alg\u00fan tipo de acci\u00f3n con WordPress. La idea de la arquitectura funciona as\u00ed:<\/p>\n<ol>\n<li>Est\u00e1 la clase principal que tiene la funci\u00f3n que queremos vincular a WordPress.<\/li>\n<li>Hay una clase responsable de orquestar el enlace de la funci\u00f3n de la clase a WordPress.<\/li>\n<\/ol>\n<p>Bastante f\u00e1cil, \u00bfverdad? Pero aqu\u00ed est\u00e1 el problema: la clase responsable de registrar las funciones de una clase determinada con WordPress es el punto que requiere una decisi\u00f3n de dise\u00f1o.<\/p>\n<p>Primero, llamemos a la clase <strong>HookRegistry<\/strong> para que podamos referirnos a ella correctamente. A continuaci\u00f3n, llamemos a la clase con las funciones que queremos vincular a <strong>AcmeColumn<\/strong> simplemente para representar una clase que agrega una nueva columna al tablero de la p\u00e1gina en el \u00e1rea de administraci\u00f3n de WordPress.<\/p>\n<p>Con eso en su lugar, la decisi\u00f3n de dise\u00f1o se reduce a esto:<\/p>\n<ol>\n<li>\u00bfDebe <strong>HookRegistery<\/strong> saber acerca de <strong>AcmeColumn?<\/strong><\/li>\n<li>\u00bfDebe <strong>AcmeColumn<\/strong> conocer el <strong>HookRegistry<\/strong>? <\/li>\n<\/ol>\n<p>S\u00e9 que hay otras formas de organizar esto y tambi\u00e9n hay estrategias sobre c\u00f3mo manejar esto (como <a href=\"https:\/\/carlalexander.ca\/dependency-inversion-principle-wordpress\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">la inversi\u00f3n de control<\/a>) y estos son temas que vale la pena explorar, pero para mantener esta idea inicial lo m\u00e1s clara posible, la presentar\u00e9 para una publicaci\u00f3n futura.<\/p>\n<h3>usando la clase<\/h3>\n<p>Dadas las opciones anteriores, pasaremos una instancia de <strong>AcmeColumn<\/strong> a <strong>HookRegistry<\/strong> cuando las clases se instancian durante el proceso inicial de inicio del complemento de WordPress. Esto puede parecerse <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-01-startup-process-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">a esto<\/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>Luego, siempre que sea el momento de que <strong>AcmeColumn\u00a0<\/strong> registre su funci\u00f3n con WordPress, llamaremos a <strong>HookRegistry<\/strong> y le indicaremos que lo haga.<\/p>\n<p>Primero, <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>Entonces el <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>Opcionalmente, tambi\u00e9n podemos mantener una lista de las distintas clases y ganchos que se han registrado. Esto puede o no ser \u00fatil seg\u00fan su implementaci\u00f3n, por lo que lo comparto simplemente como &quot;aqu\u00ed hay algo que quiz\u00e1s desee hacer&quot;.<\/p>\n<p>Y eso podr\u00eda <a href=\"https:\/\/gist.github.com\/tommcfarlin\/340900ba153fa9c3b30b83f7b163210c#file-03-hook-registry-improved-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">verse as\u00ed<\/a> (usando una matriz asociativa simple):<\/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>Observe que en la clase anterior, ahora acepta un <strong>$id<\/strong> como par\u00e1metro. Hay varias formas de identificar la informaci\u00f3n que ingresa en un registro, la m\u00e1s f\u00e1cil de las cuales es crear la identificaci\u00f3n usted mismo.<\/p>\n<p>Sin embargo, si quisiera usar algo como el nombre del enlace o el nombre de la clase, eso tambi\u00e9n funcionar\u00eda. Solo tenga en cuenta que, dado que es una matriz asociativa, solo puede mantener un valor \u00fanico por clave, por lo que puede terminar desechando los datos anteriores si no tiene cuidado.<\/p>\n<p>Independientemente, esto es algo que considero opcional, pero si se implementa, es importante asegurarse de tener las funciones adecuadas para recuperar una instancia del objeto mediante una clave.<\/p>\n<h2>Uno de tantos<\/h2>\n<p>Al igual que con todo lo relacionado con este tipo de trabajo, es posible redise\u00f1arlo o reorientarlo de una manera que funcione de manera diferente o que se adapte a sus necesidades. El prop\u00f3sito no es mostrar el patr\u00f3n definitivo de c\u00f3mo hacer algo, sino una forma de abordarlo y adaptarlo (al igual que cualquier patr\u00f3n de dise\u00f1o).<\/p>\n<p>Adem\u00e1s, est\u00e1 destinado a asegurarse de que nuestras clases mantengan las responsabilidades para las que fueron creadas al mismo tiempo que les permite registrarse en WordPress seg\u00fan sea necesario. Esta vez, sin embargo, la clase no tiene que hacerlo por s\u00ed misma.<\/p>\n<p>En cambio, pasa la responsabilidad a una clase que tiene la responsabilidad exclusiva de registrar dichos ganchos. Entonces, aunque introduce m\u00e1s clases, aumenta la cohesi\u00f3n y disminuye el acoplamiento.<\/p>\n<p>Esto ofrece beneficios en el mantenimiento, las pruebas y el dise\u00f1o general.<\/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>Se trata de registrar ganchos de WordPress utilizando un enfoque orientado a objetos para disminuir el acoplamiento y aumentar la cohesi\u00f3n en el complemento.<\/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":[892,810,716,914,861],"tags":[1172],"class_list":["post-229010","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-codigo","category-complementos","category-desarrollador","category-otro","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229010","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=229010"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/229010\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/223973"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=229010"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=229010"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=229010"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}