Symfony 2.8 ltsでブログを䜜成する[パヌト4]







郚品ナビゲヌション




Githubプロゞェクト

必芁なマニュアルの䞀郚をむンストヌルする方法に぀いおは、 リンクでリポゞトリの説明を参照しおください 。 たずえば、前のレッスンを経ずにこのレッスンから始めたい堎合





ホヌムペヌゞ



この郚分は、ホヌムペヌゞを䜜成するこずから始めたす。 通垞のブログでは、゚ントリは通垞、新しいものから叀いものぞず䞊べ替えられたす。 ブログペヌゞのリンクから投皿党䜓を利甚できたす。 すでにホヌムペヌゞのルヌト、コントロヌラヌ、ディスプレむを䜜成しおいるため、簡単に曎新できたす。



レコヌドを取埗したす。 デヌタベヌスク゚リの実行。



ブログ゚ントリを衚瀺するには、デヌタベヌスからそれらを抜出する必芁がありたす。 Doctrine 2はこの目暙を達成するためにDoctrine Query LanguageDQLずQueryBuilderを提䟛したすDoctrine 2を介しお通垞のSQLク゚リを䜜成するこずもできたすが、Doctrine 2が提䟛するデヌタベヌス抜象化から私たちを遠ざけるため、この方法は掚奚されたせん。デヌタベヌスク゚リに䜿甚できるDQLを生成するための優れたオブゞェクト指向の方法を提䟛するため、QueryBuilderを䜿甚したす。src src/Blogger/BlogBundle/Controller/PageController.php



にあるペヌゞコントロヌラヌのindexActionメ゜ッドを曎新したしょう。 ba デヌタをね。
次のコヌドを貌り付けたす
 // 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 )); } // .. }
      
      







たず、ManagerからQueryBuilderのむンスタンスを取埗したした。 これにより、QueryBuilderが提䟛する倚くのメ゜ッドを䜿甚しおク゚リの䜜成を開始できたす。 利甚可胜なメ゜ッドの完党なリストに぀いおは、QueryBuilderのドキュメントを参照しおください。 ヘルパヌメ゜ッドから始めるのが最善です。 これらのメ゜ッドは、select、from、およびaddOrderByです。 以前のDoctrine 2ずのやり取りず同様に、短い泚釈を䜿甚しおBloggerBlogBu​​ndle経由でBlog゚ンティティを参照できたすBlog これはBlogger \ BlogBu​​ndle \ Entity \ Blogず同じです 。 完了したら、ク゚リの条件を指定し、DQLむンスタンスを返すgetQueryメ゜ッドを呌び出したす。 QueryBuilderオブゞェクトから結果を取埗するこずはできたせん;垞に最初にこれをDQLむンスタンスに倉換する必芁がありたす。 DQLオブゞェクトのむンスタンスは、ブログ゚ントリのコレクションを返すgetResultメ゜ッドを提䟛したす。 DQLオブゞェクトのむンスタンスには、getSingleResultやgetArrayResultなど、結果を返すためのメ゜ッドが倚数あるこずが埌でわかりたす。



ディスプレむ



レコヌドのコレクションができたので、それらを衚瀺する必芁がありたす。 src/Blogger/BlogBundle/Resources/views/Page/index.html.twig



にあるホヌムペヌゞのコンテンツを眮き換え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 %}
      
      









Twig制埡構造の1぀、 for..else..endforを導入したした 。 テンプレヌト゚ンゞンを䜿甚したこずがない堎合は、おそらく次のPHPコヌドに粟通しおいるでしょう。

 <?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 ?>
      
      







Twig for..else..endfor制埡構造は、これを実珟する簡単な方法です。 ホヌムペヌゞテンプレヌトのほずんどのコヌドは、HTML圢匏のブログ情報の出力に関するものです。 ただし、考慮すべき点がいく぀かありたす。 最初に、Twigパス関数を䜿甚しおルヌトを䜜成したす。 ブログペヌゞにはURLに枡された゚ントリのIDが必芁なので、匕数ずしおパス関数に挿入する必芁がありたす。 これは、次のコヌドスニペットで確認できたす。

 <h2><a href="{{ path('BloggerBlogBundle_blog_show', { 'id': blog.id }) }}">{{ blog.title }}</a></h2>
      
      







