Portuguese (Português) translation by João Fagner (you can also view the original English article)
No post anterior desta série, nós revimos o tópico trabalhando com Ajax no WordPress. Em última análise, o objetivo é aprimorar uma série anterior que foi publicada no site há alguns anos.
Para reiterar, não é que as técnicas ensinadas na série original estavam erradas, mas é que software muda ao longo do tempo, por isso é sempre bom revisar conceitos que foram cobertos alguns anos atrás e tentar atualizá-los para algo mais atual.
Lembre-se do post anterior, nós olhamos para o seguinte comentário da série original:
Vamos dar uma breve visão geral do Ajax, o que é, como funciona, como configurá-lo na frente e entender os ganchos que o WordPress nos oferece. Nós iremos construir um pequeno projeto que coloca a teoria em prática. Nós caminharemos através do código-fonte e nos assegurarmos que estará disponível também no GitHub.
Naquele post, revisamos algumas maneiras avançadas para incorporar a API Ajax de WordPress em nossos projetos usando programação procedural. Neste post, nós vamos pegar o código que escrevemos na primeira parte desta série e refatorá-lo para que ele possa usar uma abordagem orientada a objeto.
Em última análise, o objetivo não é fazer uma comparação para ver qual paradigma deve ser usado; em vez disso, é mostrar como nós podemos alcançar a mesma funcionalidade independentemente da abordagem que você escolher para criar seus plugins.
Planejando o Plugin
Antes de começarmos, refatorar o código é algo que precisamos considerar é como nós vamos colocar para fora os vários arquivos. Depois de tudo, parte do processo de começar um novo projeto—ou até mesmo usar um velho—vem a parte de planejar como o trabalho deve ser feito.
Para este plugin específico, nós vamos precisar do seguinte:
- um arquivo de inicialização que é responsável por inicializar a classe principal e começar o plugin
- uma classe que é responsável por carregar as dependências como o JavaScript
- uma classe que serve como a classe principal do plugin
Como você pode ver, não há muita coisa que precisamos fazer para o plugin. Nós vamos também re-organizar alguns arquivos para ter uma estrutura de diretórios consistente, e vamos ter certeza de documentar corretamente todo o código para serguir os padrões de codificação do WordPress.
Com isso dito, vamos começar.
Organizando os Arquivos
Antes de começarmos a escrever algum código, vamos fazer o seguinte:
- Crie um diretório com o nome de
assets
. - Crie um diretório com o nome
js
que estará localizado no diretórioassets
. - Mova
frontend.js
para o diretório dejs
.



