Index: project.inc
===================================================================
RCS file: /Users/wright/drupal/local_repo/contributions/modules/project/project.inc,v
retrieving revision 1.159
diff -u -p -r1.159 project.inc
--- project.inc	30 Jan 2011 00:37:43 -0000	1.159
+++ project.inc	30 Jan 2011 18:50:10 -0000
@@ -668,10 +668,61 @@ function project_promote_project_form_va
 }
 
 /**
- * Submit handler for project promote form.
+ * Submit handler for project promote form. Redirects to a confirm form.
  */
 function project_promote_project_form_submit($form, &$form_state) {
-  $project = node_load($form_state['values']['pid']);
+  if (isset($form_state['values']['shortname'])) {
+    $_SESSION['project_promote_project_shortname'] = $form_state['values']['shortname'];
+  }
+  $form_state['redirect'] = 'node/' . $form_state['values']['pid'] . '/edit/promote/confirm';
+}
+
+/**
+ * Build a confirmation form for promoting sandbox projects to full projects.
+ */
+function project_promote_project_confirm_form($form_state, $project) {
+  if (empty($project)) {
+    drupal_set_message(t('Error: you cannot confirm promoting a sandbox to a full project without specifying the project.'), 'error');
+    return drupal_goto();
+  }
+  $form['nid'] = array(
+    '#type' => 'value',
+    '#value' => $project->nid,
+  );
+
+  if (isset($_SESSION['project_promote_project_shortname'])) {
+    $shortname = $_SESSION['project_promote_project_shortname'];
+    unset($_SESSION['project_promote_project_shortname']);
+  }
+  else {
+    $shortname = $project->project['uri'];
+  }
+  $form['shortname'] = array(
+    '#type' => 'value',
+    '#value' => $shortname,
+  );
+
+  // If the shortname can't otherwise be changed, make sure they understand
+  // this is *really* permanent once they press "Promote".
+  if (!variable_get('project_allow_uri_update', TRUE)) {
+    $confirm_text = t('The project will use the shortname %shortname which can not be changed later. Furthermore, once a project is promoted, it can not be turned back into a sandbox.', array('%shortname' => $shortname));
+  }
+  else {
+    $confirm_text = t('Once a project is promoted, it can not be turned back into a sandbox.');
+  }
+  return confirm_form(
+    $form,
+    t('Are you sure you want to promote %title from a sandbox to a full project with the shortname %shortname?', array('%title' => $project->title, '%shortname' => $shortname)),
+    'node/' . $project->nid . '/edit/promote',
+    $confirm_text, t('Promote'), t('Cancel')
+  );
+}
+
+/**
+ * Submit handler for project promote form.
+ */
+function project_promote_project_confirm_form_submit($form, &$form_state) {
+  $project = node_load($form_state['values']['nid']);
   $project->project['sandbox'] = 0;
 
   // Only update the shortname if it is relevant, and included in the original
@@ -679,9 +730,10 @@ function project_promote_project_form_su
   if (variable_get('project_sandbox_numeric_shortname', FALSE)) {
     $project->project['uri'] = $form_state['values']['shortname'];
   }
+
   node_save($project);
   drupal_set_message(t('The project %project_name has been promoted to a full project.', array('%project_name' => $project->title)));
-  $form_state['redirect'] = 'node/'. $project->nid;
+  $form_state['redirect'] = 'node/' . $project->nid;
 
   // Notify that this promotion has occurred.
   module_invoke_all('project_promote_sandbox', $project);
Index: project.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/contributions/modules/project/project.module,v
retrieving revision 1.370
diff -u -p -r1.370 project.module
--- project.module	30 Jan 2011 02:31:41 -0000	1.370
+++ project.module	30 Jan 2011 18:49:25 -0000
@@ -586,6 +586,15 @@ function project_menu() {
     'file' => 'project.inc',
     'type' => MENU_LOCAL_TASK,
   );
+  $items['node/%project_edit_project/edit/promote/confirm'] = array(
+    'title' => 'Promote',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('project_promote_project_confirm_form', 1),
+    'access callback' => 'project_promote_project_access',
+    'access arguments' => array(1),
+    'file' => 'project.inc',
+    'type' => MENU_CALLBACK,
+  );
   return $items;
 }
 
Index: release/project_release.module
===================================================================
RCS file: /Users/wright/drupal/local_repo/contributions/modules/project/release/project_release.module,v
retrieving revision 1.160
diff -u -p -r1.160 project_release.module
--- release/project_release.module	16 Jan 2011 12:45:33 -0000	1.160
+++ release/project_release.module	30 Jan 2011 18:49:25 -0000
@@ -825,6 +825,9 @@ function project_release_form_alter(&$fo
   if ($form_id == 'project_promote_project_form') {
     return project_release_alter_project_promote_form($form, $form_state);
   }
+  if ($form_id == 'project_promote_project_confirm_form') {
+    return project_release_alter_project_promote_confirm_form($form, $form_state);
+  }
 }
 
 /**
@@ -920,6 +923,9 @@ function project_release_alter_project_s
  * Alters the form for promoting a project from sandbox to a full project.
  */
 function project_release_alter_project_promote_form(&$form, &$form_state) {
+  // Unset this in case the user cancels on the confirm form so we don't leak
+  // this into the $_SESSION permanently. Also ensures we start clean.
+  unset($_SESSION['project_promote_project_releases']);
   if (!variable_get('project_release_sandbox_allow_release', TRUE)) {
     $node = node_load($form['pid']['#value']);
     $form['releases'] = array(
@@ -936,9 +942,38 @@ function project_release_alter_project_p
 
 /**
  * Submit handler for project promote form.
+ *
+ * This just saves the value of the 'Enable releases' checkbox into the
+ * SESSION so it can persist when building the confirm form.
  */
 function project_release_project_promote_form_submit($form, &$form_state) {
-  db_query("UPDATE {project_release_projects} SET releases = %d WHERE nid = %d", $form_state['values']['releases'], $form_state['values']['pid']);
+  if (isset($form_state['values']['releases'])) {
+    $_SESSION['project_promote_project_releases'] = $form_state['values']['releases'];
+  }
+}
+
+/**
+ * Alters the confirm form for promoting sandbox into a full project.
+ */
+function project_release_alter_project_promote_confirm_form(&$form, &$form_state) {
+  if (isset($_SESSION['project_promote_project_releases'])) {
+    $form['releases'] = array(
+      '#type' => 'value',
+      '#value' => $_SESSION['project_promote_project_releases'],
+    );
+    // Note: we can't unset this value from the $_SEESSION here, or this form
+    // element won't be included when building the form during submission. So,
+    // we'll unset once we actually submit the confirm form.
+  }
+  $form['#submit'][] = 'project_release_project_promote_confirm_form_submit';
+}
+
+/**
+ * Submit handler for project promote confirm form.
+ */
+function project_release_project_promote_confirm_form_submit($form, &$form_state) {
+  db_query("UPDATE {project_release_projects} SET releases = %d WHERE nid = %d", $form_state['values']['releases'], $form_state['values']['nid']);
+  unset($_SESSION['project_promote_project_releases']);
 }
 
 /**
