2012-05-25 153 views
2

我有一個Expression Engine網站,它具有以下要求。表達式引擎掛鉤

我需要能夠通過一對匹配字段來過濾通道條目結果集,例如我的入場將有一個field_a和field_b。如果這些字段匹配,我希望它成爲返回結果集的一部分。我不能在前端執行這個檢查,因爲那麼結果數量將不正確。我在想我可以使用鉤子將字段傳遞到exp:channel:entries標記並更改返回的數據。

這看起來是否合理,如果有的話,是否有人知道操縱數據的細節?看着文檔的我想我想使用'channel_entries_query_result'鉤子,但我不知道如何實際操作數據。我創建了正常觸發的鉤子,並且可以看到模板tag_data等,但我不確定接下來要去哪裏。

感謝

回答

0

這聽起來像它需要一個自定義查詢,您將不使用任何的電子工程師掛鉤做到這一點。

你可以編寫自己的插件/模塊或使用EE的本地查詢模塊。

你只需要用你的查詢來比較兩列。例如:

SELECT 
    * 
FROM 
    some_table 
WHERE 
    col1 = col2 
+0

當然,我會那樣做。但我仍然需要諸如分頁等方式來處理本地exp:channel:entries調用。使用自定義查詢我不知道維護該功能的簡單方法? – alanablett

+0

分頁與查詢模塊一起工作。 –

0

對於任何對此感興趣的人來說,這裏是代碼。我沿着鉤子路線走,並用以下代碼綁定到'channel_entries_query_result'鉤子。

public function query_result_filtered($c, $res){ 
    # maybe this can be done better? Grabs the tag data for this template call 
    $tags = $c->EE->TMPL->tag_data; 

    foreach($tags as $tag): 
     # We're only interested in exp:channel:entries 
     if($tag['class'] == 'channel' && $tag['method'] == 'entries'): 
      # We're only interested if the tag has a param of matching, e.g. {exp:channel:entries matching="field_1|field_2"} 
      if(isset($tag['params']['matching'])): 
       $res = $this->_parse_results($res, $tag['params']['matching']); 
      endif; 
     endif; 
    endforeach; 

    return $res; 
} 

private function _parse_results($res, $fields){ 

    $ret = array(); 
    $fields = explode('|', $fields); 

    //If we dont have multiple tags to match against, return the result set as is 
    if(!is_array($fields)): 
     return $res; 
    endif; 

    # Get the field id's and count how many fields we're checking against 
    $fields = $this->_get_field_ids($fields); 
    $field_count = count($fields); 

    foreach($res as $row): 
     # Value to match against (just use the first value) 
     $tomatch = $row[$fields[0]]; 
     # Keep a count on how many matches, so we can check that they all match 
     $match = 0; 

     foreach($fields as $field): 
      # If the current field matches that of the first field then we have a match, increment the count 
      if($row[$field] == $tomatch): 
       $match++; 
      endif; 
     endforeach; 

     # If we have matched all fields then add this row to the returned array 
     if($match == $field_count): 
      $ret[] = $row; 
     endif; 

    endforeach; 

    return $ret; 
} 

private function _get_field_ids($fields){ 

    $ret = array(); 

    # Loop through the fields given and find their ID's (this could be better and check site id for multisite compatibility) 
    foreach($fields as $field): 
     $q = $this->EE->db->select('field_id')->where('field_name', $field)->get('exp_channel_fields'); 
     # Create a nice name that we can use as an array key when we check each rows value 
     $ret[] = 'field_id_' . $q->row('field_id'); 
    endforeach; 

    return $ret; 
} 

不是特別優雅,但它的工作。如果其他人有更好的解決方案,我很樂意聽到它。謝謝

+0

我試圖做類似的事情,但似乎這隻影響顯示的條目,分頁後生效。我想在應用限制或分頁之前影響完整的結果集... –

2

您可以編寫自己的模塊,擴展通道條目循環。

你會使用這樣的:

{exp:custom_module:entries} 

這種方法將支持任何默認參數。

模塊中的方法是這樣的:

public function entries() 
{ 
    if(! class_exists('Channel')) 
    { 
     require_once PATH_MOD.'channel/mod.channel.php'; 
    } 

    // queries grabbing entry ids you want 
    .... 

    $this->EE->TMPL->tagparams['entry_id'] = implode('|', $entry_ids); 

    $channel = new Channel(); 
    $tagdata = $channel->entries(); 

    return $tagdata; 
}