Tableless

Busca Menu

Iniciando com Symfony 2 – Parte 05

Seja o primeiro a comentar por

No tutorial anterior, criamos a entidade Author, e fizemos o relacionamento com os posts, neste tutorial vamos fazer as configurações adequadas para que possamos deixar nossa aplicação estruturada corretamente, e vamos criar e configurar a página index, onde os usuários terão acesso para visualizar e ler os posts.

Configurando

Vamos começar com as configurações.
Entrando no bundle CoreBundle, caminho: src/Tableless/CoreBundle, exclua a pasta Controller.
Excluindo a pasta controller

Ainda neste mesmo bundle vamos excluir a pasta view, caminho: src/Tableless/CoreBundle/Resources/view.

Excluindo a pasta view

Agora vamos entrar no bundle ModelBundle, caminho: src/Tableless/ModelBundle.
E vamos mover a pasta Controller desse bundle para o bundle CoreBundle

Vamos mover também a pasta view do ModelBundle para o bundle CoreBundle.

Depois das mudanças, nossa estrutura de pastas ficará como na imagem abaixo:
Estrutura de pastas pronta

Configurando os Controllers

Vamos continuar nossas configurações, agora vamos alterar nossos controllers para que os mesmos fiquem de acordo com a estrutura de pasta atual.

Primeiramente, vamos excluir a rota do ModelBundle, pois não vamos usá-la.
Entre no arquivo app/config/routing.yml e exclua as linhas abaixo:

tableless_model:
    resource: "@TablelessModelBundle/Controller/"
    type:     annotation
    prefix:   /

Deixando somente a rota tableless_core como mostrado na imagem abaixo:

Arquivo routing.yml

Agora vamos excluir o DefaultController.php, pois não vamos usar esse controller.

Abra o arquivo AuthorController.php, caminho: src/Tableless/CoreBundle/Controller/AuthorController.php

Na linha 3, mude o namespace.
De: Tableless\ModelBundle\Controller;
Para: Tableless\CoreBundle\Controller;

Na linha 43, mude a annotation:
De: @Template(“TablelessModelBundle:Author:new.html.twig”)
Para: @Template(“TablelessCoreBundle:Author:new.html.twig”)

Agora vamos configurar o controller PostController, caminho: src/Tableless/CoreBundle/Controller/PostController.php, vamos fazer a mesma alteração.

Na linha 3, mude o namespace.
De: Tableless\ModelBundle\Controller;
Para: Tableless\CoreBundle\Controller;

Na linha 43, mude a annotation:
De: @Template(“TablelessModelBundle:Post:new.html.twig”)
Para: @Template(“TablelessCoreBundle:Post:new.html.twig”)

Para verificarmos se correu tudo bem, vamos fazer o teste.
Rode o servidor

$ app/console server:run

Entre nas urls:
http://127.0.0.1:8000/post/
http://127.0.0.1:8000/author/

Se tudo foi configurado corretamente, nossa aplicação voltará a funcionar perfeitamente, veja:

Página index, e show

Criando um Controller

Nesse momento vamos criar um index, para nossa aplicação, para que seja nossa pagina principal, e possamos visualizar os posts de forma correta.
Podemos criar o controller codificando, porém para efeito de didática vamos criar através do console.

Entre no terminal e digite:

$ php app/console generate:controller

Ao digitarmos o comando acima e darmos enter, entramos no assistente do console do Symfony e ele nos comunica: Primeiro, você precisa dar o nome do controlador que você deseja gerar. Você deve usar a notação de atalho como AcmeBlogBundle:Post

Nesse momento digitamos:

$ Controller name: TablelessCoreBundle:IndexControler

Ao darmos o nome do nosso controller e darmos enter, o assistente nos pergunta: Qual o formato que vamos configurar a nossa rota?
E nos indica annotation, vamos deixar como está, e apenas damos enter:

$ Routing format (php, xml, yml, annotation) [annotation]:

A próxima pergunta é:
Qual o formato que vamos usar para template?
Ele mesmo nos indica o twig. Apenas damos enter.

$ Template format (twig, php) [twig]:

