When I test deploy module, I found it's not work when enabling upload module.
After I choose a node which is new created and sync it, I get successful message in source server, but content of destination server is not changed.
After researching code, we found the problem should be from line 1025 in include/form.inc:

if (_form_button_was_clicked($form)) { ------------------- (1025 line)
...
...
...
if (isset($form['#submit'])) {
$form_state['submit_handlers'] = $form['#submit'];
}
}

After enabling upload moudle, the value of $form_state['submit_handlers'] will changed from "node_form_submit" to "node_form_submit_build_node", so the synchronized node will not save.

Thanks!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

johngriffin’s picture

I can confirm that this is still occuring with the current dev versions of both services 2.x and deploy modules.

My fix is to temporarily disable upload module on the destination.

markmainsail’s picture

Hello. I just installed the deploy module but when i try to actually deploy anything I get this error:

Error
category: illegal value.

it appears to have something to do with a text field 'category' that I've created to filter nodes in views?

Is there anything I can do to make this work?

thanks!

mcrittenden’s picture

Title: Deply module isn't work with upload module » Deply module doesn't work with upload module
stijnbe’s picture

A little quick fix is to add this in node_deploy.module on line 188:

  //temporary fix for upload module 
  unset($node->attach);
mcrittenden’s picture

Title: Deply module doesn't work with upload module » Deploy module doesn't work with upload module
toh’s picture

Still having issues here with the latest dev release. Unfortunately it's not feasible to temporarily disable the Upload module, and my group is rather update-happy, so a patch isn't exactly do-able for us either. I guess I can only throw my support behind a fix for this in the next dev release.

Thanks for the work on Deployment. It's quite a tool and I'm glad to the project's still actively going strong!

ngstigator’s picture

great module! confirmed on latest dev version. thanks for all your work :-)

gdd’s picture

Category: bug » feature
Priority: Critical » Normal

Changing this to feature request, since it is not actually a bug (I never attempted to support upload module.)

moropo’s picture

Any change on this subject?
I think that feature request or bug... whatever... it is really important to support upload module.
The concept and implementation of Deployment module is excellent and fulfill the needs of many of us.

dixon_’s picture

@moropo We are supporting the FileField module, as that is a much more widely used approach to uploading. Could that be an alternative to you?

thezombieguy’s picture

I used the unset($node->attach); suggestion above, but I'm not sure what other effects that might have.

However I disabled file uploads, and used filefield for attaching images/media to my content as well as Insert for inserting media automatically. So far it's a perfect replacement.

longwave’s picture

Status: Active » Needs review
FileSize
921 bytes
2.07 KB

Confirm that the fix in #4 works, as far as content types with file attachments enabled actually get deployed instead of failing silently, but attachments themselves are not transferred or attached.

The attached modules extend this further. upload_deploy ensures that file attachments are given UUIDs and are deployed in a similar way to filefields, and upload_service handles saving $node->files on the remote end after the node has been transferred. I couldn't get this working directly during node deployment; new nodes would transfer correctly, but when updating existing nodes, $node->files always ended up empty after drupal_execute()'ing the node form, even if all values (including 'new') were set correctly - this seems to be a limitation of the way the upload element is attached to the node form and Form API's handling of this. This workaround of sending the file list afterwards seems to work.

The fix in #4 is included in upload_deploy but should perhaps be moved to node_deploy so deploy does not fail when upload is enabled but deployment of uploads is not required.

Development of these modules was sponsored by Opsview.

dixon_’s picture

Status: Needs review » Needs work

Would it be possible to get these modules as actual git patches? That way we can test and review them properly.

longwave’s picture

Status: Needs work » Needs review
FileSize
8.25 KB
dixon_’s picture

Status: Needs review » Needs work

The patch seems to do it's job! Nice! But I'm not totally satisfied with the approach, though. I would like it to use the already existing file_service.module for deploying the actual file.

I won't mark this as a beta blocker, but I will definitely come back and work on this later.

dixon_’s picture

To help version 6.x-1.x move forward, please see this issue: #526936: Find best way to proceeding with 6.x-1.x and more specifically this comment: http://drupal.org/node/526936#comment-4931548

kenorb’s picture

Pasting code for easier understanding:

upload_deploy module:

/**
 * @file
 * Deployment API which enables modules to deploy items between servers.
 *
 * This module manages deployment-related issues for files added via the
 * core upload module.
 */

/**
 * Implementation of hook_nodeapi().
 *
 * Ensure new uploads are given a UUID.
 */
function upload_deploy_nodeapi(&$node, $op, $teaser) {
  switch ($op) {
    case 'insert':
    case 'update':
      if (isset($node->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);
}

upload_service module:

/**
 * Implementation of hook_service().
 */
function upload_service_service() {
  return array(

    // node.saveUploads
    array(
      '#method'           => '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.')),
  );
}
kenorb’s picture

Created sandbox module for the fixes:
https://drupal.org/sandbox/kenorb/2108059

kenorb’s picture

Priority: Normal » Minor
Issue summary: View changes