function workbench_scheduler_update_7200 in Workbench Scheduler 7.2
Update from 7.x-1.x version to 7.x-2.0 version.
File
- ./
workbench_scheduler.install, line 120 - Contains install and update functions for workbench_scheduler.
Code
function workbench_scheduler_update_7200(&$sandbox) {
$message = t('Workbench Scheduler updates completed.');
// First pass, no progress set.
if (!isset($sandbox['phase'])) {
// Check to see if old fields exist. Only run update if upgrading from 1.x.
if (db_field_exists('workbench_scheduler_schedules', 'start_state')) {
// Set phase.
$sandbox['phase'] = 1;
}
else {
//Can skip updating.
$sandbox['phase'] = 6;
}
$sandbox['max_phases'] = 6;
}
// Change actions based on phase.
switch ($sandbox['phase']) {
// Phase one(1): Add new DB fields.
case 1:
$schema = workbench_scheduler_schema();
// Add default to prevent errors during update.
$schedule_fields = array(
'start_state',
'end_state',
);
foreach ($schedule_fields as $field) {
if (db_field_exists('workbench_scheduler_schedules', $field)) {
db_change_field('workbench_scheduler_schedules', $field, $field, array(
'type' => 'varchar',
'length' => 255,
'not null' => FALSE,
));
}
}
// Update the following fields
$node_schedule_fields = array(
'start_date',
'end_date',
);
foreach ($node_schedule_fields as $field) {
if (db_field_exists('workbench_scheduler_nodes', $field)) {
db_change_field('workbench_scheduler_nodes', $field, $field, array(
'type' => 'int',
'length' => 10,
'not null' => FALSE,
));
}
}
// Updating unique keys.
if (db_field_exists('workbench_scheduler_nodes', 'sid')) {
db_drop_unique_key('workbench_scheduler_nodes', 'vid');
db_add_unique_key('workbench_scheduler_nodes', 'vid', array(
'vid',
'sid',
));
}
// Add new Schedules DB fields.
if (!db_field_exists('workbench_scheduler_schedules', 'transition')) {
db_add_field('workbench_scheduler_schedules', 'transition', $schema['workbench_scheduler_schedules']['fields']['transition']);
}
// Add new Nodes DB fields.
if (!db_field_exists('workbench_scheduler_nodes', 'date')) {
db_add_field('workbench_scheduler_nodes', 'date', $schema['workbench_scheduler_nodes']['fields']['date']);
}
// Move onto Phase two(2).
$sandbox['phase'] = 2;
// Set current schedule.
$sandbox['current_sid'] = 0;
// Set schedule progress.
$sandbox['schedule_progress'] = 0;
// Get schedule max
$sandbox['schedule_max'] = db_query('SELECT COUNT(*) FROM {workbench_scheduler_schedules} WHERE transition IS NULL')
->fetchField();
break;
// Phase two(2): Update any existing schedules.
case 2:
$states_labels = workbench_moderation_states();
// Fetch one schedule. Only going to process one schedule at a time.
$schedule = db_select('workbench_scheduler_schedules', 's')
->fields('s', array(
'sid',
'name',
'label',
'start_state',
'end_state',
))
->condition('sid', $sandbox['current_sid'], '>')
->condition('transition', NULL)
->range(0, 1)
->orderBy('sid', 'ASC')
->execute()
->fetchObject();
if (!empty($schedule)) {
// Load the full schedule object.
$schedule = workbench_scheduler_schedules_load($schedule->sid);
// Query all the nodes assigned to the schedule and return their current state.
// All the current states are going to tbe the from_name.
$query = db_select('workbench_scheduler_nodes', 'wsn');
$query
->join('workbench_moderation_node_history', 'wmnh', 'wmnh.vid = wsn.vid');
$query
->fields('wmnh', array(
'state',
));
$query
->condition('wsn.sid', $schedule->sid)
->condition('wsn.completed', 0)
->condition('wmnh.is_current', TRUE);
$result = $query
->execute()
->fetchCol();
$names = array_unique($result);
// Define empty schedule candidate array.
$schedules = array();
// Does this schedule have start state and end state?
// If so, then we're going to use that as the basis for the from_name and
// to_name of the transition.
if (!empty($schedule->start_state) && !empty($schedule->end_state)) {
// If a schedule has a start state and an end state, then we need to
// create a new schedule that transitions from wildcard (node current state)
// state to that start state.
foreach ($names as $from_name) {
if ($from_name != $schedule->start_state) {
$info = array(
'types' => $schedule->types,
'transition' => array(
'from_name' => $from_name,
'to_name' => $schedule->start_state,
),
);
// Only add the new schedule candidate if it's not in the array.
if (!in_array($info, $schedules)) {
$schedules[] = $info;
}
}
}
$schedules[] = array(
'sid' => $schedule->sid,
'types' => $schedule->types,
'transition' => array(
'from_name' => $schedule->start_state,
'to_name' => $schedule->end_state,
),
);
}
else {
// Get the to_name value from start_state or end_state (whatever value is provided).
if (!empty($schedule->start_state)) {
$to_name = $schedule->start_state;
}
elseif (!empty($schedule->end_state)) {
$to_name = $schedule->end_state;
}
foreach ($names as $from_name) {
if ($from_name != $to_name) {
$info = array(
'types' => $schedule->types,
'transition' => array(
'from_name' => $from_name,
'to_name' => $to_name,
),
);
// Only add the new schedule candidate if it's not in the array.
if (!in_array($info, $schedules)) {
$schedules[] = $info;
}
}
}
}
// Loop through the schedule candidates and see if they already exist or need
// to be created.
foreach ($schedules as $schedule_candidate) {
$transition = $schedule_candidate['transition'];
// Fetch the transition id.
$transition_id = db_select('workbench_moderation_transitions ', 't')
->fields('t', array(
'id',
))
->condition('from_name', $transition['from_name'])
->condition('to_name', $transition['to_name'])
->range(0, 1)
->execute()
->fetchField();
// If transition doesn't exist, create it.
if (empty($transition_id)) {
$transition_id = db_insert('workbench_moderation_transitions')
->fields(array(
'name' => $states_labels[$transition['from_name']]->label . ' to ' . $states_labels[$transition['to_name']]->label,
'from_name' => $transition['from_name'],
'to_name' => $transition['to_name'],
))
->execute();
}
// If sid is set, that means the transition belongs the current schedule.
if (!empty($schedule_candidate['sid'])) {
$existing_schedule = $schedule;
}
else {
$db_or = db_or()
->condition(db_and()
->condition('start_state', '')
->condition('end_state', $transition->to_name))
->condition(db_and()
->condition('start_state', $transition->to_name)
->condition('end_state', ''));
$existing_schedule = db_select('workbench_scheduler_schedules', 's')
->fields('s', array(
'name',
'label',
))
->condition($db_or)
->isNull('transition')
->range(0, 1)
->execute()
->fetchObject();
}
// Save or update schedules.
if (!empty($existing_schedule)) {
// Load the full schedule object:
$existing_schedule_obj = workbench_scheduler_schedules_load($existing_schedule->sid);
// Merge content types.
$types = array_unique(array_merge($existing_schedule_obj->types, $schedule_candidate['types']));
$save_schedule = array(
'name' => $existing_schedule->name,
'label' => $existing_schedule->label,
'types' => $types,
'transition' => $transition_id,
);
}
else {
$save_schedule = array(
'name' => $transition['from_name'] . '_' . $transition['to_name'],
'label' => $states_labels[$transition['from_name']]->label . ' to ' . $states_labels[$transition['to_name']]->label,
'types' => $schedule_candidate['types'],
'transition' => $transition_id,
);
}
// Then save transition into schedule.
workbench_scheduler_save_schedule($save_schedule['name'], array(
'label' => $save_schedule['label'],
'types' => $save_schedule['types'],
'transition' => $transition_id,
));
}
// Move on to next schedule
$sandbox['current_sid'] = $schedule->sid;
// Update percentage complete.
$sandbox['schedule_progress']++;
}
else {
// set progress to max.
$sandbox['schedule_progress'] = $sandbox['schedule_max'];
// Go to phase four(4)
$sandbox['phase'] = 3;
// Set current node.
$sandbox['current_nid'] = 0;
// Set node progress.
$sandbox['node_progress'] = 0;
// Get node max.
$sandbox['node_max'] = db_query('SELECT COUNT(*) FROM {workbench_scheduler_nodes} WHERE `date` = 0')
->fetchField();
// Set current node.
}
break;
// Phase three(3): Update nodes.
case 3:
// Query for next nid.
$nid = db_select('workbench_scheduler_nodes', 'n')
->fields('n', array(
'nid',
))
->condition('nid', $sandbox['current_nid'], '>')
->condition('date', 0)
->orderBy('nid', 'ASC')
->execute()
->fetchField();
// Have a nid?
if ($nid) {
// Get next three(3) revisions to update.
$query = db_select('workbench_scheduler_nodes', 'wsn');
$query
->fields('wsn', array(
'sid',
'nid',
'vid',
'completed',
'start_date',
'end_date',
));
$query
->fields('wmnh', array(
'state',
));
$query
->join('workbench_moderation_node_history', 'wmnh', 'wmnh.vid = wsn.vid');
$query
->condition('wsn.nid', $nid)
->condition('wsn.date', 0)
->condition('wmnh.is_current', TRUE)
->orderBy('nid', 'ASC')
->orderBy('vid', 'ASC');
$revisions = $query
->execute();
// Have revisions?
if ($revisions
->rowCount() > 0) {
// Loop through each revision.
foreach ($revisions as $revision) {
// Has the revision already been completed?
if ($revision->completed) {
// Use end date if set, else use the start date.
$date = $revision->end_date ? $revision->end_date : $revision->start_date;
// Set the value of the date field.
db_update('workbench_scheduler_nodes')
->fields(array(
'date' => $date,
))
->condition('nid', $nid)
->condition('vid', $revision->vid)
->execute();
}
else {
// Load the schedule that is already assigned to this node.
$schedule = workbench_scheduler_schedules_load($revision->sid);
// from_name will almost always be the node's current state.
$from_name = $revision->state;
// If transition is null we need to pull the correct schedule, we'll
// use that when we save/update the node schedule.
if (empty($schedule->transition)) {
if (empty($schedule->start_state) || empty($schedule->end_state)) {
$to_name = !empty($schedule->start_state) ? $schedule->start_state : $schedule->end_state;
}
$query = db_select('workbench_scheduler_schedules', 'wss');
$query
->fields('wss', array(
'sid',
));
$query
->join('workbench_moderation_transitions', 'wmt', 'wss.transition = wmt.id');
$query
->condition('wmt.from_name', $from_name);
$query
->condition('wmt.to_name', $to_name);
$sid = $query
->execute()
->fetchField();
$schedule = workbench_scheduler_schedules_load($sid);
}
// Load this transition.
// Get the from_name of this schedule. We'll use it as the 'two_name' for the next transition.
$transition = db_select('workbench_moderation_transitions', 'wmt')
->fields('wmt', array(
'from_name',
'to_name',
))
->condition('id', $schedule->transition)
->execute()
->fetch();
// 'to_name' will almost always be the same as the transition's to_name.
$to_name = $transition->to_name;
// If start_date and end_date have a value then we need to add
// another schedule to this.
if (!empty($revision->start_date) && !empty($revision->end_date)) {
// Update just the date on this node scheudle.
// Run a merge query to insert or update the row.
$node_schedule = array(
'sid' => $schedule->sid,
'date' => $revision->end_date,
);
workbench_scheduler_save_node_schedule($revision->nid, $revision->vid, $node_schedule);
// Insert the other schedule.
$to_name = $transition->from_name;
$date = $revision->start_date;
}
else {
$date = !empty($revision->start_date) ? $revision->start_date : $revision->end_date;
}
// Grab the appropriate schedule and transition. We may be
// updating or inserting a node schedule depending on whether we find it.
$query = db_select('workbench_scheduler_schedules', 'wss')
->fields('wss', array(
'sid',
));
$query
->join('workbench_moderation_transitions', 'wmt', 'wss.transition = wmt.id');
$query
->condition('wmt.from_name', $from_name)
->condition('wmt.to_name', $to_name);
$sid = $query
->execute()
->fetchField();
if (!empty($sid)) {
// Saving the new node schedule.
$node_schedule = array(
'sid' => $sid,
'date' => $date,
);
// Run a merge query to insert or update the row.
workbench_scheduler_save_node_schedule($revision->nid, $revision->vid, $node_schedule);
}
}
$sandbox['node_progress']++;
}
}
$sandbox['current_nid'] = $nid;
}
else {
// Set progress to max.
$sandbox['node_progress'] = $sandbox['node_max'];
// Set message.
$message = t('All Workbench Scheduler nodes updated.');
// Go to phase five(5)
$sandbox['phase'] = 4;
}
break;
// Phase four(4): Remove any schedules that have NULL for transition.
case 4:
// Remove all schedules where transition = NULL
$names = db_select('workbench_scheduler_schedules', 's')
->fields('s', array(
'name',
))
->isNull('transition')
->execute()
->fetchCol();
if (!empty($names)) {
workbench_scheduler_delete_schedules($names);
}
else {
// Go to phase four(4)
$sandbox['phase'] = 5;
}
break;
// Phase four(4): Delete old DB fields.
case 5:
// Drop Schedule fields.
if (db_field_exists('workbench_scheduler_schedules', 'start_state')) {
db_drop_field('workbench_scheduler_schedules', 'start_state');
db_drop_field('workbench_scheduler_schedules', 'end_state');
}
// Drop node fields.
if (db_field_exists('workbench_scheduler_nodes', 'start_date')) {
db_drop_field('workbench_scheduler_nodes', 'start_date');
db_drop_field('workbench_scheduler_nodes', 'end_date');
}
$sandbox['phase'] = 6;
break;
}
$sandbox['#finished'] = $sandbox['phase'] / $sandbox['max_phases'];
return $message;
}