2016-07-06 79 views
1

On hook_user_login我想要刪除超過21天的給定內容類型的登錄用戶擁有的節點。下面drupal 7 | db_select | date_field條件

的代碼工作正常(無日期條件):

function mymodule_user_login(&$edit, $account) { 
    global $user; 
    $myuid = $user->uid; 
    $mytype = 'testdelete'; 
    $mydate = '2016-07-06 18:45:00'; 

    $results = db_select('node', 'n') 
     ->fields('n', array('nid')) 
     ->condition('type', $mytype) 
     ->condition('uid', $myuid) 
     ->execute(); 

    foreach ($results as $result) { 
    $nids[] = $result->nid; 
    } 

    if (!empty($nids)) { 
    node_delete_multiple($nids); 
    drupal_set_message(t('%count nodes has been deleted', array('%count' => count($nids)))); 
    } 
} 

現在我因爲堅持了一個多星期與日期條件。我的日期字段是內容類型「testdelete」被稱爲「datum」,窗口小部件是彈出日曆。

我已經試過:

->fields('n', array('nid','field_datum')) 

->fields('n', array('nid','datum')) 

兩個結果異常:

PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'n.field_datum' in 'field list': SELECT n.nid AS nid, n.field_datum AS field_datum FROM {node} n WHERE (type = :db_condition_placeholder_0) AND (uid = :db_condition_placeholder_1) ; Array ([:db_condition_placeholder_0] => testdelete [:db_condition_placeholder_1] => 4) in mymodule_user_login() 

應該如何的情況看:

->condition('datum', $mydate,'<') 

而$指明MyDate應該是這樣的:now() -21 days

另一個問題:

我擔心hook_user_login是不正確的地方這個工作還是可以嗎?
我應該使用像hook_cron一樣的東西嗎?

+0

爲什麼不張貼在[Drupal Answers](http://drupal.stackexchange.com/)? –

+0

對不起 - 我下次會這樣做 – user2699953

回答

0

要根據字段值選擇節點集合,您應該使用EntityFieldQuery而不是db_select()db_select()是一個簡單的查詢編寫工具,假定您知道數據庫中正在使用的存儲結構。 EntityFieldQuery旨在抽象出數據存儲並允許您僅瞭解內容類型結構。

在你的情況下,它看起來是這樣的:

$query = new EntityFieldQuery(); 

$query->entityCondition('entity_type', 'node') 
    ->entityCondition('bundle', 'testdelete') 
    ->entityCondition('uid', $myuid) 
    ->fieldCondition('field_datum', 'value', $mydate, '<') 

$results = $query->execute(); 

至於hook_user_login() VS hook_cron()這取決於你的目標。如果您希望在時間軸之後刪除內容,則無論用戶活動如何,hook_cron()都是更好的選擇。如果您希望內容保留到用戶返回,則hook_user_login()是正確的工具。

使用hook_user_login()如果您有用戶生成大量需要在登錄時刪除的內容,您將無法及時處理所有必需的任務。如果是這種情況,你會想要創建一個批處理作業或者使用Drupal的任務隊列來讓Drupal完成一些不需要用戶等待它完成的大量工作。

0

您擁有的db_select查詢只是從節點表中進行選擇。
但是,字段值存儲在它們自己的表中。
要使用日期字段執行db_select,您必須加入datnum字段表。
如(未測試):

$query = db_select('node', 'n'); 
$query->join('field_data_field_datnum', 'datnum', 'n.nid = datnum.entity_id'); 
$query->fields('n', array('nid')); 
$query->fields('datnum', array('datnum_value')); 
// add conditions here 

一個更好的選擇是可能使用EntityFieldQuery
如何使用EntityFieldQuery可以看到HERE

至於在HOOK_user_login中這樣做,它真的取決於你的情況。
在高流量網站上進行用戶登錄可能不是一個好主意。
我會在HOOK_cron上做到這一點。

0

謝謝兩位,

@acrosman - 我用你的計算策略有兩個小變化

->propertyCondition('uid', $myuid,'=') 

和 「;」 在

->fieldCondition('field_datum', 'value', $mydate, '<'); 

末對於所有其他與也許是同樣的問題
我的代碼在最初的問題刪除節點

foreach ($results as $result) { 
    $nids[] = $result->nid; } 

等等.....沒有工作了

我用下面的代碼,它工作正常

foreach($results['node'] as $node){ 
    node_delete($node->nid); 
} 

謝謝大家
湯姆