pkgreqfuncs.inc.php 7.63 KB
Newer Older
1
<?php
2
3

include_once("confparser.inc.php");
4
5
include_once("pkgbasefuncs.inc.php");

6
7
8
9
10
11
12
13
14
15
16
/**
 * Get the number of package requests
 *
 * @return int The total number of package requests
 */
function pkgreq_count() {
	$dbh = DB::connect();
	$q = "SELECT COUNT(*) FROM PackageRequests";
	return $dbh->query($q)->fetchColumn();
}

17
18
19
/**
 * Get a list of all package requests
 *
20
21
22
 * @param int $offset The index of the first request to return
 * @param int $limit The maximum number of requests to return
 *
23
24
 * @return array List of pacakge requests with details
 */
25
function pkgreq_list($offset, $limit) {
26
27
28
29
30
31
32
33
	$dbh = DB::connect();

	$q = "SELECT PackageRequests.ID, ";
	$q.= "PackageRequests.PackageBaseID AS BaseID, ";
	$q.= "PackageRequests.PackageBaseName AS Name, ";
	$q.= "PackageRequests.MergeBaseName AS MergeInto, ";
	$q.= "RequestTypes.Name AS Type, PackageRequests.Comments, ";
	$q.= "Users.Username AS User, PackageRequests.RequestTS, ";
34
	$q.= "PackageRequests.Status, PackageRequests.Status = 0 AS Open ";
35
36
37
	$q.= "FROM PackageRequests INNER JOIN RequestTypes ON ";
	$q.= "RequestTypes.ID = PackageRequests.ReqTypeID ";
	$q.= "INNER JOIN Users ON Users.ID = PackageRequests.UsersID ";
38
	$q.= "ORDER BY Open DESC, RequestTS DESC ";
39
	$q.= "LIMIT " . $limit . " OFFSET " . $offset;
40
41
42
43

	return $dbh->query($q)->fetchAll();
}

Lukas Fleischer's avatar
Lukas Fleischer committed
44
45
46
47
48
49
50
51
/**
 * Get a list of all open package requests belonging to a certain package base
 *
 * @param int $baseid The package base ID to retrieve requests for
 * @param int $type The type of requests to obtain
 *
 * @return array List of package request IDs
 */
52
function pkgreq_by_pkgbase($baseid, $type=false) {
Lukas Fleischer's avatar
Lukas Fleischer committed
53
54
55
56
57
58
	$dbh = DB::connect();

	$q = "SELECT PackageRequests.ID ";
	$q.= "FROM PackageRequests INNER JOIN RequestTypes ON ";
	$q.= "RequestTypes.ID = PackageRequests.ReqTypeID ";
	$q.= "WHERE PackageRequests.Status = 0 ";
59
60
61
62
63
	$q.= "AND PackageRequests.PackageBaseID = " . intval($baseid);

	if ($type) {
		$q .= " AND RequestTypes.Name = " . $dbh->quote($type);
	}
Lukas Fleischer's avatar
Lukas Fleischer committed
64
65
66
67

	return $dbh->query($q)->fetchAll(PDO::FETCH_COLUMN, 0);
}

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/**
 * Obtain the package base that belongs to a package request.
 *
 * @param int $id Package request ID to retrieve the package base for
 *
 * @return int The name of the corresponding package base
 */
function pkgreq_get_pkgbase_name($id) {
	$dbh = DB::connect();

	$q = "SELECT PackageBaseName FROM PackageRequests ";
	$q.= "WHERE ID = " . intval($id);
	$result = $dbh->query($q);
	return $result->fetch(PDO::FETCH_COLUMN, 0);
}

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/**
 * Obtain the email address of the creator of a package request
 *
 * @param int $id Package request ID to retrieve the creator for
 *
 * @return int The email address of the creator
 */
function pkgreq_get_creator_email($id) {
	$dbh = DB::connect();

	$q = "SELECT Email FROM Users INNER JOIN PackageRequests ";
	$q.= "ON Users.ID = PackageRequests.UsersID ";
	$q.= "WHERE PackageRequests.ID = " . intval($id);
	$result = $dbh->query($q);
	return $result->fetch(PDO::FETCH_COLUMN, 0);
}

101
102
103
104
105
106
107
108
/**
 * 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
 *
109
 * @return array Tuple of success/failure indicator and error message
110
 */
