/**
 * Update the DB with the new file info for a given release node.
 *
 * @todo This assumes 1:1 relationship of release nodes to files.
 */
function package_release_update_node($nid, $file_path)
{
    global $dest_root, $task;
    $full_path = $dest_root . '/' . $file_path;
    // PHP will cache the results of stat() and give us stale answers
    // here, unless we manually tell it otherwise!
    clearstatcache();
    // Now that we have the official file, compute some metadata:
    $file_name = basename($file_path);
    $file_date = filemtime($full_path);
    $file_size = filesize($full_path);
    $file_hash = md5_file($full_path);
    $file_mime = file_get_mimetype($full_path);
    $uid = db_result(db_query("SELECT n.uid FROM {node} n WHERE n.nid = %d", $nid));
    // Finally, save this file to the DB.
    // First, see if we already have a file for this release node
    $file_data = db_fetch_object(db_query("SELECT * FROM {project_release_file} WHERE nid = %d  GROUP BY nid ORDER BY fid DESC", $nid));
    if (empty($file_data)) {
        // Don't have an file data for this release, insert a new record.
        db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date);
        $fid = db_last_insert_id('files', 'fid');
        db_query("INSERT INTO {project_release_file} (fid, nid, filehash) VALUES (%d, %d, '%s')", $fid, $nid, $file_hash);
    } else {
        // Already have a file for this release, update it.
        db_query("UPDATE {files} SET uid = %d, filename = '%s', filepath = '%s', filemime = '%s', filesize = %d, status = %d, timestamp = %d WHERE fid = %d", $uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date, $file_data->fid);
        db_query("UPDATE {project_release_file} SET filehash = '%s' WHERE fid = %d", $file_hash, $file_data->fid);
    }
    // Don't auto-publish security updates.
    if ($task == 'tag' && db_result(db_query("SELECT COUNT(*) FROM {term_node} WHERE nid = %d AND tid = %d", $nid, SECURITY_UPDATE_TID))) {
        watchdog('package_security', "Not auto-publishing security update release.", array(), WATCHDOG_NOTICE, l(t('view'), 'node/' . $nid));
        return;
    }
    // Finally publish the node if it is currently unpublished.  Instead of
    // directly updating {node}.status, we use node_save() so that other modules
    // which implement hook_nodeapi() will know that this node is now published.
    // However, we don't want to waste too much RAM by leaving all these loaded
    // nodes in RAM, so we reset the node_load() cache each time we call it.
    $status = db_result(db_query("SELECT status from {node} WHERE nid = %d", $nid));
    if (empty($status)) {
        // If the site is using DB replication, force this node_load() to use the
        // primary database to avoid node_load() failures.
        if (function_exists('db_set_ignore_slave')) {
            db_set_ignore_slave();
        }
        $node = node_load($nid, NULL, TRUE);
        if (!empty($node->nid)) {
            $node->status = 1;
            node_save($node);
        } else {
            wd_err('node_load(@nid) failed', array('@nid' => $nid));
        }
    }
}
/**
 * Update the DB with the new file info for a given release node.
 *
 * @param $nid
 *   The node ID of the release node to update.
 * @param $files
 *   Array of files to add to the release node.
 * @param $package_contents
 *   Optional. Array of nids of releases contained in a release package.
 */
function package_release_update_node($nid, $files, $package_contents = array())
{
    global $drupal_root, $dest_root, $task;
    // PHP will cache the results of stat() and give us stale answers
    // here, unless we manually tell it otherwise!
    clearstatcache();
    // Make sure we're back at the webroot so node_load() and node_save()
    // can always find any files they (and the hooks they invoke) need.
    if (!drupal_chdir($drupal_root)) {
        return FALSE;
    }
    // If the site is using DB replication, force this node_load() to use the
    // primary database to avoid node_load() failures.
    if (function_exists('db_set_ignore_slave')) {
        db_set_ignore_slave();
    }
    // We don't want to waste too much RAM by leaving all these loaded nodes
    // in RAM, so we reset the node_load() cache each time we call it.
    $node = node_load($nid, NULL, TRUE);
    if (empty($node->nid)) {
        wd_err('node_load(@nid) failed', array('@nid' => $nid));
        return FALSE;
    }
    foreach ($files as $file_path) {
        // Compute the metadata for this file that we care about.
        $full_path = $dest_root . '/' . $file_path;
        $file_name = basename($file_path);
        $file_date = filemtime($full_path);
        $file_size = filesize($full_path);
        $file_hash = md5_file($full_path);
        $file_mime = file_get_mimetype($full_path);
        // First, see if we already have this file for this release node
        $file_data = db_fetch_object(db_query("SELECT prf.* FROM {project_release_file} prf INNER JOIN {files} f ON prf.fid = f.fid WHERE prf.nid = %d AND f.filename = '%s'", $node->nid, $file_name));
        // Insert or update the record in the DB as need.
        if (empty($file_data)) {
            // Don't have this file, insert a new record.
            db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $node->uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date);
            $fid = db_last_insert_id('files', 'fid');
            db_query("INSERT INTO {project_release_file} (fid, nid, filehash) VALUES (%d, %d, '%s')", $fid, $node->nid, $file_hash);
        } else {
            // Already have this file for this release, update it.
            db_query("UPDATE {files} SET uid = %d, filename = '%s', filepath = '%s', filemime = '%s', filesize = %d, status = %d, timestamp = %d WHERE fid = %d", $node->uid, $file_name, $file_path, $file_mime, $file_size, FILE_STATUS_PERMANENT, $file_date, $file_data->fid);
            db_query("UPDATE {project_release_file} SET filehash = '%s' WHERE fid = %d", $file_hash, $file_data->fid);
        }
    }
    // Store package contents if necessary.
    if (!empty($package_contents) && module_exists('project_package')) {
        foreach ($package_contents as $item_nid) {
            db_query("INSERT INTO {project_package_local_release_item} (package_nid, item_nid) VALUES (%d, %d)", $nid, $item_nid);
        }
    }
    // Don't auto-publish security updates.
    $security_update_tid = variable_get('project_release_security_update_tid', 0);
    if ($task == 'tag' && !empty($node->taxonomy[$security_update_tid])) {
        watchdog('package_security', 'Not auto-publishing security update release.', array(), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid));
        return;
    }
    // Finally publish the node if it is currently unpublished. Instead of
    // directly updating {node}.status, we use node_save() so that other modules
    // which implement hook_nodeapi() will know that this node is now published.
    if (empty($node->status)) {
        $node->status = 1;
        node_save($node);
    }
}