You are here

workbench_moderation.install in Workbench Moderation 7

Install file for the Workbench Moderation module.

File

workbench_moderation.install
View source
<?php

/**
 * @file
 * Install file for the Workbench Moderation module.
 */

/**
 * Implements hook_install().
 */
function workbench_moderation_install() {

  // Create tables.
  _workbench_moderation_insert_values();
  db_update('system')
    ->fields(array(
    'weight' => 5,
  ))
    ->condition('name', 'workbench_moderation')
    ->execute();
}

/**
 * Implements hook_uninstall().
 */
function workbench_moderation_uninstall() {

  // Delete workbench_moderation variables.
  variable_del('workbench_moderation_nodedraft_disabled');
  variable_del('workbench_moderation_per_node_type');
  variable_del('workbench_moderation_show_revision_navigation');

  // Get all node types. Loop through them and delete workbench-related variables.
  $types = node_type_get_types();
  foreach ($types as $type_object) {
    $type = $type_object->type;
    variable_del("workbench_moderation_default_state_{$type}");

    // Get node options that might hold a moderation flag.
    $node_options = variable_get("node_options_{$type}", array());
    foreach ($node_options as $key => $option) {
      if ($option === 'moderation') {
        unset($node_options[$key]);
      }
    }
    variable_set("node_options_{$type}", $node_options);
  }
}

/**
 * Implements hook_schema().
 */
