์ง๋ ์ค๊ฑฐ๋ฆฌ
์ง๋ ์๊ฐ ์๋ ์ฝ๋๋ฅผ ํด๋น ์ฝ๋์ ์์ฑ์ ๋ง๋ ๋ค๋ฅธ ํ์ผ๋ค๋ก ์ด๋์ํค๋ ์์ ์ ํตํด ๋ฆฌํํ ๋ง์ ์ดํด๋ณด์์ต๋๋ค. ๋ํ ๋ชจ๋ธ์ ์์ฑ์ ๊ดํ ์ฝ๋๋ฅผ ์ก์ ์์ ๋ชจ๋ธ๋ก ์ฎ๊ธฐ๋ ๊ฒ๋ ์ดํด๋ณด์์ต๋๋ค.
์ง๊ธ๊น์ง ๊ฐ๋ฐ๋ ์ฝ๋๋ ๊น๋ํ์ง๋ง ์์ง ๋ ๊ฐ๋ฐํด์ผ ํ ๊ธฐ๋ฅ์ด ๋ง์ต๋๋ค. ์ค๋์ 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('«', 'question/list?page=1') ?> <?php echo link_to('<', '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('>', 'question/list?page='.$question_pager->getNextPage()) ?> <?php echo link_to('»', '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.