Skip to content
Caution: You are browsing the legacy symfony 1.x part of this website.

symfony advent calendar day five: forms and pager

Language

์ง€๋‚œ ์ค„๊ฑฐ๋ฆฌ

์ง€๋‚œ ์‹œ๊ฐ„ ์—๋Š” ์ฝ”๋“œ๋ฅผ ํ•ด๋‹น ์ฝ”๋“œ์˜ ์†์„ฑ์— ๋งž๋Š” ๋‹ค๋ฅธ ํŒŒ์ผ๋“ค๋กœ ์ด๋™์‹œํ‚ค๋Š” ์ž‘์—…์„ ํ†ตํ•ด ๋ฆฌํŽ™ํ† ๋ง์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋ชจ๋ธ์˜ ์†์„ฑ์— ๊ด€ํ•œ ์ฝ”๋“œ๋ฅผ ์•ก์…˜์—์„œ ๋ชจ๋ธ๋กœ ์˜ฎ๊ธฐ๋Š” ๊ฒƒ๋„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

์ง€๊ธˆ๊นŒ์ง€ ๊ฐœ๋ฐœ๋œ ์ฝ”๋“œ๋Š” ๊น”๋”ํ•˜์ง€๋งŒ ์•„์ง ๋” ๊ฐœ๋ฐœํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ์ด ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ askeet ์‚ฌ์ดํŠธ๋ฅผ ์‚ฌ์šฉ์ž์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜์ดํผ๋งํฌ (hyperlink) ์ด์™ธ์— HTML ์„ ์‚ฌ์šฉ์ž์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” form ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์˜ค๋Š˜์˜ ๋ชฉํ‘œ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ณ , ๋ฉ”์ธํŽ˜์ด์ง€์˜ ์งˆ๋ฌธ ๋ชฉ๋ก์„ ํŽ˜์ด์ง€๋ฅผ ๋‚˜๋ˆ„์–ด ๋ณด์—ฌ์ฃผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ค๋Š˜์€ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ์ง€ ์•Š์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ์–ด์ œ์˜ ๊ธด ํŠœํ† ๋ฆฌ์–ผ์— ์ง€์น˜์…จ๋‹ค๋ฉด ๊ฑฑ์ •ํ•˜์ง€ ์•Š์œผ์…”๋„ ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ ํผ

ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋“ค์—๋Š” ์‚ฌ์šฉ์ž ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค๋งŒ ์‹œ์Šคํ…œ์ด ์ด๋ฅผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์€ ์‚ฌ์‹ค ์—†์Šต๋‹ˆ๋‹ค. ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ํŽ˜์ด์ง€์—์„œ ๋กœ๊ทธ์ธ ํผ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธ€๋กœ๋ฒŒ ๋ ˆ์ด์•„์›ƒ ํŒŒ์ผ์ธ askeet/apps/frontend/templates/layout.php ํŒŒ์ผ์„ ์—ด๊ณ  about ๋งํฌ ์•ž์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

<li><?php echo link_to('sign in', 'user/login') ?></li>

์ฐธ๊ณ : ํ˜„์žฌ์˜ ๋ ˆ์ด์•„์›ƒ์€ ์›น ๋””๋ฒ„๊ทธ ํˆด๋ฐ” ์•„๋ž˜์— ๊ฐ€๋ ค์ ธ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฉ๊ธˆ ์ถ”๊ฐ€ํ•œ ๋งํฌ๋ฅผ ๋ณด์‹œ๊ธฐ ์œ„ํ•ด์„œ๋Š” 'Sf' ์•„์ด์ฝ˜์„ ํด๋ฆญํ•˜์…”์„œ ํˆด๋ฐ”๋ฅผ ๋‹ซ์œผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ user ๋ชจ๋“ˆ์„ ๋งŒ๋“ค๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‘๋ฒˆ์งธ๋‚ ์— ๋งŒ๋“ค์—ˆ๋˜ question ๋ชจ๋“ˆ๊ณผ๋Š” ๋‹ฌ๋ฆฌ, ์ด๋ฒˆ์—๋Š” ๋นˆ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค๊ณ  ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ฑ„์›Œ๋„ฃ๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

$ symfony init-module frontend user

์ฐธ๊ณ : ์œ„ ๋ช…๋ น์„ ํ†ตํ•ด index ์•ก์…˜๊ณผ indexSuccess.php ํ…œํ”Œ๋ฆฟ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ๋‘˜ ๋ชจ๋‘๊ฐ€ ํ•„์š”์—†์œผ๋ฏ€๋กœ ์•ก์…˜๊ณผ ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ์ง€์šฐ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

user/login ์•ก์…˜ ๋งŒ๋“ค๊ธฐ

askeet/apps/frontend/modules/ ๋””๋ ‰ํ† ๋ฆฌ์˜ user/action/action.class.php ํŒŒ์ผ์— login ์•ก์…˜์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

public function executeLogin()
{
  $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());
 
  return sfView::SUCCESS;
}

