Store package groups in the database
[aur.git] / web / lib / pkgfuncs.inc.php
blobf80d4b4bb39d9906ece885a559ffa5c03816390b
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
12 * @param string $atype The account type of the user trying to delete a comment
13 * @param string|int $uid The user ID of the individual trying to delete a comment
15 * @return bool True if the user can delete the comment, otherwise false
17 function can_delete_comment($comment_id=0, $atype="", $uid=0) {
18 if (!$uid) {
19 /* Unauthenticated users cannot delete anything. */
20 return false;
22 if ($atype == "Trusted User" || $atype == "Developer") {
23 /* TUs and developers can delete any comment. */
24 return true;
27 $dbh = DB::connect();
29 $q = "SELECT COUNT(*) FROM PackageComments ";
30 $q.= "WHERE ID = " . intval($comment_id) . " AND UsersID = " . $uid;
31 $result = $dbh->query($q);
33 if (!$result) {
34 return false;
37 $row = $result->fetch(PDO::FETCH_NUM);
38 return ($row[0] > 0);
41 /**
42 * Determine if the user can delete a specific package comment using an array
44 * Only the comment submitter, Trusted Users, and Developers can delete
45 * comments. This function is used for the frontend side of comment deletion.
47 * @param array $comment All database information relating a specific comment
48 * @param string $atype The account type of the user trying to delete a comment
49 * @param string|int $uid The user ID of the individual trying to delete a comment
51 * @return bool True if the user can delete the comment, otherwise false
53 function can_delete_comment_array($comment, $atype="", $uid=0) {
54 if (!$uid) {
55 /* Unauthenticated users cannot delete anything. */
56 return false;
57 } elseif ($atype == "Trusted User" || $atype == "Developer") {
58 /* TUs and developers can delete any comment. */
59 return true;
60 } else if ($comment['UsersID'] == $uid) {
61 /* Users can delete their own comments. */
62 return true;
64 return false;
67 /**
68 * Determine if the visitor can submit blacklisted packages.
70 * Only Trusted Users and Developers can delete blacklisted packages. Packages
71 * are blacklisted if they are include in the official repositories.
73 * @param string $atype The account type of the user
75 * @return bool True if the user can submit blacklisted packages, otherwise false
77 function can_submit_blacklisted($atype = "") {
78 if ($atype == "Trusted User" || $atype == "Developer") {
79 /* Only TUs and developers can submit blacklisted packages. */
80 return true;
82 else {
83 return false;
87 /**
88 * Check to see if the package name already exists in the database
90 * @param string $name The package name to check
92 * @return string|void Package name if it already exists
94 function pkg_from_name($name="") {
95 if (!$name) {return NULL;}
96 $dbh = DB::connect();
97 $q = "SELECT ID FROM Packages ";
98 $q.= "WHERE Name = " . $dbh->quote($name);
99 $result = $dbh->query($q);
100 if (!$result) {
101 return;
103 $row = $result->fetch(PDO::FETCH_NUM);
104 return $row[0];
108 * Get package dependencies for a specific package
110 * @param int $pkgid The package to get dependencies for
112 * @return array All package dependencies for the package
114 function pkg_dependencies($pkgid) {
115 $deps = array();
116 $pkgid = intval($pkgid);
117 if ($pkgid > 0) {
118 $dbh = DB::connect();
119 $q = "SELECT pd.DepName, dt.Name, pd.DepCondition, p.ID FROM PackageDepends pd ";
120 $q.= "LEFT JOIN Packages p ON pd.DepName = p.Name ";
121 $q.= "LEFT JOIN DependencyTypes dt ON dt.ID = pd.DepTypeID ";
122 $q.= "WHERE pd.PackageID = ". $pkgid . " ";
123 $q.= "ORDER BY pd.DepName";
124 $result = $dbh->query($q);
125 if (!$result) {
126 return array();
128 while ($row = $result->fetch(PDO::FETCH_NUM)) {
129 $deps[] = $row;
132 return $deps;
136 * Get package relations for a specific package
138 * @param int $pkgid The package to get relations for
140 * @return array All package relations for the package
142 function pkg_relations($pkgid) {
143 $rels = array();
144 $pkgid = intval($pkgid);
145 if ($pkgid > 0) {
146 $dbh = DB::connect();
147 $q = "SELECT pr.RelName, rt.Name, pr.RelCondition, p.ID FROM PackageRelations pr ";
148 $q.= "LEFT JOIN Packages p ON pr.RelName = p.Name ";
149 $q.= "LEFT JOIN RelationTypes rt ON rt.ID = pr.RelTypeID ";
150 $q.= "WHERE pr.PackageID = ". $pkgid . " ";
151 $q.= "ORDER BY pr.RelName";
152 $result = $dbh->query($q);
153 if (!$result) {
154 return array();
156 while ($row = $result->fetch(PDO::FETCH_NUM)) {
157 $rels[] = $row;
160 return $rels;
164 * Get the ID of a dependency type given its name
166 * @param string $name The name of the dependency type
168 * @return int The ID of the dependency type
170 function pkg_dependency_type_id_from_name($name) {
171 $dbh = DB::connect();
172 $q = "SELECT ID FROM DependencyTypes WHERE Name = ";
173 $q.= $dbh->quote($name);
174 $result = $dbh->query($q);
175 return $result->fetch(PDO::FETCH_COLUMN, 0);
179 * Get the ID of a relation type given its name
181 * @param string $name The name of the relation type
183 * @return int The ID of the relation type
185 function pkg_relation_type_id_from_name($name) {
186 $dbh = DB::connect();
187 $q = "SELECT ID FROM RelationTypes WHERE Name = ";
188 $q.= $dbh->quote($name);
189 $result = $dbh->query($q);
190 return $result->fetch(PDO::FETCH_COLUMN, 0);
194 * Get the HTML code to display a package dependency link
196 * @param string $name The name of the dependency
197 * @param string $type The name of the dependency type
198 * @param string $cond The package dependency condition string
199 * @param int $pkg_id The package of the package to display the dependency for
201 * @return string The HTML code of the label to display
203 function pkg_depend_link($name, $type, $cond, $pkg_id) {
204 if ($type == 'optdepends' && strpos($name, ':') !== false) {
205 $tokens = explode(':', $name, 2);
206 $name = $tokens[0];
207 $desc = $tokens[1];
208 } else {
209 $desc = '(unknown)';
212 $link = '<a href="';
213 if (is_null($pkg_id)) {
214 $link .= 'https://www.archlinux.org/packages/?q=' . urlencode($name);
215 } else {
216 $link .= htmlspecialchars(get_pkg_uri($name), ENT_QUOTES);
218 $link .= '" title="' . __('View packages details for') .' ' . htmlspecialchars($name) . '">';
219 $link .= htmlspecialchars($name) . '</a>';
220 $link .= htmlspecialchars($cond);
222 if ($type == 'makedepends') {
223 $link .= ' <em>(make)</em>';
224 } elseif ($type == 'checkdepends') {
225 $link .= ' <em>(check)</em>';
226 } elseif ($type == 'optdepends') {
227 $link .= ' <em>(optional) &ndash; ' . htmlspecialchars($desc) . ' </em>';
230 return $link;
234 * Determine packages that depend on a package
236 * @param string $name The package name for the dependency search
238 * @return array All packages that depend on the specified package name
240 function pkg_required($name="") {
241 $deps = array();
242 if ($name != "") {
243 $dbh = DB::connect();
244 $q = "SELECT DISTINCT p.Name, PackageID FROM PackageDepends pd ";
245 $q.= "JOIN Packages p ON pd.PackageID = p.ID ";
246 $q.= "WHERE DepName = " . $dbh->quote($name) . " ";
247 $q.= "ORDER BY p.Name";
248 $result = $dbh->query($q);
249 if (!$result) {return array();}
250 while ($row = $result->fetch(PDO::FETCH_NUM)) {
251 $deps[] = $row;
254 return $deps;
258 * Get all package sources for a specific package
260 * @param string $pkgid The package ID to get the sources for
262 * @return array All sources associated with a specific package
264 function pkg_sources($pkgid) {
265 $sources = array();
266 $pkgid = intval($pkgid);
267 if ($pkgid > 0) {
268 $dbh = DB::connect();
269 $q = "SELECT Source FROM PackageSources ";
270 $q.= "WHERE PackageID = " . $pkgid;
271 $q.= " ORDER BY Source";
272 $result = $dbh->query($q);
273 if (!$result) {
274 return array();
276 while ($row = $result->fetch(PDO::FETCH_NUM)) {
277 $sources[] = $row[0];
280 return $sources;
284 * Determine package names from package IDs
286 * @param string|array $pkgids The package IDs to get names for
288 * @return array|string All names if multiple package IDs, otherwise package name
290 function pkg_name_from_id($pkgids) {
291 if (is_array($pkgids)) {
292 $pkgids = sanitize_ids($pkgids);
293 $names = array();
294 $dbh = DB::connect();
295 $q = "SELECT Name FROM Packages WHERE ID IN (";
296 $q.= implode(",", $pkgids) . ")";
297 $result = $dbh->query($q);
298 if ($result) {
299 while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
300 $names[] = $row['Name'];
303 return $names;
305 elseif ($pkgids > 0) {
306 $dbh = DB::connect();
307 $q = "SELECT Name FROM Packages WHERE ID = " . $pkgids;
308 $result = $dbh->query($q);
309 if ($result) {
310 $name = $result->fetch(PDO::FETCH_NUM);
312 return $name[0];
314 else {
315 return NULL;
320 * Determine if a package name is on the database blacklist
322 * @param string $name The package name to check
324 * @return bool True if the name is blacklisted, otherwise false
326 function pkg_name_is_blacklisted($name) {
327 $dbh = DB::connect();
328 $q = "SELECT COUNT(*) FROM PackageBlacklist ";
329 $q.= "WHERE Name = " . $dbh->quote($name);
330 $result = $dbh->query($q);
332 if (!$result) return false;
333 return ($result->fetchColumn() > 0);
337 * Get the package details
339 * @param string $id The package ID to get description for
341 * @return array The package's details OR error message
343 function pkg_get_details($id=0) {
344 $dbh = DB::connect();
346 $q = "SELECT Packages.*, PackageBases.Name AS BaseName, ";
347 $q.= "PackageBases.CategoryID, PackageBases.NumVotes, ";
348 $q.= "PackageBases.OutOfDateTS, PackageBases.SubmittedTS, ";
349 $q.= "PackageBases.ModifiedTS, PackageBases.SubmitterUID, ";
350 $q.= "PackageBases.MaintainerUID, PackageCategories.Category ";
351 $q.= "FROM Packages, PackageBases, PackageCategories ";
352 $q.= "WHERE PackageBases.ID = Packages.PackageBaseID ";
353 $q.= "AND PackageBases.CategoryID = PackageCategories.ID ";
354 $q.= "AND Packages.ID = " . intval($id);
355 $result = $dbh->query($q);
357 $row = array();
359 if (!$result) {
360 $row['error'] = __("Error retrieving package details.");
362 else {
363 $row = $result->fetch(PDO::FETCH_ASSOC);
364 if (empty($row)) {
365 $row['error'] = __("Package details could not be found.");
369 return $row;
373 * Display the package details page
375 * @global string $AUR_LOCATION The AUR's URL used for notification e-mails
376 * @global bool $USE_VIRTUAL_URLS True if using URL rewriting, otherwise false
377 * @param string $id The package ID to get details page for
378 * @param array $row Package details retrieved by pkg_get_details()
379 * @param string $SID The session ID of the visitor
381 * @return void
383 function pkg_display_details($id=0, $row, $SID="") {
384 global $AUR_LOCATION;
385 global $USE_VIRTUAL_URLS;
387 $dbh = DB::connect();
389 if (isset($row['error'])) {
390 print "<p>" . $row['error'] . "</p>\n";
392 else {
393 $base_id = pkgbase_from_pkgid($id);
394 $pkgbase_name = pkgbase_name_from_id($base_id);
396 include('pkg_details.php');
398 if ($SID) {
399 include('actions_form.php');
400 include('pkg_comment_form.php');
403 $limit = isset($_GET['comments']) ? 0 : 10;
404 $comments = pkgbase_comments($base_id, $limit);
405 if (!empty($comments)) {
406 include('pkg_comments.php');
411 /* pkg_search_page(SID)
412 * outputs the body of search/search results page
414 * parameters:
415 * SID - current Session ID
416 * preconditions:
417 * package search page has been accessed
418 * request variables have not been sanitized
420 * request vars:
421 * O - starting result number
422 * PP - number of search hits per page
423 * C - package category ID number
424 * K - package search string
425 * SO - search hit sort order:
426 * values: a - ascending
427 * d - descending
428 * SB - sort search hits by:
429 * values: c - package category
430 * n - package name
431 * v - number of votes
432 * m - maintainer username
433 * SeB- property that search string (K) represents
434 * values: n - package name
435 * nd - package name & description
436 * x - package name (exact match)
437 * m - package maintainer's username
438 * s - package submitter's username
439 * do_Orphans - boolean. whether to search packages
440 * without a maintainer
443 * These two are actually handled in packages.php.
445 * IDs- integer array of ticked packages' IDs
446 * action - action to be taken on ticked packages
447 * values: do_Flag - Flag out-of-date
448 * do_UnFlag - Remove out-of-date flag
449 * do_Adopt - Adopt
450 * do_Disown - Disown
451 * do_Delete - Delete (requires confirm_Delete to be set)
452 * do_Notify - Enable notification
453 * do_UnNotify - Disable notification
455 function pkg_search_page($SID="") {
456 $dbh = DB::connect();
459 * Get commonly used variables.
460 * TODO: Reduce the number of database queries!
462 if ($SID)
463 $myuid = uid_from_sid($SID);
464 $cats = pkgbase_categories($dbh);
466 /* Sanitize paging variables. */
467 if (isset($_GET['O'])) {
468 $_GET['O'] = intval($_GET['O']);
469 if ($_GET['O'] < 0)
470 $_GET['O'] = 0;
472 else {
473 $_GET['O'] = 0;
476 if (isset($_GET["PP"])) {
477 $_GET["PP"] = intval($_GET["PP"]);
478 if ($_GET["PP"] < 50)
479 $_GET["PP"] = 50;
480 else if ($_GET["PP"] > 250)
481 $_GET["PP"] = 250;
483 else {
484 $_GET["PP"] = 50;
488 * FIXME: Pull out DB-related code. All of it! This one's worth a
489 * choco-chip cookie, one of those nice big soft ones.
492 /* Build the package search query. */
493 $q_select = "SELECT ";
494 if ($SID) {
495 $q_select .= "CommentNotify.UserID AS Notify,
496 PackageVotes.UsersID AS Voted, ";
498 $q_select .= "Users.Username AS Maintainer,
499 PackageCategories.Category,
500 Packages.Name, Packages.Version, Packages.Description,
501 PackageBases.NumVotes, Packages.ID, Packages.PackageBaseID,
502 PackageBases.OutOfDateTS ";
504 $q_from = "FROM Packages
505 LEFT JOIN PackageBases ON (PackageBases.ID = Packages.PackageBaseID)
506 LEFT JOIN Users ON (PackageBases.MaintainerUID = Users.ID)
507 LEFT JOIN PackageCategories
508 ON (PackageBases.CategoryID = PackageCategories.ID) ";
509 if ($SID) {
510 /* This is not needed for the total row count query. */
511 $q_from_extra = "LEFT JOIN PackageVotes
512 ON (PackageBases.ID = PackageVotes.PackageBaseID AND PackageVotes.UsersID = $myuid)
513 LEFT JOIN CommentNotify
514 ON (PackageBases.ID = CommentNotify.PackageBaseID AND CommentNotify.UserID = $myuid) ";
515 } else {
516 $q_from_extra = "";
519 $q_where = "WHERE 1 = 1 ";
521 * TODO: Possibly do string matching on category to make request
522 * variable values more sensible.
524 if (isset($_GET["C"]) && intval($_GET["C"])) {
525 $q_where .= "AND PackageBases.CategoryID = ".intval($_GET["C"])." ";
528 if (isset($_GET['K'])) {
529 if (isset($_GET["SeB"]) && $_GET["SeB"] == "m") {
530 /* Search by maintainer. */
531 $q_where .= "AND Users.Username = " . $dbh->quote($_GET['K']) . " ";
533 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "s") {
534 /* Search by submitter. */
535 $q_where .= "AND SubmitterUID = ".uid_from_username($_GET['K'])." ";
537 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "n") {
538 /* Search by name. */
539 $K = "%" . addcslashes($_GET['K'], '%_') . "%";
540 $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . ") ";
542 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "b") {
543 /* Search by package base name. */
544 $K = "%" . addcslashes($_GET['K'], '%_') . "%";
545 $q_where .= "AND (PackageBases.Name LIKE " . $dbh->quote($K) . ") ";
547 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "N") {
548 /* Search by name (exact match). */
549 $q_where .= "AND (Packages.Name = " . $dbh->quote($_GET['K']) . ") ";
551 elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "B") {
552 /* Search by package base name (exact match). */
553 $q_where .= "AND (PackageBases.Name = " . $dbh->quote($_GET['K']) . ") ";
555 else {
556 /* Search by name and description (default). */
557 $K = "%" . addcslashes($_GET['K'], '%_') . "%";
558 $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . " OR ";
559 $q_where .= "Description LIKE " . $dbh->quote($K) . ") ";
563 if (isset($_GET["do_Orphans"])) {
564 $q_where .= "AND MaintainerUID IS NULL ";
567 if (isset($_GET['outdated'])) {
568 if ($_GET['outdated'] == 'on') {
569 $q_where .= "AND OutOfDateTS IS NOT NULL ";
571 elseif ($_GET['outdated'] == 'off') {
572 $q_where .= "AND OutOfDateTS IS NULL ";
576 $order = (isset($_GET["SO"]) && $_GET["SO"] == 'd') ? 'DESC' : 'ASC';
578 $q_sort = "ORDER BY ";
579 $sort_by = isset($_GET["SB"]) ? $_GET["SB"] : '';
580 switch ($sort_by) {
581 case 'c':
582 $q_sort .= "CategoryID " . $order . ", ";
583 break;
584 case 'v':
585 $q_sort .= "NumVotes " . $order . ", ";
586 break;
587 case 'w':
588 if ($SID) {
589 $q_sort .= "Voted " . $order . ", ";
591 break;
592 case 'o':
593 if ($SID) {
594 $q_sort .= "Notify " . $order . ", ";
596 break;
597 case 'm':
598 $q_sort .= "Maintainer " . $order . ", ";
599 break;
600 case 'a':
601 $q_sort .= "ModifiedTS " . $order . ", ";
602 break;
603 default:
604 break;
606 $q_sort .= " Packages.Name " . $order . " ";
608 $q_limit = "LIMIT ".$_GET["PP"]." OFFSET ".$_GET["O"];
610 $q = $q_select . $q_from . $q_from_extra . $q_where . $q_sort . $q_limit;
611 $q_total = "SELECT COUNT(*) " . $q_from . $q_where;
613 $result = $dbh->query($q);
614 $result_t = $dbh->query($q_total);
615 if ($result_t) {
616 $row = $result_t->fetch(PDO::FETCH_NUM);
617 $total = $row[0];
619 else {
620 $total = 0;
623 if ($result && $total > 0) {
624 if (isset($_GET["SO"]) && $_GET["SO"] == "d"){
625 $SO_next = "a";
627 else {
628 $SO_next = "d";
632 /* Calculate the results to use. */
633 $first = $_GET['O'] + 1;
635 /* Calculation of pagination links. */
636 $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50;
637 $current = ceil($first / $per_page);
638 $pages = ceil($total / $per_page);
639 $templ_pages = array();
641 if ($current > 1) {
642 $templ_pages['&laquo; ' . __('First')] = 0;
643 $templ_pages['&lsaquo; ' . __('Previous')] = ($current - 2) * $per_page;
646 if ($current - 5 > 1)
647 $templ_pages["..."] = false;
649 for ($i = max($current - 5, 1); $i <= min($pages, $current + 5); $i++) {
650 $templ_pages[$i] = ($i - 1) * $per_page;
653 if ($current + 5 < $pages)
654 $templ_pages["... "] = false;
656 if ($current < $pages) {
657 $templ_pages[__('Next') . ' &rsaquo;'] = $current * $per_page;
658 $templ_pages[__('Last') . ' &raquo;'] = ($pages - 1) * $per_page;
661 include('pkg_search_form.php');
663 if ($result) {
664 while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
665 $searchresults[] = $row;
669 include('pkg_search_results.php');
671 return;
675 * Determine if a POST string has been sent by a visitor
677 * @param string $action String to check has been sent via POST
679 * @return bool True if the POST string was used, otherwise false
681 function current_action($action) {
682 return (isset($_POST['action']) && $_POST['action'] == $action) ||
683 isset($_POST[$action]);
687 * Determine if sent IDs are valid integers
689 * @param array $ids IDs to validate
691 * @return array All sent IDs that are valid integers
693 function sanitize_ids($ids) {
694 $new_ids = array();
695 foreach ($ids as $id) {
696 $id = intval($id);
697 if ($id > 0) {
698 $new_ids[] = $id;
701 return $new_ids;
705 * Get all package information in the database for a specific package
707 * @param string $pkgname The name of the package to get details for
709 * @return array All package details for a specific package
711 function pkg_details_by_name($pkgname) {
712 $dbh = DB::connect();
713 $q = "SELECT Packages.*, PackageBases.Name AS BaseName, ";
714 $q.= "PackageBases.CategoryID, PackageBases.NumVotes, ";
715 $q.= "PackageBases.OutOfDateTS, PackageBases.SubmittedTS, ";
716 $q.= "PackageBases.ModifiedTS, PackageBases.SubmitterUID, ";
717 $q.= "PackageBases.MaintainerUID FROM Packages ";
718 $q.= "INNER JOIN PackageBases ";
719 $q.= "ON PackageBases.ID = Packages.PackageBaseID WHERE ";
720 $q.= "Packages.Name = " . $dbh->quote($pkgname);
721 $result = $dbh->query($q);
722 if ($result) {
723 $row = $result->fetch(PDO::FETCH_ASSOC);
725 return $row;
729 * Add package information to the database for a specific package
731 * @param int $base_id ID of the package base
732 * @param string $pkgname Name of the new package
733 * @param string $license License of the new package
734 * @param string $pkgver Version of the new package
735 * @param string $pkgdesc Description of the new package
736 * @param string $pkgurl Upstream URL for the new package
738 * @return int ID of the new package
740 function pkg_create($base_id, $pkgname, $license, $pkgver, $pkgdesc, $pkgurl) {
741 $dbh = DB::connect();
742 $q = sprintf("INSERT INTO Packages (PackageBaseID, Name, License, " .
743 "Version, Description, URL) VALUES (%d, %s, %s, %s, %s, %s)",
744 $base_id, $dbh->quote($pkgname), $dbh->quote($license),
745 $dbh->quote($pkgver), $dbh->quote($pkgdesc),
746 $dbh->quote($pkgurl));
747 $dbh->exec($q);
748 return $dbh->lastInsertId();
752 * Add a dependency for a specific package to the database
754 * @param int $pkgid The package ID to add the dependency for
755 * @param string $type The type of dependency to add
756 * @param string $depname The name of the dependency to add
757 * @param string $depcondition The type of dependency for the package
759 * @return void
761 function pkg_add_dep($pkgid, $type, $depname, $depcondition) {
762 $dbh = DB::connect();
763 $q = sprintf("INSERT INTO PackageDepends (PackageID, DepTypeID, DepName, DepCondition) VALUES (%d, %d, %s, %s)",
764 $pkgid,
765 pkg_dependency_type_id_from_name($type),
766 $dbh->quote($depname),
767 $dbh->quote($depcondition)
769 $dbh->exec($q);
773 * Add a relation for a specific package to the database
775 * @param int $pkgid The package ID to add the relation for
776 * @param string $type The type of relation to add
777 * @param string $relname The name of the relation to add
778 * @param string $relcondition The version requirement of the relation
780 * @return void
782 function pkg_add_rel($pkgid, $type, $relname, $relcondition) {
783 $dbh = DB::connect();
784 $q = sprintf("INSERT INTO PackageRelations (PackageID, RelTypeID, RelName, RelCondition) VALUES (%d, %d, %s, %s)",
785 $pkgid,
786 pkg_relation_type_id_from_name($type),
787 $dbh->quote($relname),
788 $dbh->quote($relcondition)
790 $dbh->exec($q);
794 * Add a source for a specific package to the database
796 * @param int $pkgid The package ID to add the source for
797 * @param string $pkgsrc The package source to add to the database
799 * @return void
801 function pkg_add_src($pkgid, $pkgsrc) {
802 $dbh = DB::connect();
803 $q = "INSERT INTO PackageSources (PackageID, Source) VALUES (";
804 $q .= $pkgid . ", " . $dbh->quote($pkgsrc) . ")";
806 $dbh->exec($q);
810 * Creates a new group and returns its ID
812 * If the groups already exists, the ID of the already existing group is
813 * returned.
815 * @param string $name The name of the group to create
817 * @return int The ID of the group
819 function pkg_create_group($name) {
820 $dbh = DB::connect();
821 $q = sprintf("SELECT ID FROM Groups WHERE Name = %s", $dbh->quote($name));
822 $result = $dbh->query($q);
823 if ($result) {
824 $grpid = $result->fetch(PDO::FETCH_COLUMN, 0);
825 if ($grpid > 0) {
826 return $grpid;
830 $q = sprintf("INSERT INTO Groups (Name) VALUES (%s)", $dbh->quote($name));
831 $dbh->exec($q);
832 return $dbh->lastInsertId();
836 * Add a package to a group
838 * @param int $pkgid The package ID of the package to add
839 * @param int $grpid The group ID of the group to add the package to
841 * @return void
843 function pkg_add_grp($pkgid, $grpid) {
844 $dbh = DB::connect();
845 $q = sprintf("INSERT INTO PackageGroups (PackageID, GroupID) VALUES (%d, %d)",
846 $pkgid,
847 $grpid
849 $dbh->exec($q);