在此 DataObject 中,有一个用户提供的字段标题,必须将其转换为唯一的网址标记。
所需结果:重复的网址应获得其值的后缀。因此,使用标题Foo
保存2条记录应该会产生一条记录foo
作为列URL
的值,第二条记录的值应为foo-2
。< / p>
public function onBeforeWrite() {
parent::onBeforeWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$this->URL = $filter->filter($this->Title);
// If URL is not unique, add suffix
$i = 1;
while($this->uniqueURL($this->URL)) {
$i++;
$this->URL = $this->URL . "-" . $i;
}
}
方法:uniqueURL (在同一个班级内)
public function uniqueURL($URL) {
// Check if there is a record with the same URL
$existingURL = DataObject::get('NewsArticle', "URL = '$URL'");
if ($existingURL) {
// this is a duplicate URL
return false;
} else {
// this is a unique url
return true;
}
}
两次保存Foo
会产生foo
和foo-2
。
保存具有相同标题Foo
的两个记录时会产生两个带有foo
答案 0 :(得分:3)
为什么你有两个foo
网址?
如果在插入所有记录之前检查数据库,则表示该检查对您的记录批次不起作用。
请勿使用循环来计算唯一网址
您不需要每次循环检查并增加计数($i
)。性能方面,您最好在查询中执行COUNT()
,并将该值用于下一次插入。
// The following does exactly the same with just 1 query. No loop needed.
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
<强>解决方案强>
要做到onBeforeWrite()
,唯一的可能是查询您的数据并在保存之前检查您的记录。
或者一个结果相同的简单解决方案是您可以更改onAfterWrite()
中的网址,并检查使用相同标题的数量作为数字。
public function onAfterWrite() {
parent::onAfterWrite();
// Sanitize Title field to use for URL
$filter = URLSegmentFilter::create();
$filteredTitle= $filter->filter($this->Title);
$count = DB::query("SELECT COUNT(*) FROM Table WHERE Title LIKE '{$filteredTitle}'")->value();
if ($count > 1) {
$filteredTitle .= "-" . $count;
}
$this->URL = $filteredTitle
}