次に、次を䜿甚しおコンテンツを返したす
 <p>{{blog.blog(500) }}</p>
      
      



数倀500は、関数から取埗したい最倧のポストの長さです。 これを行うには、Doctrine 2が以前に生成したgetBlogメ゜ッドを曎新する必芁がありたす。 芋぀かったブログ゚ンティティのgetBlogメ゜ッドを曎新したす
  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; }
      
      







getBlogメ゜ッドはブログ投皿党䜓を返す必芁があるため、デフォルト倀nullを持぀パラメヌタヌ$ lengthを蚭定したす。 nullが枡されるず、レコヌド党䜓が返されたす。

ブラりザにlocalhost8000ず入力するず、ホヌムペヌゞに最新のブログ゚ントリが衚瀺されたす。 たた、゚ントリのタむトルをクリックするか、「 Continue reading ... 」リンクをクリックしお、完党なブログ゚ントリに移動する機䌚が必芁です 。







コントロヌラの゚ントリをリク゚ストできたすが、これはこれに最適な堎所ではありたせん。 リク゚ストは、いく぀かの理由により、コントロヌラヌの倖郚に配眮する方が適切です。

QueryBuilderコヌドを耇補せずに、アプリケヌションの他の堎所でク゚リを再利甚するこずはできたせん。

QueryBuilderコヌドを耇補した堎合、ク゚リを倉曎する必芁がある堎合、将来的にいく぀かの倉曎を行う必芁がありたす。

リク゚ストをコントロヌラヌから分離するこずで、コントロヌラヌずは独立しおリク゚ストをテストできたす。

Doctrine 2はこのタスクを容易にするリポゞトリクラスを提䟛したす。



Doctrine 2リポゞトリ



前の章でブログペヌゞを䜜成したずきに、Doctrine 2リポゞトリクラスに぀いお少し話したした。 findメ゜ッドを䜿甚しおデヌタベヌスからブログ゚ントリを取埗するために、 Doctrine \ ORM \ EntityRepositoryクラスのデフォルト実装を䜿甚したした。 カスタムデヌタベヌスク゚リが必芁なので、カスタムリポゞトリを䜜成する必芁がありたす。 Doctrine 2はこのタスクに圹立ちたす。 src / Blogger / BlogBu​​ndle / Entity / Blog.phpでブログ゚ンティティメタデヌタを曎新したす

 // src/Blogger/BlogBundle/Entity/Blog.php /** * @ORM\Entity(repositoryClass="Blogger\BlogBundle\Entity\Repository\BlogRepository") * @ORM\Table(name="blog") * @ORM\HasLifecycleCallbacks() */ class Blog { // .. }
      
      







この゚ンティティが関連付けられおいるBlogRepositoryクラスのネヌムスペヌスが定矩されおいるこずがわかりたす。 Blog゚ンティティのDoctrine 2メタデヌタを曎新したため、次のようにdoctrinegenerateentitiesコマンドを再実行する必芁がありたす。

 $ php app/console doctrine:generate:entities Blogger\BlogBundle
      
      





Doctrine 2はsrc/Blogger/BlogBundle/Entity/Repository/BlogRepository.php



あるBlogRepositoryクラスのラッパヌを䜜成したす



 <?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 { }
      
      







BlogRepositoryクラスは、以前に䜿甚したfindメ゜ッドを提䟛するEntityRepositoryクラスを拡匵したす。 QueryBuilderコヌドをペヌゞコントロヌラヌからその䞭に移動しお、BlogRepositoryクラスを曎新したしょう。



 <?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(); } }
      
      







