symfony开发很简洁,但是功能的数量仍然很缺乏。现在是时候进行一些askeet站点与用户之间的交互了。而HTML交互的根本--除了起链接--就是表单了。
这里我们的目标是允许用户登陆,并在主页的问题列表中进行翻阅。这对于开发而言是很快的,并且可以让我们回忆起前面的内容。
登陆表单
在测试数据中存在用户,但是程序却没有办法来进行验证。下面我们要在程序的每一个页面添加一个登陆表单。打开全局的布局文件askeet/apps/frontend/templates/layout.php,并且在到about的连接之前添加下面的代码行:
复制代码 代码如下:
<li><?php echo link_to('sign in', 'user/login') ?></li>
当前的布局将这些链接放在web调试工具栏之后。要看到这些链接,点击'Sf'图标折叠起调试工具栏就可以看到了。
现在需要创建user模块。而question模块是在第二天生成的,这一次我们只是叫symfony来创建模块框架,而我们将会自己来编写这些代码。
复制代码 代码如下:
$ symfony init-module frontend user
这个框架包含一个默认的index动作与一个indexSuccess.php模板。删除他们,因为我们并不需要他们。
创建user/login动作
复制代码 代码如下:
在user/actions/action.class.php文件中,添加下面的登陆动作:
public function executeLogin()
{
$this->getRequest()->setAttribute('referer', $this->getRequest()->getReferer());
return sfView::SUCCESS;
}
这个动作将referer保存在请求属性中。然后这个属性可为模块所用存放在一个隐藏区域中,从而这个表单的目的动作可以在成功登陆后重定向到原始的referer。
语句return sfView::SUCCESS将动作执行结果传递到loginSuccess.php模块。这条语句是在一个不包含返回语句的动作中实现的,这也就是一个动作的默认模块被称之为actionnameSuccess.php的原因。
在动作上开始更多的工作之前,我们先来看一下模块。
创建loginSuccess.php模块
web上的许多人机交互使用表单,而Symfony通过提供一个form帮助器集合来组织表单的创建与管理。
在askeet/apps/frontend/modules/user/templates/目录下,创建下面的loginSuccess.php模块:
复制代码 代码如下:
<?php echo form_tag('user/login') ?>
<fieldset>
<div>
<label for="nickname">nickname:</label>
<?php echo input_tag('nickname', $sf_params->get('nickname')) ?>
</div>
<div>
<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>
这个模块是我们第一次使用表单帮助器。这些Symfony函数可以帮助我们自动化编写表单标签。form_tag()打开一从此标签,使用POST作为默认的动作,并且指向作为参数传递的动作。input_tag()帮助器产生一个<input>标签,并且依据所传递的第一个参数自动添加一个id属性;而默认值则是由第二个参数得到。我们可以在Symfony一书的相关章节查找到更多的关于表单帮助器与他们所产生的HTML代码的内容。
这里的实质是当表单提交时则会调用这个动作。所以我们返回来看一下这个动作。
处理表单提交
用下面的代码来替换我们刚才所编写的登陆动作:
复制代码 代码如下:
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'));
}
}
}
}