111
function pkgreq_file($ids, $type, $merge_into, $comments) {
112
113
114
115
	if (!has_credential(CRED_PKGREQ_FILE)) {
		return array(false, __("You must be logged in to file package requests."));
	}

116
	if (!empty($merge_into) && !preg_match("/^[a-z0-9][a-z0-9\.+_-]*$/D", $merge_into)) {
117
118
119
		return array(false, __("Invalid name: only lowercase letters are allowed."));
	}

120
121
122
123
	if (!empty($merge_into) && !pkgbase_from_name($merge_into)) {
		return array(false, __("Cannot find package to merge votes and comments into."));
	}

124
125
126
127
128
129
130
131
	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. */
132
	$base_id = intval($ids[0]);
133
134
	$pkgbase_name = pkgbase_name_from_id($base_id);

135
136
137
138
	if ($merge_into == $pkgbase_name) {
		return array(false, __("Cannot merge a package base with itself."));
	}

139
140
141
142
143
144
145
146
147
148
149
	$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 . ", ";
150
	$q.= $base_id . ", " .  $dbh->quote($pkgbase_name) . ", ";
151
	$q.= $dbh->quote($merge_into) . ", " . $uid . ", ";
152
	$q.= $dbh->quote($comments) . ", " . strval(time()) . ")";
153
154
155
	$dbh->exec($q);
	$request_id = $dbh->lastInsertId();

156
157
158
159
	/* Send e-mail notifications. */
	$params = array('request-open', $uid, $request_id, $type, $base_id);
	if ($type === 'merge') {
		$params[] = $merge_into;
160
	}
161
	notify($params);
162

163
	$auto_orphan_age = config_get('options', 'auto_orphan_age');
164
	$auto_delete_age = config_get('options', 'auto_delete_age');
165
166
	$details = pkgbase_get_details($base_id);
	if ($type == 'orphan' && $details['OutOfDateTS'] > 0 &&
167
168
	    time() - $details['OutOfDateTS'] >= $auto_orphan_age &&
	    $auto_orphan_age > 0) {
169
170
171
172
173
174
		/*
		 * 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.
		 */
175
		$out_of_date_time = gmdate("Y-m-d", intval($details["OutOfDateTS"]));
176
177
178
		pkgreq_close($request_id, "accepted",
			     "The package base has been flagged out-of-date " .
			     "since " . $out_of_date_time . ".", true);
179
180
181
		$q = "UPDATE PackageBases SET MaintainerUID = NULL ";
		$q.= "WHERE ID = " . $base_id;
		$dbh->exec($q);
182
183
184
185
186
187
188
189
190
191
192
193
194
	} 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);
195
196
	}

197
198
199
200
201
202
203
	return array(true, __("Added request successfully."));
}

/**
 * Close a deletion/orphan request
 *
 * @param int $id The package request to close
204
 * @param string $reason Whether the request was accepted or rejected
205
 * @param string $comments Comments to be added to the notification email
206
 * @param boolean $auto_close (optional) Whether the request is auto-closed
207
 *
208
 * @return array Tuple of success/failure indicator and error message
209
 */
210
function pkgreq_close($id, $reason, $comments, $auto_close=false) {
211
212
213
214
215
216
217
218
	switch ($reason) {
	case 'accepted':
		$status = 2;
		break;
	case 'rejected':
		$status = 3;
		break;
	default:
219
220
221
		return array(false, __("Invalid reason."));
	}

222
223
	$dbh = DB::connect();
	$id = intval($id);
224
	$uid = $auto_close ? 0 : uid_from_sid($_COOKIE["AURSID"]);
225

226
	if (!$auto_close && !has_credential(CRED_PKGREQ_CLOSE)) {
227
228
229
		return array(false, __("Only TUs and developers can close requests."));
	}

230
231
	$q = "UPDATE PackageRequests SET Status = " . intval($status) . ", ";
	$q.= "ClosureComment = " . $dbh->quote($comments) . " ";
232
	$q.= "WHERE ID = " . intval($id);
233
234
	$dbh->exec($q);

235
	/* Send e-mail notifications. */
236
	notify(array('request-close', $uid, $id, $reason));
237
238
239

	return array(true, __("Request closed successfully."));
}