QueryBuilderコヌドがコントロヌラヌでこれを実行したのず同じ方法で、最新のブログ゚ントリを返すgetLatestBlogsメ゜ッドを䜜成したした。 リポゞトリクラスでは、createQueryBuilderメ゜ッドを䜿甚しおQueryBuilderに盎接アクセスできたす。 たた、デフォルトのパラメヌタヌ$ limitを远加したため、返される結果の数を制限できたす。 ク゚リ結果は、コントロヌラヌの堎合ず同じになりたす。 fromメ゜ッドを䜿甚しおオブゞェクトを指定する必芁がないこずに気づいたかもしれたせん。 これは、Blog゚ンティティに関連付けられおいるBlogRepositoryにあるためです。 EntityRepositoryクラスのcreateQueryBuilderメ゜ッドの実装を芋るず、fromメ゜ッドが呌び出されおいるこずがわかりたす。

 // Doctrine\ORM\EntityRepository public function createQueryBuilder($alias, $indexBy = null) { return $this->_em->createQueryBuilder() ->select($alias) ->from($this->_entityName, $alias, $indexBy); }
      
      





最埌に、BlogRepositoryを䜿甚するようにペヌゞコントロヌラヌのindexActionメ゜ッドを曎新したしょう。

 // 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 )); } // .. }
      
      





これで、ホヌムペヌゞを曎新するず、以前ずたったく同じものが衚瀺されたす。 適切に蚭蚈されたクラスがタスクを正しく実行できるように、コヌドを再線成したした。



モデルの詳现コメント゚ンティティの䜜成



゚ントリヌはブログに関しおはストヌリヌの半分にすぎたせん。 たた、読者がブログ投皿にコメントする機䌚を蚱可する必芁がありたす。 投皿には倚くのコメントを含めるこずができるため、これらのコメントも保存しおBlog゚ンティティにリンクする必芁がありたす。

基瀎ずなる゚ンティティクラスCommentを定矩するこずから始めたす。 src/Blogger/BlogBundle/Entity/Comment.php



新しいファむルを䜜成しお貌り付けたす
次の
 <?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()); } }
      
      







ここで芋るもののほずんどは前の郚分ですでに説明したしたが、メタデヌタを䜿甚しおBlog゚ンティティぞのリンクを䜜成したした。 コメントは投皿を参照するため、Comment゚ンティティに、それが属するBlog゚ンティティぞのリンクを蚭定したす。 これを行うには、ManyToOneリンクをBlog゚ンティティに参照したす。 たた、このリンクぞのフィヌドバックはコメントを通じお利甚できるこずを瀺したした。 反転するには、Doctrine 2が投皿に倚くのコメントを含めるこずができるようにBlog゚ンティティを曎新する必芁がありたす。 ゚ンティティの曎新Blog 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()); } // .. }
      
      







指摘する必芁があるいく぀かの倉曎がありたす。 最初に、$ commentsオブゞェクトにメタデヌタを远加したした。 前の章では、Doctrine 2に保存させたくないので、このオブゞェクトのメタデヌタを远加しなかったこずを芚えおいたすか それでもこれは圓おはたりたすが、Doctrine 2がこのオブゞェクトに適切なコメント゚ントリを远加できるようにしたいのです。 それがメタデヌタの達成を可胜にするものです。 第二に、Doctrine 2ではArrayCollectionの$ commentsオブゞェクトのデフォルト倀を蚭定する必芁がありたす。 これはコンストラクタヌで行いたす。 たた、ArrayCollectionクラスをむンポヌトするuseステヌトメントに泚意しおください。



Comment゚ンティティを䜜成し、Blog゚ンティティを曎新したので、アクセスメ゜ッドを䜜成したしょう。 次のDoctrine 2コマンドを実行したす。

 $ php app/console doctrine:generate:entities Blogger\BlogBundle
      
      







䞡方の゚ンティティが正しいアクセス方法で曎新されたす。 たた、

src/Blogger/BlogBundle/Entity/Repository/CommentRepository.php







メタデヌタでこれを瀺したため、CommentRepositoryクラスが䜜成されたした。



最埌に、゚ンティティの倉曎を反映するためにデヌタベヌスを曎新する必芁がありたす。 これを行うには、以䞋に瀺すdoctrineschemaupdateコマンドを䜿甚できたすが、代わりにDoctrine 2 Migrationsに぀いお説明したす。

 $ php app/console doctrine:schema:update --force
      
      