์œ„ ์•ก์…˜์—์„œ๋Š” ์‚ฌ์šฉ์ž ์š”์ฒญ ๊ฐ’์œผ๋กœ ๋ ˆํผ๋Ÿฌ (referer) ๊ฐ’์„ ์ €์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋กœ๊ทธ์ธ์‹œ ๋ ˆํผ๋Ÿฌ๋ฅผ ํผ์˜ ์ˆจ๊ฒจ์ง„ ๊ฐ’๋“ค ์ค‘ ํ•˜๋‚˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ, ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋А ํŽ˜์ด์ง€์—์„œ ๋กœ๊ทธ์ธ์„ ํ•˜์˜€๋Š”์ง€๋ฅผ ํ™•์ธํ•˜์—ฌ ๋กœ๊ทธ์ธ ํ›„ ์‚ฌ์šฉ์ž๋ฅผ ์›๋ž˜ ์žˆ์—ˆ๋˜ ํŽ˜์ด์ง€๋กœ ๋Œ๋ ค ๋ณด๋‚ด๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

return sfView::SUCCESS ๋Š” ์•ก์…˜์˜ ๊ฒฐ๊ณผ๋ฅผ loginSuccess.php ํ…œํ”Œ๋ฆฟ์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฌธ์žฅ์€ ์•ก์…˜์ด ์•„๋ฌด๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์—๋„ ์ž๋™์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋งŒ์•ฝ ์•ก์…˜์ด ๋ฐ˜ํ™˜๊ฐ’์—†์ด ์ข…๋ฃŒ๋œ๋‹ค๋ฉด, <์•ก์…˜์ด๋ฆ„>Success.php ๊ฐ€ ์ž๋™์œผ๋กœ ํ˜ธ์ถœ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์•ก์…˜์„ ๋” ๊ณ ์น˜๊ธฐ ์ „์—, ํ…œํ”Œ๋ฆฟ์„ ์‚ดํŽด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

loginSuccess.php ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ

์ธ๊ฐ„๊ณผ ์ปดํ“จํ„ฐ๊ฐ€ ์ƒํ˜ธ์ž‘์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์›น์—์„œ๋Š” ํผ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์‹ฌํฌ๋‹ˆ๋Š” ํผ์˜ ์ƒ์„ฑ๊ณผ ๊ด€๋ฆฌ๋ฅผ ๋•๊ธฐ ์œ„ํ•ด์„œ ํผ ํ—ฌํผ ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

askeet/apps/frontend/modules/user/templates/ ๋””๋ ‰ํ† ๋ฆฌ์—์„œ loginSuccess.php ํ…œํ”Œ๋ฆฟ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

<?php echo form_tag('user/login') ?>
 
  <fieldset>
 
  <div class="form-row">
    <label for="nickname">nickname:</label>
    <?php echo input_tag('nickname', $sf_params->get('nickname')) ?>
  </div>
 
  <div class="form-row">
    <label for="password">password:</label>
    <?php echo input_password_tag('password') ?>
  </div>
 
  </fieldset>
 
  <?php echo input_hidden_tag('referer', $sf_request->getAttribute('referer')) ?>
  <?php echo submit_tag('sign in') ?>
 
</form>

์œ„ ํ…œํ”Œ๋ฆฟ์—์„œ๋Š” ๋ช‡๊ฐ€์ง€ ๊ธฐ๋ณธ์ ์ธ ํผ ํ—ฌํผ๋“ค์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„ ํผ ํ—ฌํผ๋“ค์„ ํ†ตํ•ด ํผ ์ƒ์„ฑ์„ ์ž๋™ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. form_tag() ํ—ฌํผ๋Š” ๊ธฐ๋ณธ ๋งค์˜๋“œ๋กœ POST ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ํผ ์•ก์…˜๊ฐ’์œผ๋กœ ์ธ์ž๋กœ ๋ฐ›์€ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋Š” ํผ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. input_tag() ํ—ฌํผ๋Š” <input> ํ…Œํฌ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฒซ๋ฒˆ์งธ ์ธ์ž๋ฅผ id ๊ฐ’์„ ๊ฐ™๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋‘๋ฒˆ์งธ ์ธ์ž๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ์—๋Š” ์ด๋ฅผ <input> ํ…Œ๊ทธ์˜ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์˜จ๋ผ์ธ ๋ฌธ์„œ์ค‘ ํผ ํ—ฌํผ ๋ถ€๋ถ„ ์—์„œ ํผ ํ—ฌํผ ๋ฐ ํผ ํ—ฌํผ๊ฐ€ ์ƒ์„ฑํ•˜๋Š” HTML ์ฝ”๋“œ๋“ค์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์‚ฌ์šฉ์ž๊ฐ€ ํผ์˜ ํ™•์ธ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„๋•Œ, form_tag() ๊ฐ€ ์ธ์ž๋กœ ๋ฐ›์€ login ์•ก์…˜์ด ์‹คํ–‰๋  ๊ฒƒ์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ œ ์•ก์…˜์œผ๋กœ ๋Œ์•„๊ฐ€๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Handle the login form submission

login ์•ก์…˜์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

