You are here

public function NodeOrderManager::addToList in Node Order 8

Push new or newly orderable node to the top of ordered list.

Parameters

\Drupal\node\NodeInterface $node: The node to add to the top of the list.

int $tid: The term ID to order the node in.

Overrides NodeOrderManagerInterface::addToList

File

src/NodeOrderManager.php, line 57

Class

NodeOrderManager
Defines a service that creates & manages node ordering within taxonomy terms.

Namespace

Drupal\nodeorder

Code

public function addToList(NodeInterface $node, $tid) {

  // Append new orderable node. Get the cached weights.
  $weights = $this
    ->getTermMinMax($tid);
  \Drupal::database()
    ->update('taxonomy_index')
    ->fields([
    'weight' => $weights['min'] - 1,
  ])
    ->condition('nid', $node
    ->id())
    ->condition('tid', $tid)
    ->execute();

  // If new node out of range, push top nodes down filling the order gap
  // this is when old list's min weight is top range
  // except when new orderable node increases range (new list is not even).
  $taxonomy_nids = \Drupal::database()
    ->select('taxonomy_index', 'ti')
    ->fields('ti', [
    'nid',
  ])
    ->condition('ti.tid', $tid)
    ->orderBy('ti.weight')
    ->execute()
    ->fetchCol('nid');
  $new_node_out_of_range = count($taxonomy_nids) % 2 == 0 && $weights['min'] == -ceil(count($taxonomy_nids) / 2);
  if ($new_node_out_of_range) {

    // Collect top nodes. Note that while the node data is not yet updated
    // in the database, the taxonomy is.
    $top_range_nids = [];
    $previous_weight = $weights['min'] - 2;
    foreach ($taxonomy_nids as $taxonomy_nid) {
      $taxonomy_node_weight = \Drupal::database()
        ->select('taxonomy_index', 'i')
        ->fields('i', [
        'weight',
      ])
        ->condition('tid', $tid)
        ->condition('nid', $taxonomy_nid)
        ->execute()
        ->fetchField();
      if ($taxonomy_node_weight > $previous_weight + 1) {
        break;
      }
      $previous_weight = $taxonomy_node_weight;
      $top_range_nids[] = $taxonomy_nid;
    }

    // Move top nodes down.
    $query = \Drupal::database()
      ->update('taxonomy_index');
    $query
      ->expression('weight', 'weight + 1');
    $query
      ->condition('nid', $top_range_nids, 'IN')
      ->condition('tid', $tid)
      ->execute();
  }

  // Make sure the weight cache is invalidated.
  $this
    ->getTermMinMax($tid, TRUE);
}