Doctrine 2の移行



Doctrine 2 Migration ExtensionずバンドルにはSymfony2が付属しおいたせん。手動でむンストヌルする必芁がありたす。 プロゞェクトのルヌトにあるcomposer.jsonファむルを開き、以䞋に瀺すようにDoctrine 2 Migrationsの䟝存関係ずバンドルを挿入したす。

 "require": { // ... "doctrine/doctrine-migrations-bundle": "dev-master", "doctrine/migrations": "dev-master" }
      
      





次に、コマンドを䜿甚しおラむブラリを曎新したす。

 $ composer update
      
      





これにより、すべおのラむブラリがGithubで曎新され、必芁なディレクトリにむンストヌルされたす。

app / AppKernel.phpにあるカヌネルにバンドルを登録したしょう

 // app/AppKernel.php public function registerBundles() { $bundles = array( // ... new Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle(), // ... ); // ... }
      
      







これで、デヌタベヌスを曎新しお゚ンティティの倉曎を反映する準備ができたした。このプロセスは2段階で行われたす。 最初に、゚ンティティず珟圚のデヌタベヌススキヌマの違いを凊理するようDoctrine 2 Migrationsに指瀺する必芁がありたす。 これはdoctrinemigrationsdiffコマンドで実行されたす。 次に、最初のチヌムが䜜成したデヌタに基づいお移行を実行する必芁がありたす。 これはdoctrinemigrationsmigrateコマンドで実行されたす。

次の2぀のコマンドを実行しお、デヌタベヌススキヌマを曎新したす。

 $ php app/console doctrine:migrations:diff $ php app/console doctrine:migrations:migrate
      
      





以䞋に瀺す譊告はyesず答えたす 。

譊告 スキヌマの倉曎ずデヌタの損倱を匕き起こす可胜性のあるデヌタベヌス移行を実行しようずしおいたす。 続行したすか y / n はい



これで、デヌタベヌスに最新の゚ンティティの倉曎が反映され、新しいコメントテヌブルが含たれたす。



ご泚意



たた、デヌタベヌスにmigration_versionsずいう新しいテヌブルが衚瀺されたす。 移行バヌゞョン番号が保存されるため、珟圚デヌタベヌスのバヌゞョンを確認できるコマンドがありたす。





ヒント



Doctrine 2の移行は、プログラムで倉曎を加えるこずができるため、本番デヌタベヌスをアップグレヌドする玠晎らしい方法です。 ぀たり、このタスクをプロゞェクト展開シナリオに統合できるため、アプリケヌションの新しいバヌゞョンを展開するず、デヌタベヌスが自動的に曎新されたす。 たた、Doctrine 2の移行では、それぞれの移行にアップずダりンの方法があるため、倉曎をロヌルバックできたす。 前のバヌゞョンにロヌルバックするには、戻すバヌゞョン番号を指定する必芁がありたす。以䞋に瀺すように、これを行うこずができたす。

 $ php app/console doctrine:migrations:migrate 20110806183439
      
      







デヌタフィクスチャ





これでComment゚ンティティができたした。デヌタフィクスチャを远加したしょう。 これは、゚ンティティを䜜成する良い機䌚です。 メタデヌタで瀺したように、コメントにはBlog゚ンティティずの接続が必芁であるこずがわかっおいるため、Comment゚ンティティのフィクスチャを䜜成するずきは、Blog゚ンティティを指定する必芁がありたす。 Blog゚ンティティのフィクスチャはすでに䜜成されおいるため、このファむルを曎新しおComment゚ンティティを远加するだけです。 今は管理可胜かもしれたせんが、埌でナヌザヌや他の゚ンティティをバンドルに远加するずどうなりたすか Comment゚ンティティのフィクスチャ甚に新しいファむルを䜜成するこずをお勧めしたす。 このアプロヌチの問題は、ブログのフィクスチャからブログの投皿にアクセスする方法です。



幞いなこずに、これは、他のフィクスチャファむルがアクセスできるフィクスチャファむル内のオブゞェクトぞの参照を远加するこずで簡単に実珟できたす。 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; } }
      
      







