symfony askeet Day 13 続き
タグ
- 昨日やったこと
- 質問タグを表示する
- タグが付いている質問リストを表示する
質問タグを表示する
タグモジュールを作る
symfony init-module frontend tag
モデルを拡張する。
場所: askeet2/lib/model/Question.php
public function getTags() { $c = new Criteria(); $c->clearSelectColumns(); $c->addSelectColumn(QuestionTagPeer::NORMALIZED_TAG); $c->add(QuestionTagPeer::QUESTION_ID,$this->getId()); $c->setDistinct(); $c->addAscendingOrderByColumn(QuestionTagPeer::NORMALIZED_TAG); $tags = array(); $rs = QuestionTagPeer::doSelectRS($c); while($rs->next()) { $tags[] = $rs->getString(1); } return $tags; }
ビューを修正する。
まずはview.ymlを書く。
場所: askeet2/apps/frontend/modules/question/config/view.yml
showSuccess: components: sidebar: [sidebar, question]
sidebarモジュールのコンポーネントに追加する。
場所: askeet2/apps/frontend/modules/sidebar/actions/components.class.php
public function executeQuestion() { $this->question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title')); }
フラグメントを書く
場所: askeet2/apps/frontend/modules/sidebar/templates/_question.php
<?php include_partial('sidebar/default') ?> <h2>タグ</h2> <ul id="question_tags"> <?php include_partial('tag/question_tags',array('question' => $question, 'tags' => $question->getTags())) ?> </ul>
パーシャルを書く
場所: askeet2/apps/frontend/modules/tag/templates/_question_tags.php
<?php foreach($tags as $tag): ?> <li><?php echo link_to($tag,'@tag?tag='.$tag,'rel=tag') ?></li> <?php endforeach; ?>
ルーティングの追加
場所: askeet2/apps/frontend/config/routing.yml
tag: url: /tag/:tag param: { module: tag, action: show }
質問に使われているタグを表示する
モデルを修正する
場所: askeet2/lib/model/Question.php
public function getPopularTags($max=5) { $tags = array(); $con = Propel::getConnection(); $query = ' SELECT %s AS tag, COUNT(%s) AS count FROM %s WHERE %s = ? GROUP BY %s ORDER BY count DESC '; $query = sprintf($query, QuestionTagPeer::NORMALIZED_TAG, QuestionTagPeer::NORMALIZED_TAG, QuestionTagPeer::TABLE_NAME, QuestionTagPeer::QUESTION_ID, QuestionTagPeer::NORMALIZED_TAG ); $stmt = $con->prepareStatement($query); $stmt->setInt(1,$this->getId()); $stmt->setLimit($max); $rs = $stmt->executeQuery(); while($rs->next()) { $tags[$rs->getString('tag')] = $rs->getInt('count'); } return $tags; }
ビューを修正する。
場所: askeet2/apps/frontend/modules/question/templates/_list.php
<div class="question_body"> <?php echo truncate_text(strip_tags($question->getHtmlBody()),200) ?> </div> tags: <?php echo tags_for_question($question) ?>
tags_for_question()をヘルパーに書く。
場所: askeet2/apps/frontend/lib/helper/QuestionHelper.php
<?php function tags_for_question($question, $max = 5) { $tags = array(); foreach ($question->getPopularTags($max) as $tag => $count) { $tags[] = link_to($tag, '@tag?tag='.$tag); } return implode(' + ', $tags); }
タグが付いている質問リストを表示する
たとえば[これはひどい]タグが付いていたとして
http://askeet.localhost/tag/これはひどい にアクセスすると
[これはひどい]と付けられた質問がリストで表示されるものを作りたい。
まずはアクションを書く。
場所: askeet2/apps/frontend/modules/tag/actions/actions.class.php
public function executeShow() { $this->question_pager = QuestionPeer::getPopularByTag($this->getRequestParameter('tag'),$this->getRequestParameter('page')); }
モデルを拡張する
場所: askeet2/lib/model/QuestionPeer.php
public static function getPopularByTag($tag,$page) { $c = new Criteria(); $c->add(QuestionTagPeer::NORMALIZED_TAG,$tag); $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS); $c->addJoin(QuestionTagPeer::QUESTION_ID,QuestionPeer::ID,Criteria::LEFT_JOIN); $pager = new sfPropelPager('Question',sfConfig::get('app_pager_homepage_max')); $pager->setCriteria($c); $pager->setPage($page); $pager->init(); return $pager; }
テンプレートを書く
場所: askeet2/apps/frontend/modules/tag/templates/showSuccess.php
<h1><?php echo $sf_params->get('tag') ?>で人気の質問</h1> <?php include_partial('question/list',array('question_pager' => $question_pager,'rule' => '@tag?tag='.$sf_params->get('tag'))) ?>
ルーティングを修正する
場所: askeet2/apps/frontend/config/routing.yml
tag: url: /tag/:tag/:page param: { module: tag, action: show, page: 1 }
エラーが出たら、question/listを修正してみる。
<?php include_partial('interested_user',array('question' => $question)) ?>
を
<?php include_partial('question/interested_user',array('question' => $question)) ?>
に修正。