2016-11-17 18 views
1

在此數據對象有一個用戶提供的字段標題必須轉換爲唯一的URL段落。SilverStripe唯一URL(調試)

預期結果:重複的網址應該爲其值添加後綴。因此,使用標題Foo保存2條記錄應得到一條記錄,其foo值爲列URL,第二條記錄的值應爲同一列的值foo-2

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兩次將導致foofoo-2

當保存兩個記錄具有相同名稱Foo產生兩個URL字段與foo

+0

你的問題是什麼,第一個案例需要'foo'和'foo-2',第二個案例呢?或在兩種情況下'foo-1'和'foo-2'? – Timmetje

+0

'foo'爲第一,'foo-2'爲第二個 – Faloude

回答

2

爲什麼你有兩個foo網址嗎?

如果您在插入所有記錄之前檢查數據庫,這意味着該檢查不會在您的記錄批處理中工作。

不要使用循環計數唯一URL

你並不需要循環,檢查每一個時間和增加計數($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 
} 
+0

工程就像一個魅力。 'else'語句是必須的,否則'$ this-> URL'將是唯一的NULL。 – Faloude

+0

啊,我錯過了你是絕對正確的,我改變了正確答案。現在看起來好多了;) – Timmetje