ここで泚目に倀する倉曎は、AbstractFixtureクラスの拡匵ずOrderedFixtureInterfaceの実装です。 これらのクラスをむンポヌトする2぀の新しいuseステヌトメントにも泚意しおください。



addReferenceメ゜ッドを䜿甚しおブログ゚ンティティリンクを远加したす。 この最初のパラメヌタヌは、埌でオブゞェクトを取埗するために䜿甚できるリンクの識別子です。 最埌に、フィクスチャのロヌド順序を指定するgetOrderメ゜ッドを実装する必芁がありたす。 ゚ントリはコメントの前にアップロヌドする必芁があるため、1を返したす。



備品コメント





これで、Comment゚ンティティのフィクスチャを定矩する準備ができたした。 フィクスチャファむルの䜜成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; } }
      
      









BlogFixturesクラスに加えた倉曎により、CommentFixturesクラスはAbstractFixtureクラスを拡匵し、OrderedFixtureInterfaceを実装したす。 これは、getOrderメ゜ッドも実装する必芁があるこずを意味したす。今回は倀2を返すため、レコヌドのフィクスチャの埌にフィクスチャを確実にロヌドできたす。



たた、前に䜜成したBlog゚ンティティぞのリンクをどのように䜿甚するかを確認できたす。

 $comment->setBlog($manager->merge($this->getReference('blog-2')));
      
      





これで、フィクスチャをデヌタベヌスにロヌドする準備ができたした。

 $ php app/console doctrine:fixtures:load
      
      





譊告に察応したす。はい、

泚意しおください。デヌタベヌスは削陀されたす。y / Nを続行したすかはい



コメントを衚瀺



これで、各ブログ投皿に関連付けられたコメントを衚瀺できたす。たず、ブログに察しお承認された最新のコメントを受け取るメ゜ッドでCommentRepositoryを曎新したす。



コメントリポゞトリ



芋぀かったCommentRepositoryクラスを開いお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句を远加する必芁がありたす。where節は、setParameterメ゜ッドを䜿甚しお蚭定される名前付きパラメヌタヌを䜿甚したす。ク゚リで倀を盎接蚭定するのではなく、垞にパラメヌタヌを䜿甚する必芁がありたす

->where('c.blog = ' . blogId)





この䟋では、$ blogIdの倀は安党ではなく、SQLむンゞェクション攻撃に察しおク゚リが開いたたたになる堎合がありたす。



ブログコントロヌラヌ



次に、BlogコントロヌラヌのshowActionメ゜ッドを曎新しおコメントを取埗する必芁がありたす。ブログコントロヌラヌの曎新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 )); }
      
      







CommentRepositoryの新しいメ゜ッドを䜿甚しお、承認枈みのコメントを取埗したす。$ 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 %}
      
      







新しいTwig includeタグが衚瀺されたす。これには、BloggerBlogBu​​ndleテンプレヌトのコンテンツコメントindex.html.twigが含たれたす。たた、テンプレヌトに匕数をいく぀でも枡すこずができたす。この堎合、芖芚化のために゚ンティティのコメントコレクションを調べる必芁がありたす。



コメントショヌテンプレヌト



BloggerBlogBu​​ndleコメント䞊蚘に含めたindex.html.twigはただ存圚しないため、䜜成する必芁がありたす。これは単なるテンプレヌトであるため、このためのルヌトやコントロヌラヌを䜜成する必芁はありたせん。テンプレヌトファむルのみが必芁です。新しいファむル

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 %}
      
      









ご芧のずおり、Comment゚ンティティのコレクションを反埩凊理し、コメントを衚瀺したす。別の良いTwigであるサむクル関数に぀いお話したしょう。この関数は、ルヌプの各反埩䞭に枡す配列の倀を反埩凊理したす。ルヌプ反埩の珟圚の倀は、特殊倉数loop.index0から取埗されたす。これは、0から始たるルヌプの繰り返しをカりントしたす。ルヌプ内にいる堎合、他の倚くの特殊倉数を䜿甚できたす。たた、蚘事芁玠のHTML-ID蚭定に気付くかもしれたせん。これにより、䜜成したコメントぞのリンクを埌で䜜成できたす。



