You are here

function commerce_product_update_7103 in Commerce Core 7

Add support for product revisions.

File

modules/product/commerce_product.install, line 247

Code

function commerce_product_update_7103(&$sandbox) {
  if (!isset($sandbox['progress'])) {
    $commerce_product_revision_schema = array(
      'description' => 'Saves information about each saved revision of a {commerce_product}.',
      'fields' => array(
        'product_id' => array(
          'description' => 'The {commerce_product}.product_id of the product this revision belongs to.',
          'type' => 'int',
          'unsigned' => TRUE,
          'not null' => TRUE,
          'default' => 0,
        ),
        'revision_id' => array(
          'description' => 'The primary identifier for this revision.',
          'type' => 'serial',
          'unsigned' => TRUE,
          'not null' => TRUE,
        ),
        'sku' => array(
          'description' => 'The unique, human-readable identifier of a product for this revision.',
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
        ),
        'title' => array(
          'description' => 'The title of this product for this revision',
          'type' => 'varchar',
          'length' => 255,
          'not null' => TRUE,
          'default' => '',
        ),
        'revision_uid' => array(
          'description' => 'The {users}.uid that owns the product at this revision.',
          'type' => 'int',
          'not null' => TRUE,
          'default' => 0,
        ),
        'status' => array(
          'description' => 'The status of this revision.',
          'type' => 'int',
          'size' => 'tiny',
          'not null' => TRUE,
          'default' => 1,
        ),
        'log' => array(
          'description' => 'The log entry explaining the changes in this version.',
          'type' => 'text',
          'not null' => TRUE,
          'size' => 'big',
        ),
        'revision_timestamp' => array(
          'description' => 'The Unix timestamp when this revision was created.',
          'type' => 'int',
          'not null' => TRUE,
          'default' => 0,
        ),
        'data' => array(
          'type' => 'blob',
          'not null' => FALSE,
          'size' => 'big',
          'serialize' => TRUE,
          'description' => 'A serialized array of additional data for this revision.',
        ),
      ),
      'primary key' => array(
        'revision_id',
      ),
      'indexes' => array(
        'product_id' => array(
          'product_id',
        ),
        'revision_uid' => array(
          'revision_uid',
        ),
      ),
      'foreign keys' => array(
        'product' => array(
          'table' => 'commerce_product',
          'columns' => array(
            'product_id' => 'product_id',
          ),
        ),
        'owner' => array(
          'table' => 'users',
          'columns' => array(
            'revision_uid' => 'uid',
          ),
        ),
      ),
    );
    if (!db_table_exists('commerce_product_revision')) {
      db_create_table('commerce_product_revision', $commerce_product_revision_schema);
    }

    // If another module had added a {commerce_product}.revision_id field,
    // then change it to the expected specification. Otherwise, add the field.
    $product_revision_id_spec = array(
      'description' => 'The current {commerce_product_revision}.revision_id version identifier.',
      'type' => 'int',
      'unsigned' => TRUE,
      'not null' => FALSE,
      'default' => NULL,
    );
    if (db_field_exists('commerce_product', 'revision_id')) {

      // db_change_field() will fail if any records have type = NULL, so update
      // them to the new default value.
      db_update('commerce_product')
        ->fields(array(
        'revision_id' => $product_revision_id_spec['default'],
      ))
        ->isNull('revision_id')
        ->execute();

      // Indexes using a field being changed must be dropped prior to calling
      // db_change_field(). However, the database API doesn't provide a way to do
      // this without knowing what the old indexes are. Therefore, it is the
      // responsibility of the module that added them to drop them prior to
      // allowing this module to be updated.
      db_change_field('commerce_product', 'revision_id', 'revision_id', $product_revision_id_spec);
    }
    else {
      db_add_field('commerce_product', 'revision_id', $product_revision_id_spec);
    }
    if (!db_index_exists('commerce_product', 'revision_id')) {
      db_add_unique_key('commerce_product', 'revision_id', array(
        'revision_id',
      ));
    }
  }
  $max_products = db_query('SELECT COUNT(DISTINCT product_id) FROM {commerce_product}')
    ->fetchField();

  // If we have already products in the {commerce_product} table we must create
  // the current revision for them.
  if ($max_products) {
    if (!isset($sandbox['progress'])) {
      $sandbox['progress'] = 0;
      $sandbox['current_product_id'] = 0;
      $sandbox['max'] = $max_products;
    }
    $products = db_select('commerce_product', 'cp')
      ->fields('cp', array(
      'product_id',
      'sku',
      'title',
      'uid',
      'status',
      'created',
      'data',
    ))
      ->condition('product_id', $sandbox['current_product_id'], '>')
      ->range(0, 50)
      ->orderBy('product_id', 'ASC')
      ->execute()
      ->fetchAllAssoc('product_id', PDO::FETCH_ASSOC);
    foreach ($products as $product) {

      // The log can't be empty.
      $product['log'] = '';
      $product['revision_uid'] = $product['uid'];
      $product['revision_timestamp'] = $product['created'];
      unset($product['uid']);
      unset($product['created']);
      $revision_id = db_insert('commerce_product_revision')
        ->fields($product)
        ->execute();
      db_update('commerce_product')
        ->fields(array(
        'revision_id' => $revision_id,
      ))
        ->condition('product_id', $product['product_id'])
        ->execute();
      $sandbox['progress']++;
      $sandbox['current_product_id'] = $product['product_id'];
    }
    if (empty($sandbox['progress']) || $sandbox['progress'] == $max_products) {
      $sandbox['progress'] = $sandbox['max'];
    }
    $sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['progress'] / $sandbox['max'];
  }
  return t('The update for commerce product revisions ran successfully.');
}