function workbench_moderation_schema() {
  $schema['workbench_moderation_states'] = array(
    'description' => 'Defines all possible states',
    'fields' => array(
      'name' => array(
        'description' => 'The machine name of the moderation state.',
        'type' => 'varchar',
        'length' => '255',
        'not null' => TRUE,
      ),
      'label' => array(
        'description' => 'A label for the moderation state.',
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      ),
      'description' => array(
        'description' => 'A description of the moderation state.',
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      ),
      'weight' => array(
        'description' => 'Sort weight for the moderation state.',
        'type' => 'int',
        'default' => 0,
      ),
    ),
    'primary key' => array(
      'name',
    ),
  );
  $schema['workbench_moderation_transitions'] = array(
    'description' => 'Defines the valid transitions for states',
    'fields' => array(
      'id' => array(
        'type' => 'serial',
        'not null' => TRUE,
        'unsigned' => TRUE,
        'description' => 'Primary Key: Unique workbench_moderation transition identifier.',
      ),
      'name' => array(
        'description' => 'The machine-readable name of this workbench_moderation transition.',
        'type' => 'varchar',
        'length' => 255,
        'initial' => 'from_name',
      ),
      'from_name' => array(
        'description' => 'The starting moderation state.',
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      ),
      'to_name' => array(
        'description' => 'The ending moderation state.',
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      ),
    ),
    'primary key' => array(
      'id',
    ),
  );
  $schema['workbench_moderation_node_history'] = array(
    'fields' => array(
      'hid' => array(
        'description' => 'Node history entry key.',
        'type' => 'serial',
        'not null' => TRUE,
      ),
      'vid' => array(
        'description' => 'Node revision id. Foreign key to {node_revision}',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'nid' => array(
        'description' => 'Node id. Foreign key to {node}',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'from_state' => array(
        'description' => 'The old moderation state of the node',
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      ),
      'state' => array(
        'description' => 'The current moderation state of the node.',
        'type' => 'varchar',
        'length' => '255',
        'not null' => FALSE,
      ),
      'uid' => array(
        'description' => 'The user id of the moderator who made the change. Foreign key to {users}.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'stamp' => array(
        'description' => 'The timestamp of the change.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'published' => array(
        'description' => 'Indicated the live revision of a node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
      'is_current' => array(
        'description' => 'Indicated the current revision of a node.',
        'type' => 'int',
        'unsigned' => TRUE,
        'not null' => TRUE,
        'default' => 0,
      ),
    ),
    'primary key' => array(
      'hid',
    ),
    'indexes' => array(
      'nid' => array(
        'nid',
      ),
      'vid' => array(
        'vid',
      ),
    ),
    'foreign_keys' => array(
      'nid' => array(
        'node' => 'nid',
      ),
      'vid' => array(
        'node_revision' => 'vid',
      ),
      'uid' => array(
        'users' => 'uid',
      ),
    ),
  );
  return $schema;
}

/**
 * Adds default data for workflow states
 */
function _workbench_moderation_insert_values() {

  // Default states.
  $states = array(
    array(
      'name' => 'draft',
      'label' => 'Draft',
      'description' => 'Work in progress',
      'weight' => -99,
    ),
    array(
      'name' => 'needs_review',
      'label' => 'Needs Review',
      'description' => 'Ready for moderation',
      'weight' => 0,
    ),
    array(
      'name' => 'published',
      'label' => 'Published',
      'description' => 'Make this version live',
      'weight' => 99,
    ),
  );

  // Save default states to the database.
  $query = db_insert('workbench_moderation_states')
    ->fields(array(
    'name',
    'label',
    'description',
    'weight',
  ));
  foreach ($states as $state) {
    $query
      ->values($state);
  }
  $query
    ->execute();

  // Default transitions.
  $transitions = array(
    array(
      'name' => 'Submit for Review',
      'from_name' => 'draft',
      'to_name' => 'needs_review',
    ),
    array(
      'name' => 'Reject',
      'from_name' => 'needs_review',
      'to_name' => 'draft',
    ),
    array(
      'name' => 'Publish',
      'from_name' => 'needs_review',
      'to_name' => 'published',
    ),
  );

  // Save default transitions to the database.
  $query = db_insert('workbench_moderation_transitions')
    ->fields(array(
    'name',
    'from_name',
    'to_name',
  ));
  foreach ($transitions as $transition) {
    $query
      ->values($transition);
  }
  $query
    ->execute();
}

/**
 * Update the 'weight' field on {workbench_moderation_states}.
 *
 * Accept standard Drupal weight values.
 */
function workbench_moderation_update_7001() {
  db_change_field('workbench_moderation_states', 'weight', 'weight', array(
    'description' => 'Sort weight for the moderation state.',
    'type' => 'int',
    'default' => 0,
  ));
  return t('Updated the weight field on the moderation states table.');
}

/**
 * Drop the unused 'ntypes' field from workbench_moderation_transitions.
 */
function workbench_moderation_update_7002() {
  db_drop_field('workbench_moderation_transitions', 'ntype');
  return t('Dropped unused field from the moderation transitions table.');
}

/**
 * Use "revision" instead of "version" when referring to node revisions.
 */
function workbench_moderation_update_7003() {
  $old_permission = 'unpublish live version';
  $new_permission = 'unpublish live revision';

  // Which roles have the old permission?
  $roles = db_select('role_permission', 'role_permission')
    ->condition('permission', $old_permission)
    ->condition('module', 'workbench_moderation')
    ->fields('role_permission', array(
    'rid',
  ))
    ->execute()
    ->fetchCol();

  // Grant these roles the new permission. Normally, this would use
  // user_role_grant_permissions(), but since update hooks run regardless of
  // whether a module is enabled, we can't guarantee that workbench_moderation
  // permissions will be available when user.module invokes hook_permission().
  foreach ($roles as $rid) {
    db_merge('role_permission')
      ->key(array(
      'rid' => $rid,
      'permission' => $new_permission,
    ))
      ->fields(array(
      'module' => 'workbench_moderation',
    ))
      ->execute();
  }

  // Delete all grants of the old permission.
  db_delete('role_permission')
    ->condition('permission', $old_permission)
    ->condition('module', 'workbench_moderation')
    ->execute();
  return t('The renamed permission was updated for !count roles.', array(
    '!count' => count($roles),
  ));
}

/**
 * Use "Published" instead of "Publish" and "Needs Review" instead of "Review" for state names.
 */
function workbench_moderation_update_7004() {

  // Update workbench_moderation_states
  db_update('workbench_moderation_states')
    ->fields(array(
    'description' => 'Draft content is visible only to its author',
  ))
    ->condition('Name', 'Draft', '=')
    ->execute();
  db_update('workbench_moderation_states')
    ->fields(array(
    'Name' => 'Needs Review',
    'description' => 'Needs Review content is brought to the attention administrators and editors who may then publish it',
  ))
    ->condition('Name', 'Review', '=')
    ->execute();
  db_update('workbench_moderation_states')
    ->fields(array(
    'Name' => 'Published',
    // Normally we would use workbench_moderation_state_published(), but we can't guarantee that workbench_moderation is enabled.
    'description' => 'Published content is visible to the world',
  ))
    ->condition('Name', 'Publish', '=')
    ->execute();

  // Update workbench_moderation_transitions
  db_update('workbench_moderation_transitions')
    ->fields(array(
    'from_name' => 'Needs Review',
  ))
    ->condition('from_name', 'Review', '=')
    ->execute();
  db_update('workbench_moderation_transitions')
    ->fields(array(
    'to_name' => 'Needs Review',
  ))
    ->condition('to_name', 'Review', '=')
    ->execute();
  db_update('workbench_moderation_transitions')
    ->fields(array(
    'from_name' => 'Published',
  ))
    ->condition('from_name', 'Publish', '=')
    ->execute();
  db_update('workbench_moderation_transitions')
    ->fields(array(
    'to_name' => 'Published',
  ))
    ->condition('to_name', 'Publish', '=')
    ->execute();

  // Update workbench_moderation_node_history
  db_update('workbench_moderation_node_history')
    ->fields(array(
    'from_state' => 'Needs Review',
  ))
    ->condition('from_state', 'Review', '=')
    ->execute();
  db_update('workbench_moderation_node_history')
    ->fields(array(
    'state' => 'Needs Review',
  ))
    ->condition('state', 'Review', '=')
    ->execute();
  db_update('workbench_moderation_node_history')
    ->fields(array(
    'from_state' => 'Published',
  ))
    ->condition('from_state', 'Publish', '=')
    ->execute();
  db_update('workbench_moderation_node_history')
    ->fields(array(
    'state' => 'Published',
  ))
    ->condition('state', 'Publish', '=')
    ->execute();

  // Update role_permission table
  // Grab all of the workbench_moderation permissions
  $perms = db_select('role_permission', 'rp')
    ->fields('rp', array(
    'permission',
  ))
    ->condition('permission', '%moderate content from %', 'LIKE')
    ->execute()
    ->fetchCol();

  // This function doesn't need duplicates
  $perms = array_unique($perms);
  foreach ($perms as $key => $perm) {
    $new_perm = $perm;

    // Check that this permission hasn't had this change already
    if (!strpos($perm, 'Published')) {
      $new_perm = str_replace('Publish', 'Published', $perm);
    }

    // Check that this permission hasn't had this change already
    if (!strpos($new_perm, 'Needs Review')) {
      $new_perm = str_replace('Review', 'Needs Review', $new_perm);
    }

    //Update the records
    db_update('role_permission')
      ->fields(array(
      'permission' => $new_perm,
    ))
      ->condition('permission', $perm, '=')
      ->execute();
  }
  return t("Updated state names and transitions.");
}

/**
 * Shorten descriptions for default states
 */
function workbench_moderation_update_7005() {

  // Update workbench_moderation_states
  db_update('workbench_moderation_states')
    ->fields(array(
    'description' => 'Visible only to the author',
  ))
    ->condition('Name', 'Draft', '=')
    ->execute();
  db_update('workbench_moderation_states')
    ->fields(array(
    'description' => 'Visible to the author and editors',
  ))
    ->condition('Name', 'Needs Review', '=')
    ->execute();
  db_update('workbench_moderation_states')
    ->fields(array(
    'description' => 'Visible to the world',
  ))
    ->condition('Name', 'Published', '=')
    ->execute();
  return t("Updated state descriptions.");
}

/**
 * Add machine names to moderation states.
 */
function workbench_moderation_update_7006() {

  // Drop the unique key on name which will be converted to label.
  db_drop_unique_key('workbench_moderation_states', 'name');

  // Add the new field.
  $spec = array(
    'description' => 'A label for the moderation state.',
    'type' => 'varchar',
    'length' => '255',
    'not null' => FALSE,
  );
  db_add_field('workbench_moderation_states', 'label', $spec);

  // Transform names into machine_names, saving the original name into the new
  // 'label' field.
  $states = db_select('workbench_moderation_states', 'states')
    ->fields('states', array(
    'name',
    'label',
    'description',
    'weight',
  ))
    ->orderBy('states.weight', 'ASC')
    ->execute()
    ->fetchAllAssoc('name');
  foreach ($states as $state) {
    $machine_name = preg_replace('/[^a-z]+/', '_', strtolower($state->name));
    db_update('workbench_moderation_states')
      ->fields(array(
      'name' => $machine_name,
      'label' => $state->name,
    ))
      ->condition('name', $state->name)
      ->execute();
    db_update('workbench_moderation_transitions')
      ->fields(array(
      'from_name' => $machine_name,
    ))
      ->condition('from_name', $state->name)
      ->execute();
    db_update('workbench_moderation_transitions')
      ->fields(array(
      'to_name' => $machine_name,
    ))
      ->condition('to_name', $state->name)
      ->execute();
    db_update('workbench_moderation_node_history')
      ->fields(array(
      'from_state' => $machine_name,
    ))
      ->condition('from_state', $state->name)
      ->execute();
    db_update('workbench_moderation_node_history')
      ->fields(array(
      'state' => $machine_name,
    ))
      ->condition('state', $state->name)
      ->execute();
  }

  // Add a primary key on {workbench_moderation_states}.
  db_add_primary_key('workbench_moderation_states', array(
    'name',
  ));

  // Get content types where moderation is enabled and update
  // 'workbench_moderation_default_state_TYPE_NAME' variables
  $entity_info = entity_get_info('node');
  foreach (array_keys($entity_info['bundles']) as $content_type) {
    $options = variable_get("node_options_{$content_type}", array());
    if (in_array('revision', $options) && in_array('moderation', $options)) {
      $orig_name = variable_get('workbench_moderation_default_state_' . $content_type, 'Draft');
      $machine_name = preg_replace('/[^a-z]+/', '_', strtolower($orig_name));
      variable_set('workbench_moderation_default_state_' . $content_type, $machine_name);
    }
  }

  // Update transition permissions with new permission strings
  // Normally we would use workbench_moderation_states(), but we can't guarantee that workbench_moderation is enabled.
  $states = db_select('workbench_moderation_states', 'states')
    ->fields('states', array(
    'name',
    'label',
    'description',
    'weight',
  ))
    ->orderBy('states.weight', 'ASC')
    ->execute()
    ->fetchAllAssoc('name');

  // Normally we would use workbench_moderation_transitions(), but we can't guarantee that workbench_moderation is enabled.
  $query = db_select('workbench_moderation_transitions', 't')
    ->fields('t', array(
    'from_name',
    'to_name',
  ));
  $alias_from = $query
    ->addJoin('INNER', 'workbench_moderation_states', NULL, 't.from_name = %alias.name');
  $alias_to = $query
    ->addJoin('INNER', 'workbench_moderation_states', NULL, 't.to_name = %alias.name');
  $query
    ->orderBy("{$alias_from}.weight", 'ASC')
    ->orderBy("{$alias_to}.weight", 'ASC');
  $transitions = $query
    ->execute()
    ->fetchAll();
  foreach ($transitions as $transition) {
    $old_perm = "moderate content from {$states[$transition->from_name]->label} to {$states[$transition->to_name]->label}";
    $new_perm = "moderate content from {$transition->from_name} to {$transition->to_name}";
    db_update('role_permission')
      ->fields(array(
      'permission' => $new_perm,
    ))
      ->condition('permission', $old_perm)
      ->execute();
  }
  return t("Added column to store moderation state labels.");
}

/**
 * Replace the "Unpublish the current live revision" permission with a transition.
 */
function workbench_moderation_update_7007() {

  // Normally we would use workbench_moderation_states(), but we can't guarantee that workbench_moderation is enabled.
  $states = db_select('workbench_moderation_states', 'states')
    ->fields('states', array(
    'name',
    'label',
    'description',
    'weight',
  ))
    ->orderBy('states.weight', 'ASC')
    ->execute()
    ->fetchAllAssoc('name');

  // Add an unpublish transition from published to draft. The 'published' state
  // currently can't be deleted, but the draft state may or may not be present.
  $transition = (object) array(
    'from_name' => 'published',
    'to_name' => isset($states['draft']) ? 'draft' : key($states),
  );

  // Normally we would use workbench_moderation_transition_save(), but we can't guarantee that workbench_moderation is enabled.
  db_merge('workbench_moderation_transitions')
    ->key(array(
    'from_name' => $transition->from_name,
    'to_name' => $transition->to_name,
  ))
    ->fields((array) $transition)
    ->execute();

  // Change permission grants from the deprecated unpublish permission to the
  // new transition permission.
  $roles = user_roles(FALSE, 'unpublish live revision');
  $permissions = array(
    'unpublish live revision' => FALSE,
    "moderate content from {$transition->from_name} to {$transition->to_name}" => TRUE,
  );
  foreach ($roles as $rid => $role) {
    user_role_change_permissions($rid, $permissions);
  }
  return t("Added a new transition from %from to %to and updated unpublish permissions. Unpublishing content is now controlled by transition permissions, and roles with the 'Bypass moderation restrictions' permission may unpublish content.", array(
    '%from' => $transition->from_name,
    '%to' => $transition->to_name,
  ));
}

/**
 * Fix the not null column schema for {workbench_moderation_states}.name.
 */
function workbench_moderation_update_7008() {
  db_drop_primary_key('workbench_moderation_states');
  db_change_field('workbench_moderation_states', 'name', 'name', array(
    'description' => 'The machine name of the moderation state.',
    'type' => 'varchar',
    'length' => '255',
    'not null' => TRUE,
  ));
  db_add_primary_key('workbench_moderation_states', array(
    'name',
  ));
}

/**
 * Add new fields to workbench_moderation_transitions table.
 */
function workbench_moderation_update_7009() {
  $fields = array(
    'id' => array(
      'type' => 'serial',
      'not null' => TRUE,
      'unsigned' => TRUE,
      'description' => 'Primary Key: Unique workbench_moderation transition identifier.',
    ),
    'name' => array(
      'description' => 'The machine-readable name of this workbench_moderation transition.',
      'type' => 'varchar',
      'length' => 255,
      'initial' => 'from_name',
    ),
  );

  // Add index too.
  $index = array(
    'primary key' => array(
      'id',
    ),
  );
  db_add_field('workbench_moderation_transitions', 'id', $fields['id'], $index);
  db_add_field('workbench_moderation_transitions', 'name', $fields['name']);

  // Fill in the blanks.
  db_update('workbench_moderation_transitions')
    ->expression('name', "CONCAT(from_name, '-', to_name)")
    ->execute();
}

/**
 * Comply with SQL-99:  Rename the 'current' column to 'is_current'.
 */
function workbench_moderation_update_7010() {
  $table = 'workbench_moderation_node_history';
  $field = 'current';
  $field_new = 'is_current';
  $spec = array(
    'description' => 'Indicated the current revision of a node.',
    'type' => 'int',
    'unsigned' => TRUE,
    'not null' => TRUE,
    'default' => 0,
  );
  db_change_field($table, $field, $field_new, $spec);
  return t("Renamed 'current' column in node_history table");
}

Functions

Namesort descending Description
workbench_moderation_install Implements hook_install().
workbench_moderation_schema Implements hook_schema().
workbench_moderation_uninstall Implements hook_uninstall().
workbench_moderation_update_7001 Update the 'weight' field on {workbench_moderation_states}.
workbench_moderation_update_7002 Drop the unused 'ntypes' field from workbench_moderation_transitions.
workbench_moderation_update_7003 Use "revision" instead of "version" when referring to node revisions.
workbench_moderation_update_7004 Use "Published" instead of "Publish" and "Needs Review" instead of "Review" for state names.
workbench_moderation_update_7005 Shorten descriptions for default states
workbench_moderation_update_7006 Add machine names to moderation states.
workbench_moderation_update_7007 Replace the "Unpublish the current live revision" permission with a transition.
workbench_moderation_update_7008 Fix the not null column schema for {workbench_moderation_states}.name.
workbench_moderation_update_7009 Add new fields to workbench_moderation_transitions table.
workbench_moderation_update_7010 Comply with SQL-99: Rename the 'current' column to 'is_current'.
_workbench_moderation_insert_values Adds default data for workflow states