diff --git a/modules/upload_deploy/upload_deploy.info b/modules/upload_deploy/upload_deploy.info new file mode 100644 index 0000000..19b45a1 --- /dev/null +++ b/modules/upload_deploy/upload_deploy.info @@ -0,0 +1,7 @@ +name = "Deploy Uploads" +description = "Deploy uploaded file attachments using the Deployment framework" +dependencies[] = deploy +dependencies[] = deploy_uuid +dependencies[] = upload +package = Deployment +core = 6.x diff --git a/modules/upload_deploy/upload_deploy.module b/modules/upload_deploy/upload_deploy.module new file mode 100644 index 0000000..62e04bb --- /dev/null +++ b/modules/upload_deploy/upload_deploy.module @@ -0,0 +1,159 @@ +files)) { + foreach ($node->files as $fid => $file) { + if (!deploy_uuid_get_files_uuid($fid)) { + deploy_uuid_file_insert($file); + } + } + } + break; + } +} + +/** + * Implementation of hook_deploy() on behalf of upload.module. + * + * This is a copy of filefield_deploy() that removes the dependency on + * field_file_load(). + */ +function upload_deploy($fid) { + $file_info = db_fetch_array(db_query('SELECT f.* FROM {files} f WHERE f.fid = %d', $fid)); + if (empty($file_info)) { + return xmlrpc_error($xmlrpcusererr + 1, t('File not found')); + } + + // Save the base64_encode()d file into the file_info array for transfer + $filepath = file_create_path($file_info['filepath']); + $binaryfile = fopen($filepath, 'rb'); + $filelength = filesize($filepath); + $file = base64_encode(fread($binaryfile, $filelength)); + $file_info['file'] = $file; + + // Normally, like with users and nodes, the uuid is added to the object in the 'load' + // op of their hook. Files have no load op, so we have to get it by hand. + $file_info['uuid'] = deploy_uuid_get_files_uuid($fid); + $remote_key = deploy_get_remote_key($file_info['uuid'], 'files'); + $file_info['fid'] = isset($remote_key['fid']) ? $remote_key['fid'] : NULL; + + // If there is no remote file, then we also set the status to + // FILE_STATUS_TEMPORARY. If you don't do this, then Filefield + // will fail out with a validation error on the remote site. + // It will get set to FILE_STATUS_PERMANENT when the node + // is saved. + if (isset($remote_key['fid'])) { + $file_info['fid'] = $remote_key['fid']; + } + else { + $file_info['fid'] = NULL; + $file_info['status'] = FILE_STATUS_TEMPORARY; + } + // The filefield service requires an object and I don't have time + // to go change all the above at the moment + $file_info = (object) $file_info; + + // And we're off. + $fid = deploy_send(array('file.save'), array($file_info)); + + return $fid; +} + +/** + * Implementation of hook_node_deploy_check(). + * + * This is the dependency checking hook for nodes, called when + * a deployment has been requested that includes a node. + * + * @param $node + * The node object being deployed + */ +function upload_deploy_node_deploy_check($node) { + $pid = variable_get('deploy_pid', 0); + + if (variable_get("upload_$node->type", 1) == 1) { + if (!empty($node->files)) { + foreach ($node->files as $file) { + if (!deploy_item_is_in_plan($pid, 'upload', $file->fid)) { + // Does this file exist on the remote server? + $uuid = deploy_uuid_get_files_uuid($file->fid); + $remote_key = deploy_get_remote_key($uuid, 'files'); + + // If not we're going to add it to the deployment plan, with a weight + // of min(weight) - 1. + if (!$remote_key) { + deploy_add_to_plan($pid, 'upload', 'File: '. $file->filename, $file->fid, deploy_get_min_weight($pid)-1, DEPLOY_FILE_GROUP_WEIGHT); + } + } + } + } + + // Ensure the list of files is sent after the node itself. + $weight = db_result(db_query("SELECT MAX(weight) FROM {deploy_plan_items} WHERE pid = %d", $pid)); + deploy_add_to_plan($pid, 'node_uploads', 'Uploads: '. $node->title, $node->nid, $weight + 1, DEPLOY_NODE_GROUP_WEIGHT); + } +} + +/** + * Implementation of hook_deploy(), + * + * @param $nid + * Unique identifier for the node we're deploying. + * @return + * The results of our xmlrpc call. + */ +function node_uploads_deploy($nid) { + // Bail if this node doesn't exist. + $node = node_load($nid); + if (empty($node)) { + return xmlrpc_error($xmlrpcusererr + 1, t('Node not found')); + } + + // This should have been handled in Bail if this node doesn't exist. + $remote_key = deploy_get_remote_key($node->uuid, 'node'); + if (!$remote_key) { + return xmlrpc_error($xmlrpcusererr + 1, t('Remote node not found')); + } + $remote_nid = $remote_key['nid']; + + // Convert the fid of each file. + $files = array(); + foreach ($node->files as $fid => $file) { + $file = (array) $file; + $file['uuid'] = deploy_uuid_get_files_uuid($fid); + $remote_key = deploy_get_remote_key($file['uuid'], 'files'); + $file['fid'] = $remote_key['fid']; + $files[$file['fid']] = $file; + } + + // Send the files. + deploy_send(array('node.saveUploads'), array($remote_nid, $files)); + + return TRUE; +} + +/** + * Implementation of hook_node_deploy(), + * + * @param $node + * The node we're deploying. + */ +function upload_node_deploy($node) { + // This causes drupal_execute() to fail at the remote end, so we remove it. + unset($node->attach); +} \ No newline at end of file diff --git a/services/upload_service/upload_service.inc b/services/upload_service/upload_service.inc new file mode 100644 index 0000000..1ad9eb8 --- /dev/null +++ b/services/upload_service/upload_service.inc @@ -0,0 +1,40 @@ + &$file) { + // Create files that don't exist, update files that do. + $file['new'] = !isset($node->files[$fid]); + unset($node->files[$fid]); + } + + // Any remaining files need to be deleted. + foreach ($node->files as $fid => $file) { + $files[$fid] = array('remove' => TRUE); + } + + $node->files = $files; + upload_save($node); +} + +/** + * Check if the user has the permission to save a node. + * + * @param $node + * Object. The node object. + * @return + * Boolean. TRUE if the user has the permission to save a node. + */ +function upload_service_save_access($nid, $files) { + $node = node_load($nid); + return node_access('update', $nid); +} diff --git a/services/upload_service/upload_service.info b/services/upload_service/upload_service.info new file mode 100644 index 0000000..74833b5 --- /dev/null +++ b/services/upload_service/upload_service.info @@ -0,0 +1,5 @@ +name = Upload Service +description = Provides a node attachment upload service. +package = Services - services +dependencies[] = node_service +core = 6.x diff --git a/services/upload_service/upload_service.module b/services/upload_service/upload_service.module new file mode 100644 index 0000000..cf0fb5d --- /dev/null +++ b/services/upload_service/upload_service.module @@ -0,0 +1,26 @@ + 'node.saveUploads', + '#callback' => 'upload_service_save', + '#access callback' => 'upload_service_save_access', + '#file' => array('file' => 'inc', 'module' => 'upload_service'), + '#args' => array( + array( + '#name' => 'nid', + '#type' => 'int', + '#description' => t('A node ID.')), + array( + '#name' => 'files', + '#type' => 'array', + '#description' => t('A set of files to attach to a node.'))), + '#help' => t('Attach file uploads to a node.')), + ); +}