<?php

/**
 * All the articles that used to have the "citation" field populated in the new
 * site will have the term "Geo Original" and those who haven't will receive
 * the "Repost" term.
 */
use Drupal\node\Entity\node;
use Drupal\taxonomy\Entity\Term;
use Drupal\Core\Database\Database;

$term_repost = create_term_if_not_exists('Repost', 'article_type');
$term_geo_original = create_term_if_not_exists('GEO Original', 'article_type');

$repost_entities = getArticleEntities(FALSE);
$original_entities = getArticleEntities(TRUE);

// Add the term to all the entities that hasn't a value in the citation field.
apply_term($term_repost->id(), $repost_entities);
apply_term($term_geo_original->id(), $original_entities);

/**
 * Return a list of entities depending if it  used to have populated the field
 * citation in the old site.
 */
function getArticleEntities($has_citation = FALSE) {
  if ($has_citation) {
    $condition = 'IS NOT NULL';
  }
  else {
    $condition = 'IS NULL';
  }

  $db = Database::getConnection('default', 'drupal7');
  $query = $db->query("
  SELECT 
    n.nid 
  FROM  
    node as n 
  LEFT JOIN 
    field_data_field_citiations as  fdfc 
  ON 
    (n.nid = fdfc.entity_id)   
  WHERE n.type = 'story' 
  AND 
  fdfc.field_citiations_value " . $condition . ";"
  );
  return $query->fetchAll(PDO::FETCH_ASSOC);
}


/**
 * Return a term and create it if does not exist.
 *
 * @param string $term_name
 *   The term that is going to be loaded or created.
 * @param string $vocabulary
 *   The vocabulary of the term.
 *
 * @return \Drupal\taxonomy\Entity\Term
 */
function create_term_if_not_exists($term_name, $vocabulary) {
  $term = taxonomy_term_load_multiple_by_name($term_name, $vocabulary);
  // Create the term if it does not exist and load it.
  if (empty($term)) {
    Term::create([
      'name' => $term_name,
      'vid' => 'article_type',
    ])->save();
    $term = taxonomy_term_load_multiple_by_name($term_name, $vocabulary);
  }
  return current($term);

}

/**
 * @param int $term_id
 *   The term that is going to be applied to all the nodes.
 * @param array $entity_ids
 *   The entities which are going to receive the term.
 *
 */
function apply_term($term_id, $entity_ids) {
  foreach ($entity_ids as $entity) {
    $entity =  Node::load($entity['nid']);
    $entity_terms = $entity->get('field_article_type')->getValue();

    // Check if the entity hasn't the term already.
    $add_term = TRUE;
    foreach ($entity_terms as $term_node) {
      if ($term_node['target_id'] == $term_id) {
        $add_term = FALSE;
      }
    }
    if ($add_term == TRUE) {
      $entity_terms = array_merge($entity->get('field_article_type')->getValue(), [['target_id' => $term_id]]);
      $entity->set('field_article_type', $entity_terms);
      // Prevent this cleanup from changing the updated time of all our articles.
      $entity->setChangedTime($entity->getChangedTime());
      $entity->save();
    }

  }
}

