Commits

eugenio pombi committed 1f58677

puts book data in mysql
adds book detail

Comments (0)

Files changed (9)

app/AppKernel.php

             new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
             new Symfony\Bundle\AsseticBundle\AsseticBundle(),
             new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),
+            new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(),
+            new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),
             new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
             new PUGX\BookBundle\PUGXBookBundle(),
         );

app/DoctrineMigrations/Version20130312160153.php

+<?php
+
+namespace Application\Migrations;
+
+use Doctrine\DBAL\Migrations\AbstractMigration,
+    Doctrine\DBAL\Schema\Schema;
+
+/**
+ * Auto-generated Migration: Please modify to your need!
+ */
+class Version20130312160153 extends AbstractMigration
+{
+    public function up(Schema $schema)
+    {
+        // this up() migration is auto-generated, please modify it to your needs
+        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'.");
+        
+        $this->addSql("CREATE TABLE book (id INT AUTO_INCREMENT NOT NULL, title VARCHAR(255) NOT NULL, author VARCHAR(255) NOT NULL, publication_date DATE NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB");
+    }
+
+    public function down(Schema $schema)
+    {
+        // this down() migration is auto-generated, please modify it to your needs
+        $this->abortIf($this->connection->getDatabasePlatform()->getName() != "mysql", "Migration can only be executed safely on 'mysql'.");
+        
+        $this->addSql("DROP TABLE book");
+    }
+}

src/PUGX/BookBundle/Controller/DefaultController.php

 namespace PUGX\BookBundle\Controller;
 
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
-use PUGX\BookBundle\Entity\Book;
 
 class DefaultController extends Controller
 {
 
     public function booksAction()
     {
-        $books = array(
-            new Book("Extreme Programming Explained: Embrace Change", "Kent Beck", new \DateTime('1999-10-5')),
-            new Book("The Clean Coder", "Robert C. Martin", new \DateTime('2011-5-23')),
-            new Book("Domain-Driven Design: Tackling Complexity in the Heart of Software", "Eric Evans", new \DateTime('2003-8-30')),
-        );
+        $em    = $this->getDoctrine()->getManager();
+        $books = $em->getRepository('PUGXBookBundle:Book')->findBy(array(), array('title' => 'ASC'));
 
         return $this->render('PUGXBookBundle:Default:books.html.twig', array('books' => $books));
     }
+
+    public function bookDetailAction($bookId)
+    {
+        $em   = $this->getDoctrine()->getManager();
+        $book = $em->getRepository('PUGXBookBundle:Book')->findOneById($bookId);
+
+        if (!$book) {
+            throw $this->createNotFoundException('Book not found');
+        }
+
+        return $this->render('PUGXBookBundle:Default:bookDetail.html.twig', array('book' => $book));
+    }
 }

src/PUGX/BookBundle/DataFixtures/ORM/LoadBookData.php

+<?php
+
+namespace PUGX\BookBundle\DataFixtures\ORM;
+
+use Doctrine\Common\DataFixtures\AbstractFixture;
+use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
+use Doctrine\Common\Persistence\ObjectManager;
+use PUGX\BookBundle\Entity\Book;
+
+class LoadBookData extends AbstractFixture implements OrderedFixtureInterface
+{
+    public function load(ObjectManager $manager)
+    {
+        $books = array(
+            new Book("Extreme Programming Explained: Embrace Change", "Kent Beck", new \DateTime('1999-10-5')),
+            new Book("The Clean Coder", "Robert C. Martin", new \DateTime('2011-5-23')),
+            new Book("Domain-Driven Design: Tackling Complexity in the Heart of Software", "Eric Evans", new \DateTime('2003-8-30')),
+        );
+
+        foreach ($books as $book) {
+            $manager->persist($book);
+        }
+
+        $manager->flush();
+    }
+   
+    
+    public function getOrder()
+    {
+        return 1;
+    }
+}