O motivo para isso é que estamos entrando em um estilo de programação orientada a objeto. E parte disso inclui organizar nossos arquivos para que eles sigam as convenções, isso inclui como os pacotes serão considerados.
No nosso caso, o diretório assets
inclui todas as coisas necessárias para fazer o programa funcionar. Para alguns plugins, isso poderia ser JavaScript, CSS, imagens, fontes e assim por diante. Neste caso, temos um único arquivo de JavaScript.
O Carregador de Dependência
Em seguida, temos de introduzir uma classe que será responsável por carregar as dependências para o nosso projeto. Para este plugin em específico, a única dependência que temos é o arquivo de JavaScript que só colocamos no diretório assets
.
Parte da programação orientada a objeto significa certificar-se de que cada classe tem uma finalidade específica. Neste caso, a classe que estamos prestes a apresentar será responsável por carregar o JavaScript usando a API do WordPress.
Vamos começar criando a estrutura básica da classe:
<?php /** * Loads and enqueues dependencies for the plugin. * * @since 1.0.0 * * @package WPA/includes */ class Dependency_Loader { }
Em seguida, vamos adicionar um método que será responsável para o enfileiramento do JavaScript conforme API do WordPress.
<?php /** * Loads and registers dependencies. * * @since 1.0.0 * * @package WPA * @author Tom McFarlin * @license https://www.gnu.org/licenses/gpl-2.0.txt * @link https://tommcfarlin.com/ */ /** * Loads and enqueues dependencies for the plugin. * * @package WPA * @subpackage WPA/includes * @since 1.0.0 * @author Tom McFarlin * @license http://www.gnu.org/licenses/gpl-2.0.txt * @link https://tommcfarlin.com/ */ class Dependency_Loader { /** * Initializes the plugin by enqueuing the necessary dependencies. * * @since 1.0.0 */ public function initialize() { $this->enqueue_scripts(); } /** * Enqueues the front-end scripts for getting the current user's information * via Ajax. * * @access private * * @since 1.0.0 */ private function enqueue_scripts() { wp_enqueue_script( 'ajax-script', plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js', array( 'jquery' ) ); wp_localize_script( 'ajax-script', 'sa_demo', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); } }
Depois disso, precisamos levar as funções responsáveis por manipular as solicitações de Ajax e fornecer respostas e em seguida adicioná-los à classe. Uma vez que eles estarão dentro do contexto de uma classe, precisamos adicionar uma nova função que irá registrá-los com o WordPress.
Vamos criar uma função de setup_ajax_handlers
. Se parece como isto:
<?php /** * Registers the callback functions responsible for providing a response * to Ajax requests setup throughout the rest of the plugin. * * @since 1.0.0 */ public function setup_ajax_handlers() { add_action( 'wp_ajax_get_current_user_info', array( $this, 'get_current_user_info' ) ); add_action( 'wp_ajax_nopriv_get_current_user_info', array( $this, 'get_current_user_info' ) ); }
Em seguida, precisamos realmente mudar as funções para esta classe. Note que as funções foram originalmente prefixadas com _sa
já não são marcadas como tal. Uma vez que estão no contexto da classe, podemos retirar o prefixo e também retirar o sublinhado em favor da palavra-chave private
.
<?php public function get_current_user_info() { $user_id = get_current_user_id(); if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) { wp_send_json_success( wp_json_encode( get_user_by( 'id', $user_id ) ) ); } } private function user_is_logged_in( $user_id ) { $is_logged_in = true; if ( 0 === $user_id ) { wp_send_json_error( new WP_Error( '-2', 'The visitor is not currently logged into the site.' ) ); $is_logged_in = false; } return $is_logged_in; } private function user_exists( $user_id ) { $user_exists = true; if ( false === get_user_by( 'id', $user_id ) ) { wp_send_json_error( new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' ) ); $user_exists = false; } return $user_exists; }
Então nós vamos salvar esse arquivo como um includes
no diretório raiz do diretório do plugin. O includes
no diretório é muitas vezes na onde se encontra o código que é usado ao longo de um projeto. Mais poderia ser dito sobre este diretório em específico, mas isso seria um conteúdo para um longo post.
A versão final dessa classe deve se parecer como este:
<?php /** * Loads and registers dependencies. * * @since 1.0.0 * * @package WPA * @author Tom McFarlin * @license http://www.gnu.org/licenses/gpl-2.0.txt * @link https://tommcfarlin.com/ */ /** * Loads and enqueues dependencies for the plugin. * * @package WPA * @subpackage WPA/includes * @since 1.0.0 * @author Tom McFarlin * @license http://www.gnu.org/licenses/gpl-2.0.txt * @link https://tommcfarlin.com/ */ class Dependency_Loader { /** * Initializes the plugin by enqueuing the necessary dependencies. * * @since 1.0.0 */ public function initialize() { $this->enqueue_scripts(); } /** * Enqueues the front-end scripts for getting the current user's information * via Ajax. * * @access private * * @since 1.0.0 */ private function enqueue_scripts() { wp_enqueue_script( 'ajax-script', plugin_dir_url( dirname( __FILE__ ) ) . 'assets/js/frontend.js', array( 'jquery' ) ); wp_localize_script( 'ajax-script', 'sa_demo', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) ); } /** * Registers the callback functions responsible for providing a response * to Ajax requests setup throughout the rest of the plugin. * * @since 1.0.0 */ public function setup_ajax_handlers() { add_action( 'wp_ajax_get_current_user_info', array( $this, 'get_current_user_info' ) ); add_action( 'wp_ajax_nopriv_get_current_user_info', array( $this, 'get_current_user_info' ) ); } /** * Retrieves information about the user who is currently logged into the site. * * This function is intended to be called via the client-side of the public-facing * side of the site. * * @since 1.0.0 */ public function get_current_user_info() { $user_id = get_current_user_id(); if ( $this->user_is_logged_in( $user_id ) && $this->user_exists( $user_id ) ) { wp_send_json_success( wp_json_encode( get_user_by( 'id', $user_id ) ) ); } } /** * Determines if a user is logged into the site using the specified user ID. If not, * then the following error code and message will be returned to the client: * * -2: The visitor is not currently logged into the site. * * @access private * @since 1.0.0 * * @param int $user_id The current user's ID. * * @return bool $is_logged_in Whether or not the current user is logged in. */ private function user_is_logged_in( $user_id ) { $is_logged_in = true; if ( 0 === $user_id ) { wp_send_json_error( new WP_Error( '-2', 'The visitor is not currently logged into the site.' ) ); $is_logged_in = false; } return $is_logged_in; } /** * Determines if a user with the specified ID exists in the WordPress database. If not, then will * the following error code and message will be returned to the client: * * -1: No user was found with the specified ID [ $user_id ]. * * @access private * @since 1.0.0 * * @param int $user_id The current user's ID. * * @return bool $user_exists Whether or not the specified user exists. */ private function user_exists( $user_id ) { $user_exists = true; if ( false === get_user_by( 'id', $user_id ) ) { wp_send_json_error( new WP_Error( '-1', 'No user was found with the specified ID [' . $user_id . ']' ) ); $user_exists = false; } return $user_exists; } }
A Classe Principal
Agora estamos prontos para escrever a classe principal para o plugin. Esta classe em particular irá residir na raiz do diretório do plugin e a estrutura básica da classe ficará assim:
<?php /** * Loads and enqueues dependencies for the plugin. * * @since 1.0.0 * * @package WPA */ class WP_Simple_Ajax { }
Em seguida, vamos adicionar algumas propriedades que nós definiremos quando a classe é instanciada:
<?php class WP_Simple_Ajax { private $version; private $loader; }
Depois disso, vamos criar um construtor e uma função de inicialização que será usada para configurar o plugin em ação:
<?php /** * The primary class for the plugin * * Stores the plugin version, loads and enqueues dependencies * for the plugin. * * @since 1.0.0 * * @package WPA * @author Tom McFarlin * @license http://www.gnu.org/licenses/gpl-2.0.txt * @link https://tommcfarlin.com/ */ /** * Stores the plugin version, loads and enqueues dependencies * for the plugin. * * @package WPA * @author Tom McFarlin * @license http://www.gnu.org/licenses/gpl-2.0.txt * @link https://tommcfarlin.com/ */ class WP_Simple_Ajax { /** * Represents the current version of this plugin. * * @access private * @since 1.0.0 * @var string */ private $version; /** * A reference to the Dependency Loader. * * @access private * @since 1.0.0 * @var Dependency_Loader */ private $loader; /** * Initializes the properties of the class. * * @access private * @since 1.0.0 */ public function __construct() { $this->version = '1.0.0'; $this->loader = new Dependency_Loader(); } /** * Initializes this plugin and the dependency loader to include * the JavaScript necessary for the plugin to function. * * @access private * @since 1.0.0 */ public function initialize() { $this->loader->initialize(); $this->loader->setup_ajax_handlers(); } }
No código acima, o construtor define as propriedades e instancia as dependências necessárias para configurar o plugin em ação.
Quando initialize
é chamado, o plugin irá iniciar e ele chamará o método initialize da classe de dependência que criamos no início deste tutorial.
A Inicialização
A última coisa que precisamos fazer é pegar o arquivo principal que temos e usar o include
do PHP, e tenha certeza de que são os arquivos PHP necessários que estamos usando.
<?php /** * Loads and registers dependencies. */ include_once( 'includes/class-dependency-loader.php' ); /** * The primary class for the plugin */ include_once( 'class-wp-simple-ajax.php' );
Depois disso, precisamos definir um método que irá inicializar o arquivo de plugin principal e pôr tudo em ação.
<?php /** * Instantiates the main class and initializes the plugin. */ function wpa_start_plugin() { $plugin = new WP_Simple_Ajax(); $plugin->initialize(); }
A versão final do arquivo de inicialização deve se parecer como este:
<?php /** * This plugin demonstrates how to use the WordPress Ajax APIs. * * @package WPA * * @wordpress-plugin * Plugin Name: Simple Ajax Demo * Description: A simple demonstration of the WordPress Ajax APIs. * Version: 1.0.0 * Author: Tom McFarlin * Author URI: https://tommcfarlin.com/ * License: GPL-2.0+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt */ // If this file is called directly, abort. if ( ! defined( 'WPINC' ) ) { die; } /** * Loads and registers dependencies. */ include_once( 'includes/class-dependency-loader.php' ); /** * The primary class for the plugin */ include_once( 'class-wp-simple-ajax.php' ); /** * Instantiates the main class and initializes the plugin. */ function wpa_start_plugin() { $plugin = new WP_Simple_Ajax(); $plugin->initialize(); } wpa_start_plugin();
Primeiro, o arquivo verifica se estão sendo acessados diretamente, verificando se a constante do WordPress foi definida. Se não, então a execução para.
Depois disso, ele inclui várias classes que criamos através deste tutorial. Finalmente, ele define uma função que é chamada quando o WordPress carrega o plugin que inicia e define toda a ação.
Conclusão
E isso leva-nos até o fim desta série de duas partes. Espero que vocês tenham aprendido algumas das melhores práticas para incorporar o Ajax em seus projetos com WordPress, mas também um pouco sobre como documentar código procedural e orientado a objeto, bem como ver a diferença em como colocar o código para fora.
Em um post futuro, talvez revisemos alguns conceitos orientados a objeto que foram introduzidos aqui que serão cobertos com mais detalhes. Por enquanto, no entanto, deem uma olhada no plugin usando no link do GitHub na barra lateral desta página.
Lembre-se, você pode pegar todos os meus cursos e tutoriais na página do meu perfil, e você pode me seguir no meu blog e/ou Twitter no @tommcfarlin onde falo sobre desenvolvimento de software no contexto do WordPress.
Como de costume, por favor não hesite em deixar suas perguntas ou comentários no feed abaixo, que irei responder a cada um deles.
Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Update me weekly