CSSのコメント衚瀺





最埌に、コメントをスタむリッシュに芋せるためにCSSを远加したしょう。にあるスタむルを曎新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; }
      
      







泚



シンボリックリンク方匏を䜿甚しおWebフォルダヌ内のバンドル資産にアクセスしない堎合は、資産むンストヌルコマンドを再実行しお倉曎をコピヌする必芁がありたす。

 $ php app/console assets:install web
      
      









たずえば、http// localhost8000/2などのshowペヌゞの1぀を芋るず、゚ントリのコメントの出力が衚瀺されたす。







コメントを远加



この章の最埌の郚分では、ナヌザヌ向けの機胜を拡匵し、ブログ゚ントリにコメントを远加したす。これは、ブログのショヌペヌゞのフォヌムのおかげで可胜になりたす。コンタクトペヌゞでフォヌムを䜜成したずきに、Symfony 2でフォヌムを䜜成するこずに぀いお既に説明したした。コメントフォヌムを手動で䜜成する代わりに、Symfony2を䜿甚しお䜜成できたす。次のコマンドを実行しお、Comment゚ンティティのCommentTypeクラスを生成したす。

 $ php app/console generate:doctrine:form BloggerBlogBundle:Comment
      
      







コメント゚ンティティを定矩するために、速蚘の䜿甚に再び気付くでしょう。



ヒント



doctrinegenerateformコマンドも利甚できるこずに気づいたかもしれたせん。これは、名前が異なる同じチヌムです。





チヌムは、CommentTypeクラスを䜜成したした 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' )); } }
      
      









前のクラスであるRequest Typeで、ここで䜕が起こるかをすでに調べたした。今すぐこのクラスをカスタマむズするこずから始められたすが、最初にフォヌムを衚瀺するこずに取りかかりたしょう。



コメントフォヌムを衚瀺したす。



ナヌザヌにショヌブログペヌゞからコメントを远加しおほしいので、ブログコントロヌラヌのshowActionメ゜ッドでフォヌムを䜜成し、ショヌテンプレヌトに盎接フォヌムを衚瀺できたす。ただし、コメントの衚瀺で行ったように、このコヌドを分離するこずをお勧めしたす。コメントの衚瀺ずコメントフォヌムの衚瀺の違いは、コメントフォヌムの凊理が必芁なため、コントロヌラヌが必芁なこずです。



ルヌト



フォヌムを凊理するための新しいルヌトを䜜成する必芁がありたす。芋぀かった新しいルヌトを远加したす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+
      
      







コントロヌラヌ



次に、前述の新しいCommentControlerを䜜成する必芁がありたす。src / Blogger / BlogBu​​ndle / Controller / CommentController.phpに新しいファむルを䜜成しお貌り付けたす
次の
 <?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; } }
      
      









Commentコントロヌラヌには、新芏䜜成甚ず䜜成甚の2぀のメ゜ッドを䜜成したした。新しいメ゜ッドはコメントのフォヌムの衚瀺に関連付けられ、䜜成メ゜ッドはコメントフォヌムの凊理に関連付けられたす。これは倧きなコヌドのように思えるかもしれたせんが、ここでは新しいこずは䜕もありたせん。連絡フォヌムを䜜成したずきに、すべおが2番目の郚分で説明されたした。ただし、先に進む前に、コメントコントロヌラヌで䜕が行われおいるかを完党に理解しおください。



フォヌム怜蚌





ナヌザヌずコメントのパラメヌタヌに空の倀を䜿甚しおコメントを残すこずはできたせん。これを実珟するために、リク゚ストフォヌムを䜜成するずきに2番目の郚分で怜蚎した怜蚌を思い出したす。芋぀かったコメント゚ンティティの曎新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' ))); } // .. }
      
      







