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

に修正。

確認