Make deleted comments visible to Trusted Users
[aur.git] / web / lib / pkgfuncs.inc.php
blob69b1c94c34748e6eb44795584b742eb114b16e9e
1 <?php
2 include_once("config.inc.php");
3 include_once("pkgbasefuncs.inc.php");
5 /**
6 * Determine if the user can delete a specific package comment
8 * Only the comment submitter, Trusted Users, and Developers can delete
9 * comments. This function is used for the backend side of comment deletion.
11 * @param string $comment_id The comment ID in the database
13 * @return bool True if the user can delete the comment, otherwise false
15 function can_delete_comment($comment_id=0) {
16 if (!uid_from_sid($_COOKIE["AURSID"])) {
17 /* Unauthenticated users cannot delete anything. */
18 return false;
20 if (has_credential(CRED_COMMENT_DELETE)) {
21 /* TUs and developers can delete any comment. */
22 return true;
25 $dbh = DB::connect();
27 $q = "SELECT COUNT(*) FROM PackageComments ";
28 $q.= "WHERE ID = " . intval($comment_id) . " AND UsersID = " . $uid;
29 $result = $dbh->query($q);
31 if (!$result) {
32 return false;
35 $row = $result->fetch(PDO::FETCH_NUM);
36 return ($row[0] > 0);
39 /**
40 * Determine if the user can delete a specific package comment using an array
42 * Only the comment submitter, Trusted Users, and Developers can delete
43 * comments. This function is used for the frontend side of comment deletion.
45 * @param array $comment All database information relating a specific comment
47 * @return bool True if the user can delete the comment, otherwise false
49 function can_delete_comment_array($comment) {
50 return has_credential(CRED_COMMENT_DELETE, array($comment['UsersID']));
53 /**
54 * Determine if the visitor can submit blacklisted packages.
56 * Only Trusted Users and Developers can delete blacklisted packages. Packages
57 * are blacklisted if they are include in the official repositories.
59 * @return bool True if the user can submit blacklisted packages, otherwise false
61 function can_submit_blacklisted() {
62 return has_credential(CRED_PKGBASE_SUBMIT_BLACKLISTED);
65 /**
66 * Check to see if the package name already exists in the database
68 * @param string $name The package name to check
70 * @return string|void Package name if it already exists
72 function pkg_from_name($name="") {
73 if (!$name) {return NULL;}
74 $dbh = DB::connect();
75 $q = "SELECT ID FROM Packages ";
76 $q.= "WHERE Name = " . $dbh->quote($name);
77 $result = $dbh->query($q);
78 if (!$result) {
79 return;
81 $row = $result->fetch(PDO::FETCH_NUM);
82 return $row[0];
85 /**
86 * Get licenses for a specific package
88 * @param int $pkgid The package to get licenses for
90 * @return array All licenses for the package
92 function pkg_licenses($pkgid) {
93 $lics = array();
94 $pkgid = intval($pkgid);
95 if ($pkgid > 0) {
96 $dbh = DB::connect();
97 $q = "SELECT l.Name FROM Licenses l ";
98 $q.= "INNER JOIN PackageLicenses pl ON pl.LicenseID = l.ID ";
99 $q.= "WHERE pl.PackageID = ". $pkgid;
100 $result = $dbh->query($q);
101 if (!$result) {
102 return array();
104 while ($row = $result->fetch(PDO::FETCH_COLUMN, 0)) {
105 $lics[] = $row;
108 return $lics;
112 * Get package groups for a specific package
114 * @param int $pkgid The package to get groups for
116 * @return array All package groups for the package
118 function pkg_groups($pkgid) {
119 $grps = array();
120 $pkgid = intval($pkgid);
121 if ($pkgid > 0) {
122 $dbh = DB::connect();
123 $q = "SELECT g.Name FROM Groups g ";
124 $q.= "INNER JOIN PackageGroups pg ON pg.GroupID = g.ID ";
125 $q.= "WHERE pg.PackageID = ". $pkgid;
126 $result = $dbh->query($q);
127 if (!$result) {
128 return array();
130 while ($row = $result->fetch(PDO::FETCH_COLUMN, 0)) {
131 $grps[] = $row;
134 return $grps;
138 * Get package dependencies for a specific package
140 * @param int $pkgid The package to get dependencies for
142 * @return array All package dependencies for the package
144 function pkg_dependencies($pkgid) {
145 $deps = array();
146 $pkgid = intval($pkgid);
147 if ($pkgid > 0) {
148 $dbh = DB::connect();
149 $q = "SELECT pd.DepName, dt.Name, pd.DepCondition, p.ID FROM PackageDepends pd ";
150 $q.= "LEFT JOIN Packages p ON pd.DepName = p.Name ";
151 $q.= "OR SUBSTRING(pd.DepName FROM 1 FOR POSITION(': ' IN pd.DepName) - 1) = p.Name ";
152 $q.= "LEFT JOIN DependencyTypes dt ON dt.ID = pd.DepTypeID ";
153 $q.= "WHERE pd.PackageID = ". $pkgid . " ";
154 $q.= "ORDER BY pd.DepName";
155 $result = $dbh->query($q);
156 if (!$result) {
157 return array();
159 while ($row = $result->fetch(PDO::FETCH_NUM)) {
160 $deps[] = $row;
163 return $deps;
167 * Get package relations for a specific package
169 * @param int $pkgid The package to get relations for
171 * @return array All package relations for the package
173 function pkg_relations($pkgid) {
174 $rels = array();
175 $pkgid = intval($pkgid);
176 if ($pkgid > 0) {
177 $dbh = DB::connect();
178 $q = "SELECT pr.RelName, rt.Name, pr.RelCondition, p.ID FROM PackageRelations pr ";
179 $q.= "LEFT JOIN Packages p ON pr.RelName = p.Name ";
180 $q.= "LEFT JOIN RelationTypes rt ON rt.ID = pr.RelTypeID ";
181 $q.= "WHERE pr.PackageID = ". $pkgid . " ";
182 $q.= "ORDER BY pr.RelName";
183 $result = $dbh->query($q);
184 if (!$result) {
185 return array();
187 while ($row = $result->fetch(PDO::FETCH_NUM)) {
188 $rels[] = $row;
191 return $rels;
195 * Get the ID of a dependency type given its name
197 * @param string $name The name of the dependency type
199 * @return int The ID of the dependency type
201 function pkg_dependency_type_id_from_name($name) {
202 $dbh = DB::connect();
203 $q = "SELECT ID FROM DependencyTypes WHERE Name = ";
204 $q.= $dbh->quote($name);
205 $result = $dbh->query($q);
206 return $result->fetch(PDO::FETCH_COLUMN, 0);
210 * Get the ID of a relation type given its name
212 * @param string $name The name of the relation type
214 * @return int The ID of the relation type
216 function pkg_relation_type_id_from_name($name) {
217 $dbh = DB::connect();
218 $q = "SELECT ID FROM RelationTypes WHERE Name = ";
219 $q.= $dbh->quote($name);
220 $result = $dbh->query($q);
221 return $result->fetch(PDO::FETCH_COLUMN, 0);
225 * Get the HTML code to display a package dependency link
227 * @param string $name The name of the dependency
228 * @param string $type The name of the dependency type
229 * @param string $cond The package dependency condition string
230 * @param int $pkg_id The package of the package to display the dependency for
232 * @return string The HTML code of the label to display
234 function pkg_depend_link($name, $type, $cond, $pkg_id) {
235 if ($type == 'optdepends' && strpos($name, ':') !== false) {
236 $tokens = explode(':', $name, 2);
237 $name = $tokens[0];
238 $desc = $tokens[1];
239 } else {
240 $desc = '(unknown)';
243 $link = '<a href="';
244 if (is_null($pkg_id)) {
245 $link .= 'https://www.archlinux.org/packages/?q=' . urlencode($name);
246 } else {
247 $link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
249 $link .= '" title="' . __('View packages details for') .' ' . htmlspecialchars($name) . '">';
250 $link .= htmlspecialchars($name) . '</a>';
251 $link .= htmlspecialchars($cond);
253 if ($type == 'makedepends') {
254 $link .= ' <em>(make)</em>';
255 } elseif ($type == 'checkdepends') {
256 $link .= ' <em>(check)</em>';
257 } elseif ($type == 'optdepends') {
258 $link .= ' <em>(optional) &ndash; ' . htmlspecialchars($desc) . ' </em>';
261 return $link;
265 * Determine packages that depend on a package
267 * @param string $name The package name for the dependency search
269 * @return array All packages that depend on the specified package name
271 function pkg_required($name="") {
272 $deps = array();
273 if ($name != "") {
274 $dbh = DB::connect();
275 $q = "SELECT DISTINCT p.Name, PackageID FROM PackageDepends pd ";
276 $q.= "JOIN Packages p ON pd.PackageID = p.ID ";
277 $q.= "WHERE DepName = " . $dbh->quote($name) . " ";
278 $q.= "ORDER BY p.Name";
279 $result = $dbh->query($q);
280 if (!$result) {return array();}
281 while ($row = $result->fetch(PDO::FETCH_NUM)) {
282 $deps[] = $row;
285 return $deps;
289 * Get all package sources for a specific package
291 * @param string $pkgid The package ID to get the sources for
293 * @return array All sources associated with a specific package
295 function pkg_sources($pkgid) {
296 $sources = array();
297 $pkgid = intval($pkgid);
298 if ($pkgid > 0) {
299 $dbh = DB::connect();
300 $q = "SELECT Source FROM PackageSources ";
301 $q.= "WHERE PackageID = " . $pkgid;
302 $q.= " ORDER BY Source";
303 $result = $dbh->query($q);
304 if (!$result) {
305 return array();
307 while ($row = $result->fetch(PDO::FETCH_NUM)) {
308 $sources[] = $row[0];
311 return $sources;
315 * Determine package names from package IDs
317 * @param string|array $pkgids The package IDs to get names for
319 * @return array|string All names if multiple package IDs, otherwise package name
321 function pkg_name_from_id($pkgids) {
322 if (is_array($pkgids)) {
323 $pkgids = sanitize_ids($pkgids);
324 $names = array();
325 $dbh = DB::connect();
326 $q = "SELECT Name FROM Packages WHERE ID IN (";
327 $q.= implode(",", $pkgids) . ")";
328 $result = $dbh->query($q);
329 if ($result) {
330 while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
331 $names[] = $row['Name'];
334 return $names;
336 elseif ($pkgids > 0) {
337 $dbh = DB::connect();
338 $q = "SELECT Name FROM Packages WHERE ID = " . $pkgids;
339 $result = $dbh->query($q);
340 if ($result) {
341 $name = $result->fetch(PDO::FETCH_NUM);
343 return $name[0];
345 else {
346 return NULL;
351 * Determine if a package name is on the database blacklist
353 * @param string $name The package name to check
355 * @return bool True if the name is blacklisted, otherwise false
357 function pkg_name_is_blacklisted($name) {
358 $dbh = DB::connect();
359 $q = "SELECT COUNT(*) FROM PackageBlacklist ";
360 $q.= "WHERE Name = " . $dbh->quote($name);
361 $result = $dbh->query($q);
363 if (!$result) return false;
364 return ($result->fetchColumn() > 0);
368 * Get the package details
370 * @param string $id The package ID to get description for
372 * @return array The package's details OR error message
374 function pkg_get_details($id=0) {
375 $dbh = DB::connect();
377 $q = "SELECT Packages.*, PackageBases.ID AS BaseID, ";
378 $q.= "PackageBases.Name AS BaseName, PackageBases.CategoryID, ";
379 $q.= "PackageBases.NumVotes, PackageBases.OutOfDateTS, ";
380 $q.= "PackageBases.SubmittedTS, PackageBases.ModifiedTS, ";
381 $q.= "PackageBases.SubmitterUID, PackageBases.MaintainerUID, ";
382 $q.= "PackageBases.PackagerUID, PackageCategories.Category, ";
383 $q.= "(SELECT COUNT(*) FROM PackageRequests ";
384 $q.= " WHERE PackageRequests.PackageBaseID = Packages.PackageBaseID ";
385 $q.= " AND PackageRequests.Status = 0) AS RequestCount ";
386 $q.= "FROM Packages, PackageBases, PackageCategories ";
387 $q.= "WHERE PackageBases.ID = Packages.PackageBaseID ";
388 $q.= "AND PackageBases.CategoryID = PackageCategories.ID ";
389 $q.= "AND Packages.ID = " . intval($id);
390 $result = $dbh->query($q);
392 $row = array();
394 if (!$result) {
395 $row['error'] = __("Error retrieving package details.");
397 else {
398 $row = $result->fetch(PDO::FETCH_ASSOC);
399 if (empty($row)) {
400 $row['error'] = __("Package details could not be found.");
404 return $row;
408 * Display the package details page
410 * @global string $AUR_LOCATION The AUR's URL used for notification e-mails
411 * @global bool $USE_VIRTUAL_URLS True if using URL rewriting, otherwise false
412 * @param string $id The package ID to get details page for
413 * @param array $row Package details retrieved by pkg_get_details()
414 * @param string $SID The session ID of the visitor
416 * @return void
418 function pkg_display_details($id=0, $row, $SID="") {
419 global $AUR_LOCATION;
420 global $USE_VIRTUAL_URLS;
422 $dbh = DB::connect();
424 if (isset($row['error'])) {
425 print "<p>" . $row['error'] . "</p>\n";
427 else {
428 $base_id = pkgbase_from_pkgid($id);
429 $pkgbase_name = pkgbase_name_from_id($base_id);
431 include('pkg_details.php');
433 if ($SID) {
434 include('actions_form.php');
435 include('pkg_comment_form.php');
438 $limit = isset($_GET['comments']) ? 0 : 10;
439 $include_deleted = has_credential(CRED_COMMENT_VIEW_DELETED);
440 $comments = pkgbase_comments($base_id, $limit, $include_deleted);
441 if (!empty($comments)) {
442 include('pkg_comments.php');
447 /* pkg_search_page(SID)
448 * outputs the body of search/search results page
450 * parameters:
451 * SID - current Session ID
452 * preconditions:
453 * package search page has been accessed
454 * request variables have not been sanitized
456 * request vars:
457 * O - starting result number
458 * PP - number of search hits per page
459 * C - package category ID number
460 * K - package search string
461 * SO - search hit sort order:
462 * values: a - ascending
463 * d - descending
464 * SB - sort search hits by:
465 * values: c - package category
466 * n - package name
467 * v - number of votes
468 * m - maintainer username
469 * SeB- property that search string (K) represents
470 * values: n - package name
471 * nd - package name & description
472 * x - package name (exact match)
473 * m - package maintainer's username
474 * s - package submitter's username
475 * do_Orphans - boolean. whether to search packages
476 * without a maintainer
479 * These two are actually handled in packages.php.
481 * IDs- integer array of ticked packages' IDs
482 * action - action to be taken on ticked packages
483 * values: do_Flag - Flag out-of-date
484 * do_UnFlag - Remove out-of-date flag
485 * do_Adopt - Adopt
486 * do_Disown - Disown
487 * do_Delete - Delete (requires confirm_Delete to be set)
488 * do_Notify - Enable notification
489 * do_UnNotify - Disable notification
491 function pkg_search_page($SID="") {
492 $dbh = DB::connect();
495 * Get commonly used variables.
496 * TODO: Reduce the number of database queries!
498 if ($SID)
499 $myuid = uid_from_sid($SID);
500 $cats = pkgbase_categories($dbh);
502 /* Sanitize paging variables. */
503 if (isset($_GET['O'])) {
504 $_GET['O'] = max(intval($_GET['O']), 0);
505 } else {
506 $_GET['O'] = 0;
509 if (isset($_GET["PP"])) {
510 $_GET["PP"] = bound(intval($_GET["PP"]), 50, 250);
511 } else {
512 $_GET["PP"] = 50;
516 * FIXME: Pull out DB-related code. All of it! This one's worth a
517 * choco-chip cookie, one of those nice big soft ones.
520 /* Build the package search query. */
521 $q_select = "SELECT ";
522 if ($SID) {
523 $q_select .= "CommentNotify.UserID AS Notify,
524 PackageVotes.UsersID AS Voted, ";
526 $q_select .= "Users.Username AS Maintainer,
527 PackageCategories.Category,
528 Packages.Name, Packages.Version, Packages.Description,
529 PackageBases.NumVotes, Packages.ID, Packages.PackageBaseID,
530 PackageBases.OutOfDateTS ";
532 $q_from = "FROM Packages
533 LEFT JOIN PackageBases ON (PackageBases.ID = Packages.PackageBaseID)
534 LEFT JOIN Users ON (PackageBases.MaintainerUID = Users.ID)
535 LEFT JOIN PackageCategories
536 ON (PackageBases.CategoryID = PackageCategories.ID) ";
537 if ($SID) {
538 /* This is not needed for the total row count query. */
539 $q_from_extra = "LEFT JOIN PackageVotes
540 ON (PackageBases.ID = PackageVotes.PackageBaseID AND PackageVotes.UsersID = $myuid)
541 LEFT JOIN CommentNotify
542 ON (PackageBases.ID = CommentNotify.PackageBaseID AND CommentNotify.UserID = $myuid) ";
543 } else {
544 $q_from_extra = "";
547 $q_where = "WHERE 1 = 1 ";
549 * TODO: Possibly do string matching on category to make request
550 * variable values more sensible.
552 if (isset($_GET["C"]) && intval($_GET["C"])) {
553 $q_where .= "AND PackageBases.CategoryID = ".intval($_GET["C"])." ";
556 if (isset($_GET['K'])) {
557 if (isset($_GET["SeB"]) && $_GET["SeB"] == "m") {
558 /* Search by maintainer. */
559 $q_where .= "AND Users.Username = " . $dbh->quote($_GET['K']) . " ";
561 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "s") {
562 /* Search by submitter. */
563 $q_where .= "AND SubmitterUID = " . intval(uid_from_username($_GET['K'])) . " ";
565 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "n") {
566 /* Search by name. */
567 $K = "%" . addcslashes($_GET['K'], '%_') . "%";
568 $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . ") ";
570 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "b") {
571 /* Search by package base name. */
572 $K = "%" . addcslashes($_GET['K'], '%_') . "%";
573 $q_where .= "AND (PackageBases.Name LIKE " . $dbh->quote($K) . ") ";
575 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "N") {
576 /* Search by name (exact match). */
577 $q_where .= "AND (Packages.Name = " . $dbh->quote($_GET['K']) . ") ";
579 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "B") {
580 /* Search by package base name (exact match). */
581 $q_where .= "AND (PackageBases.Name = " . $dbh->quote($_GET['K']) . ") ";
583 else {
584 /* Search by name and description (default). */
585 $K = "%" . addcslashes($_GET['K'], '%_') . "%";
586 $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . " OR ";
587 $q_where .= "Description LIKE " . $dbh->quote($K) . ") ";
591 if (isset($_GET["do_Orphans"])) {
592 $q_where .= "AND MaintainerUID IS NULL ";
595 if (isset($_GET['outdated'])) {
596 if ($_GET['outdated'] == 'on') {
597 $q_where .= "AND OutOfDateTS IS NOT NULL ";
599 elseif ($_GET['outdated'] == 'off') {
600 $q_where .= "AND OutOfDateTS IS NULL ";
604 $order = (isset($_GET["SO"]) && $_GET["SO"] == 'd') ? 'DESC' : 'ASC';
606 $q_sort = "ORDER BY ";
607 $sort_by = isset($_GET["SB"]) ? $_GET["SB"] : '';
608 switch ($sort_by) {
609 case 'c':
610 $q_sort .= "CategoryID " . $order . ", ";
611 break;
612 case 'v':
613 $q_sort .= "NumVotes " . $order . ", ";
614 break;
615 case 'w':
616 if ($SID) {
617 $q_sort .= "Voted " . $order . ", ";
619 break;
620 case 'o':
621 if ($SID) {
622 $q_sort .= "Notify " . $order . ", ";
624 break;
625 case 'm':
626 $q_sort .= "Maintainer " . $order . ", ";
627 break;
628 case 'a':
629 $q_sort .= "ModifiedTS " . $order . ", ";
630 break;
631 default:
632 break;
634 $q_sort .= " Packages.Name " . $order . " ";
636 $q_limit = "LIMIT ".$_GET["PP"]." OFFSET ".$_GET["O"];
638 $q = $q_select . $q_from . $q_from_extra . $q_where . $q_sort . $q_limit;
639 $q_total = "SELECT COUNT(*) " . $q_from . $q_where;
641 $result = $dbh->query($q);
642 $result_t = $dbh->query($q_total);
643 if ($result_t) {
644 $row = $result_t->fetch(PDO::FETCH_NUM);
645 $total = $row[0];
647 else {
648 $total = 0;
651 if ($result && $total > 0) {
652 if (isset($_GET["SO"]) && $_GET["SO"] == "d"){
653 $SO_next = "a";
655 else {
656 $SO_next = "d";
660 /* Calculate the results to use. */
661 $first = $_GET['O'] + 1;
663 /* Calculation of pagination links. */
664 $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50;
665 $current = ceil($first / $per_page);
666 $pages = ceil($total / $per_page);
667 $templ_pages = array();
669 if ($current > 1) {
670 $templ_pages['&laquo; ' . __('First')] = 0;
671 $templ_pages['&lsaquo; ' . __('Previous')] = ($current - 2) * $per_page;
674 if ($current - 5 > 1)
675 $templ_pages["..."] = false;
677 for ($i = max($current - 5, 1); $i <= min($pages, $current + 5); $i++) {
678 $templ_pages[$i] = ($i - 1) * $per_page;
681 if ($current + 5 < $pages)
682 $templ_pages["... "] = false;
684 if ($current < $pages) {
685 $templ_pages[__('Next') . ' &rsaquo;'] = $current * $per_page;
686 $templ_pages[__('Last') . ' &raquo;'] = ($pages - 1) * $per_page;
689 include('pkg_search_form.php');
691 if ($result) {
692 while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
693 $searchresults[] = $row;
697 include('pkg_search_results.php');
699 return;
703 * Determine if a POST string has been sent by a visitor
705 * @param string $action String to check has been sent via POST
707 * @return bool True if the POST string was used, otherwise false
709 function current_action($action) {
710 return (isset($_POST['action']) && $_POST['action'] == $action) ||
711 isset($_POST[$action]);
715 * Determine if sent IDs are valid integers
717 * @param array $ids IDs to validate
719 * @return array All sent IDs that are valid integers
721 function sanitize_ids($ids) {
722 $new_ids = array();
723 foreach ($ids as $id) {
724 $id = intval($id);
725 if ($id > 0) {
726 $new_ids[] = $id;
729 return $new_ids;
733 * Add package information to the database for a specific package
735 * @param int $base_id ID of the package base
736 * @param string $pkgname Name of the new package
737 * @param string $pkgver Version of the new package
738 * @param string $pkgdesc Description of the new package
739 * @param string $pkgurl Upstream URL for the new package
741 * @return int ID of the new package
743 function pkg_create($base_id, $pkgname, $pkgver, $pkgdesc, $pkgurl) {
744 $dbh = DB::connect();
745 $q = sprintf("INSERT INTO Packages (PackageBaseID, Name, Version, " .
746 "Description, URL) VALUES (%d, %s, %s, %s, %s)",
747 $base_id, $dbh->quote($pkgname), $dbh->quote($pkgver),
748 $dbh->quote($pkgdesc), $dbh->quote($pkgurl));
749 $dbh->exec($q);
750 return $dbh->lastInsertId();
754 * Add a dependency for a specific package to the database
756 * @param int $pkgid The package ID to add the dependency for
757 * @param string $type The type of dependency to add
758 * @param string $depname The name of the dependency to add
759 * @param string $depcondition The type of dependency for the package
761 * @return void
763 function pkg_add_dep($pkgid, $type, $depname, $depcondition) {
764 $dbh = DB::connect();
765 $q = sprintf("INSERT INTO PackageDepends (PackageID, DepTypeID, DepName, DepCondition) VALUES (%d, %d, %s, %s)",
766 $pkgid,
767 pkg_dependency_type_id_from_name($type),
768 $dbh->quote($depname),
769 $dbh->quote($depcondition)
771 $dbh->exec($q);
775 * Add a relation for a specific package to the database
777 * @param int $pkgid The package ID to add the relation for
778 * @param string $type The type of relation to add
779 * @param string $relname The name of the relation to add
780 * @param string $relcondition The version requirement of the relation
782 * @return void
784 function pkg_add_rel($pkgid, $type, $relname, $relcondition) {
785 $dbh = DB::connect();
786 $q = sprintf("INSERT INTO PackageRelations (PackageID, RelTypeID, RelName, RelCondition) VALUES (%d, %d, %s, %s)",
787 $pkgid,
788 pkg_relation_type_id_from_name($type),
789 $dbh->quote($relname),
790 $dbh->quote($relcondition)
792 $dbh->exec($q);
796 * Add a source for a specific package to the database
798 * @param int $pkgid The package ID to add the source for
799 * @param string $pkgsrc The package source to add to the database
801 * @return void
803 function pkg_add_src($pkgid, $pkgsrc) {
804 $dbh = DB::connect();
805 $q = "INSERT INTO PackageSources (PackageID, Source) VALUES (";
806 $q .= $pkgid . ", " . $dbh->quote($pkgsrc) . ")";
808 $dbh->exec($q);
812 * Creates a new group and returns its ID
814 * If the groups already exists, the ID of the already existing group is
815 * returned.
817 * @param string $name The name of the group to create
819 * @return int The ID of the group
821 function pkg_create_group($name) {
822 $dbh = DB::connect();
823 $q = sprintf("SELECT ID FROM Groups WHERE Name = %s", $dbh->quote($name));
824 $result = $dbh->query($q);
825 if ($result) {
826 $grpid = $result->fetch(PDO::FETCH_COLUMN, 0);
827 if ($grpid > 0) {
828 return $grpid;
832 $q = sprintf("INSERT INTO Groups (Name) VALUES (%s)", $dbh->quote($name));
833 $dbh->exec($q);
834 return $dbh->lastInsertId();
838 * Add a package to a group
840 * @param int $pkgid The package ID of the package to add
841 * @param int $grpid The group ID of the group to add the package to
843 * @return void
845 function pkg_add_grp($pkgid, $grpid) {
846 $dbh = DB::connect();
847 $q = sprintf("INSERT INTO PackageGroups (PackageID, GroupID) VALUES (%d, %d)",
848 $pkgid,
849 $grpid
851 $dbh->exec($q);
855 * Creates a new license and returns its ID
857 * If the license already exists, the ID of the already existing license is
858 * returned.
860 * @param string $name The name of the license to create
862 * @return int The ID of the license
864 function pkg_create_license($name) {
865 $dbh = DB::connect();
866 $q = sprintf("SELECT ID FROM Licenses WHERE Name = %s", $dbh->quote($name));
867 $result = $dbh->query($q);
868 if ($result) {
869 $licid = $result->fetch(PDO::FETCH_COLUMN, 0);
870 if ($licid > 0) {
871 return $licid;
875 $q = sprintf("INSERT INTO Licenses (Name) VALUES (%s)", $dbh->quote($name));
876 $dbh->exec($q);
877 return $dbh->lastInsertId();
881 * Add a license to a package
883 * @param int $pkgid The package ID of the package
884 * @param int $grpid The ID of the license to add
886 * @return void
888 function pkg_add_lic($pkgid, $licid) {
889 $dbh = DB::connect();
890 $q = sprintf("INSERT INTO PackageLicenses (PackageID, LicenseID) VALUES (%d, %d)",
891 $pkgid,
892 $licid
894 $dbh->exec($q);
898 * Determine package information for latest package
900 * @param int $numpkgs Number of packages to get information on
902 * @return array $packages Package info for the specified number of recent packages
904 function latest_pkgs($numpkgs) {
905 $dbh = DB::connect();
907 $q = "SELECT Packages.*, MaintainerUID, SubmittedTS ";
908 $q.= "FROM Packages LEFT JOIN PackageBases ON ";
909 $q.= "PackageBases.ID = Packages.PackageBaseID ";
910 $q.= "ORDER BY SubmittedTS DESC ";
911 $q.= "LIMIT " . intval($numpkgs);
912 $result = $dbh->query($q);
914 $packages = array();
915 if ($result) {
916 while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
917 $packages[] = $row;
921 return $packages;