Symfony 2でのCRUDアプリケーションの作成、パート2

Symfony 2の紹介記事の続き。 最初の部分では、レコード編集フォームを変更するプロセスについて説明しました。2番目の部分では、レコードリストインターフェイスを変更します。 doctrine:generate:crudコマンドが生成するテンプレートテンプレートとレコードリストコントローラーには、少なくともレコード検索フォームとページナビゲーションがありません。



検索フォームのクラス



検索フォームを追加することから始めましょう。 検索フォームを作成するには、検索が実行されるパラメーターが格納されるドメインオブジェクトのクラスを作成する必要があります。 たとえば、ニュースリストの場合、カテゴリのリストから選択し、ニュースの日付で検索する「部分文字列検索」になります。 検索フォームクラスも作成する必要があります。 Symfonyでのそのようなクラスの配置は規制されていません。検索クラスに名前空間を使用します

バンドルディレクトリの構造(バンドルの作成の開始、 最初の部分を参照)は次のとおりです。







ニュース検索オプションを備えたドメインオブジェクト



フォームが送信された後、データはドメインオブジェクトに転送されます。 次に、このオブジェクトのデータを使用して、リスト内のレコードを選択するための条件を作成します。



<?php namespace Test\NewsBundle\Entity\Search; use Symfony\Component\Validator\Constraints as Assert; class News { /** *   * @var string */ public $search; /** *    * @var integer */ public $category; /** *      * @var DateTime * @Assert\DateTime */ public $dateFrom; /** * ,     * @var DateTime * @Assert\DateTime */ public $dateTo; }
      
      







ニュース検索フォーム



なぜなら 検索パラメータの保存に使用されるドメインオブジェクトの場合、データベーステーブルとの接続は記述されていません。カテゴリフィールド(ドロップダウンリスト)の場合、リストの設定に使用されるエンティティを明示的に指定する必要があります。 日付が入力されるフィールドは、テキストフィールドとして表示されます(パラメータウィジェット= single_text)。 class = date属性がテキストフィールドに追加され、 jQueryUIでセレクターとして使用されます (テンプレートで後述)。 フォームでCSRF保護が無効になっているため、フォームの送信後、URLに追加のパラメーターはありません。



 <?php namespace Test\NewsBundle\Form\Search; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilder; class NewsType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder->add('search', 'search', array('required' => false, 'label' => ' ')) ->add('category', 'entity', array( 'label' => '', 'required' => false, 'class' => 'Test\\NewsBundle\\Entity\\NewsCategory')) ->add('dateFrom', 'date', array( 'label' => '', 'widget' => 'single_text', 'format' => 'yyyy-MM-dd', 'attr' => array('class' => 'date'), 'required' => false)) ->add('dateTo', 'date', array( 'label' => '', 'widget' => 'single_text', 'format' => 'yyyy-MM-dd', 'attr' => array('class' => 'date'), 'required' => false)); } public function getDefaultOptions(array $options) { return array( 'csrf_protection' => false, ); } function getName() { return 'searchorg'; } }
      
      







コントローラー