public function executeLogin()
{
  if ($this->getRequest()->getMethod() != sfRequest::POST)
  {
    // display the form
    $this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());
  }
  else
  {
    // handle the form submission
    $nickname = $this->getRequestParameter('nickname');
 
    $c = new Criteria();
    $c->add(UserPeer::NICKNAME, $nickname);
    $user = UserPeer::doSelectOne($c);
 
    // nickname exists?
    if ($user)
    {
      // password is OK?
      if (true)
      {
        $this->getUser()->setAuthenticated(true);
        $this->getUser()->addCredential('subscriber');
 
        $this->getUser()->setAttribute('subscriber_id', $user->getId(), 'subscriber');
        $this->getUser()->setAttribute('nickname', $user->getNickname(), 'subscriber');
 
        // redirect to last page
        return $this->redirect($this->getRequestParameter('referer', '@homepage'));
      }
    }
  }
}

๋กœ๊ทธ์ธ ์•ก์…˜์€ ๋กœ๊ทธ์ธ ํผ์„ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ๋„ ํ•˜๊ณ , ๋กœ๊ทธ์ธ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ๋„ ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์กŒ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๊ฒฝ์šฐ์— ํผ์„ ๋ณด์—ฌ์ฃผ๊ณ , ์–ด๋–ค ๊ฒฝ์šฐ์— ๋กœ๊ทธ์ธ์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•ด์„œ, ์–ด๋–ค ๋ฉ”์†Œ๋“œ๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ์•ก์…˜์ด ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๋ฅผ ํŒŒ์•…ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์•ก์…˜์ด POST ๋ฉ”์˜๋“œ๋กœ ํ˜ธ์ถœ๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด, ์ด๋Š” ํ•˜์ดํผ๋งํฌ๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœ๋˜์—ˆ๋‹ค๋Š” ์˜๋ฏธ๊ฐ€ ๋˜๊ณ  ์ด ๊ฒฝ์šฐ์—๋Š” ํผ์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์•ก์…˜์ด POST ๋ฉ”์˜๋“œ๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋‹ค๋ฉด, ์‚ฌ์šฉ์ž๊ฐ€ ํผ์˜ ํ™•์ธ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅธ ๊ฒƒ์ด๊ณ  ์ด ๊ฒฝ์šฐ์—๋Š” ๋กœ๊ทธ์ธ์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์•ก์…˜์€ ์‚ฌ์šฉ์ž ์š”์ฒญ๊ฐ’๋“ค ์ค‘์—์„œ nickname ํ•„๋“œ์˜ ๊ฐ’์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ , ์ด nickname ๊ฐ’์ด User ํ…Œ์ด๋ธ”์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

์ถ”ํ›„์—๋Š” ์•”ํ˜ธ๋ฅผ ํ†ตํ•ด์„œ ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ง€๊ธˆ์€ ๋‹จ์ง€ ์‚ฌ์šฉ์ž์˜ id ์™€ nickname ์„ ์„ธ์…˜๊ฐ’์— ์ €์žฅํ•˜๋„๋ก ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ์•ก์…˜์€ ์ฒ˜์Œ ์šฐ๋ฆฌ๊ฐ€ ์ˆจ๊ฒจ์ง„ ๊ฐ’์œผ๋กœ ์ €์žฅํ–ˆ๋˜ referer ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž๋ฅผ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ˜ธ์ถœํ•œ URL ๋กœ ๋Œ๋ ค๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ด ๊ฐ’์ด ๋น„์–ด์žˆ๋‹ค๋ฉด, ์šฐ๋ฆฌ๊ฐ€ ๋‘๋ฒˆ์งธ๋กœ ์ง€์ •ํ•œ @homepage, ์ฆ‰ ๋ผ์šฐํŒ… ๊ทœ์น™ ์ค‘ ํ•˜๋‚˜์ธ question/list, ์ด ์‚ฌ์šฉ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ์—์„œ๋Š” ๋‘๊ฐ€์ง€ ๋‹ค๋ฅธ ์†์„ฑ๊ฐ’๋“ค์ด ์‚ฌ์šฉ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋Š” ์‚ฌ์šฉ์ž ์š”์ฒญ๊ฐ’ ์œผ๋กœ ($this->getRequest()->setAttribute()), ์ด๋Š” ํ…œํ”Œ๋ฆฟ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ’์„ ์ž ์‹œ ๊ธฐ์–ตํ•˜๋Š” ์šฉ๋„๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’๋“ค์€ ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋œ ์ดํ›„์—๋Š” ๋ชจ๋‘ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ๋˜ ๋‹ค๋ฅธ ํ•˜๋‚˜๋Š” ์„ธ์…˜ ๊ฐ’ ์œผ๋กœ ($this->getUser()->setAttribute()) ์‚ฌ์šฉ์ž์˜ ์„ธ์…˜์ด ์œ ์ง€๋˜๋Š” ๋™์•ˆ์—๋Š” ๊ณ„์† ๋ณด์กด๋˜๋ฉฐ, ์ดํ›„ ๋‹ค๋ฅธ ์•ก์…˜๋“ค์—์„œ ์ด ๊ฐ’๋“ค์„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•ด ์ข€ ๋” ์•Œ๊ณ  ์‹ถ์œผ์‹œ๋‹ค๋ฉด ์˜จ๋ผ์ธ ๋ฌธ์„œ๋“ค ์ค‘ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ด€๋ จ ๋ถ€๋ถ„ ์„ ์ฐธ์กฐํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๊ถŒํ•œ ์„ค์ •

