WordPress - Criando um formulário de contato sem plugin - Parte 2

No post anterior, montamos nossa view, com os campos do formulário, e deixamos preparada a interface que irá receber o retorno do envio.
Hoje nós veremos como a view receberá as informações que ela precisa, mantendo a ordem dos nossos arquivos :D

Criando nosso controller

Primeiramente, como temos uma página nova, vamos criar um controller que irá gerenciar todas as informações para essa página. No momento, temos só um formulário de contato. Mas poderíamos ter informações de contato, endereço, etc., em uma sidebar. Então já vamos deixar nossa aplicação escalável, separando corretamente as responsabilidades.

Crie um novo arquivo chamado controller-contact.php em functions/controllers, e vamos gerar o código padrão para o nosso controller:

1
2
3
4
5
6
7
8
9
10
<?php
require_once __DIR__ . '/../security.php';

class Controller_Contact {
public function __construct() {
add_filter( 'send_contact_form', array( new Service_Contact_Form, 'send_contact_form' ) );
}
}

new Controller_Contact;

Usamos a mesma base utilizada para criar nosso controller-single.php.

_Hey, o que é aquele new Service_Contact_Form?_

Como eu disse acima, vamos separar as responsabilidades das coisas. Se o controller ficar responsável por tratar os dados e exibí-los por toda a nossa página, quanto mais informações tivermos, maior ficará nosso arquivo, e pior para dar manutenção. Então vamos utilizar services que nos ajudarão a organizar o código.

Os services basicamente servirão para tratar todas a parte “bruta” do código. Cada service terá uma única responsabilidade. Nesse caso, o Service_Contact_Form servirá somente para tratar os dados de envio do nosso formulário. Se houver a necessidade de exibir informações de contato na sidebar, então nós iremos criar outro service para isso.

Os controllers podem chamar quantos services forem necessários. Por isso nós iremos criar um controller por página, e quantos services forem necessários, para cada controller.

Agora, explicando a chamada acima:

Você deve lembrar que, no artigo que falamos sobre controlar a exibição dos dados na nossa single, usamos um array, e passamos como primeiro parâmetro o $this, que é a referência para o objeto instanciado à partir daquela classe. Agora, nós estamos usando outra classe, chamada Service_Contact_Form. Por isso, instanciamos ela, e passamos como segundo parâmetro o método que nós esperamos que ela nos retorne os dados, para que sejam enviados à view, no momento em que o hook send_contact_form for ativado.

Esse hook está no início da nossa view, como vimos no post anterior.

Ficou claro até aqui? Vamos seguir então :)

Agora vamos criar nosso service. Crie um diretório service dentro do diretório functions/, e, dentro desse diretório, crie o arquivo service-contact-form.php.

Antes de continuarmos, precisamos incluir nossos arquivos para que eles possam ser utilizados na nossa aplicação. Até aqui, o início do nosso functions.php está assim:

1
2
require_once __DIR__ . '/functions/security.php';
require_once __DIR__ . '/functions/controllers/controller-single.php';

Vamos adicionar nosso controller da página de contato e também o service:

1
2
3
4
require_once __DIR__ . '/functions/security.php';
require_once __DIR__ . '/functions/services/service-contact-form.php';
require_once __DIR__ . '/functions/controllers/controller-single.php';
require_once __DIR__ . '/functions/controllers/controller-contact.php';

É muito importante a ordem que você inclui suas classes. No nosso caso, vamos sempre chamar os services antes dos controllers. Não é necessário manter uma ordem entre os services, ou entre os controllers, pois um service nunca consultará outro _service, igualmente um controller nunca consultará outro controller.

Agora, vamos começar a criar nosso service. Em functions/services/service-contact-form.php, adicione o seguinte código:

1
2
3
4
5
6
7
8
9
10
11
<?php
require_once __DIR__ . '/../security.php';

class Service_Contact_Form {
public function send_contact_form() {
return (object) array(
'status' => 'success',
'message' => 'Seu e-mail foi enviado com sucesso!'
);
}
}

Antes de qualquer coisa, precisamos testar se tudo funciona, então, por enquanto, vamos somente retornar os dados necessários à nossa interface.

O que tem de diferente nesse arquivo?

Nosso controller espera um método chamado send_contact_form, dentro da classe Service_Contact_Form, para enviar os dados à nossa view.

Na view, nós esperamos que a resposta seja um objeto, com as propriedades status e message. Por isso estamos retornando esse valor no nosso método.

Por que aquele (object) ali?

Estava esperando você perguntar! :)

Como você pode perceber, nosso método retorna um array, mas nossa view espera que o retorno seja um objeto. Além da classe StdClass(), que instancia uma nova classe vazia em PHP, para que você crie seus próprios métodos e propriedades rapidamente, podemos usar esse formato para converter um array para objeto.

Dessa forma, poderemos acessar corretamente esses dados na view, com:

1
2
$post_response->status; // "success"
$post_response->message; // "Seu e-mail foi enviado com sucesso!"

Agora é o momento de você usar a sua criatividade e usar CSS para estilizar a mensagem, para que ela fique “apresentável” ao usuário final :)

Teste mensagens com muito texto, com pouco texto, mude o status para error para saber como deve ser mostrada uma mensagem de erro. Nos próximos artigos continuaremos nossa saga para tratar os dados inputados pelo usuário, tratar algumas regras de segurança, para enfim fazer o envio do e-mail! Não perca os próximos episódios :D

Até lá!

Ficou alguma dúvida? Comente! :)

Link para o índice dessa série:
https://blog.da2k.com.br/2015/01/11/indice-da-serie-como-criar-temas-para-wordpress/

Post anterior:
https://blog.da2k.com.br/2015/02/22/wordpress-criando-um-formulario-de-contato-sem-plugin-parte-1/

Próximo post:
https://blog.da2k.com.br/2015/02/28/wordpress-criando-um-formulario-de-contato-sem-plugin-parte-3/

Sobre o #1postperday: https://blog.da2k.com.br/2014/12/31/um-post-por-dia/

Tem alguma sugestão para os próximos posts do #1postperday? Deixe ela aqui: https://github.com/fdaciuk/fdaciuk.github.io/issues/1