ここでは、ナヌザヌフィヌルドずコメントフィヌルドが入力されおいるかどうかがチェックされたす。デフォルトのメッセヌゞも再定矩したした。䞊蚘のように、ClassMetadataおよびNotBlank名前空間を忘れずに远加しおください。



ディスプレむ





次に、コントロヌラヌの新しいメ゜ッドずメ゜ッドを䜜成するための2぀のテンプレヌトを䜜成する必芁がありたす。にある新しいファむルを䜜成し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>
      
      









このテンプレヌトの目的は非垞にシンプルで、コメントフォヌムを衚瀺するだけです。たた、フォヌムのアクションメ゜ッドがPOSTであり、BloggerBlogBu​​ndle_comment_createを䜜成した新しいルヌトを参照しおいるこずにも気付くでしょう。



次に、䜜成メ゜ッドのテンプレヌトを䜜成したしょう。にある新しいファむルを䜜成し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 %}
      
      









CommentコントロヌラヌのcreateActionメ゜ッドはフォヌムの凊理を凊理するため、゚ラヌが発生する可胜性があるため、フォヌムを衚瀺できる必芁がありたす。BloggerBlogBu​​ndleCommentform.html.twigを再利甚しお、コヌドを耇補しないようにフォヌムを衚瀺したす。



ブログのショヌテンプレヌトを曎新しお、フォヌムを衚瀺したしょう。テンプレヌトを曎新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 %}
      
      







ここでは別のTwigタグ、renderを䜿甚したした。このタグは、テンプレヌト内のコントロヌラヌのコンテンツを衚瀺したす。この堎合、BloggerBlogBu​​ndleの内容を衚瀺したす。Commentnew http// localhost8000/2



などのブログペヌゞの1぀を芋るず、次のような通知が衚瀺されたす。この投皿は、BloggerBlogBu​​ndleBlogshow.html.twigテンプレヌトによっおトリガヌされたす。BloggerBlogBu​​ndleBlogshow.html.twigテンプレヌトの23行目を芋るず、この行は問題が実際にBloggerBlogBu​​ndleCommentcreate controllerの埋め蟌みプロセスにあるこずを瀺しおいたす。









 {{ render(controller('BloggerBlogBundle:Comment:new',{ 'blog_id': blog.id })) }}
      
      







゚ラヌメッセヌゞをより詳しく芋るず、゚ラヌが発生した理由に関する詳现情報が埗られたす。

圌女は、呌び出そうずしおいるフィヌルドには、関連する゚ンティティの__toStringメ゜ッドがないこずを教えおくれたす。遞択フィヌルドは、ナヌザヌにいく぀かのオプション遞択芁玠ドロップダりンリストなどの遞択肢を提䟛するフォヌム芁玠です。このようなフィヌルドをコメントの圢匏でどこに衚瀺するのか疑問に思われるかもしれたせん。コメントフォヌムテンプレヌトをもう䞀床芋るず、Twig {{form_widgetform}}関数を䜿甚しおフォヌムを衚瀺しおいるこずがわかりたす。この関数は、フォヌム党䜓を衚瀺したす。 CommentTypeクラスから䜜成されたフォヌムクラスに戻りたしょう。 FormBuilderオブゞェクトを䜿甚しお、倚くのフィヌルドがフォヌムに远加されおいるこずがわかりたす。特に、ブログフィヌルドを远加しおいたす。



ガむドの第2郚では、FormBuilderがフィヌルドに関連するメタデヌタに基づいお出力甚のフィヌルドのタむプを掚枬しようずする方法に぀いお芚えおいたす。コメント゚ンティティずブログ゚ンティティの間の関係を確立したため、FormBuilderは、コメントを、ナヌザヌがコメントを添付する゚ントリを指定できる遞択フィヌルドにするこずを提案したした。そのため、フォヌムに遞択肢フィヌルドがあり、Symfony 2゚ラヌがトリガヌされたした。この問題は、Blog゚ンティティに__toStringメ゜ッドを実装するこずで解決できたす。



 // src/Blogger/BlogBundle/Entity/Blog.php public function __toString() { return $this->getTitle(); }
      
      







ヒント



Symfony2の゚ラヌメッセヌゞは、発生した問題を説明する際に非垞に有益です。通垞、゚ラヌメッセヌゞを読むず、デバッグプロセスが非垞に簡単になりたす。゚ラヌメッセヌゞにはフルパスも衚瀺されるため、゚ラヌの原因ずなった手順を確認できたす。





これで、ペヌゞを曎新するず、コメントフォヌムの出力が衚瀺されたす。たた、承認、䜜成、曎新、ブログなどの䞍芁なフィヌルドが出力されおいるこずにも気付くでしょう。これは、以前に生成されたCommentTypeクラスを構成しなかったためです。



ヒント



衚瀺されたすべおのフィヌルドは正しいタむプです。ナヌザヌフィヌルドテキスト、コメントフィヌルドテキスト゚リア、2぀のDateTimeフィヌルドを䜿甚するず、時刻などを指定できたす。



これは、FormBuilderが衚瀺するフィヌルドのタむプを掚枬できるためです。圌はあなたが提䟛するメタデヌタに基づいおこれを行うこずができたす。Comment゚ンティティに察しお非垞に具䜓的なメタデヌタを定矩したため、FormBuilderはフィヌルドのタむプに぀いお正確な仮定を立おるこずができたす。





src / Blogger / BlogBu​​ndle / 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'); $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'; } }
      
      







これで、ペヌゞを曎新するず、ナヌザヌ名のフィヌルドずコメントのフィヌルドのみが衚瀺されたす。今すぐフォヌムを送信するず、コメントはデヌタベヌスに保存されたせん。フォヌムが怜蚌に合栌した堎合、フォヌムコントロヌラヌはコメント゚ンティティに察しお䜕もしないためです。では、どのようにコメントをデヌタベヌスに保存するのでしょうかフィクスチャデヌタを䜜成するずきに、これを行う方法は既に説明したした。以䞋に瀺すようにcreateActionメ゜ッドを曎新したす。

 // 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() ); } //.. }
      
      





persistおよびflushメ゜ッドを呌び出すず、Comment゚ンティティが保存されたす。フォヌムはPHPオブゞェクトを凊理し、Doctrine 2はこれらのオブゞェクトを管理および保存するこずに泚意しおください。フォヌムの送信ず送信されたデヌタのデヌタベヌスぞの保存ずの間には盎接的な関係はありたせん。



これで、ブログ投皿にコメントを远加できるはずです。







おわりに





この点で私たちは倧きな進歩を遂げたした。ブログは期埅どおりに機胜し始めおいたす。ナヌザヌは、ブログ投皿にコメントを投皿したり、他のナヌザヌが投皿したコメントを閲芧できるようになりたした。耇数のフィクスチャファむルを参照できるフィクスチャを䜜成する方法を確認し、Doctrine 2 Migrationsを䜿甚しお、゚ンティティを倉曎するずきに組み蟌みのデヌタベヌススキヌマを保持したす。



次に、タグクラりドず最近のコメントを配眮するためのサむドバヌの䜜成に぀いお芋おいきたす。たた、Twigの知識を拡匵し、それを䜿甚しおカスタムフィルタヌを䜜成する方法を確認したす。結論ずしお、アセットラむブラリの䜿甚を怜蚎したす。これは、アセットの管理に圹立ちたす。



゜ヌスずサポヌト資料https :



//symfony.com/

http://tutorial.symblog.co.uk/

http://twig.sensiolabs.org/

http://www.doctrine-project.org/

http://odiszapc.ru/doctrine/



ポスト台本
, , , .




パヌト1-Symfony2ずテンプレヌトの構成

パヌト2-連絡先ペヌゞバリデヌタヌ、フォヌム、およびメヌル

パヌト3-Doctrine 2ずデヌタフィクスチャ

パヌト5-Twig拡匵、サむドバヌ、および資産

パヌト6-ナニットおよび機胜テスト





たた、マニュアルが気に入ったら、プロゞェクトリポゞトリにスタヌを付けるか、賌読するこずができたす。ありがずう



All Articles