์‚ฌ์šฉ์ž๋“ค์ด askeet ์›น์‚ฌ์ดํŠธ์— ๋กœ๊ทธ์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์€ ์ข‹์€ ์ผ์ด์ง€๋งŒ, ์‚ฌ์šฉ์ž๋“ค์ด ๊ทธ๋ƒฅ ํ•˜์ง€๋Š” ์•Š๊ฒ ์ง€์š”? ๋กœ๊ทธ์ธ๋œ ์‚ฌ์šฉ์ž๋งŒ์ด ์ƒˆ๋กœ์šด ์งˆ๋ฌธ์„ ์“ฐ๊ฑฐ๋‚˜, ์งˆ๋ฌธ์— ๋Œ€ํ•œ ํฅ๋ฏธ๋„๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜, ๋˜๋Š” ๋‹ต๋ณ€๋“ค์„ ํ‰๊ฐ€ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ณ„ํš์ž…๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ชจ๋“  ์•ก์…˜๋“ค์€ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž๋“ค๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” sfUser ๊ฐ์ฑ„์˜ ->setAuthenticated() ๋ฉ”์˜๋“œ๋ฅผ ํ˜ธ์ถœํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ์„ธ๋ฐ€ํ•œ ๊ถŒํ•œ์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ฆ๋ช…์„œ ์ฒด๊ณ„ (credential mechanism) ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ข€ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์‚ฌ์šฉ์ž ์ฆ๋ช…์„œ ๋ถ€๋ถ„ ์„ ์ฐธ์กฐํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋‹ค์Œ ๋‘ ์ค„์„ ํ†ตํ•ด ๊ถŒํ•œ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

$this->getContext()->getUser()->setAuthenticated(true);
$this->getContext()->getUser()->addCredential('subscriber');

์‚ฌ์šฉ์ž ์ด๋ฆ„์ด ํ™•์ธ ๋œ ์ดํ›„์— ์„ธ์…˜๊ฐ’๋“ค์— ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋งŒ์„ ์ €์žฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์‚ฌ์ดํŠธ์˜ ์ œํ•œ๋œ ๊ตฌ์—ญ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์˜ ๊ถŒํ•œ์— ๋”ฐ๋ผ ์‚ฌ์ดํŠธ์˜ ์ด์šฉ์„ ์ œํ•œํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚ด์ผ ๊ณ„์†ํ•ด์„œ ์‚ดํŽด๋ณผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

user/logout ์•ก์…˜

->setAttribute() ๋ฉ”์˜๋“œ์—๋Š” ์šฐ๋ฆฌ๊ฐ€ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ณ  ๋„˜์–ด๊ฐ„ ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ->setAttribute() ๋ฉ”์˜๋“œ์˜ ๋งˆ์ง€๋ง‰ ์ธ์ž๋Š” (์œ„์˜ ๊ฒฝ์šฐ์— subscriber) ๊ฐ’๋“ค์ด ์ €์žฅ๋  ์ด๋ฆ„๊ณต๊ฐ„ ์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฆ„๊ณต๊ฐ„์€ ๋‹ค๋ฅธ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ™์€ ์ด๋ฆ„์„ ๊ฐ–๋Š” ๊ฐ’๋“ค์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ ์ด์™ธ์—๋„, ํ•ด๋‹น ์ด๋ฆ„๊ณต๊ฐ„์ด ๊ฐ€์ง€๋Š” ๊ฐ’๋“ค์„ ์‰ฝ๊ฒŒ ์ง€์šธ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

public function executeLogout()
{
  $this->getUser()->setAuthenticated(false);
  $this->getUser()->clearCredentials();
 
  $this->getUser()->getAttributeHolder()->removeNamespace('subscriber');
 
  $this->redirect('@homepage');
}

์ด๋ฆ„๊ณต๊ฐ„์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ’๋“ค์„ ํ•˜๋‚˜์”ฉ ์ง€์šฐ๋Š” ๋Œ€์‹  ํ•˜๋‚˜์˜ ๋ช…๋ น์œผ๋กœ ๋ชจ๋‘ ์ง€์šธ ์ˆ˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์œผ๋ฆ„์€ ์ข‹์€ ๊ฒƒ์ž…๋‹ˆ๋‹ค!

๋ ˆ์ด์•„์›ƒ ๋ณ€๊ฒฝ

์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ์„ ํ•œ ์ดํ›„์—๋„ ๋ ˆ์ด์•„์›ƒ์„ 'login' ๋งํฌ๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ๊ณ ์ณ๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. askeet/apps/frontend/templates/layout.php ํŒŒ์ผ์„ ์—ด๊ณ  ์˜ค๋Š˜ ์ˆ˜์ •ํ•œ ๋ถ€๋ถ„์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ณ ์นฉ๋‹ˆ๋‹ค.

