symfony vol.14

【授業内容】
askeet 10日目

☆ 新しい質問を追加する。

[画像挿入予定地1]

手順1 アクセスを制限する

[画像挿入予定地2]

  askeet/apps/frontend/modules/question/config/security.yml

○ 作ったら、以下のことを入力

add:
  is_secure:   on
  credentials: subscriber

all:
  is_secure:   off

[画像挿入予定地2]

Loginしていない人が、質問しようとしたら、その人はログインアクションに飛ばされる。
↑これを実現させるには……

  askeet/apps/frontend/config/settings.yml

○開いたら以下のことを入力

all:
  .actions:
    login_module:           user
    login_action:           login

[画像挿入予定地3]

手順2 addのactionとtemplateを作る。

question/addアクションはフォーム表示と処理の両方で使われる。

(1) actionをいじってみる。

  askeet/apps/frontend/modules/question/actions/action.class.php

○ 開いたら、1番下に、以下のメソッドを追加する。

public function executeAdd()
{
}
 
public function handleErrorAdd()
{
  return sfView::SUCCESS;
}

[画像挿入予定地4]


(2) templateを作ってみる。(addSuccess.php)

  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>

[画像挿入予定地5]

手順3 フォームのバリデーションを作ってみよう(add.yml)

  askeet/apps/frontend/modules/question/validate/add.yml

○ 開いたら、以下の内容をずらずら〜っと入れる。 ☆[day 6]でValidationは一回作った!

methods:
  post:            [title, body]

names:
  title:
    required:      Yes
    required_msg:  You must give a title to your question

  body:
    required:      Yes
    required_msg:  You must provide a brief context for your question
    validators:    bodyValidator

bodyValidator:
    class:         sfStringValidator
    param:
      min:         10
      min_error:   Please, give some more details
手順4 フォームで投稿されたものを処理する

[画像挿入予定地6]

  askeet/apps/frontend/modules/question/actions/action.class.php

○開いたら、以下のことを追加

public function executeAdd()
{
  if ($this->getRequest()->getMethod() == sfRequest::POST)
  {
    // 質問を作る
    $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());
  }
}

[画像挿入予定地7]

?? なんでforward()じゃなくて、redirect()を使うの?
[画像挿入予定地8]

○ まだ実装してない User/isInterestedメソッドを追加する

  askeet/lib/model/User.php

○開いたら、以下のことを追加

public function isInterestedIn($question)
{
  $interest = new Interest();
  $interest->setQuestion($question);
  $interest->setUserId($this->getId());
  $interest->save();
}

[画像挿入予定地9]

☆☆ここまで出来たらテストしてみよう
[画像挿入予定地10]


☆ 新しい回答を追加する

手順1 AJAXフォームを追加する(question/showSuccess.php)

  askeet/apps/frontend/modules/question/templates/showSuccess.php

○ 開いたら、一番下に以下のことを追加する。

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

[画像挿入予定地11]

○ ↑で使ってるけど実体がない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)));
  }
}

[画像挿入予定地12]

手順2 フォームで投稿されたものを処理する

(1)answer/にaddのactionを作る!

○ まずルーティングルールに、add_answerを追加する。

  askeet/apps/frontend/config/routing.yml

○ 開いたら、以下のルールを追加する。

add_answer:
  url:   /add_anwser
  param: { module: answer, action: add }

○ addのactionを追加する

  askeet/apps/frontend/modules/answer/actions/action.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);
 
    // 通常のユーザーもしくは匿名ユーザー
    $user = $this->getUser()->isAuthenticated() ? $this->getUser()->getSubscriber() : UserPeer::retriveByNickname('anonymous');
 
    // 回答する
    $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();
}

[画像挿入予定地13]


(2)answerにaddのテンプレートを作る。

↑でもsfview::SUCCESSで呼んでいるaddSuccess.phpを実装しよう

  askeet/apps/frontend/modules/answer/templates/addSuccess.php

○ 開いたら、以下を追加する

<?php include_partial('answer', array('answer' => $answer)) ?>

[画像挿入予定地14]

○このアクション用のレイアウトを無効にしないとね!

  askeet/apps/frontend/modules/answer/config/view.yml

addSuccess:
  has_layout: off

↑これをやっておかないと、Grobalで設定してるlayoutが当たってしまう。



☆★*********☆*********★*********★☆
10日目終了!お疲れさまでした!!
☆★*********☆*********★*********★☆



以上、今日の授業でした!