You can find out how to install the part of the manual you need in the description of the repository by the link . (For example, if you want to start with this lesson without going through the previous one)
src/Blogger/BlogBundle/Controller/PageController.php
to get entries from ba s data. // src/Blogger/BlogBundle/Controller/PageController.php class PageController extends Controller { public function indexAction() { $em = $this->getDoctrine() ->getManager(); $blogs = $em->createQueryBuilder() ->select('b') ->from('BloggerBlogBundle:Blog', 'b') ->addOrderBy('b.created', 'DESC') ->getQuery() ->getResult(); return $this->render('BloggerBlogBundle:Page:index.html.twig', array( 'blogs' => $blogs )); } // .. }
src/Blogger/BlogBundle/Resources/views/Page/index.html.twig
{# src/Blogger/BlogBundle/Resources/views/Page/index.html.twig #} {% extends 'BloggerBlogBundle::layout.html.twig' %} {% block body %} {% for blog in blogs %} <article class="blog"> <div class="date"><time datetime="{{ blog.created|date('c') }}">{{ blog.created|date('l, F j, Y') }}</time></div> <header> <h2><a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id }) }}">{{ blog.title }}</a></h2> </header> <img src="{{ asset(['images/', blog.image]|join) }}" /> <div class="snippet"> <p>{{ blog.blog(500) }}</p> <p class="continue"><a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id }) }}">Continue reading...</a></p> </div> <footer class="meta"> <p>Comments: -</p> <p>Posted by <span class="highlight">{{blog.author}}</span> at {{ blog.created|date('h:iA') }}</p> <p>Tags: <span class="highlight">{{ blog.tags }}</span></p> </footer> </article> {% else %} <p>There are no blog entries for symblog</p> {% endfor %} {% endblock %}
<?php if (count($blogs)): ?> <?php foreach ($blogs as $blog): ?> <h1><?php echo $blog->getTitle() ?><?h1> <!-- rest of content --> <?php endforeach ?> <?php else: ?> <p>There are no blog entries</p> <?php endif ?>
<h2><a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id }) }}">{{ blog.title }}</a></h2>
<p>{{blog.blog(500) }}</p>
The number 500 is the maximum length of the post that we want to get back from the function. To do this, we need to update the getBlog method that Doctrine 2 generated for us earlier. Update the getBlog method in the Blog Entity, located src/Blogger/BlogBundle/Entity/Blog.php
// src/Blogger/BlogBundle/Entity/Blog.php public function getBlog($length = null) { if (false === is_null($length) && $length > 0) return substr($this->blog, 0, $length); else return $this->blog; }
// src/Blogger/BlogBundle/Entity/Blog.php /** * @ORM\Entity(repositoryClass="Blogger\BlogBundle\Entity\Repository\BlogRepository") * @ORM\Table(name="blog") * @ORM\HasLifecycleCallbacks() */ class Blog { // .. }
$ php app/console doctrine:generate:entities Blogger\BlogBundle
src/Blogger/BlogBundle/Entity/Repository/BlogRepository.php
<?php namespace Blogger\BlogBundle\Entity\Repository; /** * BlogRepository * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. */ class BlogRepository extends \Doctrine\ORM\EntityRepository { }
<?php namespace Blogger\BlogBundle\Entity\Repository; /** * BlogRepository * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. */ class BlogRepository extends \Doctrine\ORM\EntityRepository { public function getLatestBlogs($limit = null) { $qb = $this->createQueryBuilder('b') ->select('b') ->addOrderBy('b.created', 'DESC'); if (false === is_null($limit)) $qb->setMaxResults($limit); return $qb->getQuery() ->getResult(); } }
// Doctrine\ORM\EntityRepository public function createQueryBuilder($alias, $indexBy = null) { return $this->_em->createQueryBuilder() ->select($alias) ->from($this->_entityName, $alias, $indexBy); }
// src/Blogger/BlogBundle/Controller/PageController.php class PageController extends Controller { public function indexAction() { $em = $this->getDoctrine() ->getManager(); $blogs = $em->getRepository('BloggerBlogBundle:Blog') ->getLatestBlogs(); return $this->render('BloggerBlogBundle:Page:index.html.twig', array( 'blogs' => $blogs )); } // .. }
src/Blogger/BlogBundle/Entity/Comment.php
and paste <?php // src/Blogger/BlogBundle/Entity/Comment.php namespace Blogger\BlogBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass="Blogger\BlogBundle\Entity\Repository\CommentRepository") * @ORM\Table(name="comment") * @ORM\HasLifecycleCallbacks */ class Comment { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\Column(type="string") */ protected $user; /** * @ORM\Column(type="text") */ protected $comment; /** * @ORM\Column(type="boolean") */ protected $approved; /** * @ORM\ManyToOne(targetEntity="Blog", inversedBy="comments") * @ORM\JoinColumn(name="blog_id", referencedColumnName="id") */ protected $blog; /** * @ORM\Column(type="datetime") */ protected $created; /** * @ORM\Column(type="datetime") */ protected $updated; public function __construct() { $this->setCreated(new \DateTime()); $this->setUpdated(new \DateTime()); $this->setApproved(true); } /** * @ORM\preUpdate */ public function setUpdatedValue() { $this->setUpdated(new \DateTime()); } }
src/Blogger/BlogBundle/Entity/Blog.php
<?php // src/Blogger/BlogBundle/Entity/Blog.php namespace Blogger\BlogBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Doctrine\Common\Collections\ArrayCollection; /** * @ORM\Entity(repositoryClass="Blogger\BlogBundle\Entity\Repository\BlogRepository") * @ORM\Table(name="blog") * @ORM\HasLifecycleCallbacks */ class Blog { // .. /** * @ORM\OneToMany(targetEntity="Comment", mappedBy="blog") */ protected $comments; // .. public function __construct() { $this->comments = new ArrayCollection(); $this->setCreated(new \DateTime()); $this->setUpdated(new \DateTime()); } // .. }
$ php app/console doctrine:generate:entities Blogger\BlogBundle
src/Blogger/BlogBundle/Entity/Repository/CommentRepository.php
$ php app/console doctrine:schema:update --force
"require": { // ... "doctrine/doctrine-migrations-bundle": "dev-master", "doctrine/migrations": "dev-master" }
$ composer update
// app/AppKernel.php public function registerBundles() { $bundles = array( // ... new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(), // ... ); // ... }
$ php app/console doctrine:migrations:diff $ php app/console doctrine:migrations:migrate
The note
You will also see a new table in the database called migration_versions . It stores the version numbers of the migrations so there is a command with which you can find out which version of the database is currently.
The board
Doctrine 2 Migrations are a great way to update a database on production, because the changes can be made programmatically. This means that we can integrate this task into the project deployment scenario, so the database will update automatically when a new version of the application is deployed. Doctrine 2 migrations also allow you to roll back the changes, since each migration has an up and down method. To roll back to the previous version, you need to specify the version number to which you would like to return, you can do it, as shown below.$ php app/console doctrine:migrations:migrate 20110806183439
src/Blogger/BlogBundle/DataFixtures/ORM/BlogFixtures.php
<?php // src/Blogger/BlogBundle/DataFixtures/ORM/BlogFixtures.php namespace Blogger\BlogBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Blogger\BlogBundle\Entity\Blog; class BlogFixtures extends AbstractFixture implements OrderedFixtureInterface { public function load(ObjectManager $manager) { // .. $manager->flush(); $this->addReference('blog-1', $blog1); $this->addReference('blog-2', $blog2); $this->addReference('blog-3', $blog3); $this->addReference('blog-4', $blog4); $this->addReference('blog-5', $blog5); } public function getOrder() { return 1; } }
src/Blogger/BlogBundle/DataFixtures/ORM/CommentFixtures.php
<?php // src/Blogger/BlogBundle/DataFixtures/ORM/CommentFixtures.php namespace Blogger\BlogBundle\DataFixtures\ORM; use Doctrine\Common\DataFixtures\AbstractFixture; use Doctrine\Common\DataFixtures\OrderedFixtureInterface; use Doctrine\Common\Persistence\ObjectManager; use Blogger\BlogBundle\Entity\Comment; use Blogger\BlogBundle\Entity\Blog; class CommentFixtures extends AbstractFixture implements OrderedFixtureInterface { public function load(ObjectManager $manager) { $comment = new Comment(); $comment->setUser('symfony'); $comment->setComment('To make a long story short. You can\'t go wrong by choosing Symfony! And no one has ever been fired for using Symfony.'); $comment->setBlog($manager->merge($this->getReference('blog-1'))); $manager->persist($comment); $comment = new Comment(); $comment->setUser('David'); $comment->setComment('To make a long story short. Choosing a framework must not be taken lightly; it is a long-term commitment. Make sure that you make the right selection!'); $comment->setBlog($manager->merge($this->getReference('blog-1'))); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Dade'); $comment->setComment('Anything else, mom? You want me to mow the lawn? Oops! I forgot, New York, No grass.'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Kate'); $comment->setComment('Are you challenging me? '); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 06:15:20")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Dade'); $comment->setComment('Name your stakes.'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 06:18:35")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Kate'); $comment->setComment('If I win, you become my slave.'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 06:22:53")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Dade'); $comment->setComment('Your SLAVE?'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 06:25:15")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Kate'); $comment->setComment('You wish! You\'ll do shitwork, scan, crack copyrights...'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 06:46:08")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Dade'); $comment->setComment('And if I win?'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 10:22:46")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Kate'); $comment->setComment('Make it my first-born!'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-23 11:08:08")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Dade'); $comment->setComment('Make it our first-date!'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-24 18:56:01")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Kate'); $comment->setComment('I don\'t DO dates. But I don\'t lose either, so you\'re on!'); $comment->setBlog($manager->merge($this->getReference('blog-2'))); $comment->setCreated(new \DateTime("2011-07-25 22:28:42")); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Stanley'); $comment->setComment('It\'s not gonna end like this.'); $comment->setBlog($manager->merge($this->getReference('blog-3'))); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Gabriel'); $comment->setComment('Oh, come on, Stan. Not everything ends the way you think it should. Besides, audiences love happy endings.'); $comment->setBlog($manager->merge($this->getReference('blog-3'))); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Mile'); $comment->setComment('Doesn\'t Bill Gates have something like that?'); $comment->setBlog($manager->merge($this->getReference('blog-5'))); $manager->persist($comment); $comment = new Comment(); $comment->setUser('Gary'); $comment->setComment('Bill Who?'); $comment->setBlog($manager->merge($this->getReference('blog-5'))); $manager->persist($comment); $manager->flush(); } public function getOrder() { return 2; } }
$comment->setBlog($manager->merge($this->getReference('blog-2')));
$ php app/console doctrine:fixtures:load
src/Blogger/BlogBundle/Entity/Repository/CommentRepository.php
<?php // src/Blogger/BlogBundle/Entity/Repository/CommentRepository.php namespace Blogger\BlogBundle\Entity\Repository; use Doctrine\ORM\EntityRepository; /** * CommentRepository * * This class was generated by the Doctrine ORM. Add your own custom * repository methods below. */ class CommentRepository extends EntityRepository { public function getCommentsForBlog($blogId, $approved = true) { $qb = $this->createQueryBuilder('c') ->select('c') ->where('c.blog = :blog_id') ->addOrderBy('c.created') ->setParameter('blog_id', $blogId); if (false === is_null($approved)) $qb->andWhere('c.approved = :approved') ->setParameter('approved', $approved); return $qb->getQuery() ->getResult(); } }
->where('c.blog = ' . blogId)
src/Blogger/BlogBundle/Controller/BlogController.php
// src/Blogger/BlogBundle/Controller/BlogController.php public function showAction($id) { // .. if (!$blog) { throw $this->createNotFoundException('Unable to find Blog post.'); } $comments = $em->getRepository('BloggerBlogBundle:Comment') ->getCommentsForBlog($blog->getId()); return $this->render('BloggerBlogBundle:Blog:show.html.twig', array( 'blog' => $blog, 'comments' => $comments )); }
show src/Blogger/BlogBundle/Resources/views/Blog/show.html.twig
{# src/Blogger/BlogBundle/Resources/views/Blog/show.html.twig #} {# .. #} {% block body %} {# .. #} <section class="comments" id="comments"> <section class="previous-comments"> <h3>Comments</h3> {% include 'BloggerBlogBundle:Comment:index.html.twig' with { 'comments': comments } %} </section> </section> {% endblock %}
src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig
{# src/Blogger/BlogBundle/Resources/views/Comment/index.html.twig #} {% for comment in comments %} <article class="comment {{ cycle(['odd', 'even'], loop.index0) }}" id="comment-{{ comment.id }}"> <header> <p><span class="highlight">{{ comment.user }}</span> commented <time datetime="{{ comment.created|date('c') }}">{{ comment.created|date('l, F j, Y') }}</time></p> </header> <p>{{ comment.comment }}</p> </article> {% else %} <p>There are no comments for this post. Be the first to comment...</p> {% endfor %}
src/Blogger/BlogBundle/Resouces/public/css/blog.css
/** src/Blogger/BlogBundle/Resorces/public/css/blog.css **/ .comments { clear: both; } .comments .odd { background: #eee; } .comments .comment { padding: 20px; } .comments .comment p { margin-bottom: 0; } .comments h3 { background: #eee; padding: 10px; font-size: 20px; margin-bottom: 20px; clear: both; } .comments .previous-comments { margin-bottom: 20px; }
assets web, assets .$ php app/console assets:install web
$ php app/console generate:doctrine:form BloggerBlogBundle:Comment
hint
, doctrine:generate:form . -.
src/Blogger/BlogBundle/Form/CommentType.php
<?php namespace Blogger\BlogBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class CommentType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('user') ->add('comment') ->add('approved') ->add('created', 'datetime') ->add('updated', 'datetime') ->add('blog') ; } /** * @param OptionsResolver $resolver */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Blogger\BlogBundle\Entity\Comment' )); } }
src/Blogger/BlogBundle/Resources/config/routing.yml
BloggerBlogBundle_comment_create: path: /comment/{blog_id} defaults: { _controller: "BloggerBlogBundle:Comment:create" } requirements: methods: POST blog_id: \d+
<?php // src/Blogger/BlogBundle/Controller/CommentController.php namespace Blogger\BlogBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Blogger\BlogBundle\Entity\Comment; use Blogger\BlogBundle\Form\CommentType; use Symfony\Component\HttpFoundation\Request; /** * Comment controller. */ class CommentController extends Controller { public function newAction($blog_id) { $blog = $this->getBlog($blog_id); $comment = new Comment(); $comment->setBlog($blog); $form = $this->createForm(CommentType::class, $comment); return $this->render('BloggerBlogBundle:Comment:form.html.twig', array( 'comment' => $comment, 'form' => $form->createView() )); } public function createAction(Request $request, $blog_id) { $blog = $this->getBlog($blog_id); $comment = new Comment(); $comment->setBlog($blog); $form = $this->createForm(CommentType::class, $comment); $form->handleRequest($request); if ($form->isValid()) { // TODO: Persist the comment entity return $this->redirect($this->generateUrl('BloggerBlogBundle_blog_show', array( 'id' => $comment->getBlog()->getId())) . '#comment-' . $comment->getId() ); } return $this->render('BloggerBlogBundle:Comment:create.html.twig', array( 'comment' => $comment, 'form' => $form->createView() )); } protected function getBlog($blog_id) { $em = $this->getDoctrine() ->getManager(); $blog = $em->getRepository('BloggerBlogBundle:Blog')->find($blog_id); if (!$blog) { throw $this->createNotFoundException('Unable to find Blog post.'); } return $blog; } }
src/Blogger/BlogBundle/Entity/Comment.php
<?php // src/Blogger/BlogBundle/Entity/Comment.php // .. use Symfony\Component\Validator\Mapping\ClassMetadata; use Symfony\Component\Validator\Constraints\NotBlank; // .. class Comment { // .. public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('user', new NotBlank(array( 'message' => 'You must enter your name' ))); $metadata->addPropertyConstraint('comment', new NotBlank(array( 'message' => 'You must enter a comment' ))); } // .. }
src/Blogger/BlogBundle/Resources/views/Comment/form.html.twig
{# src/Blogger/BlogBundle/Resources/views/Comment/form.html.twig #} {{ form_start(form, { 'action': path('BloggerBlogBundle_comment_create' , { 'blog_id' : comment.blog.id }), 'method': 'POST', 'attr': {'class': 'blogger'} }) }} {{ form_widget(form) }} <p> <input type="submit" value="Submit"> </p>
src/Blogger/BlogBundle/Resources/views/Comment/create.html.twig
{% extends 'BloggerBlogBundle::layout.html.twig' %} {% block title %}Add Comment{% endblock%} {% block body %} <h1>Add comment for blog post "{{ comment.blog.title }}"</h1> {% include 'BloggerBlogBundle:Comment:form.html.twig' with { 'form': form } %} {% endblock %}
src/Blogger/BlogBundle/Resources/views/Blog/show.html
{# src/Blogger/BlogBundle/Resources/views/Blog/show.html.twig #} {# .. #} {% block body %} {# .. #} <section class="comments" id="comments"> {# .. #} <h3>Add Comment</h3> {{ render(controller('BloggerBlogBundle:Comment:new',{ 'blog_id': blog.id })) }} </section> {% endblock %}
{{ render(controller('BloggerBlogBundle:Comment:new',{ 'blog_id': blog.id })) }}
// src/Blogger/BlogBundle/Entity/Blog.php public function __toString() { return $this->getTitle(); }
hint
Symfony2 , . , . , , , .
hint
, . text, textarea, 2 DateTime , .
- FormBuilder , . , . Comment, FormBuilder .
<?php namespace Blogger\BlogBundle\Form; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; class CommentType extends AbstractType { /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('user'); $builder->add('comment'); } /** * @param OptionsResolver $resolver */ public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults(array( 'data_class' => 'Blogger\BlogBundle\Entity\Comment' )); } public function getBlockPrefix() { return 'blogger_blogbundle_commenttype'; } }
// src/Blogger/BlogBundle/Controller/CommentController.php public function createAction(Request $request, $blog_id) { //.. if ($form->isValid()) { $em = $this->getDoctrine() ->getManager(); $em->persist($comment); $em->flush(); return $this->redirect($this->generateUrl('BloggerBlogBundle_blog_show', array( 'id' => $comment->getBlog()->getId())) . '#comment-' . $comment->getId() ); } //.. }
, , , .
Part 1 - Configuring Symfony2 and Templates
Part 2 - Contact page: validators, forms, and email
Part 3 - Doctrine 2 and Data Fixtures
Part 5 - Twig Extensions, Sidebar (sidebar) and Assetic
Part 6 - Modular and Functional Testing
Source: https://habr.com/ru/post/302602/
All Articles