/** * Adopt or disown packages * * @param array $base_ids Array of package base IDs to adopt/disown * @param bool $action Adopts if true, disowns if false. Adopts by default * @param int $via Package request to close upon adoption * * @return array Tuple of success/failure indicator and error message */ function pkgbase_adopt($base_ids, $action = true, $via) { $dbh = DB::connect(); $uid = uid_from_sid($_COOKIE["AURSID"]); if (!$uid) { if ($action) { return array(false, __("You must be logged in before you can adopt packages.")); } else { return array(false, __("You must be logged in before you can disown packages.")); } } /* Verify package ownership. */ $base_ids = sanitize_ids($base_ids); $q = "SELECT ID FROM PackageBases "; $q .= "WHERE ID IN (" . implode(",", $base_ids) . ") "; if ($action && !has_credential(CRED_PKGBASE_ADOPT)) { /* Regular users may only adopt orphan packages. */ $q .= "AND MaintainerUID IS NULL"; } if (!$action && !has_credential(CRED_PKGBASE_DISOWN)) { /* Regular users may only disown their own packages. */ $q .= "AND MaintainerUID = " . $uid; } $result = $dbh->query($q); $base_ids = $result->fetchAll(PDO::FETCH_COLUMN, 0); /* Error out if the list of remaining packages is empty. */ if (empty($base_ids)) { if ($action) { return array(false, __("You did not select any packages to adopt.")); } else { return array(false, __("You did not select any packages to disown.")); } } /* * Close package request if the disownment was initiated through the * request interface. NOTE: This needs to happen *before* the actual * disown operation. Otherwise, the former maintainer will not be * included in the Cc list of the request notification email. */ if ($via) { pkgreq_close(intval($via), 'accepted', ''); } /* Scan through pending orphan requests and close them. */ if (!$action) { $username = username_from_sid($_COOKIE['AURSID']); foreach ($base_ids as $base_id) { $pkgreq_ids = pkgreq_by_pkgbase($base_id, 'orphan'); foreach ($pkgreq_ids as $pkgreq_id) { pkgreq_close(intval($pkgreq_id), 'accepted', 'The user ' . $username . ' disowned the package.', true); } } } /* Adopt or disown the package. */ if ($action) { $q = "UPDATE PackageBases "; $q .= "SET MaintainerUID = {$uid} "; $q .= "WHERE ID IN (" . implode(",", $base_ids) . ") "; $dbh->exec($q); } else { /* Update the co-maintainer list when disowning a package. */ if (has_credential(CRED_PKGBASE_DISOWN)) { foreach ($base_ids as $base_id) { pkgbase_set_comaintainers($base_id, array()); } $q = "UPDATE PackageBases "; $q .= "SET MaintainerUID = NULL "; $q .= "WHERE ID IN (" . implode(",", $base_ids) . ") "; $dbh->exec($q); } else { foreach ($base_ids as $base_id) { $comaintainers = pkgbase_get_comaintainers($base_id); if (count($comaintainers) > 0) { $uid = uid_from_username($comaintainers[0]); $comaintainers = array_diff($comaintainers, array($comaintainers[0])); pkgbase_set_comaintainers($base_id, $comaintainers); } else { $uid = "NULL"; } $q = "UPDATE PackageBases "; $q .= "SET MaintainerUID = " . $uid . " "; $q .= "WHERE ID = " . $base_id; $dbh->exec($q); } } } if ($action) { pkgbase_notify($base_ids); return array(true, __("The selected packages have been adopted.")); } else { return array(true, __("The selected packages have been disowned.")); } }
} else { $output = __("The selected packages have not been deleted, check the confirmation checkbox."); $ret = false; } } elseif (current_action("do_Notify")) { list($ret, $output) = pkgbase_notify($ids); } elseif (current_action("do_UnNotify")) { list($ret, $output) = pkgbase_notify($ids, false); } elseif (current_action("do_DeleteComment")) { list($ret, $output) = pkgbase_delete_comment(); } elseif (current_action("do_SetKeywords")) { list($ret, $output) = pkgbase_set_keywords($base_id, preg_split("/[\\s,;]+/", $_POST['keywords'], -1, PREG_SPLIT_NO_EMPTY)); } elseif (current_action("do_FileRequest")) { list($ret, $output) = pkgreq_file($ids, $_POST['type'], $_POST['merge_into'], $_POST['comments']); } elseif (current_action("do_CloseRequest")) { list($ret, $output) = pkgreq_close($_POST['reqid'], $_POST['reason'], $_POST['comments']); } elseif (current_action("do_EditComaintainers")) { list($ret, $output) = pkgbase_set_comaintainers($base_id, explode("\n", $_POST['users'])); } elseif (current_action("do_AddComment")) { $uid = uid_from_sid($_COOKIE["AURSID"]); list($ret, $output) = pkgbase_add_comment($base_id, $uid, $_REQUEST['comment']); $fragment = '#news'; } elseif (current_action("do_EditComment")) { list($ret, $output) = pkgbase_edit_comment($_REQUEST['comment']); if ($ret && isset($_POST["comment_id"])) { $fragment = '#comment-' . intval($_POST["comment_id"]); } } if ($ret) { if (current_action("do_CloseRequest") || current_action("do_Delete") && $_POST['via']) { /* Redirect back to package request page on success. */
/** * File a deletion/orphan request against a package base * * @param string $ids The package base IDs to file the request against * @param string $type The type of the request * @param string $merge_into The target of a merge operation * @param string $comments The comments to be added to the request * * @return array Tuple of success/failure indicator and error message */ function pkgreq_file($ids, $type, $merge_into, $comments) { if (!has_credential(CRED_PKGREQ_FILE)) { return array(false, __("You must be logged in to file package requests.")); } if (!empty($merge_into) && !preg_match("/^[a-z0-9][a-z0-9\\.+_-]*\$/D", $merge_into)) { return array(false, __("Invalid name: only lowercase letters are allowed.")); } if (!empty($merge_into) && !pkgbase_from_name($merge_into)) { return array(false, __("Cannot find package to merge votes and comments into.")); } if (empty($comments)) { return array(false, __("The comment field must not be empty.")); } $dbh = DB::connect(); $uid = uid_from_sid($_COOKIE["AURSID"]); /* TODO: Allow for filing multiple requests at once. */ $base_id = intval($ids[0]); $pkgbase_name = pkgbase_name_from_id($base_id); if ($merge_into == $pkgbase_name) { return array(false, __("Cannot merge a package base with itself.")); } $q = "SELECT ID FROM RequestTypes WHERE Name = " . $dbh->quote($type); $result = $dbh->query($q); if ($row = $result->fetch(PDO::FETCH_ASSOC)) { $type_id = $row['ID']; } else { return array(false, __("Invalid request type.")); } $q = "INSERT INTO PackageRequests "; $q .= "(ReqTypeID, PackageBaseID, PackageBaseName, MergeBaseName, "; $q .= "UsersID, Comments, RequestTS) VALUES (" . $type_id . ", "; $q .= $base_id . ", " . $dbh->quote($pkgbase_name) . ", "; $q .= $dbh->quote($merge_into) . ", " . $uid . ", "; $q .= $dbh->quote($comments) . ", UNIX_TIMESTAMP())"; $dbh->exec($q); $request_id = $dbh->lastInsertId(); /* Send e-mail notifications. */ $params = array('request-open', $uid, $request_id, $type, $base_id); if ($type === 'merge') { $params[] = $merge_into; } notify($params, $comments); $auto_orphan_age = config_get('options', 'auto_orphan_age'); $auto_delete_age = config_get('options', 'auto_delete_age'); $details = pkgbase_get_details($base_id); if ($type == 'orphan' && $details['OutOfDateTS'] > 0 && time() - $details['OutOfDateTS'] >= $auto_orphan_age && $auto_orphan_age > 0) { /* * Close package request. NOTE: This needs to happen *before* * the actual disown operation. Otherwise, the former * maintainer will not be included in the Cc list of the * request notification email. */ $out_of_date_time = gmdate("Y-m-d", intval($details["OutOfDateTS"])); pkgreq_close($request_id, "accepted", "The package base has been flagged out-of-date " . "since " . $out_of_date_time . ".", true); $q = "UPDATE PackageBases SET MaintainerUID = NULL "; $q .= "WHERE ID = " . $base_id; $dbh->exec($q); } else { if ($type == 'deletion' && $details['MaintainerUID'] == $uid && $details['SubmittedTS'] > 0 && $auto_delete_age > 0 && time() - $details['SubmittedTS'] <= $auto_delete_age) { /* * Close package request. NOTE: This needs to happen *before* * the actual deletion operation. Otherwise, the former * maintainer will not be included in the Cc list of the * request notification email. */ pkgreq_close($request_id, "accepted", "Deletion of a fresh package requested by its " . "current maintainer.", true); pkgbase_delete(array($base_id), NULL, NULL, true); } } return array(true, __("Added request successfully.")); }