Test / NewsBundle / Controller / NewsControllerコントローラーで、作成されたクラスの使用をindexAction()メソッドに追加します。



 .. use Test\NewsBundle\Entity\Search\News as SearchNews; use Test\NewsBundle\Form\Search\NewsType as SearchNewsType; /** * News controller. * * @Route("/news") */ class NewsController extends Controller { /** *   * * @Route("/", name="news") * @Template() */ public function indexAction() { //  ,      $searchNews = new SearchNews(); //   $searchForm = $this->createForm(new SearchNewsType(), $searchNews); $searchForm->bindRequest($this->getRequest()); //   Doctrine $qb = $this->getDoctrine()->getEntityManager()->getRepository('TestNewsBundle:News') ->createQueryBuilder('n'); //   left join c  "" //          $qb->select('n,c')->leftJoin('n.newsCategory', 'c')->orderBy('n.pubDate'); //    -    LIKE   title, announce, text if ($searchNews->search) { foreach (array('n.title', 'n.announce', 'n.text') as $field) $qb->orWhere($qb->expr()->like($field, $qb->expr()->literal('%' . $searchNews->search . '%'))); } //  if ($searchNews->category) $qb->andWhere($qb->expr()->eq('c.id', $searchNews->category)); //     if ($searchNews->dateFrom) $qb->andWhere($qb->expr()->gt('n.pubDate', $qb->expr()->literal($searchNews->dateFrom->format('Ym-d')))); //     if ($searchNews->dateTo) $qb->andWhere($qb->expr()->lt('n.pubDate', $qb->expr()->literal($searchNews->dateTo->format('Ym-d')))); $entities = $qb->getQuery()->getResult(); return array('entities' => $entities, 'search_form' => $searchForm->createView()); } .... }
      
      







検索フォームとレコードリストテンプレート



次に、フォーム表示コードを追加するTest / NewsBundle / Resources / views / News / index.html.twigテンプレートを変更します。



 {% extends '::base.html.twig' %} {% block body %} <h1></h1> {% form_theme search_form 'form_table_layout.html.twig' %} <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script> <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.0/themes/redmond/jquery-ui.css"> <script> $(function() { $("form input.date").datepicker({ dateFormat: 'yy-mm-dd'}); }); </script> <form action="{{ path('news') }}" method="get"> {{ form_errors(search_form) }} <table> {{ form_row(search_form.search) }} {{ form_row(search_form.category)}} <tr> <td colspan="2"> </td> </tr> {{ form_row(search_form.dateFrom)}} {{ form_row(search_form.dateTo)}} {{ form_rest(search_form) }} </table> <button type="submit"></button> </form> <table class="records_list"> <thead> <tr> <th>Id</th> <th></th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody> {% for entity in entities %} <tr> <td><a href="{{ path('news_show', { 'id': entity.id }) }}">{{ entity.id }}</a></td> <td>{{ entity.title }}</td> <td>{{ entity.announce }}</td> <td>{{ entity.newsCategory }}</td> <td>{{ entity.pubDate|date('Ym-d') }}</td> <td> <ul> <li><a href="{{ path('news_show', { 'id': entity.id }) }}"></a></li> <li><a href="{{ path('news_edit', { 'id': entity.id }) }}"></a></li> </ul> </td> </tr> {% endfor %} </tbody> </table> <ul> <li> <a href="{{ path('news_new') }}">   </a> </li> </ul> {% endblock %}
      
      





ニュースリストは次のようになります。







ページナビゲーションバンドルのインストール



次に、ページナビゲーションを追加する必要があります。 独自のコードを作成することもできますが、 KnpPaginatorBundleなどの既製のバンドルを使用する方がはるかに簡単です 。 このバンドルをインストールするには、ファイルにdepsを追加します。



 [knp-components] git=http://github.com/KnpLabs/knp-components.git [KnpPaginatorBundle] git=http://github.com/KnpLabs/KnpPaginatorBundle.git target=bundles/Knp/Bundle/PaginatorBundle
      
      





ダウンロードするには、コマンドラインに入力する必要があります:

 php bin/vendors install --reinstall
      
      





bin / vendorsスクリプトはGitを使用します。新しいバンドルをダウンロードするには、システムにインストールする必要があります。

app / autoload.phpファイルに追加する必要があります:

 $loader->registerNamespaces(array( 'Knp\\Component' => __DIR__.'/../vendor/knp-components/src', 'Knp\\Bundle' => __DIR__.'/../vendor/bundles', // ... ));
      
      





app / AppKernel.phpファイルへ

 public function registerBundles() { return array( // ... new Knp\Bundle\PaginatorBundle\KnpPaginatorBundle(), // ... ); }
      
      







コントローラーの変更



コントローラーTest / NewsBundle / Controller / NewsControllerで、QueryBuilderオブジェクトでデータベースクエリを生成した後、indexAction()メソッドにKnpPaginatorの使用を追加します。 テンプレートのレコードの標準リストの代わりに、Paginatorクラスのオブジェクトを返します。



  $paginator = $this->get('knp_paginator'); $pagination = $paginator->paginate( $qb->getQuery(), $this->get('request')->query->get('page', 1)/*page number*/, 10/*limit per page*/ ); return array('entities' => $pagination, 'search_form' => $searchForm->createView());
      
      







テンプレートの変更



テンプレートTest / NewsBundle / Resources / views / News / index.html.twigで、エントリのリストを含むテーブルの下に、paginateタグへの呼び出しを追加します。



 <div id="navigation"> {{ entities.render()|raw }} </div>
      
      





ニュースリストは次のようになります。







レコードリストインターフェイスには、検索フォームとページごとのナビゲーションがあります。 提示されたコードの大部分はすでに自動的に生成されているため、改善のためのコードの量はそれほど多くないことに注意してください。



All Articles