1

I want to publish unpublished nodes in a custom action. To do this, I query the database on a specific condition and want to use 'exists' condition to find the node IDs to publish. This is the code I am using.

$query = \Drupal::entityQuery('node');

foreach($i_selected as $is) {
  $nids = $query->andConditionGroup()
    ->condition('type', 'level3')
    ->condition('title', $file_name)
    ->condition('status', '0')
    ->exists('nid')
    ->execute();

  $nids->setPublished(TRUE)->save();
}

I get this error,

Error: Call to undefined method Drupal\Core\Entity\Query\Sql\Condition::execute()

The SQL query I am trying to achieve is:

   select nid, status, title from node_field_data where status = '0' and title = $filename

of the result, I want to see if the nids exists and publish those nids.

How do I fix that error?

2
  • 1
    Once the question is answered, you cannot change it, not even to add an update basing on given answers. Questions aren't for a back-and-forth with the users who answer.
    – apaderno
    Jul 9, 2021 at 11:34
  • I checked you answer only after figuring out on my end. I will make sure to not update questions. Thanks for your support :)
    – Jiah
    Jul 9, 2021 at 16:26

1 Answer 1

4

The code is calling execute() on the object returned from $query->andConditionGroup(), but that object doesn't implement any execute() method.

The correct way to use andConditionGroup() is shown in QueryBase::andConditionGroup().

$query = \Drupal::entityQuery('drawing');
$group = $query->andConditionGroup()
  ->condition('figures.color', 'red')
  ->condition('figures.shape', 'triangle');
$query->condition($group);
$group = $query->andConditionGroup()
  ->condition('figures.color', 'blue')
  ->condition('figures.shape', 'circle');
$query->condition($group);
$entity_ids = $query->execute();

In your case, using andConditionGroup() isn't necessary, as the query executed by that code returns all nodes for which:

  • The content type is level3
  • The title is $file_name
  • The status is 0

It doesn't return all the nodes for which at least one of those conditions is true. It's similar to what the following code does, which returns all the page nodes where the value of field_some_field is higher than 14.

$query = \Drupal::entityQuery('node')
  ->condition('type', 'page')
  ->condition('field_some_field', 14, '>');
$results = $query->execute();

$query->execute() returns an array of entity IDs, not an entity nor an array of entities. $nids = $query->execute(); $nids->setPublished(TRUE)->save(); is still wrong, as an array doesn't implement the setPublished() method.
Given an array of node IDs $nids, the correct code to load the nodes is the following one.

$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple(array_values($nids));

$nodes will contain an array of entities. Publishing them can be achieved with the following code.

foreach ($nodes as $node) {
  $node->setPublished(TRUE)->save();
}

The object returned from \Drupal::entityQuery() verifies the currently logged-in user has view access to the returned nodes. In most of the cases, the user doesn't have access to unpublished nodes. To avoid the query returns only the nodes the currently logged-in user can view, it's necessary to call $query->accessCheck(FALSE), as in $query = \Drupal::entityQuery('node')->checkAccess(FALSE);

Furthermore, the exists('nid') call isn't necessary, as the node ID is always saved for nodes.

Leaving out the loop on $i_selected, the code I would use is the following one.

$query = \Drupal::entityQuery('node')->checkAccess(FALSE);

$nids = $query->condition('type', 'level3')
  ->condition('title', $file_name)
  ->condition('status', '0')
  ->execute();

$nodes = \Drupal::entityTypeManager()->getStorage('node')->loadMultiple(array_values($nids));

foreach ($nodes as $node) {
  $node->setPublished(TRUE)->save();
}
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.