drupal 7 | db_select | date_field条件

时间:2016-07-06 08:43:19

标签: date drupal conditional-statements

在hook_user_login上我想删除超过21天的给定内容类型的登录用户拥有的节点。

以下代码正常(没有日期条件):

$.ajax({
        url: url,
        dataType: 'json',
        type: 'POST',
        data: newValue,
        success: function(data) {
            if (data.perrorCode){//there is a validation error
                this.setState({error: `Validation Error. Expected format: ${data.perrorMessage}. Got format: ${data.pvalue}`});
                callback(false);
            } else
                callback(true);
        }.bind(this),
        error: function(xhr, status, err) {
            console.error(url, status, err.toString());
        }.bind(this)

现在我因为约会条件已经过了一个星期了。我的日期字段是内容类型" testdelete"被称为"数据"和小部件是弹出日历。

我试过了:

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))));
  }
}

->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() 

虽然$ mydate应该是:->condition('datum', $mydate,'<')

其他问题:

我担心hook_user_login不是这个职位的合适地方还是那个好吗? 我应该使用像hook_cron这样的东西吗?

3 个答案:

答案 0 :(得分: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上做。

答案 1 :(得分: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由于时间密集的工作而不会迫使用户等待它完成。

答案 2 :(得分:0)

谢谢你们两个,

@acrosman - 我用你的approch进行了两次小改动

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

末尾的“;”
->fieldCondition('field_datum', 'value', $mydate, '<');

对于所有其他可能有同样问题的人 关于删除节点的初始问题的代码

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

依此类推......不再适用了

我使用了以下代码,工作正常

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

谢谢大家 汤姆