src/PUGX/BookBundle/Entity/Book.php

 
 namespace PUGX\BookBundle\Entity;
 
+use Doctrine\ORM\Mapping as ORM;
+
+/**
+ *
+ * @ORM\Entity
+ * @ORM\Table(name="book")
+ */
 class Book
 {
+    /**
+     * @var integer $id
+     *
+     * @ORM\Column(name="id", type="integer")
+     * @ORM\Id
+     * @ORM\GeneratedValue(strategy="AUTO")
+     */
+    protected $id;
+
+    /**
+     * @ORM\Column(type="string", name="title", length=255)
+     */
     protected $title;
 
+    /**
+     * @ORM\Column(type="string", name="author", length=255)
+     */
     protected $author;
 
+    /**
+     * @ORM\Column(type="date", name="publication_date")
+     */
     protected $publicationDate;
 
     /**
     {
         return $this->title;
     }
+
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
 }

src/PUGX/BookBundle/Resources/config/routing.yml

 pugx_book_list:
     pattern:  /books
     defaults: { _controller: PUGXBookBundle:Default:books }
+
+pugx_book_detail:
+    pattern:  /books/{bookId}
+    defaults: { _controller: PUGXBookBundle:Default:bookDetail }

src/PUGX/BookBundle/Resources/views/Default/bookDetail.html.twig

+{% extends '::base.html.twig' %}
+
+{% block content %}
+<article id="book-detail">
+    <h1>{{ book.title }}</h1> by {{ book.author }}
+    <p>
+        Published: {{ book.publicationDate|date("d/m/Y") }}
+    </p>
+</article>
+{% endblock %}

src/PUGX/BookBundle/Resources/views/Default/books.html.twig

         <tbody>
             {% for book in books %}
                 <tr>
-                    <td>{{ book.title }}</td>
+                    <td><a href="{{ path('pugx_book_detail', {'bookId':book.id}) }}">{{ book.title }}</a></td>
                     <td>{{ book.author }}</td>
                     <td>{{ book.publicationDate | date('d-m-Y') }}</td>
                 </tr>

src/PUGX/BookBundle/Tests/Controller/DefaultControllerTest.php

         $this->assertTrue($crawler->filter(".book-list")->count() > 0);
         $this->assertEquals(3, $crawler->filter(".book-list > tbody > tr")->count());
         $this->assertEquals(3, $crawler->filter(".book-list > tbody > tr:nth-child(1) > td")->count());
+        $this->assertRegExp("/Domain-Driven Design/i", $crawler->filter('.book-list > tbody > tr:nth-child(1) > td:nth-child(1)')->text());
+        $this->assertRegExp("/Extreme Programming Explained/i", $crawler->filter('.book-list > tbody > tr:nth-child(2) > td:nth-child(1)')->text());
+        $this->assertRegExp("/The Clean Coder/i", $crawler->filter('.book-list > tbody > tr:nth-child(3) > td:nth-child(1)')->text());
+    }
+
+    public function testBookDetailOk()
+    {
+        $client  = static::createClient();
+        $crawler = $client->request('GET', '/books');
+        $link    = $crawler->filter('.book-list > tbody > tr:nth-child(1) > td:nth-child(1) > a')->link();
+        $crawler = $client->click($link);
+        $this->assertTrue($client->getResponse()->isSuccessful());
+        $this->assertRegExp("/Eric Evans/i", $crawler->filter('#book-detail')->text());
+        $this->assertRegExp("/Domain-Driven Design/i", $crawler->filter('#book-detail')->text());
+        $this->assertRegExp("/30\/08\/2003/i", $crawler->filter('#book-detail')->text());
+    }
+
+    public function testBookDetail404()
+    {
+        $client  = static::createClient();
+        $crawler = $client->request('GET', '/books/unexistent');
+        $this->assertTrue($client->getResponse()->isNotFound());
     }
 }