Drupal PHP Cross Reference Content Management Systems

Source: /modules/taxonomy/taxonomy.install - 882 lines - 28969 bytes - Summary - Text - Print

   1  <?php
   2  
   3  /**
   4   * @file
   5   * Install, update and uninstall functions for the taxonomy module.
   6   */
   7  
   8  /**
   9   * Implements hook_uninstall().
  10   */
  11  function taxonomy_uninstall() {
  12    // Remove variables.
  13    variable_del('taxonomy_override_selector');
  14    variable_del('taxonomy_terms_per_page_admin');
  15    // Remove taxonomy_term bundles.
  16    $vocabularies = db_query("SELECT machine_name FROM {taxonomy_vocabulary}")->fetchCol();
  17    foreach ($vocabularies as $vocabulary) {
  18      field_attach_delete_bundle('taxonomy_term', $vocabulary);
  19    }
  20  }
  21  
  22  /**
  23   * Implements hook_schema().
  24   */
  25  function taxonomy_schema() {
  26    $schema['taxonomy_term_data'] = array(
  27      'description' => 'Stores term information.',
  28      'fields' => array(
  29        'tid' => array(
  30          'type' => 'serial',
  31          'unsigned' => TRUE,
  32          'not null' => TRUE,
  33          'description' => 'Primary Key: Unique term ID.',
  34        ),
  35        'vid' => array(
  36          'type' => 'int',
  37          'unsigned' => TRUE,
  38          'not null' => TRUE,
  39          'default' => 0,
  40          'description' => 'The {taxonomy_vocabulary}.vid of the vocabulary to which the term is assigned.',
  41        ),
  42        'name' => array(
  43          'type' => 'varchar',
  44          'length' => 255,
  45          'not null' => TRUE,
  46          'default' => '',
  47          'description' => 'The term name.',
  48          'translatable' => TRUE,
  49        ),
  50        'description' => array(
  51          'type' => 'text',
  52          'not null' => FALSE,
  53          'size' => 'big',
  54          'description' => 'A description of the term.',
  55          'translatable' => TRUE,
  56        ),
  57        'format' => array(
  58          'type' => 'varchar',
  59          'length' => 255,
  60          'not null' => FALSE,
  61          'description' => 'The {filter_format}.format of the description.',
  62        ),
  63        'weight' => array(
  64          'type' => 'int',
  65          'not null' => TRUE,
  66          'default' => 0,
  67          'description' => 'The weight of this term in relation to other terms.',
  68        ),
  69      ),
  70      'primary key' => array('tid'),
  71      'foreign keys' => array(
  72        'vocabulary' => array(
  73          'table' => 'taxonomy_vocabulary',
  74          'columns' => array('vid' => 'vid'),
  75        ),
  76      ),
  77      'indexes' => array(
  78        'taxonomy_tree' => array('vid', 'weight', 'name'),
  79        'vid_name' => array('vid', 'name'),
  80        'name' => array('name'),
  81      ),
  82    );
  83  
  84    $schema['taxonomy_term_hierarchy'] = array(
  85      'description' => 'Stores the hierarchical relationship between terms.',
  86      'fields' => array(
  87        'tid' => array(
  88          'type' => 'int',
  89          'unsigned' => TRUE,
  90          'not null' => TRUE,
  91          'default' => 0,
  92          'description' => 'Primary Key: The {taxonomy_term_data}.tid of the term.',
  93        ),
  94        'parent' => array(
  95          'type' => 'int',
  96          'unsigned' => TRUE,
  97          'not null' => TRUE,
  98          'default' => 0,
  99          'description' => "Primary Key: The {taxonomy_term_data}.tid of the term's parent. 0 indicates no parent.",
 100        ),
 101      ),
 102      'indexes' => array(
 103        'parent' => array('parent'),
 104      ),
 105      'foreign keys' => array(
 106        'taxonomy_term_data' => array(
 107          'table' => 'taxonomy_term_data',
 108          'columns' => array('tid' => 'tid'),
 109        ),
 110      ),
 111      'primary key' => array('tid', 'parent'),
 112    );
 113  
 114    $schema['taxonomy_vocabulary'] = array(
 115      'description' => 'Stores vocabulary information.',
 116      'fields' => array(
 117        'vid' => array(
 118          'type' => 'serial',
 119          'unsigned' => TRUE,
 120          'not null' => TRUE,
 121          'description' => 'Primary Key: Unique vocabulary ID.',
 122        ),
 123        'name' => array(
 124          'type' => 'varchar',
 125          'length' => 255,
 126          'not null' => TRUE,
 127          'default' => '',
 128          'description' => 'Name of the vocabulary.',
 129          'translatable' => TRUE,
 130        ),
 131        'machine_name' => array(
 132          'type' => 'varchar',
 133          'length' => 255,
 134          'not null' => TRUE,
 135          'default' => '',
 136          'description' => 'The vocabulary machine name.',
 137        ),
 138        'description' => array(
 139          'type' => 'text',
 140          'not null' => FALSE,
 141          'size' => 'big',
 142          'description' => 'Description of the vocabulary.',
 143          'translatable' => TRUE,
 144        ),
 145        'hierarchy' => array(
 146          'type' => 'int',
 147          'unsigned' => TRUE,
 148          'not null' => TRUE,
 149          'default' => 0,
 150          'size' => 'tiny',
 151          'description' => 'The type of hierarchy allowed within the vocabulary. (0 = disabled, 1 = single, 2 = multiple)',
 152        ),
 153        'module' => array(
 154          'type' => 'varchar',
 155          'length' => 255,
 156          'not null' => TRUE,
 157          'default' => '',
 158          'description' => 'The module which created the vocabulary.',
 159        ),
 160        'weight' => array(
 161          'type' => 'int',
 162          'not null' => TRUE,
 163          'default' => 0,
 164          'description' => 'The weight of this vocabulary in relation to other vocabularies.',
 165        ),
 166      ),
 167      'primary key' => array('vid'),
 168      'indexes' => array(
 169        'list' => array('weight', 'name'),
 170      ),
 171      'unique keys' => array(
 172        'machine_name' => array('machine_name'),
 173      ),
 174    );
 175  
 176    $schema['taxonomy_index'] = array(
 177      'description' => 'Maintains denormalized information about node/term relationships.',
 178      'fields' => array(
 179        'nid' => array(
 180          'description' => 'The {node}.nid this record tracks.',
 181          'type' => 'int',
 182          'unsigned' => TRUE,
 183          'not null' => TRUE,
 184          'default' => 0,
 185        ),
 186        'tid' => array(
 187           'description' => 'The term ID.',
 188           'type' => 'int',
 189           'unsigned' => TRUE,
 190           'not null' => TRUE,
 191           'default' => 0,
 192        ),
 193        'sticky' => array(
 194          'description' => 'Boolean indicating whether the node is sticky.',
 195          'type' => 'int',
 196          'not null' => FALSE,
 197          'default' => 0,
 198          'size' => 'tiny',
 199        ),
 200        'created' => array(
 201          'description' => 'The Unix timestamp when the node was created.',
 202          'type' => 'int',
 203          'not null' => TRUE,
 204          'default'=> 0,
 205        ),
 206      ),
 207      'indexes' => array(
 208        'term_node' => array('tid', 'sticky', 'created'),
 209        'nid' => array('nid'),
 210      ),
 211      'foreign keys' => array(
 212        'tracked_node' => array(
 213          'table' => 'node',
 214          'columns' => array('nid' => 'nid'),
 215        ),
 216        'term' => array(
 217          'table' => 'taxonomy_term_data',
 218          'columns' => array('tid' => 'tid'),
 219        ),
 220      ),
 221    );
 222  
 223    return $schema;
 224  }
 225  
 226  /**
 227   * Implements hook_field_schema().
 228   */
 229  function taxonomy_field_schema($field) {
 230    return array(
 231      'columns' => array(
 232        'tid' => array(
 233          'type' => 'int',
 234          'unsigned' => TRUE,
 235          'not null' => FALSE,
 236        ),
 237      ),
 238      'indexes' => array(
 239        'tid' => array('tid'),
 240      ),
 241      'foreign keys' => array(
 242        'tid' => array(
 243          'table' => 'taxonomy_term_data',
 244          'columns' => array('tid' => 'tid'),
 245        ),
 246      ),
 247    );
 248  }
 249  
 250  /**
 251   * Implements hook_update_dependencies().
 252   */
 253  function taxonomy_update_dependencies() {
 254    // taxonomy_update_7004() migrates taxonomy term data to fields and therefore
 255    // must run after all Field modules have been enabled, which happens in
 256    // system_update_7027().
 257    $dependencies['taxonomy'][7004] = array(
 258      'system' => 7027,
 259    );
 260  
 261    return $dependencies;
 262  }
 263  
 264  /**
 265   * Utility function: get the list of vocabularies directly from the database.
 266   *
 267   * This function is valid for a database schema version 7002.
 268   *
 269   * @ingroup update_api
 270   */
 271  function _update_7002_taxonomy_get_vocabularies() {
 272    return db_query('SELECT v.* FROM {taxonomy_vocabulary} v ORDER BY v.weight, v.name')->fetchAllAssoc('vid', PDO::FETCH_OBJ);
 273  }
 274  
 275  /**
 276   * Rename taxonomy tables.
 277   */
 278  function taxonomy_update_7001() {
 279    db_rename_table('term_data', 'taxonomy_term_data');
 280    db_rename_table('term_hierarchy', 'taxonomy_term_hierarchy');
 281    db_rename_table('term_node', 'taxonomy_term_node');
 282    db_rename_table('term_relation', 'taxonomy_term_relation');
 283    db_rename_table('term_synonym', 'taxonomy_term_synonym');
 284    db_rename_table('vocabulary', 'taxonomy_vocabulary');
 285    db_rename_table('vocabulary_node_types', 'taxonomy_vocabulary_node_type');
 286  }
 287  
 288  /**
 289   * Add {vocabulary}.machine_name column.
 290   */
 291  function taxonomy_update_7002() {
 292    $field = array(
 293      'type' => 'varchar',
 294      'length' => 255,
 295      'not null' => TRUE,
 296      'default' => '',
 297      'description' => 'The vocabulary machine name.',
 298    );
 299  
 300    db_add_field('taxonomy_vocabulary', 'machine_name', $field);
 301  
 302    // Do a direct query here, rather than calling taxonomy_get_vocabularies(),
 303    // in case Taxonomy module is disabled.
 304    $vids = db_query('SELECT vid FROM {taxonomy_vocabulary}')->fetchCol();
 305    foreach ($vids as $vid) {
 306      $machine_name = 'vocabulary_' . $vid;
 307      db_update('taxonomy_vocabulary')
 308        ->fields(array('machine_name' => $machine_name))
 309        ->condition('vid', $vid)
 310        ->execute();
 311    }
 312  
 313    // The machine_name unique key can only be added after we ensure the
 314    // machine_name column contains unique values.
 315    db_add_unique_key('taxonomy_vocabulary', 'machine_name', array('machine_name'));
 316  }
 317  
 318  /**
 319   * Remove the related terms setting from vocabularies.
 320   *
 321   * This setting has not been used since Drupal 6. The {taxonomy_relations} table
 322   * itself is retained to allow for data to be upgraded.
 323   */
 324  function taxonomy_update_7003() {
 325    db_drop_field('taxonomy_vocabulary', 'relations');
 326  }
 327  
 328  /**
 329   * Move taxonomy vocabulary associations for nodes to fields and field instances.
 330   */
 331  function taxonomy_update_7004() {
 332    $taxonomy_index = array(
 333      'description' => 'Maintains denormalized information about node/term relationships.',
 334      'fields' => array(
 335        'nid' => array(
 336          'description' => 'The {node}.nid this record tracks.',
 337          'type' => 'int',
 338          'unsigned' => TRUE,
 339          'not null' => TRUE,
 340          'default' => 0,
 341        ),
 342        'tid' => array(
 343           'description' => 'The term ID.',
 344           'type' => 'int',
 345           'unsigned' => TRUE,
 346           'not null' => TRUE,
 347           'default' => 0,
 348        ),
 349        'sticky' => array(
 350          'description' => 'Boolean indicating whether the node is sticky.',
 351          'type' => 'int',
 352          'not null' => FALSE,
 353          'default' => 0,
 354          'size' => 'tiny',
 355        ),
 356        'created' => array(
 357          'description' => 'The Unix timestamp when the node was created.',
 358          'type' => 'int',
 359          'unsigned' => TRUE,
 360          'not null' => TRUE,
 361          'default'=> 0,
 362        ),
 363      ),
 364      'indexes' => array(
 365        'term_node' => array('tid', 'sticky', 'created'),
 366        'nid' => array('nid'),
 367      ),
 368      'foreign keys' => array(
 369        'tracked_node' => array(
 370          'table' => 'node',
 371          'columns' => array('nid' => 'nid'),
 372        ),
 373        'term' => array(
 374          'table' => 'taxonomy_term_data',
 375          'columns' => array('tid' => 'tid'),
 376        ),
 377      ),
 378    );
 379    db_create_table('taxonomy_index', $taxonomy_index);
 380  
 381    // Use an inline version of Drupal 6 taxonomy_get_vocabularies() here since
 382    // we can no longer rely on $vocabulary->nodes from the API function.
 383    $result = db_query('SELECT v.*, n.type FROM {taxonomy_vocabulary} v LEFT JOIN {taxonomy_vocabulary_node_type} n ON v.vid = n.vid ORDER BY v.weight, v.name');
 384    $vocabularies = array();
 385    foreach ($result as $record) {
 386      // If no node types are associated with a vocabulary, the LEFT JOIN will
 387      // return a NULL value for type.
 388      if (isset($record->type)) {
 389        $node_types[$record->vid][$record->type] = $record->type;
 390        unset($record->type);
 391        $record->nodes = $node_types[$record->vid];
 392      }
 393      elseif (!isset($record->nodes)) {
 394        $record->nodes = array();
 395      }
 396      $vocabularies[$record->vid] = $record;
 397    }
 398  
 399    foreach ($vocabularies as $vocabulary) {
 400      $field_name = 'taxonomy_' . $vocabulary->machine_name;
 401      $field = array(
 402        'field_name' => $field_name,
 403        'module' => 'taxonomy',
 404        'type' => 'taxonomy_term_reference',
 405        'cardinality' => $vocabulary->multiple || $vocabulary->tags ? FIELD_CARDINALITY_UNLIMITED : 1,
 406        'settings' => array(
 407          'required' => $vocabulary->required ? TRUE : FALSE,
 408          'allowed_values' => array(
 409            array(
 410              'vocabulary' => $vocabulary->machine_name,
 411              'parent' => 0,
 412            ),
 413          ),
 414        ),
 415      );
 416      _update_7000_field_create_field($field);
 417  
 418      foreach ($vocabulary->nodes as $bundle) {
 419        $instance = array(
 420          'label' => $vocabulary->name,
 421          'field_name' => $field_name,
 422          'bundle' => $bundle,
 423          'entity_type' => 'node',
 424          'settings' => array(),
 425          'description' => $vocabulary->help,
 426          'required' => $vocabulary->required,
 427          'widget' => array(),
 428          'display' => array(
 429            'default' => array(
 430              'type' => 'taxonomy_term_reference_link',
 431              'weight' => 10,
 432            ),
 433            'teaser' => array(
 434              'type' => 'taxonomy_term_reference_link',
 435              'weight' => 10,
 436            ),
 437          ),
 438        );
 439        if ($vocabulary->tags) {
 440          $instance['widget'] = array(
 441            'type' => 'taxonomy_autocomplete',
 442            'module' => 'taxonomy',
 443            'settings' => array(
 444              'size' => 60,
 445              'autocomplete_path' => 'taxonomy/autocomplete',
 446            ),
 447          );
 448        }
 449        else {
 450          $instance['widget'] = array(
 451            'type' => 'select',
 452            'module' => 'options',
 453            'settings' => array(),
 454          );
 455        }
 456        _update_7000_field_create_instance($field, $instance);
 457      }
 458    }
 459  
 460    // Some contrib projects stored term node associations without regard for the
 461    // selections in the taxonomy_vocabulary_node_types table, or have more terms
 462    // for a single node than the vocabulary allowed. We construct the
 463    // taxonomyextra field to store all the extra stuff.
 464  
 465    // Allowed values for this extra vocabs field is every vocabulary.
 466    $allowed_values = array();
 467    foreach (_update_7002_taxonomy_get_vocabularies() as $vocabulary) {
 468      $allowed_values[] = array(
 469        'vocabulary' => $vocabulary->machine_name,
 470        'parent' => 0,
 471      );
 472    }
 473  
 474    $field_name = 'taxonomyextra';
 475    $field = array(
 476      'field_name' => $field_name,
 477      'module' => 'taxonomy',
 478      'type' => 'taxonomy_term_reference',
 479      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
 480      'settings' => array(
 481        'required' => FALSE,
 482        'allowed_values' => $allowed_values,
 483      ),
 484    );
 485    _update_7000_field_create_field($field);
 486  
 487    foreach (_update_7000_node_get_types() as $bundle) {
 488      $instance = array(
 489        'label' => 'Taxonomy upgrade extras',
 490        'field_name' => $field_name,
 491        'entity_type' => 'node',
 492        'bundle' => $bundle->type,
 493        'settings' => array(),
 494        'description' => 'Debris left over after upgrade from Drupal 6',
 495        'widget' => array(
 496          'type' => 'taxonomy_autocomplete',
 497          'module' => 'taxonomy',
 498          'settings' => array(),
 499        ),
 500        'display' => array(
 501          'default' => array(
 502            'type' => 'taxonomy_term_reference_link',
 503            'weight' => 10,
 504          ),
 505          'teaser' => array(
 506            'type' => 'taxonomy_term_reference_link',
 507            'weight' => 10,
 508          ),
 509        ),
 510      );
 511      _update_7000_field_create_instance($field, $instance);
 512    }
 513  
 514    $fields = array('help', 'multiple', 'required', 'tags');
 515    foreach ($fields as $field) {
 516      db_drop_field('taxonomy_vocabulary', $field);
 517    }
 518  }
 519  
 520  /**
 521   * Migrate {taxonomy_term_node} table to field storage.
 522   *
 523   * @todo: This function can possibly be made much faster by wrapping a
 524   * transaction around all the inserts.
 525   */
 526  function taxonomy_update_7005(&$sandbox) {
 527    // $sandbox contents:
 528    // - total: The total number of term_node relationships to migrate.
 529    // - count: The number of term_node relationships that have been
 530    //   migrated so far.
 531    // - last: The db_query_range() offset to use when querying
 532    //   term_node; this field is incremented in quantities of $batch
 533    //   (1000) but at the end of each call to this function, last and
 534    //   count are the same.
 535    // - vocabularies: An associative array mapping vocabulary id and node
 536    //   type to field name. If a voc id/node type pair does not appear
 537    //   in this array but a term_node relationship exists mapping a
 538    //   term in voc id to node of that type, the relationship is
 539    //   assigned to the taxonomymyextra field which allows terms of all
 540    //   vocabularies.
 541    // - cursor[values], cursor[deltas]: The contents of $values and
 542    //   $deltas at the end of the previous call to this function. These
 543    //   need to be preserved across calls because a single batch of
 544    //   1000 rows from term_node may end in the middle of the terms for
 545    //   a single node revision.
 546    //
 547    // $values is the array of values about to be/most recently inserted
 548    // into the SQL data table for the taxonomy_term_reference
 549    // field. Before $values is constructed for each record, the
 550    // $values from the previous insert is checked to see if the two
 551    // records are for the same node revision id; this enables knowing
 552    // when to reset the delta counters which are incremented across all
 553    // terms for a single field on a single revision, but reset for each
 554    // new field and revision.
 555    //
 556    // $deltas is an associative array mapping field name to the number
 557    // of term references stored so far for the current revision, which
 558    // provides the delta value for each term reference data insert. The
 559    // deltas are reset for each new revision.
 560    
 561    $conditions = array(
 562      'type' => 'taxonomy_term_reference',
 563      'deleted' => 0,
 564    );
 565    $field_info = _update_7000_field_read_fields($conditions, 'field_name');
 566  
 567    // This is a multi-pass update. On the first call we need to initialize some
 568    // variables.
 569    if (!isset($sandbox['total'])) {
 570      $sandbox['last'] = 0;
 571      $sandbox['count'] = 0;
 572  
 573      // Run the same joins as the query that is used later to retrieve the
 574      // term_node data, this ensures that bad records in that table - for
 575      // tids which aren't in taxonomy_term_data or nids which aren't in {node}
 576      // are not included in the count.
 577      $sandbox['total'] = db_query('SELECT COUNT(*) FROM {taxonomy_term_data} td INNER JOIN {taxonomy_term_node} tn ON td.tid = tn.tid INNER JOIN {node} n ON tn.nid = n.nid LEFT JOIN {node} n2 ON tn.vid = n2.vid')->fetchField();
 578  
 579      // Use an inline version of Drupal 6 taxonomy_get_vocabularies() here since
 580      // we can no longer rely on $vocabulary->nodes from the API function.
 581      $result = db_query('SELECT v.vid, v.machine_name, n.type FROM {taxonomy_vocabulary} v INNER JOIN {taxonomy_vocabulary_node_type} n ON v.vid = n.vid');
 582      $vocabularies = array();
 583      foreach ($result as $record) {
 584  
 585        // If no node types are associated with a vocabulary, the LEFT JOIN will
 586        // return a NULL value for type.
 587        if (isset($record->type)) {
 588          $vocabularies[$record->vid][$record->type] = 'taxonomy_'. $record->machine_name;
 589        }
 590      }
 591  
 592      if (!empty($vocabularies)) {
 593        $sandbox['vocabularies'] = $vocabularies;
 594      }
 595  
 596      db_create_table('taxonomy_update_7005', array(
 597        'description' => 'Stores temporary data for taxonomy_update_7005.',
 598        'fields' => array(
 599          'n' => array(
 600            'description' => 'Preserve order.',
 601            'type' => 'serial',
 602            'unsigned' => TRUE,
 603            'not null' => TRUE,
 604          ),
 605          'vocab_id' => array(
 606            'type' => 'int',
 607            'unsigned' => TRUE,
 608            'not null' => TRUE,
 609            'default' => 0,
 610          ),
 611          'tid' => array(
 612            'type' => 'int',
 613            'unsigned' => TRUE,
 614            'not null' => TRUE,
 615          ),
 616          'nid' => array(
 617            'type' => 'int',
 618            'unsigned' => TRUE,
 619            'not null' => TRUE,
 620          ),
 621          'vid' => array(
 622            'type' => 'int',
 623            'unsigned' => TRUE,
 624            'not null' => FALSE,
 625            'default' => NULL,
 626          ),
 627          'type' => array(
 628            'type' => 'varchar',
 629            'length' => 32,
 630            'not null' => TRUE,
 631            'default' => '',
 632          ),
 633          'created' => array(
 634            'type' => 'int',
 635            'not null' => FALSE,
 636          ),
 637          'sticky' => array(
 638            'type' => 'int',
 639            'not null' => FALSE,
 640          ),
 641          'is_current' => array(
 642            'type' => 'int',
 643            'unsigned' => TRUE,
 644            'not null' => FALSE,
 645          ),
 646        ),
 647        'primary key' => array('n'),
 648      ));
 649  
 650      // Query selects all revisions at once and processes them in revision and
 651      // term weight order.
 652      $query = db_select('taxonomy_term_data', 'td');
 653      // We are migrating term-node relationships. If there are none for a
 654      // term, we do not need the term_data row.
 655      $query->join('taxonomy_term_node', 'tn', 'td.tid = tn.tid');
 656      // If a term-node relationship exists for a nid that does not exist, we
 657      // cannot migrate it as we have no node to relate it to; thus we do not
 658      // need that row from term_node.
 659      $query->join('node', 'n', 'tn.nid = n.nid');
 660      // If the current term-node relationship is for the current revision of
 661      // the node, this left join will match and is_current will be non-NULL
 662      // (we also get the current sticky and created in this case). This
 663      // tells us whether to insert into the current data tables in addition
 664      // to the revision data tables.
 665      $query->leftJoin('node', 'n2', 'tn.vid = n2.vid');
 666      $query->addField('td', 'vid', 'vocab_id');
 667      $query->addField('td', 'tid');
 668      $query->addField('tn', 'nid');
 669      $query->addField('tn', 'vid');
 670      $query->addField('n', 'type');
 671      $query->addField('n2', 'created');
 672      $query->addField('n2', 'sticky');
 673      $query->addField('n2', 'nid', 'is_current');
 674      // This query must return a consistent ordering across multiple calls.
 675      // We need them ordered by node vid (since we use that to decide when
 676      // to reset the delta counters) and by term weight so they appear
 677      // within each node in weight order. However, tn.vid,td.weight is not
 678      // guaranteed to be unique, so we add tn.tid as an additional sort key
 679      // because tn.tid,tn.vid is the primary key of the D6 term_node table
 680      // and so is guaranteed unique. Unfortunately it also happens to be in
 681      // the wrong order which is less efficient, but c'est la vie.
 682      $query->orderBy('tn.vid');
 683      $query->orderBy('td.weight');
 684      $query->orderBy('tn.tid');
 685      db_insert('taxonomy_update_7005')
 686        ->from($query)
 687        ->execute();
 688    }
 689    else {
 690      // We do each pass in batches of 1000.
 691      $batch = 1000;
 692  
 693      $result = db_query_range('SELECT vocab_id, tid, nid, vid, type, created, sticky, is_current FROM {taxonomy_update_7005} ORDER BY n', $sandbox['last'], $batch);
 694      if (isset($sandbox['cursor'])) {
 695        $values = $sandbox['cursor']['values'];
 696        $deltas = $sandbox['cursor']['deltas'];
 697      }
 698      else {
 699        $deltas = array();
 700      }
 701      foreach ($result as $record) {
 702        $sandbox['count'] += 1;
 703  
 704        // Use the valid field for this vocabulary and node type or use the
 705        // overflow vocabulary if there is no valid field.
 706        $field_name = isset($sandbox['vocabularies'][$record->vocab_id][$record->type]) ? $sandbox['vocabularies'][$record->vocab_id][$record->type] : 'taxonomyextra';
 707        $field = $field_info[$field_name];
 708  
 709        // Start deltas from 0, and increment by one for each term attached to a
 710        // node.
 711        if (!isset($deltas[$field_name])) {
 712          $deltas[$field_name] = 0;
 713        }
 714  
 715        if (isset($values)) {
 716  
 717          // If the last inserted revision_id is the same as the current record,
 718          // use the previous deltas to calculate the next delta.
 719          if ($record->vid == $values[2]) {
 720  
 721            // For limited cardinality fields, the delta must not be allowed to
 722            // exceed the cardinality during the update. So ensure that the
 723            // delta about to be inserted is within this limit.
 724            // @see field_default_validate().
 725            if ($field['cardinality'] != FIELD_CARDINALITY_UNLIMITED && ($deltas[$field_name] + 1) > $field['cardinality']) {
 726  
 727              // For excess values of a single-term vocabulary, switch over to
 728              // the overflow field.
 729              $field_name = 'taxonomyextra';
 730              $field = $field_info[$field_name];
 731              if (!isset($deltas[$field_name])) {
 732                $deltas[$field_name] = 0;
 733              }
 734            }
 735          }
 736          else {
 737  
 738            // When the record is a new revision, empty the deltas array.
 739            $deltas = array($field_name => 0);
 740          }
 741        }
 742  
 743        // Table and column found in the field's storage details. During upgrades,
 744        // it's always SQL.
 745        $table_name = "field_data_{$field_name}";
 746        $revision_name = "field_revision_{$field_name}";
 747        $value_column = $field_name . '_tid';
 748  
 749        // Column names and values in field storage are the same for current and
 750        // revision.
 751        $columns = array('entity_type', 'entity_id', 'revision_id', 'bundle', 'language', 'delta', $value_column);
 752        $values = array('node', $record->nid, $record->vid, $record->type, LANGUAGE_NONE, $deltas[$field_name]++, $record->tid);
 753  
 754        // Insert rows into the revision table.
 755        db_insert($revision_name)->fields($columns)->values($values)->execute();
 756  
 757        // is_current column is a node ID if this revision is also current.
 758        if ($record->is_current) {
 759          db_insert($table_name)->fields($columns)->values($values)->execute();
 760  
 761          // Update the {taxonomy_index} table.
 762          db_insert('taxonomy_index')
 763            ->fields(array('nid', 'tid', 'sticky', 'created',))
 764            ->values(array($record->nid, $record->tid, $record->sticky, $record->created))
 765            ->execute();
 766        }
 767      }
 768  
 769      // Store the set of inserted values and the current revision's deltas in the
 770      // sandbox.
 771      $sandbox['cursor'] = array(
 772        'values' => $values,
 773        'deltas' => $deltas,
 774      );
 775      $sandbox['last'] += $batch;
 776    }
 777  
 778    if ($sandbox['count'] < $sandbox['total']) {
 779      $sandbox['#finished'] = FALSE;
 780    }
 781    else {
 782      db_drop_table('taxonomy_vocabulary_node_type');
 783      db_drop_table('taxonomy_term_node');
 784  
 785      // If there are no vocabs, we're done.
 786      db_drop_table('taxonomy_update_7005');
 787      $sandbox['#finished'] = TRUE;
 788  
 789      // Determine necessity of taxonomyextras field.
 790      $field = $field_info['taxonomyextra'];
 791      $revision_name = 'field_revision_' . $field['field_name'];
 792      $node_types = db_select($revision_name)->distinct()->fields($revision_name, array('bundle'))
 793        ->execute()->fetchCol();
 794  
 795      if (empty($node_types)) {
 796        // Delete the overflow field if there are no rows in the revision table.
 797        _update_7000_field_delete_field('taxonomyextra');
 798      }
 799      else {
 800        // Remove instances which are not actually used.
 801        $bundles = db_query('SELECT bundle FROM {field_config_instance} WHERE field_name = :field_name', array(':field_name' => 'taxonomyextra'))->fetchCol();
 802        $bundles = array_diff($bundles, $node_types);
 803        foreach ($bundles as $bundle) {
 804          _update_7000_field_delete_instance('taxonomyextra', 'node', $bundle);
 805        }
 806      }
 807    }
 808  }
 809  
 810  /**
 811   * Add {taxonomy_term_data}.format column.
 812   */
 813  function taxonomy_update_7006() {
 814    db_add_field('taxonomy_term_data', 'format', array(
 815      'type' => 'int',
 816      'unsigned' => TRUE,
 817      'not null' => FALSE,
 818      'description' => 'The {filter_format}.format of the description.',
 819    ));
 820  }
 821  
 822  /**
 823   * Add index on {taxonomy_term_data}.name column to speed up taxonomy_get_term_by_name().
 824   */
 825  function taxonomy_update_7007() {
 826    db_add_index('taxonomy_term_data', 'name', array('name'));
 827  }
 828  
 829  /**
 830   * Change the weight columns to normal int.
 831   */
 832  function taxonomy_update_7008() {
 833    db_drop_index('taxonomy_term_data', 'taxonomy_tree');
 834    db_change_field('taxonomy_term_data', 'weight', 'weight', array(
 835      'type' => 'int',
 836      'not null' => TRUE,
 837      'default' => 0,
 838      'description' => 'The weight of this term in relation to other terms.',
 839    ), array(
 840      'indexes' => array(
 841         'taxonomy_tree' => array('vid', 'weight', 'name'),
 842      ),
 843    ));
 844  
 845    db_drop_index('taxonomy_vocabulary', 'list');
 846    db_change_field('taxonomy_vocabulary', 'weight', 'weight', array(
 847      'type' => 'int',
 848      'not null' => TRUE,
 849      'default' => 0,
 850      'description' => 'The weight of this vocabulary in relation to other vocabularies.',
 851    ), array(
 852      'indexes' => array(
 853        'list' => array('weight', 'name'),
 854      ),
 855    ));
 856  }
 857  
 858  /**
 859   * Change {taxonomy_term_data}.format into varchar.
 860   */
 861  function taxonomy_update_7009() {
 862    db_change_field('taxonomy_term_data', 'format', 'format', array(
 863      'type' => 'varchar',
 864      'length' => 255,
 865      'not null' => FALSE,
 866      'description' => 'The {filter_format}.format of the description.',
 867    ));
 868  }
 869  
 870  /**
 871   * Change {taxonomy_index}.created to support signed int.
 872  */
 873  function taxonomy_update_7010() {
 874    db_change_field('taxonomy_index', 'created', 'created', array(
 875      'description' => 'The Unix timestamp when the node was created.',
 876      'type' => 'int',
 877      'unsigned' => FALSE,
 878      'not null' => TRUE,
 879      'default'=> 0,
 880    ));
 881  }
 882  

title

Description

title

Description

title

Description

title

title

Body