2015-11-24 68 views
0

我工作的機構在我們的Drupal CMS和LDAP服務器之間有一個現有的和可用的集成。該集成的一個特點是能夠從LDAP中獲取記錄以填充Drupal中的字段。我們告訴Drupal使用自定義模塊來填充要填充的字段和內容類型,最初設計爲僅適用於(1)內容類型的單個機器名稱和(2)每個字段的單個機器名稱。這些使用db_or()的Drupal SQL查詢有什麼問題?

我們正試圖修改這些配置項目存在逗號 - 劃定的名單,所以我們可以提供LDAP信息可能不一定使用共享的字段內容類型的任意數量。 (2)的修改,即爲一個字段輸入多個機器名稱並且仍然填充所需數據的能力已經在起作用。但是,完成(1)所需的修改將允許記錄反饋到多個內容類型,這取決於SQL語句的相關性,我相信我一定會犯錯。

其中機器名(多個)內容類型獲取存儲由Drupal的內部調用dart_netid_content_type配置項。這裏是舊代碼,適用於一臺機器名稱,用於識別單個內容類型:

// All nodes of type from dart_netid_content_type, with either no LDAP lookup time, or over 24 hours ago 
$query = db_select('node'); 
$query->leftjoin('dart_ldap_update', 'ldap', 'node.nid = ldap.nid'); 
$query->fields('node', array('nid')) 
    ->fields('ldap', array('nid', 'ldap_updated')) 
    ->condition('type', variable_get('dart_netid_content_type', ''), '=') 
    ->condition('status', '1', '=') 
    ->condition(db_or()->condition('ldap_updated', NULL, 'IS')->condition('ldap_updated', $limit, '<')) 
    ->orderby('ldap_updated', 'ASC'); 

這裏是新的查詢,這是應該的多種內容類型的工作。有趣的是,查詢不是完全是破;如果您輸入標識單個內容類型的單個機器名稱,則該查詢將繼續有效。但是,如果你存儲的dart_netid_content_type,這是在其他配置項已經工作等,都應該有數據填充字段的機器名內的逗號劃定列表,然後查詢失敗,模塊將不會識別任何節點或填充他們的任何領域。

/* 
* Break up dart_netid_content_type into an array 
*/ 
$dart_netid_content_type_array = explode(",", variable_get('dart_netid_content_type', '')); 

/* 
* For each item in the array, create an 'or' conditional in a db_query that 
* checks for all of those content types 
*/ 
$content_type_or = db_or(); 
foreach($dart_netid_content_type_array as $content_type) { 
    $content_type_or->condition('type', $content_type, '='); 
} 

// All nodes of type from dart_netid_content_type, with either no LDAP lookup time, or over 24 hours ago 
$query = db_select('node'); 
$query->leftjoin('dart_ldap_update', 'ldap', 'node.nid = ldap.nid'); 
$query->fields('node', array('nid')) 
    ->fields('ldap', array('nid', 'ldap_updated')) 
    ->condition($content_type_or) 
    ->condition('status', '1', '=') 
    ->condition(db_or()->condition('ldap_updated', NULL, 'IS')->condition('ldap_updated', $limit, '<')) 
    ->orderby('ldap_updated', 'ASC'); 

要闡述的方式,希望能更加直觀的這兩個版本之間的差異目的:dart_netid_content_type現在可能是一個內容類型,或不止一個。上一個查詢正在搜索與WHERE type = dart_netid_content_type類似的內容。我試圖哄它現在要做的,而是看看dart_netid_content_type_array中的單個項目,並進行一個類似於WHERE (type = dart_netid_content_type_array[0]) OR (type = dart_netid_content_type_array[1]) OR ... OR (type = dart_netid_content_type_array[sizeof(dart_netid_content_type_array)])的查詢。

的東西出現在Drupal的db_query和db_or語法包裝這個時候是錯我的邏輯。

如果有需要,我可以通過共享更多的驅動LDAP到節點的功能自定義模塊的方式提供更多的背景。

非常感謝您的幫助。

+0

你可以轉儲兩種變體產生的實際SQL嗎? –

回答

0

如何使用IN,以確定該內容類型是值的陣列中?類似這樣的:

$dart_ct_array = explode(",", variable_get('dart_netid_content_type', '')); 
$dart_netid_content_types = "('" . implode("','", $dart_ct_array) . "')"; 

$query = db_select('node'); 
$query->leftjoin('dart_ldap_update', 'ldap', 'node.nid = ldap.nid'); 
$query->fields('node', array('nid')) 
    ->fields('ldap', array('nid', 'ldap_updated')) 
    ->condition('type', $dart_netid_content_types, 'IN') 
    ->condition('status', '1', '=') 
    ->condition(db_or()->condition('ldap_updated', NULL, 'IS')->condition('ldap_updated', $limit, '<')) 
    ->orderby('ldap_updated', 'ASC'); 
+0

除了這個代碼比我的更乾淨之外,它還將我置於實際問題的軌道上!在SQL查詢之外,還有另外一部分代碼基本上運行了'if($ node-> type == dart_netid_content_type){foo(); }'沒有被更新以反映'dart_netid_content_type'已被轉換爲數組的事實。這已得到解決,現在的定製工作!謝謝! –

+0

太棒了!真高興你做到了! :) –