Após o enter ele nos pede o nome de nossas ações, que são os métodos que vamos criar para o nosso controller.
A primeira ação (método) vamos chamar de indexAction, e damos enter.

$ New action name (press  to stop adding actions): indexAction

O assistente nos pede a rota, vamos digitar “/” e damos enter.

$ Action route [/index]: /

Nos pergunta o caminho da nossa template, e ele nos indica um caminho, vamos deixar como está e apenas damos enter.

$ Templatename (optional) [TablelessCoreBundle:IndexControler:index.html.twig]:

Novamente o assistente nos pede para darmos um nome para uma nova ação (método), essa nova ação fará com que o post seja visualizado para a leitura, vamos dar o nome de showAction.

$ New action name (press  to stop adding actions): showAction

O assistente nos pede a rota, e nos indica como “/show”, vamos deixar como está e damos enter.

$ Action route [/show]:

Nos pergunta sobre caminho da template, e ele nos indica um caminho, vamos deixar como está e apenas damos enter.

$ Templatename (optional) [TablelessCoreBundle:IndexControler:show.html.twig]:

Ao darmos enter, entramos no modo de criação de uma nova ação, porém não queremos nenhuma outra ação, então apenas damos um enter, para entrarmos no processo de finalização.

$ New action name (press  to stop adding actions):

Ao entramos no processo de finalização o assistente nos pergunta se queremos confirmar a geração desse controller, ele nos indica sim, como queremos, apenas damos enter.

$ Do you confirm generation [yes]?

Pronto! Nosso controller IndexController está criado, juntamente com suas templates, veja a imagem abaixo:
Index controller

Ao entrarmos na url: http://127.0.0.1:8000/, vamos entrar no nosso index, e receberemos a mensagem abaixo:

Welcome to the IndexControler:index page

Criando um repositório

Se entrarmos em nosso controller IndexController, caminho: src/Tableless/CoreBunde/ IndexController.php, vamos perceber que nossos métodos estão criados, porém não estão implementados, vamos implementá-los, mas queremos que nosso index apresente para o usuário os últimos posts escritos, para que sempre o post mais atual seja apresentado em primeiro lugar, para isso devemos criar um repositório para nossa entidade Post.

Para isso, vamos entrar no bundle ModelBundle e crie uma pasta com o nome de Repository, dentro dessa pasta crie uma classe com o nome PostRepository.

Com a classe PostRepository aberta, adicione o nemspace dessa classe, e de um extends na classe EntityRepository do Doctrine, não se esquecendo de dar um use nessa classe.

use Doctrine\ORM\EntityRepository;

Crie um método privado com o nome getQueryBuilder e acrescente a EntityManager para que possamos usar nossa entidade Post, veja abaixo:

private function getQueryBuilder()
{
    $em = $this->getEntityManager();

    $queryBuilder = $em->getRepository('TablelessModelBundle:Post')
    ->createQueryBuilder('p');

    return $queryBuilder;
 }

Agora vamos criar um método publico chamado findAllInOrder, e vamos chamar o método getQueryBuilder(), para ordená-lo da forma que queremos, para que seja mostrado o último post postado primeiro. Veja abaixo:

public function findAllInOrder()
{
    $qb = $this->getQueryBuilder()
    ->orderBy('p.createdAt', 'desc');

    return $qb->getQuery()->getResult();
}

Veja a classe PostRepository pronta:

<?php

namespace Tableless\ModelBundle\Repository;

use Doctrine\ORM\EntityRepository;

class PostRepository extends EntityRepository
{
    private function getQueryBuilder()
    {
        $em = $this->getEntityManager();
        $queryBuilder = $em->getRepository('TablelessModelBundle:Post')
            ->createQueryBuilder('p');
        return $queryBuilder;
    }

     public function findAllInOrder()
    {
        $qb = $this->getQueryBuilder()
            ->orderBy('p.createdAt', 'desc');

        return $qb->getQuery()->getResult();
    }
} 

Agora temos que indicar para a entidade Post via annotation, onde está a classe PostRepository, para isso vamos abrir a entidade Post, caminho:src/Tableless/ModelBundle/Entity/Post.php, e acrescentar a annotation (repositoryClass=”Tableless\ModelBundle\Repository\PostRepository”) na linha 12 de sua entidade, veja:

/**
 * Post
 *
 * @ORM\Table(name="post")
 * @ORM\Entity(repositoryClass="Tableless\ModelBundle\Repository\PostRepository")
 */
class Post extends Timestampable
{
    ...

Implementando o controller

Vamos voltar para nosso IndexController, para que possamos implementá- lo. Abra o IndexController , e no método indexAction() temos que chamar nossa entidade Post, para que através dela chamemos o método findAllInOrder() da classe PostRepository, e retornar o resultado em forma de array, veja abaixo:

    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $posts = $em->getRepository('TablelessModelBundle:Post')->findAllInOrder();

        return [
            'posts' => $posts,
        ];
    } 

Também vamos implementar o método showAction(), para que seja buscado apena o post clickado pelo usuário, para isso devemos passar um parâmetro id, tanto no método, quanto na annotation para rota, para que seja buscado somente o post solicitado. Temos que chamar nossa entidade Post novamente, para que através dela chamemos o método find(), que já vem pré configurado pelo Doctrine, porém se o usuário requisitar um post que não existe, temos que passar uma mensagem de erro, para informá- lo, veja abaixo:

    /**
     * @Route("/show/{id}")
     * @Template()
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $post = $em->getRepository('TablelessModelBundle:Post')->find($id);

        if (!$post) {
            throw $this->createNotFoundException('O post não existe! Volte para home!');
        }

        return [
            'post' => $post,
        ];
    }

Veja o IndexController pronto:

<?php

namespace Tableless\CoreBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class IndexControlerController extends Controller
{
     /**
     * @Route("/")
     * @Template()
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $posts = $em->getRepository('TablelessModelBundle:Post')->findAllInOrder();

        return [
            'posts' => $posts,
        ];
    }

     /**
     * @Route("/show/{id}")
     * @Template()
     */
    public function showAction($id)
    {
        $em = $this->getDoctrine()->getManager();

        $post = $em->getRepository('TablelessModelBundle:Post')->find($id);

        if (!$post) {
            throw $this->createNotFoundException('O post não existe! Volte para home!');
        }

        return [
            'post' => $post,
        ];
    }
}

Para vemos como está ficando nossa aplicação, abra a index.html.twig, do IndexController, caminho: src/Tableless/CoreBundle/Resouces/views/IndexController/index.html.twig e vamos dar um dump em posts, veja abaixo, vamos adicionar a linha 8:

{% extends "::base.html.twig" %}

{% block title %}TablelessCoreBundle:IndexControler:index{% endblock %}

{% block body %}
Welcome to the IndexControler:index page

    {{ dump(posts) }}
    
{% endblock %}

Vamos fazer a mesma modificação para o arquivo show.html.twig no mesmo diretório, porém ao em vez de dar um dump em posts, vamos dar um dump em post, sem o “s” no final, veja:

{% extends "::base.html.twig" %}

{% block title %}TablelessCoreBundle:IndexControler:show{% endblock %}

{% block body %}
Welcome to the IndexControler:show page

    {{ dump(post) }}
    
{% endblock %}

Para vemos o resultado, entre nas urls:

http://127.0.0.1:8000/
http://127.0.0.1:8000/show/{o id do seu post}

Veja as imagens para comparação:

index – url: http://127.0.0.1:8000/
index

Pagina show – url: http://127.0.0.1:8000/show/4 -> {o id do seu post} no meu caso 4.
show

Conclusão

No tutorial anterior, eu comentei que iriamos configurar nosso projeto e começarmos a trabalhar com o Twig, porém nossa configuração e a criação do index, deixou este tutorial extenso, mas no próximo tutorial, vamos trabalhar com o bootstrap e com o twig para que possamos visualizar nossos post em nossa home da forma adequada e bonita.

Links dos tutoriais anteriores:
Iniciando com Symfony 2 – Instalação
Iniciando com Symfony 2 – parte 02
Iniciando com Symfony 2 – parte 03
Iniciando com Symfony 2 – parte 04

O projeto encontra-se no GitHub!

Publicado no dia