为了不在网址中显示社交网络成员的ID,我创建了这条路线:
perfil_miembro:
url: /miembros/:nombre_apellidos
class: sfDoctrineRoute
options: { model: Usuario, type: object}
param: { module: miembros, action: show}
并在show action中添加了这一行:
$this->usuario = $this->getRoute()->getObject();
一切正常:当我点击他们的名字时,会显示相应的个人资料,网址就是这个类型:
frontend_dev.php / miembros /玛利亚+的+米格尔+尔瓦拉多
现在我想在网址中插入名称,这样我就改变了这条路线:
perfil_miembro:
url: /miembros/:nombre_apellidos_slug
class: sfDoctrineRoute
options: { model: Usuario, type: object}
param: { module: miembros, action: show}
我创造了这些方法:
public function getNombreApellidosSlug()
{
return Tirengarfio::slugify($this->getNombreApellidos());
}
class Tirengarfio
{
static public function slugify($text)
{
// replace all non letters or digits by -
$text = preg_replace('/\W+/', '-', $text);
// trim and lowercase
$text = strtolower(trim($text, '-'));
return $text;
}
}
现在,当我点击某个成员的名字时,会显示以下网址:
frontend_dev.php / miembros /玛利亚-DE-米格尔-尔瓦拉多
但它始终显示我在灯具文件中的第一个成员的个人资料。
我怎样才能让它发挥作用?
Ubuntu 8.04 - Symfony 1.3。
答案 0 :(得分:1)
slug字段需要是一个真正的列,而不是您创建的虚拟列
访问URL时,doctrine正在寻找单个对象
匹配网址中找到的字段 - 在您的情况下,这意味着没有字段,那就是
为什么你看到你桌子上的第一条记录。查询记录器
应该显示select * from tablename limit 1;
。
关于你网址的说明:你确定不会有多个网址吗?
有同名人物?如果发生这种碰撞,没有人会这样
能够看到第2,第3等人的页面。我会以/miembros/:id/:slug
的形式在网址中包含ID,这样就可以保持人类的可读性并且肯定不会发生冲突。
<强>更新强>
在第一条评论中,@ Raise建议使用ID的盐渍哈希而不是ID本身。这比我原来包含身份证的想法要好
sfDoctrineGuardPlugin为每个用户生成一个新的salt,存储它,并用于设置/验证密码。您需要在users表中为hash创建一个新字段(不需要存储salt,ID也不会更改),并且您的url将显示为/miembros/:hash/:slug
。
答案 1 :(得分:1)
您可以使用这些路由选项:options: { model: Usuario, type: object, method: getObjectBySlug }
,但您需要一个getObjectBySlug()
方法,该方法会在给定slug的情况下检索您的对象。现在你有getNombreApellidosSlug()
恰恰相反。问题是通常,没有办法知道slu“maria-martinez”是否对应用户“Maria Martinez”,“MaríaMartínez”,“MaRiA MaRtInEz”或“MaríaMartíÑez”,所以这是一个问题。您可以通过“slug”列来解决它。
我的建议是使用Sluggable behaviour of Doctrine来处理slug列。
我在this pet project上使用它来做到这一点。使用它非常简单:
首先,您在the schema中激活它:
actAs:
Timestampable: ~
Sluggable:
fields: [name]
indexName: name_slug
canUpdate: true
unique: true
它将创建并保留一个名为“slug”的列。
然后,在the routing中使用它。在我的情况下是:
list_permalink:
url: /:slug
class: sfDoctrineRoute
options: { model: SkinnyList, type: object, method: getObjectBySlug }
param: { module: list, action: show }
requirements: { sf_method: get }
您需要lib/model/doctrine/yourmodelTable.class.php中的方法getObjectBySlug:
public function getObjectBySlug($options = array())
{
if (!isset($options['slug']))
{
throw new InvalidArgumentException('The slug is required in the options');
}
$q = $this->createQuery('td')->where('td.slug = ?', $options['slug']) ;
return $q->fetchOne();
}
在操作中,您可以通过执行以下操作来检索对象:
$this->list = $this->getRoute()->getObject();