<?php if ($sf_user->isAuthenticated()): ?>
  <li><?php echo link_to('sign out', 'user/logout') ?></li>
  <li><?php echo link_to($sf_user->getAttribute('nickname', '', 'subscriber').' profile', 'user/profile') ?></li>
<?php else: ?>
  <li><?php echo link_to('sign in/register', 'user/login') ?></li>
<?php endif ?>

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์•„๋ฌด ํŽ˜์ด์ง€๋‚˜ ํด๋ฆญํ•˜์…”์„œ ์œ„ ๋งํฌ๊ฐ€ ์ œ๋Œ€๋กœ ํ‘œ์‹œ๊ฐ€ ๋˜๋Š”์ง€, 'login' ๋งํฌ๋ฅผ ํด๋ฆญํ•˜๊ณ  ์ ๋‹นํ•œ ์‚ฌ์šฉ์ž ์ด๋ฆ„์„ ์ž…๋ ฅํ•œ ํ›„ ('anonymous' ์ •๋„๊ฐ€ ์ ๋‹นํ•˜๊ฒ ์ง€์š”?) ๋กœ๊ทธ์ธ์ด ์ œ๋Œ€๋กœ ๋˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ 'login' ๋งํฌ๊ฐ€ ์ดํ›„์— 'sign out' ์œผ๋กœ ๋ฐ”๋€Œ์‹ ๋‹ค๋ฉด ์ œ๋Œ€๋กœ ํ•˜์‹  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋กœ๊ทธ์•„์›ƒ์„ ํ•ด๋ณด์‹œ๊ณ  'login' ๋งํฌ๊ฐ€ ๋‹ค์‹œ ๋‚˜ํƒ€๋‚˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ ๋œ ์ƒํƒœ

์‚ฌ์šฉ์ž ์„ธ์…˜ ์กฐ์ž‘์— ๊ด€ํ•œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์˜จ๋ผ์ธ ๋ฌธ์„œ๋“ค ์ค‘ ์‚ฌ์šฉ์ž ์„ธ์…˜ ๋ถ€๋ถ„ ์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์งˆ๋ฌธ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋‚˜๋ˆ„๊ธฐ

์‹ฌํฌ๋‹ˆ์— ๊ด€์‹ฌ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๋งŽ์€ ๋ถ„๋“ค์ด askeet ์‚ฌ์ดํŠธ๋กœ ๋ชฐ๋ ค๋“ค ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋ฉ”์ธํŽ˜์ด์ง€์— ์ถœ๋ ฅ๋˜๋Š” ์งˆ๋ฌธ ๋ชฉ๋ก์ด ๊ธˆ์„ธ ๊ธธ์–ด์งˆ ๊ฒƒ์ด ๋ถ„๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋А๋ฆฐ ๋ฐ˜์‘๊ณผ ์Šคํฌ๋กค์˜ ์••๋ฐ•์„ ๊ฒฌ๋ŽŒ๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ์งˆ๋ฌธ ๋ชฉ๋ก์˜ ํŽ˜์ด์ง€๋ฅผ ๋‚˜๋ˆ„์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‹ฌํฌ๋‹ˆ๋Š” ์œ„์˜ ๋ชฉ์ ์— ๋ถ€ํ•ฉํ•˜๋Š” sfPropelPager ๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์š”์ฒญ์„ ๊ฐ์‹ธ์„œ (encapsulate) ํ˜„์žฌ ํŽ˜์ด์ง€์— ์ถœ๋ ฅ๋  ์ž๋ฃŒ๋“ค๋งŒ ์š”์ฒญํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ์ด ๊ฐ์ฒด๊ฐ€ ํ•œ ํŽ˜์ด์ง€์— 10๊ฐœ์˜ ์ž๋ฃŒ๋งŒ ์ถœ๋ ฅํ•˜๋„๋ก ๋˜์–ด ์žˆ๋‹ค๊ณ  ํ•˜๋ฉด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์š”์ฒญ์€ 10๊ฐœ๋กœ ์ œํ•œ ๋  ๊ฒƒ์ด๊ณ  ํŽ˜์ด์ง€์— ๋งž๋Š” ์œ„์น˜๋ฅผ ์„ ์ •ํ•˜์—ฌ ์ž๋ฃŒ๋ฅผ ์š”์ฒญํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

question/list ์•ก์…˜์„ ์ˆ˜์ •ํ•˜๊ธฐ

3์ผ์งธ ์— ๋งŒ๋“ค์—ˆ๋˜ question ๋ชจ๋“ˆ์˜ list ์•ก์…˜์€ ์ƒ๋‹นํžˆ ๊ฐ„๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.

public function executeList ()
{
  $this->questions = QuestionPeer::doSelect(new Criteria());
}

์ด ์•ก์…˜์„ ์ˆ˜์ •ํ•˜์—ฌ์„œ ๋ฐฐ์—ด ๋Œ€์‹ ์— sfPropelPager ๊ฐ์ฒด๋ฅผ ํ…œํ”Œ๋ฆฟ์— ์ „๋‹ฌํ•˜๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋™์‹œ์—, ์งˆ๋ฌธ๋ชฉ๋ก์ด ํฅ๋ฏธ๋„๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ •๋ ฌ๋˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

