2014-01-16 63 views
0

我有一个简单的应用程序,有帖子和标签。CakePHP标签模型

帖子可以有多个标签和标签可以属于多个帖子。基本数据库架构是这样的:

交表:

id 
title 
slug 
content 

标签表:

id 
title 
slug 

tag_posts表:

id 
tag_id 
post_id 

因此,当一个用户保存一个帖吧将采取一个字段中的标签列表,然后首先检查标签是否存在。如果标签不存在,那么创建它们,或者如果没有获得现有的ID。 (所有标签都是较小的,所以你不能有Tagtag)。然后将标签添加到tag_posts表中,然后将该标签链接到该帖子。

这工作到目前为止,但代码做到这一点真的很可怕。我必须在标签模型下面的方法这需要的标签列表,并和前面一样:

公共职能savePostTags($帖子ID,$标签) {

// Explode the topics by comma, so we have an array to run through 
$tags = explode(',', $tags); 
// Array for collecting all the data 
$collection = array(); 

//debug($tags); 

function is_array_empty($mixed) { 
    if (is_array($mixed)) { 
     foreach ($mixed as $value) { 
      if (! is_array_empty($value)) { 
       return false; 
      } 
     } 
    } elseif (! empty($mixed)) { 
     return false; 
    } 

    return true; 
} 

if(is_array_empty($tags)) { 

    return false; 

} 

// First of all we bin off existing associations to make sure we don't duplicate 
// NOTE: The false means don't delete the topics or posts related!!! VERY IMPORTANT! 
$this->TagPost->deleteAll(array('TagPost.post_id' => $postId), false); 

$tags = array_unique($tags); 

// Make sure all tags are unique 

foreach($tags as $tag) 
{ 
    // Trim it so remove unwanted white spaces in the beginning and the end. 
    $tag = trim($tag); 

    // If tag is empty exit here 
    if(empty($tag)) { 

     return false; 

    } 

    // Make it all lowercase for consistency of tag names 
    $tag = strtolower($tag); 

    // Check if we already have a topic like this 
    $controlFind = $this->find(
     'first', 
     array(
      'conditions' => array(
       'title' => $tag 
      ) 
     ) 
    ); 

    //debug($controlFind); 

    // No record found (create new tag and link it up) 
    if(!$controlFind) 
    { 
     $this->create(); 
     if(
      !$this->save(
       array(
        'title' => $tag, 
        'slug' => Inflector::slug($tag) 
       ) 
      ) 
     ) 
     { 
      // If only one saving fails we stop the whole loop and method. 
      return false; 
     } 
     else 
     { 
      $temp = array(
       'TagPost' => array(
        'tag_id' => $this->id, 
        'post_id' => $postId 
       ) 
      ); 
     } 
    } 
    else // Or if found link it with the post 
    { 
     $temp = array(
      'TagPost' => array(
       'tag_id' => $controlFind['Tag']['id'], 
       'post_id' => $postId 
      ) 
     ); 
    } 

    $collection[] = $temp; 
} 

return $this->TagPost->saveAll($collection, array('validate' => false)); 

}

任何想法关于如何重构这个?

感觉真的很啰嗦,似乎打破了CakePHP的约定。

回答

0

试试这个

public function savePostTags($postId, $tags) 
     { 
      $tags = explode(',', $tags); 
      foreach($tags as $key=>$value){ 
       $listTags[$key] = trim(strtolower($value));  
      } 
      # find the list of existing tags 
      $listOfExistingTags = $this->find('list', 
         array('conditions' => array('title' => $tags), 
         'recursive' => -1)); 
      $newTags = array_diff($tags, $listOfExistingTags); 
      #save new tags 
      foreach($newTags as $key=>$value){ 
       $saveData[$key]['Tag']['title'] = $value; 
       $saveData[$key]['Tag']['slug'] = Inflector::slug($value); 
      } 
      if(!empty($saveData))$this->saveAll($saveData); 
      # this save all the tags 
      # now save data in tag_posts 
      $listOfExistingTags = $this->find('list', 
       array('conditions' =>array('title' => $tags), 
        'fields'=>array('id','title'), 
        'recursive' => -1)); 
      $i = 0; 
      foreach($listOfExistingTags as $key=>$value){ 
       $tagPostData[$i]['TagPost']['tag_id'] = $key; 
       $tagPostData[$i]['TagPost']['post_id'] = $postId; $i++; 
      } 
      if(!empty($tagPostData)){ 
      App::import('model','TagPost'); 
      $TagPost = new TagPost(); 
      $TagPost->saveAll($tagPostData); 
      } 
     } 
+0

酷我会试试我回家的时候。你有什么想法,为什么我发布的代码是复制2.4.4中的标签?好奇多于一切。谢谢。 – Cameron

+0

这不是cakephp 2.4.4的问题,你的做法是错误的。试试这个一次...... – Anubhav

+0

但是是什么导致了重复呢?它没有用于复制旧版本的Cake。 – Cameron

0

如何重构这个任何想法?

使用the CakeDC Tags plugin。它是单元测试和易于投入,需要大约15分钟。看到它是readme.md。它基本上只是添加行为并添加一个字段“标签”到您的表单。