在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这样的东西吗?
答案 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);
}
谢谢大家 汤姆