Doctrine 2の日付を操作します。Symfony2でナビゲートします。

すべての人に挨拶! そして、SymfonyとDoctrineのトピックを作成しましょう。



はじめに



私は普通のシベリアの開発者です。人生の主な仕事は、世界を捉えて人々を幸せにすることです。 Symfonyで、彼はいくつかのプロジェクトを作成しました。 開発中に、インターネット上に情報がまったくない、または非常にわずかで完全に明確ではないタスクがある場合があります。 したがって、私はこの議論を作成したかったのです。ここで、自分の問題のいくつかをどのように解決したかを示します。 このトピックは、上記のフレームワークまたはそのコンポーネントをよく使用する人を対象としています。 また、特定の問題の解決について話したい人のために、他の開発者と経験を共有してください。



要点をつかむ



日付関数とDoctrine


小さな個人的なブログを想像してください。 年と月でグループ化された投稿のナビゲーションを表示する必要があります。 非常に簡単なタスク。 BlogRepositoryクラスにメソッドを作成し、 getArchiveByMonths()などの名前を付けます。 マシンで、次のようなコードを記述します。



$qb = $this->createQueryBuilder('p'); return $qb ->addSelect('MONTHNAME(p.created) as month') ->addSelect('YEAR(p.created) as year') ->addSelect('COUNT(p) as cnt') ->groupBy('month, year') ->orderBy('p.created', 'DESC') ->getQuery() ->getArrayResult();
      
      







そして、エラーが発生します: Expected known function, got 'MONTHNAME'





実際のところ、Doctrineは日付を操作するためのすべての関数を知っているわけではありません。 したがって、それらを追加する必要があります。 公式ドキュメントには、これらの関数を追加する方法に関するいくつかの行があります( Tyts



解決策:素晴らしいリポジトリがあります: github.com/simukti/DoctrineExtensions 、そこには2つのクラスがあります:

DoctrineExtensions\Query\Mysql\Month;





DoctrineExtensions\Query\Mysql\Year;







なぜそれらを使用しないのですか? それらをバンドル、たとえばDqlフォルダーにコピーし、名前空間をAcme\BlogBundle\Dql



に変更して、このようなすばらしいリポジトリがあることを喜ばせます。 Monthname



関数は、 Month



の例に従ってMonthname



ます。 リンクによると、これらの機能についての教義を言わなければなりません。



config.ymlに以下を追加します:

 # Doctrine Configuration doctrine: orm: dql: datetime_functions: month: Acme\BlogBundle\Dql\Month monthname: Acme\BlogBundle\Dql\Monthname year: Acme\BlogBundle\Dql\Year
      
      







その後、関数が機能します。



Doctrineがこれらの機能を認識していないことは私にとって予想外のことでした。 しかし、あなたは他の利点のために彼女を許すことができます。



ナビゲーションとパンくずリスト


ナビゲーションを作成するには、 KnpMenuBundleを使用します 。 githubでの使用方法をご覧ください。 だから、私たちは読んで、最初のメニューを作りました、例えばこれ:

 namespace Acme\BlogBundle\Menu; use Knp\Menu\FactoryInterface; use Knp\Menu\MenuItem; use Symfony\Component\DependencyInjection\ContainerAware; class Builder extends ContainerAware { public function mainMenu (FactoryInterface $factory, array $options) { $menu = $factory->createItem('root'); $request = $this->container->get('request'); $menu ->addChild('Homepage', array( 'route' => 'homepage', )); $blog = $menu->addChild('Blog', array( 'route' => 'blog' )); $blog->addChild('BlogView',array( 'route' => 'blog_post_view', 'routeParameters' => array('id' => $request->get('id', 1)), 'display' => false )); return $menu; }
      
      







このメニューをサイトの左側/右側のどこかに持ってきました。 そして今、パン粉を取り出す必要があります。 そして、ここで私は美しく素晴らしい解決策を持っていません、誰かがこれを行う方法を教えてくれることを願っています。 それまでの間、私は決断を下します。



まず、アクティブなメニュー項目を見つける必要があります。 Knpバンドルにはもはや標準的な方法はありません。 MenuBuilderを拡張します。

 namespace Acme\BlogBundle\Menu; use Knp\Menu\FactoryInterface; use Knp\Menu\Iterator\CurrentItemFilterIterator; use Knp\Menu\Iterator\RecursiveItemIterator; use Knp\Menu\MenuItem; use Symfony\Component\DependencyInjection\ContainerAware; class Builder extends ContainerAware { public function mainMenu (FactoryInterface $factory, array $options) { $menu = $factory->createItem('root'); $request = $this->container->get('request'); $menu ->addChild('Homepage', array( 'route' => 'homepage', )); $blog = $menu->addChild('Blog', array( 'route' => 'blog' )); $blog->addChild('BlogView',array( 'route' => 'blog_view', 'routeParameters' => array('id' => $request->get('id', 1)), 'display' => false )); return $menu; } public function getCurrentItem (FactoryInterface $factory, array $options) { $menu = $this->mainMenu($factory, $options); $matcher = $this->container->get('knp_menu.matcher'); $voter = $this->container->get('knp_menu.voter.router'); $matcher->addVoter($voter); $treeIterator = new \RecursiveIteratorIterator( new RecursiveItemIterator( new \ArrayIterator(array($menu)) ), \RecursiveIteratorIterator::SELF_FIRST ); $iterator = new CurrentItemFilterIterator($treeIterator, $matcher); // Set Current as an empty Item in order to avoid exceptions on knp_menu_get $current = new MenuItem('', $factory); foreach ($iterator as $item) { $current = $item; break; } return $current; }
      
      







現在のメニュー項目を見つけるメソッドを追加しました。 今、それを取り出す必要があります。 これを行うには、私たちの見解では、次のように書きます:

 {% set breadcrumbs = knp_menu_get('AcmeBlogBundle:Builder:getCurrentItem').getBreadcrumbsArray() %} <ul class="breadcrumb"> <li> <i class="icon-home"></i> <a href="{{ path('homepage') }}">Home</a> <span class="icon-angle-right"></span> </li> {% for link in breadcrumbs %} {% if link.label != 'root' %} <li> <a href="{{ link.uri }}">{{ link.label|trans }}</a> {% if not loop.last %} <span class="icon-angle-right"></span> {% endif %} </li> {% endif %} {% endfor %} </ul>
      
      







ここで、必要なものを返すgetBreadCrumbsArray()



メソッドを使用します。



おそらくそれだけです。 役に立てば幸いです。 チュクチは作家でもチュクチ開発者でもないので、PMでエラーをお願いします。 決定を追加して、トピックをさらに便利にします。 ご清聴ありがとうございました。



All Articles