symfony askeet Day 7
- リファスタリング
- 最近の質問
- 最近の答え
- ユーザープロファイルを作る
リファスタリング
同じことを繰り返さないが原則なので
askeet/apps/question/templates/_list.phpにあるページ分割機能をヘルパーに抽出する。
ヘルパーはテンプレートにアクセス可能なPHP関数らしいです。
という説明はaskeetに書いてあるのでさっそくGlobalHelper.phpを作る。
場所はaskeet/apps/frontend/lib/helper/
<?php function pager_navigation($pager,$uri) { $navigation = ''; if ($pager->haveToPaginate()) { $uri .=(preg_match('/\?/',$uri) ? '&' :'?').'page='; // First and previous page (最初と最後のページ) if ($pager->getPage() != 1) { $navigation .= link_to(image_tag('first.gif','align=absmiddle'),$uri.'1'); $navigation .= link_to(image_tag('previous.gif','align=absmiddle'),$uri.$pager->getPreviousPage()).' '; } // Pages one by one (1つずつのページ) $links = array(); foreach ($pager->getLinks() as $page) { $links[] = link_to_unless($page == $pager->getPage(),$page,$uri,$page); } $navigation .= join(' ',$links); // Next and last page (次と最後のページ) if ($pager->getPage() != $pager->getCurrentMaxLink()) { $navigation .= ' '.link_to(image_tag('next.gif','align=absmiddle'),$uri.$pager->getNextPage()); $navigation .= link_to(image_tag('last.gif','align=absmiddle'),$uri.$pager->getLastPage()); } } return $navigation; }
ほげっと書いたら_list.phpを開く。
場所はaskeet/apps/question/templates/_list.php
<?php foreach($question_pager->getResults() as $question): ?> <div class="question"> <div class="interested_block"> <?php include_partial('interested_user', array('question' => $question)) ?> </div> <h2><?php echo link_to($question->getTitle(), 'question/show?stripped_title='.$question->getStrippedTitle()) ?></h2> <div class="question_body"> <?php echo truncate_text($question->getBody(), 200) ?> </div> </div> <?php endforeach; ?> <div id="question_pager"> <?php echo pager_navigation($question_pager,'question/list') ?> </div>
最近の質問リスト
askeetのデモサイトだとこれのことですね。
http://www.askeet.com/recent/1
なるほど。ということで実装してみる。
まずは、askeet/apps/frontend/modules/question/actions/actions.class.phpに
public function executeRecent() { $this->question_pager = QuestionPeer::getRecentPager($this->getRequestParameter('page',1)); }
とても簡単に書けます。
askeetの説明を読むと呼び出す機能のはQuestionPeerクラスのメソッドに追加するとよい。とあるので追加します。
次はテンプレートの追加。
askeet/apps/frontend/modules/question/templates/recentSuccess.phpを作成する。
<h1>recent questions</h1> <?php include_partial('list',array('question_pager' => $question_pager,'rule' => 'question/recent')) ?>
おお。
あとはルーティングの設定をする。
askeet/apps/frontend/config/routing.ymlに追加する。
recent_questions: url: /question/recent/:page param: { module: question, action: recent, page: 1 }
ルーティングの設定を終えたのでokと言いたいところですが、actionsを弄ったのでいくつか修正する。
まずはaskeet/apps/frontend/modules/question/templates/_list.php
<div id="question_pager"> <?php echo pager_navigation($question_pager, $rule) ?> </div>
askeet/apps/frontend/modules/question/templates/listSuccess.phpも忘れずに。
<h1>popular questions</h1> <?php echo include_partial('list', array('question_pager' => $question_pager,'rule' => 'question/list')) ?>
最近の答え
次は「答え」のほうを作る。
見本:http://www.askeet.com/recent/answers/1
answerモジュールを作成する。
symfony init-module frondend answer
askeet/apps/frontend/actions/actions.class.phpに↓を書く。
public function executeRecent() { $this->answer_pager = AnswerPeer::getRecentPager($this->getRequestParameter('page',1)); }
askeet/lib/model/AnswerPeer.class.phpに↓を書く。
public static function getRecentPager($page) { $pager = new sfPropelPager('Answer',sfConfig::get('app_pager_homepage_max')); $c = new Criteria(); $c->addDescendingOrderByColumn(self::CREATED_AT); $pager->setCriteria($c); $pager->setPage($page); $pager->setPeerMethod('doSelectJoinUser'); $pager->init(); return $pager; }
askeet/apps/frontend/modules/answer/templates/recentSuccess.phpを作る
<?php use_helper('Date','Global') ?> <h1>recent answers</h1> <div id="answers"> <?php foreach ($answer_pager->getResults() as $answer): ?> <div class="answer"> <h2><?php echo link_to($answer->getQuestion()->getTitle(), 'question/show?stripped_title='.$answer->getQuestion()->getStrippedTitle()) ?></h2> <?php echo count($answer->getRelevancys()) ?> points posted by <?php echo link_to($answer->getUser(),'user/show?id='.$answer->getUser()->getId()) ?> on <?php echo format_date($answer->getCreatedAt(),'p') ?> <div> <?php echo $answer->getBody() ?> </div> </div> <?php endforeach ?> </div> <div id="question_pager"> <?php echo pager_navigation($answer_pager,'answer/recent') ?> </div>
ユーザープロファイルを作る
デモサイトだと、http://www.askeet.com/user/fabpotのことですね。
ということでまずアクションを作る。
askeet/apps/frontend/modules/user/actions/actions.class.phpを作る。
public function executeShow() { $this->subscriber = UserPeer::retrieveByPk($this->getRequestParameter('id', $this->getUser()->getSubscriberId())); $this->forward404Unless($this->subscriber); $this->interests = $this->subscriber->getInterestsJoinQuestion(); $this->answers = $this->subscriber->getAnswersJoinQuestion(); $this->questions = $this->subscriber->getQuestions(); }
次はテンプレート。
askeet/apps/frontend/modules/user/templates/showSuccess.phpに書きます。
<h1><?php echo $subscriber ?>'s profile</h1> <h2>Interests</h2> <ul> <?php foreach($interests as $interest): $question = $interest->getQuestion() ?> <li><?php echo link_to($question->getTitle(),'question/show?stripped_title='.$question->getStrippedTitle()) ?></li> <?php endforeach; ?> </ul> <h2>Contributions</h2> <ul> <?php foreach($answers as $answer): $question = $answer->getQuestion() ?> <li> <?php echo link_to($question->getTitle(),'question/show?stripped_title='.$question->getStrippedTitle()) ?><br /> <?php echo $answer->getBody() ?> </li> <?php endforeach; ?> </ul> <h2>Questions</h2> <ul> <?php foreach($questions as $question): ?> <li><?php echo link_to($question->getTitle(),'question/show?stripped_title='.$question->getStrippedTitle()) ?></li> <?php endforeach; ?> </ul>
ほげーっと書いたらリンクを追加するようにする。
まずはaskeet/apps/frontend/modules/question/templates/_list.php
<?php use_helper('Text', 'Global', 'Date') ?> <?php foreach($question_pager->getResults() as $question): ?> <div class="question"> <div class="interested_block"> <?php include_partial('interested_user', array('question' => $question)) ?> </div> <h2><?php echo link_to($question->getTitle(), 'question/show?stripped_title='.$question->getStrippedTitle()) ?></h2> <div>asked by <?php echo link_to($question->getUser(), 'user/show?id='.$question->getUser()->getId()) ?> on <?php echo format_date($question->getCreatedAt(), 'f') ?></div> <div class="question_body"> <?php echo truncate_text($question->getBody(), 200) ?> </div> </div> <?php endforeach; ?> <div id="question_pager"> <?php echo pager_navigation($question_pager, $rule) ?> </div>
次はaskeet/apps/frontend/modules/user/templates/showSuccess.php
<?php use_helper('Date') ?> <div class="interested_block"> <?php include_partial('interested_user', array('question' => $question)) ?> </div> <h2><?php echo $question->getTitle() ?></h2> <div>asked by <?php echo link_to($question->getUser(), 'user/show?id='.$question->getUser()->getId()) ?> on <?php echo format_date($question->getCreatedAt(), 'f') ?></div> <div class="question_body"> <?php echo $question->getBody() ?> </div> <div id="answers"> <?php foreach ($question->getAnswers() as $answer): ?> <div class="answer"> <?php echo $answer->getRelevancyUpPercent() ?>% UP <?php echo $answer->getRelevancyDownPercent() ?> % DOWN posted by <?php echo $answer->getUser()->getFirstName().' '.$answer->getUser()->getLastName() ?> on <?php echo format_date($answer->getCreatedAt(), 'p') ?> <div> <?php echo $answer->getBody() ?> </div> </div> <?php endforeach; ?> </div>