View source
<?php
function cmis_sync_menu() {
foreach (node_get_types() as $type) {
$type_name = $type->type;
$items['admin/settings/cmis/sync/' . $type_name] = array(
'title' => 'Sync ' . $type_name,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'cmis_sync_admin_form',
$type_name,
),
'access arguments' => array(
'administer cmis',
),
'file' => 'cmis_sync.admin.inc',
'type' => MENU_NORMAL_ITEM,
'weight' => 1,
);
}
return $items;
}
function cmis_sync_theme() {
return array(
'cmis_sync_admin_field_map_table' => array(
'arguments' => array(
'form' => NULL,
),
'file' => 'cmis_sync.theme.inc',
),
);
}
function cmis_sync_nodeapi(&$node, $op, $teaser, $page) {
if (in_array($op, array(
'insert',
'update',
'delete',
))) {
$cmis_object = _cmis_sync_drupal_to_cmis_prepare($node);
if ($cmis_object && !isset($node->cmis_sync_disabled)) {
module_load_include('api.inc', 'cmis');
switch ($op) {
case 'insert':
try {
$repository = cmisapi_getRepositoryInfo();
$cmis_parent = cmisapi_getProperties($repository->repositoryId, $cmis_object->parentId);
$cmis_objectId = cmisapi_createDocument($repository->repositoryId, $cmis_object->type, $cmis_object->properties, $cmis_parent->id, $cmis_object->content);
cmisapi_updateProperties($repository->repositoryId, $cmis_objectId, NULL, $cmis_object->properties);
} catch (CMISException $e) {
cmis_error_handler('cmis_sync_nodeapi', $e);
return;
}
db_query('INSERT INTO {cmis_sync_node} (nid, cmis_objectId, changed_timestamp) VALUES (%d, \'%s\', %d)', $node->nid, $cmis_objectId, $_SERVER['REQUEST_TIME']);
break;
case 'update':
if ($cmis_objectId = db_result(db_query('SELECT cmis_objectId FROM {cmis_sync_node} WHERE nid = %d', $node->nid))) {
try {
$repository = cmisapi_getRepositoryInfo();
cmisapi_setContentStream($repository->repositoryId, $cmis_objectId, TRUE, $cmis_object->content, $cmis_object->properties);
cmisapi_updateProperties($repository->repositoryId, $cmis_objectId, NULL, $cmis_object->properties);
} catch (CMISException $e) {
cmis_error_handler('cmis_sync_nodeapi', $e);
return;
}
db_query('UPDATE {cmis_sync_node} SET changed_timestamp=%d WHERE nid = %d', $_SERVER['REQUEST_TIME'], $node->nid);
}
break;
case 'delete':
if ($cmis_object->sync_deletes && ($cmis_objectId = db_result(db_query('SELECT cmis_objectId FROM {cmis_sync_node} WHERE nid = %d', $node->nid)))) {
try {
$repository = cmisapi_getRepositoryInfo();
$cmis_object_properties = cmisapi_getProperties($repository->repositoryId, $cmis_objectId);
cmisapi_deleteObject($repository->repositoryId, $cmis_object_properties->id);
} catch (CMISException $e) {
cmis_error_handler('cmis_sync_nodeapi', $e);
return;
}
db_query('DELETE FROM {cmis_sync_node} WHERE nid = %d', $node->nid);
}
break;
}
}
}
}
function cmis_sync_cron() {
module_load_include('api.inc', 'cmis');
module_load_include('inc', 'node', 'node.pages');
try {
$repository = cmisapi_getRepositoryInfo();
} catch (CMISException $e) {
cmis_error_handler('cmis_sync_cron', $e);
return;
}
$sync_map = variable_get('cmis_sync_map', array());
$sync_map_changed = FALSE;
foreach ($sync_map as $node_type => $sync_map_type) {
if (!array_key_exists('enabled', $sync_map_type) || !$sync_map_type['enabled']) {
continue;
}
try {
_cmis_sync_cmis_to_drupal_handle_updates($repository, $sync_map_type, $node_type);
if ($sync_map_type['deletes']) {
_cmis_sync_cmis_to_drupal_handle_deletes($repository, $sync_map_type, $node_type);
}
if ($sync_map_type['full_sync_next_cron']) {
$sync_map[$node_type]['full_sync_next_cron'] = 0;
$sync_map_changed = TRUE;
}
} catch (CMISException $e) {
cmis_error_handler('cmis_sync_cron', $e);
}
}
if ($sync_map_changed) {
variable_set('cmis_sync_map', $sync_map);
}
}
function _cmis_sync_drupal_to_cmis_prepare($node) {
$sync_map = variable_get('cmis_sync_map', array());
if ($sync_map[$node->type] && $sync_map[$node->type]['enabled']) {
$cmis_object = new stdClass();
$cmis_object->type = $sync_map[$node->type]['cmis_type'];
$cmis_object->parentId = drupal_urlencode($sync_map[$node->type]['cmis_root']);
$cmis_object->properties = array(
'title' => $node->title,
);
foreach ($sync_map[$node->type]['fields'] as $drupal_field => $cmis_field) {
if (is_string($cmis_field)) {
$cmis_object->properties[$cmis_field] = _cmis_sync_node_field_value($nodem, $drupal_field);
}
elseif (is_array($cmis_field)) {
if (array_key_exists('drupal to cmis', $cmis_field) && $cmis_field['drupal to cmis'] === False) {
continue;
}
$cmis_object->properties[$cmis_field['cmis']] = _cmis_sync_node_field_value($node, $cmis_field['drupal']);
}
else {
throw new CMISException(t('Unknown field map type. Expects "string" or "array". Received @type', array(
'@type' => gettype($cmis_field),
)));
}
}
if (array_key_exists('content_field', $sync_map[$node->type])) {
$cmis_object->content = _cmis_sync_node_field_value($node, $sync_map[$node->type]['content_field']);
$cmis_object->properties['content-type'] = 'text/html';
$content_type = content_types($node->type);
$content_field_name = $sync_map[$node->type]['content_field'];
if (array_key_exists($content_field_name, $content_type['fields'])) {
if ($content_type['fields'][$content_field_name]['type'] == 'filefield') {
$content_field = $node->{$content_field_name};
$cmis_object->properties['content-type'] = $content_field[0]['filemime'];
}
}
}
$cmis_object->sync_deletes = $sync_map[$node->type]['deletes'];
return $cmis_object;
}
return FALSE;
}
function _cmis_sync_cmis_to_drupal_prepare($repository, $sync_map_type, $node_type, $cmis_object) {
module_load_include('api.inc', 'cmis');
if ($sync_map_type['enabled']) {
$drupal_nid = NULL;
if (!array_key_exists('nid', $sync_map_type['fields'])) {
if ($cmis_sync_node = db_fetch_object(db_query('SELECT nid FROM {cmis_sync_node} WHERE cmis_objectId = \'%s\'', $cmis_object->id))) {
$drupal_nid = $cmis_sync_node->nid;
}
}
else {
$drupal_nid = $cmis_object->properties[$sync_map_type['fields']['nid']];
}
$node = node_load($drupal_nid);
$node->type = $node_type;
foreach ($sync_map_type['fields'] as $node_field => $cmis_field) {
if (is_string($cmis_field)) {
_cmis_sync_node_field_value($node, $node_field, $cmis_object->properties[$cmis_field]);
}
elseif (is_array($cmis_field)) {
if (array_key_exists('cmis to drupal', $cmis_field) && $cmis_field['cmis to drupal'] === False) {
continue;
}
_cmis_sync_node_field_value($node, $cmis_field['drupal'], $cmis_object->properties[$cmis_field['cmis']]);
}
else {
throw new CMISException(t('Unknown field map type. Expects "string" or "array". Received "@type"', array(
'@type' => gettype($cmis_field),
)));
}
}
if (array_key_exists('content_field', $sync_map_type)) {
_cmis_sync_node_field_value($node, $sync_map_type['content_field'], cmisapi_getContentStream($repository->repositoryId, $cmis_object->id), array(
'cmis' => $cmis_object,
));
}
return $node;
}
return FALSE;
}
function _cmis_sync_cmis_to_drupal_handle_updates($repository, $sync_map_type, $node_type) {
$cmis_folder = cmisapi_getProperties($repository->repositoryId, drupal_urlencode($sync_map_type['cmis_root']));
$sync_subfolders_rule = $sync_map_type['subfolders'] ? 'IN_TREE' : 'IN_FOLDER';
$sync_full_rule = $sync_map_type['full_sync_next_cron'] ? '' : sprintf('AND LastModificationDate > \'%s\'', date_create('12 hour ago')
->format('Y-m-d\\TH:i:s.000-00:00'));
$cmis_query = sprintf('SELECT * FROM %s WHERE %s(\'%s\') %s', $sync_map_type['cmis_type'], $sync_subfolders_rule, $cmis_folder->id, $sync_full_rule);
$cmis_updates = cmisapi_query($repository->respositoryId, $cmis_query);
foreach ($cmis_updates as $cmis_update) {
$drupal_node = _cmis_sync_cmis_to_drupal_prepare($repository, $sync_map_type, $node_type, $cmis_update);
if (FALSE === $drupal_node) {
continue;
}
$drupal_node->cmis_sync_disabled = TRUE;
node_save($drupal_node);
if (db_fetch_object(db_query('SELECT nid FROM {cmis_sync_node} WHERE cmis_objectId = \'%s\'', $cmis_update->id))) {
db_query('UPDATE {cmis_sync_node} SET changed_timestamp=%d, nid=%d WHERE cmis_objectId = \'%s\'', $_SERVER['REQUEST_TIME'], $drupal_node->nid, $cmis_update->id);
watchdog('cmis_sync_cron', 'Updated nid @nid', array(
'@nid' => $drupal_node->nid,
));
}
else {
db_query('INSERT INTO {cmis_sync_node} (nid, cmis_objectId, changed_timestamp) VALUES (%d, \'%s\', %d)', $drupal_node->nid, $cmis_update->id, $_SERVER['REQUEST_TIME']);
watchdog('cmis_sync_cron', 'Added nid @nid', array(
'@nid' => $drupal_node->nid,
));
}
}
}
function _cmis_sync_cmis_to_drupal_handle_deletes($repository, $sync_map_type, $node_type) {
$sync_nodes = array();
$sync_nodes_query = db_query('SELECT nid, cmis_objectId FROM {cmis_sync_node}');
while ($sync_node = db_fetch_object($sync_nodes_query)) {
if (node_load($sync_node->nid)->type == $node_type) {
$sync_nodes[$sync_node->cmis_objectId] = $sync_node->nid;
}
}
if (count($sync_nodes)) {
$cmis_objects = cmisapi_query($repository, sprintf('SELECT ObjectId FROM %s WHERE ObjectId IN (\'%s\')', $sync_map_type['cmis_type'], join('\',\'', array_keys($sync_nodes))));
foreach ($cmis_objects as $cmis_object) {
if (array_key_exists($cmis_object->id, $sync_nodes)) {
unset($sync_nodes[$cmis_object->id]);
}
}
db_query('DELETE FROM {cmis_sync_node} WHERE nid IN (\'%s\')', join('\',\'', array_values($sync_nodes)));
foreach ($sync_nodes as $cmis_objectId => $drupal_nid) {
node_delete($drupal_nid);
}
}
}
function _cmis_sync_node_field_value(&$node, $field_name, $field_value = NULL, $context = array()) {
$content_type = content_types($node->type);
$value = NULL;
if (array_key_exists($field_name, $content_type['fields'])) {
$content_field = $node->{$field_name};
switch ($content_type['fields'][$field_name]['type']) {
case 'filefield':
if ($field_value == NULL) {
$value = file_get_contents($content_field[0]['filepath']);
}
else {
if (is_array($node->{$field_name})) {
file_put_contents($content_field[0]['filepath'], $field_value);
}
else {
if (array_key_exists('cmis', $context)) {
$file_drupal_path = file_directory_path() . '/cmis_' . basename($context['cmis']->properties['ObjectId']) . '_' . $context['cmis']->title;
file_put_contents($file_drupal_path, $field_value);
$file = new stdClass();
$file->filename = basename($file_drupal_path);
$file->filepath = $file_drupal_path;
$file->filemime = $context['cmis']->contentMimeType;
$file->filesize = filesize($file_drupal_path);
$file->status = FILE_STATUS_PERMANENT;
$file->timestamp = time();
drupal_write_record('files', $file);
$node->{$field_name} = array(
array(
'fid' => $file->fid,
'title' => $context['cmis']->title,
'filename' => $file->filename,
'filepath' => $file->filepath,
'filesize' => $file->filesize,
'filemime' => $context['cmis']->contentMimeType,
'list' => 1,
),
);
}
}
}
break;
case 'text':
if ($field_value == NULL) {
$value = $content_field[0]['value'];
}
else {
$content_field[0]['value'] = $field_value;
}
break;
}
}
else {
if ($field_value == NULL) {
$value = $node->{$field_name};
}
else {
$node->{$field_name} = $field_value;
}
}
return $value;
}