public function executeList ()
{
  $pager = new sfPropelPager('Question', 2);
  $c = new Criteria();
  $c->addDescendingOrderByColumn(QuestionPeer::INTERESTED_USERS);
  $pager->setCriteria($c);
  $pager->setPage($this->getRequestParameter('page', 1));
  $pager->setPeerMethod('doSelectJoinUser');
  $pager->init();
 
  $this->question_pager = $pager;
}

sfPropelPager ๊ฐ์ฒด์˜ ์ดˆ๊ธฐํ™”์—๋Š” ์–ด๋– ํ•œ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ์งˆ์˜์ธ์ง€, ๊ทธ๋ฆฌ๊ณ  ํ•œ ํŽ˜์ด์ง€์— ์–ผ๋งŒํผ์˜ ์ž๋ฃŒ๋ฅผ ๋ณด์—ฌ์ค„ ๊ฒƒ์ธ์ง€ (์œ„์˜ ์˜ˆ์—์„œ๋Š” 2๊ฐœ) ๋ฅผ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. ->setPage() ํ˜„์žฌ ํŽ˜์ด์ง€๋ฅผ ์ง€์ •ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ, ์œ„์˜ ์˜ˆ์—์„œ๋Š” ์š”์ฒญ๊ฐ’๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ ๋ฉ”์˜๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด, page ๋ผ๋Š” ์š”์ฒญ๊ฐ’์ด 2 ๋ผ๋Š” ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด sfPropelPager ๋Š” 3๋ฒˆ์งธ๋ถ€ํ„ฐ 4๋ฒˆ์งธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ page ๊ฐ’์ด ์—†๋‹ค๋ฉด ๊ธฐ๋ณธ๊ฐ’์ธ 1 ์ด ์‚ฌ์šฉ๋˜๊ณ , ๊ฐ์ฒด๋Š” ์ฒซ๋ฒˆ์งธ๋ถ€ํ„ฐ 2๋ฒˆ์งธ๊นŒ์ง€์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. sfPropelPager ๊ฐ์ฒด์™€ ๊ทธ ๋ฉ”์˜๋“œ๋“ค์— ๊ด€ํ•ด์„œ๋Š” ์˜จ๋ผ์ธ ๋ฌธ์„œ๋“ค ์ค‘ ํŽ˜์ด์ € ๋ถ€๋ถ„ ์‚ดํŽด๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์„ค์ • ๊ฐ’ ์‚ฌ์šฉํ•˜๊ธฐ

๋ณดํ†ต ์ƒ์ˆ˜๊ฐ’๋“ค์€ ์„ค์ •ํŒŒ์ผ์— ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด, ํ•œ ํŽ˜์ด์ง€๋‹น ํ‘œ์‹œ๋˜๋Š” ๊ฒฐ๊ณผ ์ˆ˜๋Š” (์œ„์˜ ์˜ˆ์—์„œ๋Š” 2๊ฐœ), ์„ค์ •ํŒŒ์ผ์˜ ๊ฐ’์œผ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์œ„์˜ new sfPropelPager ๋ถ€๋ถ„์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

...
  $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max'));

์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‚ฌ์šฉ์ž ์„ค์ •ํŒŒ์ผ์ธ askeet/apps/frontend/config/app.yml ์„ ์—ด๊ณ  ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

all:
  pager:
    homepage_max: 2

pager ํ‚ค๋Š” ์ผ์ข…์˜ ์ด๋ฆ„๊ณต๊ฐ„์œผ๋กœ ์‚ฌ์šฉ๋˜์—ˆ๊ณ , ์œ„์˜ ์ฝ”๋“œ์—์„œ pager ๊ฐ€ ์‚ฌ์šฉ๋œ ๊ฒƒ์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์„ค์ •๊ฐ’๋“ค๊ณผ ์ด๋ฅผ ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” ์˜จ๋ผ์ธ ๋ฌธ์„œ์ค‘ ์„ค์ • ๊ด€๋ จ ์„ ๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

listSuccess.php ํ…œํ”Œ๋ฆฟ ์ˆ˜์ •ํ•˜๊ธฐ

listSuccess.php ํ…œํ”Œ๋ฆฟ์„ ์—ด๊ณ  ์•„๋ž˜ ์ค„์„

<?php foreach($questions as $question): ?>

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

<?php foreach($question_pager->getResults() as $question): ?>

์ด์ œ ํŽ˜์ด์ €์— ์ €์žฅ๋œ ์ž๋ฃŒ๋“ค์ด ์ถœ๋ ฅ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํŽ˜์ด์ง€ ๋„ค๋น„๊ฒŒ์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ

์ด์ œ ํ…œํ”Œ๋ฆฟ์— ํŽ˜์ด์ง€ ๋„ค๋น„๊ฒŒ์ด์…˜์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ์ด ์ฒซ๋ฒˆ์งธ ๋‘ ์งˆ๋ฌธ์„ ์ถœ๋ ฅํ•˜๊ณ  ์žˆ๊ธฐ๋Š” ํ•˜์ง€๋งŒ, ๋‹ค์Œ ํŽ˜์ด์ง€๋กœ ๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ํ…œํ”Œ๋ฆฟ์˜ ๋งˆ์ง€๋ง‰ ๋ถ€๋ถ„์— ๋‹ค์Œ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

<div id="question_pager">
<?php if ($question_pager->haveToPaginate()): ?>
  <?php echo link_to('&laquo;', 'question/list?page=1') ?>
  <?php echo link_to('&lt;', 'question/list?page='.$question_pager->getPreviousPage()) ?>
 
  <?php foreach ($question_pager->getLinks() as $page): ?>
    <?php echo link_to_unless($page == $question_pager->getPage(), $page, 'question/list?page='.$page) ?>
    <?php echo ($page != $question_pager->getCurrentMaxLink()) ? '-' : '' ?>
  <?php endforeach; ?>
 
  <?php echo link_to('&gt;', 'question/list?page='.$question_pager->getNextPage()) ?>
  <?php echo link_to('&raquo;', 'question/list?page='.$question_pager->getLastPage()) ?>
<?php endif; ?>
</div>

์ด ์ฝ”๋“œ๋Š” sfPropelPager ๊ฐ์ฒด๊ฐ€ ์ œ๊ณตํ•˜๋Š” ์—ฌ๋Ÿฌ ๋ฉ”์˜๋“œ๋“ค์„ ํ™œ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ->haveToPaginate() ๋Š” ์ž๋ฃŒ ๊ฐฏ์ˆ˜๊ฐ€ ํ•œ ํŽ˜์ด์ง€์— ์ถœ๋ ฅ๋  ์ˆ˜ ์žˆ๋Š” ์ž๋ฃŒ ์ˆ˜๋ณด๋‹ค ๋งŽ์„๋•Œ true ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ->getPreviousPage() ->getNextPage(), ๊ทธ๋ฆฌ๊ณ  ->getLastPage() ๋Š” ํŠน๋ณ„ํžˆ ์„ค๋ช…ํ•˜์ง€ ์•Š์•„๋„ ์ดํ•ดํ•˜์‹œ๋ฆฌ๋ผ ๋ฏฟ์Šต๋‹ˆ๋‹ค. ->getLinks() ๋Š” ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ๋“ค์˜ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ->getCurrentmaxLink() ๋Š” ๋งˆ์ง€๋ง‰ ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

์œ„์˜ ์˜ˆ์—์„œ๋Š” link_to_unless() ๋ผ๋Š” ๋˜ํ•˜๋‚˜์˜ ํŽธ๋ฆฌํ•œ ์‹ฌํฌ๋‹ˆ ๋งํฌ ํ—ฌํผ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ—ฌํผ๋Š” ์ฒซ๋ฒˆ์งธ ์ธ์ž๊ฐ€ false ์ผ ๊ฒฝ์šฐ์—๋Š” ์ผ๋ฐ˜ link_to() ์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ์—๋Š” ๋งํฌ์—†์ด <span> ์œผ๋กœ ์Œ“์—ฌ์ง„ ์ผ๋ฐ˜ ํ…์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

ํŽ˜์ด์ €๋ฅผ ํ…Œ์ŠคํŠธํ•ด ๋ณด์…จ์Šต๋‹ˆ๊นŒ? ํ•ด๋ณด์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜์ •์ž‘์—…์€ ์ง์ ‘ ๋ˆˆ์œผ๋กœ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์ „์—๋Š” ๋๋‚œ ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด์„œ๋Š” ์„ธ๋ฒˆ์งธ ๋‚ ์— ๋งŒ๋“ค์—ˆ๋˜ ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์—ด๊ณ , ๋ช‡๊ฐ€์ง€ ์งˆ๋ฌธ๋“ค์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ž…๋ ฅํ•˜๊ณ , ํ™ˆํŽ˜์ด์ง€์— ๋‹ค์‹œ ์ ‘์†ํ•ด ๋ณด์‹ญ์‹œ์˜ค. ์„ฑ๊ณต์ž…๋‹ˆ๋‹ค!

ํŽ˜์ด์ง€ ๋ชฉ๋ก

ํŽ˜์ด์ง• ๊ด€๋ จ ๋ผ์šฐํŒ… ๊ทœ์น™ ์ถ”๊ฐ€ํ•˜๊ธฐ

๊ธฐ๋ณธ์ ์œผ๋กœ, ํ•˜๋ถ€ ํŽ˜์ด์ง€๋“ค์€ ์•„๋ž˜์™€ ๊ฐ™์€ URL ์„ ๊ฐ–์Šต๋‹ˆ๋‹ค.

http://askeet/frontend_dev.php/question/list/page/XX

๋ผ์šฐํŒ… ๊ทœ์น™์„ ๋ฐ”๊ฟ”์„œ ์•„๋ž˜์˜ URL ์„ ์œ„์˜ URL ์ฒ˜๋Ÿผ ์ธ์‹ํ•˜๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

http://askeet/frontend_dev.php/index/XX

apps/frontend/config/routing.yml ํŒŒ์ผ์„ ์—ด๊ณ  ๋งจ ์œ„์— ๋‹ค์Œ ๋‚ด์šฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

popular_questions: 
  url:   /index/:page 
  param: { module: question, action: list } 

๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ, ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋ฅผ ์œ„ํ•œ ๋ผ์šฐํŒ…๋„ ์ถ”๊ฐ€ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

login: 
  url:   /login 
  param: { module: user, action: login } 

๋ฆฌํŽ™ํ† ๋ง

๋ชจ๋ธ

question/list ์•ก์…˜์€ ๋ชจ๋ธ๊ณผ ๊ด€๊ณ„๋˜๋Š” ์ฝ”๋“œ๋“ค์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋“ค์„ ๋ชจ๋ธ ์†์œผ๋กœ ์˜ฎ๊ธฐ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. question/list ์•ก์…˜์„ ์•„๋ž˜ ์ฒ˜๋Ÿผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

public function executeList () 
{ 
  $this->question_pager = QuestionPeer::getHomepagePager($this->getRequestParameter('page', 1)); 
}

๊ทธ๋ฆฌ๊ณ  lib/model ์•„๋ž˜์— ์žˆ๋Š” QuestionPeer.php ํด๋ž˜์Šค์— ์•„๋ž˜ ๋ฉ”์˜๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

public static function getHomepagePager($page)
{
  $pager = new sfPropelPager('Question', sfConfig::get('app_pager_homepage_max'));
  $c = new Criteria();
  $c->addDescendingOrderByColumn(self::INTERESTED_USERS);
  $pager->setCriteria($c);
  $pager->setPage($page);
  $pager->setPeerMethod('doSelectJoinUser');
  $pager->init();
 
  return $pager;
}

์–ด์ œ ์ž‘์„ฑ๋œ question/show ์•ก์…˜๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž‘์—…ํ•ฉ๋‹ˆ๋‹ค. ์น˜ํ™˜๋œ ์ œ๋ชฉ์œผ๋กœ ์งˆ๋ฌธ์„ ์งˆ์˜ํ•˜๋Š” ๊ฒƒ๋„ ๋ชจ๋ธ์— ์†ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. question/show ์•ก์…˜์„ ์•„๋ž˜์™€ ๊ฐ™์ด ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค.

public function executeShow()
{
  $this->question = QuestionPeer::getQuestionFromTitle($this->getRequestParameter('stripped_title'));
 
  $this->forward404Unless($this->question);
}

QuestionPeer.php ์— ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

public static function getQuestionFromTitle($title)
{
  $c = new Criteria();
  $c->add(QuestionPeer::STRIPPED_TITLE, $title);
 
  return self::doSelectOne($c); 
}

ํ…œํ”Œ๋ฆฟ

question/templates/listSuccess.php ํŽ˜์ด์ง€์˜ ์งˆ๋ฌธ ๋ชฉ๋ก์€ ๋‚˜์ค‘์— ๋‹ค๋ฅธ ์–ด๋””์„ ๊ฐ€ ์ด์šฉ๋  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด์ œ ํ…œํ”Œ๋ฆฟ ์ฝ”๋“œ๋ฅผ _list.php ํŒŒ์ผ์— ๋„ฃ๊ณ  listSuccess.php ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

<h1>popular questions</h1> 
 
<?php echo include_partial('list', array('question_pager' => $question_pager)) ?> 

_list.php ํŒŒ์ผ์€ askeet SVN ์ €์žฅ์†Œ ์—์„œ ์ฐพ์œผ์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚ด์ผ ์ด ์‹œ๊ฐ„์—

๋กœ๊ทธ์ธ ํผ๊ณผ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋‚˜๋ˆ„๊ธฐ๋Š” ๊ฑฐ์˜ ๋ชจ๋“  ์›น ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ค๋Š˜ ์‹ฌํฌ๋‹ˆ๋ฅผ ํ†ตํ•ด ์ด๋“ค์„ ์–ผ๋งˆ๋‚˜ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋ณด์…จ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜๋„ ์šฐ๋ฆฌ๋Š” ๋ฆฌํŽ™ํ† ๋ง์„ ํ†ตํ•ด ์˜ค๋Š˜ ํ•˜๋ฃจ์˜ ๊ฐœ๋ฐœ์„ ๋งˆ์ณค์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ํฐ ๊ทธ๋ฆผ ์—†์ด ๊ฐœ๋ฐœ์„ ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด์•ผ๋งŒ ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค.

๋‚ด์ผ์€ ๋กœ๊ทธ์ธ ๊ณผ์ •์„ ์ข€ ๋” ์ฒ˜๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ดํŠธ์˜ ๋ช‡๋ช‡ ๋ถ€๋ถ„์„ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œํ•  ๊ฒƒ์ด๊ณ , ๋ถ€์ ์ ˆํ•œ ํผ ์ œ์ถœ์„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ ํผ ํ™•์ธ ์ž‘์—…์„ ํ•˜๋„๋ก ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

This work is licensed under the Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 Unported License license.