symfony askeet Day 10
- Day 10に入る前に。
- 新しい質問を追加できるようにする
- 答え投稿フォームを作る
Day 7でやり忘れていたことをやる
Day 7のほうにちっちゃく
コードは少なくとも2つの場所で使われているので、私達はリファクタリングして、
http://www.symfony-project.org/askeet/1_0/ja/7
qestion/showとanswer/recentの両方を使用されている_answer.phpの一部分を作成します。
(※原文のまま)
とか書いてあるのをてっきり流してしまったのですが、ここで現実を見てやることにします。
なぜ、やるか。Day 10で転けるからです。
(メモをするのを忘れたが、そのままやると_answer.phpがねぇよと怒られる><)
場所: askeet/apps/frontend/modules/question/templates/showSuccess.php
askeet/apps/frontend/modules/answer/templates/recentSuccess.php
共通してどちらにもある↓を_answer.phpとして切り出す。
場所: askeet/apps/frontend/modules/answer/_answer.php
<?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>
切り出したら↑を切り出した部分に
showSuccess.phpは
<?php include_partial('answer/answer',array('answer' => $answer)) ?>
recentSuccess.phpは
<?php include_partial('answer',array('answer' => $answer)) ?>
参考: http://develop.ddo.jp/new-tech/php/framework/symfony/memo/view/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%AE%E9%83%A8%E5%93%81%E5%8C%96%E3%81%A3%E3%81%A6
よし、できた><
Day 4は読み直す必要があるな…
ja:4日目: リファクタリング (1_0) - Symfony
en:Day 04: refactoring (1_0) - Symfony
新しい質問を追加できるようにする
ということで、仕切り直してDay 10を始めます。
ということでまず、登録ユーザー以外が登録できないようにしたい。
Day 6で作ったsecurity.ymlの確認をして
問題がなければaskeet/apps/frontend/config/setting.ymlの修正
all: .actions: # default_module: default # Default module and action to be called when # default_action: index # A routing rule doesn't set it # # error_404_module: default # To be called when a 404 error is raised # error_404_action: error404 # Or when the requested URL doesn't match any route # login_module: user # To be called when a non-authenticated user login_action: login # Tries to access a secure page
そういえば、テンプレートがない。
ということで実装する。
まずはアクションの設定。
場所: askeet/apps/frontend/modules/question/actions/actions.class.php
に↓を書き足す。
public function executeAdd() { } public function handleErrorAdd() { return sfView::SUCCESS; }
で、テンプレートを書く。
場所: askeet/apps/frontend/modules/question/templates/addSuccess.php
<?php use_helper('Validation') ?> <?php echo form_tag('@add_question') ?> <fieldset> <div class="form-row"> <?php echo form_error('title') ?> <label for="title">Question title:</label> <?php echo input_tag('title', $sf_params->get('title')) ?> </div> <div class="form-row"> <?php echo form_error('body') ?> <label for="label">Your question in details:</label> <?php echo textarea_tag('body', $sf_params->get('body')) ?> </div> </fieldset> <div class="submit-row"> <?php echo submit_tag('ask it') ?> </div> </form>
保存する場所を間違いやすいので注意した方がいいですね。
自分はさっきanswerに保存していて気づかなくてどうして動かないんだと悩んでました。
次はバリデーション
場所: askeet/apps/frontend/modules/question/validate/add.yml
methods: post: [title, body] names: title: required: Yes required_msg: You must give a title to your question body: required: Yes required_msg: Your must provide a brief context for your question bodyValidator: class: sfStringValidator param: min: 10 min_error: Please, give some more details
実際の投稿を受け付ける
投稿データを受け付けられるように編集する。
場所: askeet/apps/frontend/modules/question/actions/actions.class.php
さっきは空だったexecuteAdd()の中に書く。
public function executeAdd() { if($this->getRequest()->getMethod() == sfRequest::POST) { // create question (質問を作る) $user = $this->getUser()->getSubscriber(); $question = new Question(); $question->setTitle($this->getRequestParameter('title')); $question->setBody($this->getRequestParameter('body')); $question->setUser($user); $question->save(); $user->isInterestedIn($question); return $this->redirect('@question?stripped_title='.$question->getStrippedTitle()); } }
$user->isInterestedInを用意する。
場所: askeet/apps/frontend/modules/user/actions/actions.class.php
public function isInterestedIn($question) { $interest = new Interest(); $interest->setQuestion($question); $interest->setUserId($this->getId()); $interest->save(); }
答え投稿フォームを作ろう。
質問は投稿できるようになったけど答えが投稿できないので作りましょう。
場所: askeet/apps/frontend/modules/question/templates/showSuccess.php
<div id="answers"> <?php foreach ($question->getAnswers() as $answer): ?> <div class="answer"> <?php include_partial('answer/answer', array('answer' => $answer)) ?> </div> <?php endforeach; ?> <?php echo use_helper('User') ?> <div class="answer" id="add_answer"> <?php echo form_remote_tag(array( 'url' => '@add_answer', 'update' => array('success' => 'add_answer'), 'loading' => "Element.show('indicator')", 'complete' => "Element.hide('indicator');".visual_effect('highlight', 'add_answer'), )) ?> <div class="form-row"> <?php if ($sf_user->isAuthenticated()): ?> <?php echo $sf_user->getNickname() ?> <?php else: ?> <?php echo 'Anonymous Coward' ?> <?php echo link_to_login('login') ?> <?php endif; ?> </div> <div class="form-row"> <label for="label">Your answer:</label> <?php echo textarea_tag('body', $sf_params->get('body')) ?> </div> <div class="submit-row"> <?php echo input_hidden_tag('question_id', $question->getId()) ?> <?php echo submit_tag('answer it') ?> </div> </form> </div> </div>
link_to_login()を追加する。
場所: askeet/apps/frontend/lib/helper/UserHelper.php
function link_to_login($name,$uri = null) { if($uri && sfContext::getInstance()->getUser()->isAuthenticated()) { return link_to($name,$uri); } else { return link_to_function($name, visual_effect('blind_down','login',array('duration' => 0.5))); } }
つぎはアクションを書く。
その前にadd_answerをrouting.ymlに追加する。
場所: askeet/apps/frontend/config/routing.yml
add_answer: url: /add_answer param: { module: answer, action: add }
できたら、アクションを書く。
場所: askeet/apps/frontend/modules/answer/actions/actions.class.php
public function executeAdd() { if($this->getRequest()->getMethod() == sfRequest::POST) { if(!$this->getRequestParameter('body')) { return sfView::NONE; } $question = QuestionPeer::retrieveByPk($this->getRequestParameter('question_id')); $this->forward404Unless($question); // normal user or anonymous user (ふつーのユーザーか匿名ユーザー) $user = $this->getUser()->isAuthenticated() ? $this->getUser()->getSubscriber() : UserPeer::retriveByNickname('anonymous'); // answer $this->answer = new Answer(); $this->answer->setQuestion($question); $this->answer->setBody($this->getRequestParameter('body')); $this->answer->setUser($user); $this->answer->save(); return sfView::SUCCESS; } $this->forward404(); }