Skip to content

Instantly share code, notes, and snippets.

@skwashd
Last active December 21, 2015 14:18
Show Gist options
  • Save skwashd/6318281 to your computer and use it in GitHub Desktop.
Save skwashd/6318281 to your computer and use it in GitHub Desktop.
Example deploy_services diff logic. Most of the hacks needed to make this work have been documented. This is a PoC, not production ready.
<?php
/**
* Implements hook_menu().
*/
function deploy_services_client_menu() {
$items = array();
//$items['job/%wf_job/diff/entities'] = array(
// dev hack
$items['job/123/diff/entities'] = array(
'title' => 'Content diff',
'description' => 'Provide content of the job',
'page callback' => 'deploy_services_client_render_entity_diff',
'page arguments' => array(1),
// FIXME: Use real access checks.
'access callback' => TRUE,
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function deploy_services_client_base_remote_url(WfJob $job) {
return variable_get('deploy_services_client_endpoint_url');
}
function deploy_services_client_get_diff($url, $job) {
// This should be a services call, but it is a stub for tesing.
$response = deploy_services_diff_plan("job-123");
return $response;
}
/**
* Do not name this function deploy_services_client_entity_diff - it conflicts with hook_entity_diff().
*/
function deploy_services_client_render_entity_diff($job) {
$remote_url = deploy_services_client_base_remote_url($job);
$diffs = deploy_services_client_get_diff($remote_url, $job);
// TODO use a render array and themeing here.
$header = array('&nbsp;', t('Old Revision'), '&nbsp;', t('Current Revision'));
drupal_add_css(drupal_get_path('module', 'diff') . '/css/diff.default.css');
$output = '';
foreach ($diffs as $diff) {
$output .= '<h2>' . l($diff['info']['label'], $remote_url . $diff['info']['url']) . '</h2>';
foreach ($diff['diff'] as $field => $data) {
$output .= '<h3>' . filter_xss($diff['info']['fields'][$field]['label']) . '</h3>';
$output .= theme('table', array('header' => $header, 'rows' => $data));
//$output .= '<pre>' . print_r($data, TRUE) . '</pre>';
}
}
return $output;
}
// ALL THE CODE BELOW HERE GOES INTO THE deploy_services MODULE.
module_load_include('inc', 'diff', 'diff.pages');
// This will be needed in the real implementation
// module_load_include('inc', 'deploy', 'deploy.manager');
function deploy_services_diff_entity($type, $new_revision, $old_revision = NULL) {
$entity_info = entity_get_info($type);
$bundle_key = $entity_info['entity keys']['bundle'];
$revision_key = $entity_info['entity keys']['revision'];
$id_key = $entity_info['entity keys']['id'];
$results = entity_load($type, FALSE, array($revision_key => $new_revision));
$new_entity = reset($results);
if (NULL == $old_revision) {
$select = db_select($entity_info['revision table'], 'rt')
->condition($revision_key, $new_entity->{$revision_key}, '<')
->condition($id_key, $new_entity->{$id_key});
$select->addExpression("MAX({$revision_key})", 'max_rev');
$old_revision = $select->execute()
->fetchField();
}
$results = entity_load($type, FALSE, array($revision_key => $old_revision));
if ($results) {
$old_entity = reset($results);
}
else {
/*
If the old entity can't be found create a new empty one.
This a hack to make sure the diff shows new entities properly.
*/
$entity_values = array(
$id_key => $new_entity->{$id_key},
$revision_key => NULL,
$bundle_key => $new_entity->{$bundle_key},
);
$old_entity = entity_create($type, $entity_values);
field_attach_load($type, array($new_entity->{$id_key} => $old_entity), FIELD_LOAD_REVISION);
}
$context = array('entity_type' => $type);
$uri = entity_uri($type, $new_entity);
$diff = array();
$info = array(
'label' => entity_label($type, $new_entity),
'fields' => array(),
'url' => url($uri['path'], $uri['options']),
);
$entity_diff = diff_compare_entities($old_entity, $new_entity, $context);
foreach ($entity_diff as $field => $data) {
$info['fields'][$field] = field_info_instance($type, $field, $new_entity->{$bundle_key});
list($old_field, $new_field) = diff_extract_state($data);
$diff[$field] = diff_get_rows($old_field, $new_field, FALSE);
}
return array('diff' => $diff, 'info' => $info);
}
/**
* Provides a dummy list of entities.
*/
function deploy_services_get_dummy_entities() {
$entities = array();
$entities[] = array('type' => 'node', 'id' => 17, 'revision_id' => 18);
$entities[] = array('type' => 'node', 'id' => 17, 'revision_id' => 17);
$entities[] = array('type' => 'node', 'id' => 12, 'revision_id' => 12);
return $entities;
}
function deploy_services_diff_plan($plan_name) {
$diffs = array();
// Load the real plan - commented out for now
// $entities = deploy_manager_get_entities($plan_name);
// Dummy function for PoC
$entities = deploy_services_get_dummy_entities();
foreach ($entities as $entity) {
$diffs["{$entity['type']}-{$entity['revision_id']}"] = deploy_services_diff_entity($entity['type'], $entity['revision_id']);
}
return $diffs;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment