My use case is that I have a nodequeue that populates a Views carousel, and therefore nodes must satisfy the condition that they have a valid image to be in this queue.

The first way I tried doing this was with an implementation of hook_nodequeue_add() which checks the new node, and if it's no good, calls nodequeue_subqueue_remove_node() and displays an error message to the user.

This works, but has a major flaw. If the nodequeue has a finite size, and is full, then by the time hook_nodequeue_add() is invoked, the overflow node has already been popped off, and the hook has no way of knowing which node that was -- so the queue has been damaged by the operation and can't be restored.

function nodequeue_subqueue_add($queue, &$subqueue, $nid) {
  if (!empty($nid)) {
    db_query("INSERT INTO {nodequeue_nodes} (sqid, qid, nid, position, timestamp) VALUES (%d, %d, %d, IFNULL((SELECT MAX(position)+1 FROM (SELECT * from {nodequeue_nodes} WHERE sqid = %d) as nn), 1), %d)", $subqueue->sqid, $queue->qid, $nid, $subqueue->sqid, time());
    $subqueue->count = db_result(db_query("SELECT count(nid) FROM {nodequeue_nodes} WHERE sqid = %d", $subqueue->sqid));
    // If adding this would make the queue too big, pop the front node
    // (or nodes) out.
    if (!empty($queue->size)) {
      // 0 means infinity so never do this if FALSE.
      nodequeue_check_subqueue_size($queue, $subqueue, $queue->size);
    }
    if (module_exists('apachesolr')) {
      apachesolr_mark_node($nid);
    }
    // Invoke the hook to notify other modules of the node addition.
    module_invoke_all('nodequeue_add', $subqueue->sqid, $nid);
    # this happens after everything has been done -- too late!
  }
}

It would be nice if there were a hook_nodequeue_pre_add(), which could return FALSE to reject a node -- but I'm aware that this would have major knock-on effects in the module's UI as currently nodequeue_subqueue_add() is not at all geared for rejection from that API function.

Another possibility is at nodequeue_api_subqueues(), which calls the pseudohook QUEUE_OWNER_nodequeue_subqueues(). For my case, that callback is nodequeue_nodequeue_subqueues(), which nodequeue doesn't actually implement. So cheekily I can write that function myself and check the queue and the node and return FALSE. This takes care of hiding the node link and the node tab, though it doesn't work on the nodequeue content form. At any rate, it all hinges on nodequeue not having that function right now, so it's a bit flaky!

A third possibility would be to pass an optional $node parameter to nodequeue_queue_access(), which is passed in for situations where there is a node in question, then have that invoke an access hook where returning FALSE denies access.

Comments

joachim’s picture

Issue summary: View changes

turns out it's not a bug, I'm just stupid

venutip’s picture

For those of you finding this issue like I did, I just had this problem for a different use case. Until one of the above suggestions is implemented, I was able to use a combination of hook_nodequeue_alter() (to prevent queues from appearing on node/%nid/nodequeue) and hook_query_TAG_alter() to prevent nodes from appearing in the title autocomplete. For the latter, you need to implement greggadson's patch in #2231793: Autocomplete does not pass autocomplete text to hook.