[aur-dev] [PATCH 00/13] Split package support
This patch series adds full .AURINFO support and split package support. Implementing this requires massive database layout changes and thus, a lot of patches in this series are quite invasive. Things that need to be done: * Testing, the patches are still experimental. * Fix and extend the RPC interface. Suggestions? * Do a lot of refactoring and code cleanup. Lukas Fleischer (13): Add provisional support for package bases Store comments on a per-package base basis routing.inc.php: Add get_pkgbase_uri() Make the delete function remove package bases Add full support for the new .AURINFO format Add package base detail pages pkg_details.php: Add link to package base details Do not allow for overwriting arbitrary packages Factor out PKGBUILD parsing Only parse PKGBUILD when required UPGRADING: Add migration instructions for 3.0.0 Allow for searching by package base name Move package actions to package bases UPGRADING | 124 +++++++++ schema/aur-schema.sql | 44 +-- schema/gendummydata.py | 18 +- web/html/index.php | 18 +- web/html/packages.php | 75 ----- web/html/pkgbase.php | 135 +++++++++ web/html/pkgdel.php | 10 +- web/html/pkgmerge.php | 10 +- web/html/pkgsubmit.php | 432 +++++++++++------------------ web/lib/aur.inc.php | 34 ++- web/lib/pkgbuild-parser.inc.php | 139 ++++++++++ web/lib/pkgfuncs.inc.php | 540 +++++++++++++++++++++++++----------- web/lib/routing.inc.php | 18 ++ web/lib/stats.inc.php | 21 +- web/template/pkg_comment_form.php | 4 +- web/template/pkg_comments.php | 10 +- web/template/pkg_details.php | 34 ++- web/template/pkg_search_form.php | 4 +- web/template/pkg_search_results.php | 4 +- web/template/pkgbase_details.php | 210 ++++++++++++++ 20 files changed, 1304 insertions(+), 580 deletions(-) create mode 100644 web/html/pkgbase.php create mode 100644 web/lib/pkgbuild-parser.inc.php create mode 100644 web/template/pkgbase_details.php -- 1.9.1
This adds a PackageBases table to the database schema and moves the following fields from the Packages table to PackageBases: * CategoryID * NumVotes * OutOfDateTS * SubmittedTS * ModifiedTS * SubmitterUID * MaintainerUID It also fixes all database accesses to comply with the new layout. Having a separate PackageBases table is the first step to split package support. By now, we create one PackageBases entry per package (where the package base has the same name as the corresponding package). When adding full support for split packages later, the package base name will be derived from the pkgbase variable and a single package base will be shared amongst all packages built from one source package. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- schema/aur-schema.sql | 32 ++++--- schema/gendummydata.py | 16 ++-- web/html/pkgsubmit.php | 27 +++--- web/lib/aur.inc.php | 15 +--- web/lib/pkgfuncs.inc.php | 229 +++++++++++++++++++++++++++++++---------------- web/lib/stats.inc.php | 21 +++-- 6 files changed, 213 insertions(+), 127 deletions(-) diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index 932c1d3..a885b7a 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -92,16 +92,12 @@ INSERT INTO PackageCategories (Category) VALUES ('xfce'); INSERT INTO PackageCategories (Category) VALUES ('fonts'); --- Information about the actual packages +-- Information on package bases -- -CREATE TABLE Packages ( +CREATE TABLE PackageBases ( ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, Name VARCHAR(64) NOT NULL, - Version VARCHAR(32) NOT NULL DEFAULT '', CategoryID TINYINT UNSIGNED NOT NULL DEFAULT 1, - Description VARCHAR(255) NOT NULL DEFAULT "An Arch Package", - URL VARCHAR(255) NOT NULL DEFAULT "https://www.archlinux.org", - License VARCHAR(40) NOT NULL DEFAULT '', NumVotes INTEGER UNSIGNED NOT NULL DEFAULT 0, OutOfDateTS BIGINT UNSIGNED NULL DEFAULT NULL, SubmittedTS BIGINT UNSIGNED NOT NULL, @@ -121,6 +117,22 @@ CREATE TABLE Packages ( ) ENGINE = InnoDB; +-- Information about the actual packages +-- +CREATE TABLE Packages ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + PackageBaseID INTEGER UNSIGNED NOT NULL, + Name VARCHAR(64) NOT NULL, + Version VARCHAR(32) NOT NULL DEFAULT '', + Description VARCHAR(255) NOT NULL DEFAULT "An Arch Package", + URL VARCHAR(255) NOT NULL DEFAULT "https://www.archlinux.org", + License VARCHAR(40) NOT NULL DEFAULT '', + PRIMARY KEY (ID), + UNIQUE (Name), + FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE +) ENGINE = InnoDB; + + -- Track which dependencies a package has -- CREATE TABLE PackageDepends ( @@ -147,13 +159,13 @@ CREATE TABLE PackageSources ( -- CREATE TABLE PackageVotes ( UsersID INTEGER UNSIGNED NOT NULL, - PackageID INTEGER UNSIGNED NOT NULL, + PackageBaseID INTEGER UNSIGNED NOT NULL, INDEX (UsersID), - INDEX (PackageID), + INDEX (PackageBaseID), FOREIGN KEY (UsersID) REFERENCES Users(ID) ON DELETE CASCADE, - FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE + FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE ) ENGINE = InnoDB; -CREATE UNIQUE INDEX VoteUsersIDPackageID ON PackageVotes (UsersID, PackageID); +CREATE UNIQUE INDEX VoteUsersIDPackageID ON PackageVotes (UsersID, PackageBaseID); -- Record comments for packages -- diff --git a/schema/gendummydata.py b/schema/gendummydata.py index 361d1f9..c2cb388 100755 --- a/schema/gendummydata.py +++ b/schema/gendummydata.py @@ -199,12 +199,16 @@ for p in list(seen_pkgs.keys()): uuid = genUID() # the submitter/user - s = ("INSERT INTO Packages (ID, Name, Version, CategoryID," - " SubmittedTS, SubmitterUID, MaintainerUID) VALUES " - " (%d, '%s', '%s', %d, %d, %d, %s);\n") - s = s % (seen_pkgs[p], p, genVersion(), genCategory(), NOW, uuid, muid) + s = ("INSERT INTO PackageBases (ID, Name, CategoryID, SubmittedTS, " + "SubmitterUID, MaintainerUID) VALUES (%d, '%s', %d, %d, %d, %s);\n") + s = s % (seen_pkgs[p], p, genCategory(), NOW, uuid, muid) + out.write(s) + s = ("INSERT INTO Packages (ID, PackageBaseID, Name, Version) VALUES " + "(%d, %d, '%s', '%s');\n") + s = s % (seen_pkgs[p], seen_pkgs[p], p, genVersion()) out.write(s) + count += 1 # create random comments for this package @@ -228,7 +232,7 @@ for u in user_keys: for v in range(num_votes): pkg = random.randrange(1, len(seen_pkgs) + 1) if pkg not in pkgvote: - s = ("INSERT INTO PackageVotes (UsersID, PackageID)" + s = ("INSERT INTO PackageVotes (UsersID, PackageBaseID)" " VALUES (%d, %d);\n") s = s % (seen_users[u], pkg) pkgvote[pkg] = 1 @@ -240,7 +244,7 @@ for u in user_keys: # Update statements for package votes # for p in list(track_votes.keys()): - s = "UPDATE Packages SET NumVotes = %d WHERE ID = %d;\n" + s = "UPDATE PackageBases SET NumVotes = %d WHERE ID = %d;\n" s = s % (track_votes[p], p) out.write(s) diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 373af35..38fbb8c 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -354,7 +354,7 @@ if ($uid): if (!$error) { # First, see if this package already exists, and if it can be overwritten $pkg_id = pkgid_from_name($pkg_name); - if (can_submit_pkg($pkg_name, $_COOKIE["AURSID"])) { + if (can_submit_pkgbase($pkg_name, $_COOKIE["AURSID"])) { if (file_exists($incoming_pkgdir)) { # Blow away the existing file/dir and contents rm_tree($incoming_pkgdir); @@ -409,24 +409,25 @@ if ($uid): # This is an overwrite of an existing package, the database ID # needs to be preserved so that any votes are retained. However, # PackageDepends and PackageSources can be purged. - $packageID = $pdata["ID"]; + $pkgid = $pdata["ID"]; + $base_id = pkgbase_from_pkgid($pkgid); # Flush out old data that will be replaced with new data - remove_pkg_deps($packageID); - remove_pkg_sources($packageID); + remove_pkg_deps($pkgid); + remove_pkg_sources($pkgid); # If a new category was chosen, change it to that if ($category_id > 1) { - update_pkg_category($packageID, $category_id); + update_pkgbase_category($base_id, $category_id); } - # Update package data - update_pkgdetails($new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url'], $uid, $packageID); + # Update package base and package data + update_pkgbase($base_id, $new_pkgbuild['pkgname'], $uid); + update_pkg($pkgid, $new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url']); } else { # This is a brand new package - new_pkgdetails($new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $category_id, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url'], $uid); - $packageID = last_insert_id(); - + $base_id = create_pkgbase($new_pkgbuild['pkgname'], $category_id, $uid); + $pkgid = create_pkg($base_id, $new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url']); } # Update package depends @@ -444,7 +445,7 @@ if ($uid): else if ($deppkgname == "#") { break; } - add_pkg_dep($packageID, $deppkgname, $depcondition); + add_pkg_dep($pkgid, $deppkgname, $depcondition); } } @@ -452,14 +453,14 @@ if ($uid): if (!empty($new_pkgbuild['source'])) { $sources = explode(" ", $new_pkgbuild['source']); foreach ($sources as $src) { - add_pkg_src($packageID, $src); + add_pkg_src($pkgid, $src); } } # If we just created this package, or it was an orphan and we # auto-adopted, add submitting user to the notification list. if (!$pdata || $pdata["MaintainerUID"] === NULL) { - pkg_notify(account_from_sid($_COOKIE["AURSID"]), array($packageID), true); + pkg_notify(account_from_sid($_COOKIE["AURSID"]), array($pkgid), true); } # Entire package creation process is atomic diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index b3a800c..e786e50 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -292,11 +292,11 @@ function html_footer($ver="") { * * @return int 0 if the user can't submit, 1 if the user can submit */ -function can_submit_pkg($name="", $sid="") { +function can_submit_pkgbase($name="", $sid="") { if (!$name || !$sid) {return 0;} $dbh = DB::connect(); $q = "SELECT MaintainerUID "; - $q.= "FROM Packages WHERE Name = " . $dbh->quote($name); + $q.= "FROM PackageBases WHERE Name = " . $dbh->quote($name); $result = $dbh->query($q); $row = $result->fetch(PDO::FETCH_NUM); @@ -531,17 +531,6 @@ function end_atomic_commit() { } /** - * - * Determine the row ID for the most recently insterted row - * - * @return string The ID of the last inserted row - */ -function last_insert_id() { - $dbh = DB::connect(); - return $dbh->lastInsertId(); -} - -/** * Determine package information for latest package * * @param int $numpkgs Number of packages to get information on diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 47b8b6a..e8ac9f7 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -342,7 +342,7 @@ function pkgvotes_from_sid($sid="") { $pkgs = array(); if (!$sid) {return $pkgs;} $dbh = DB::connect(); - $q = "SELECT PackageID "; + $q = "SELECT PackageBaseID "; $q.= "FROM PackageVotes, Users, Sessions "; $q.= "WHERE Users.ID = Sessions.UsersID "; $q.= "AND Users.ID = PackageVotes.UsersID "; @@ -419,9 +419,14 @@ function pkgname_is_blacklisted($name) { function get_package_details($id=0) { $dbh = DB::connect(); - $q = "SELECT Packages.*,Category "; - $q.= "FROM Packages,PackageCategories "; - $q.= "WHERE Packages.CategoryID = PackageCategories.ID "; + $q = "SELECT Packages.*, PackageBases.Name AS BaseName, "; + $q.= "PackageBases.CategoryID, PackageBases.NumVotes, "; + $q.= "PackageBases.OutOfDateTS, PackageBases.SubmittedTS, "; + $q.= "PackageBases.ModifiedTS, PackageBases.SubmitterUID, "; + $q.= "PackageBases.MaintainerUID, PackageCategories.Category "; + $q.= "FROM Packages, PackageBases, PackageCategories "; + $q.= "WHERE PackageBases.ID = Packages.PackageBaseID "; + $q.= "AND PackageBases.CategoryID = PackageCategories.ID "; $q.= "AND Packages.ID = " . intval($id); $result = $dbh->query($q); @@ -565,17 +570,18 @@ function pkg_search_page($SID="") { } $q_select .= "Users.Username AS Maintainer, PackageCategories.Category, - Packages.Name, Packages.Version, Packages.Description, Packages.NumVotes, - Packages.ID, Packages.OutOfDateTS "; + Packages.Name, Packages.Version, Packages.Description, + PackageBases.NumVotes, Packages.ID, PackageBases.OutOfDateTS "; $q_from = "FROM Packages - LEFT JOIN Users ON (Packages.MaintainerUID = Users.ID) + LEFT JOIN PackageBases ON (PackageBases.ID = Packages.PackageBaseID) + LEFT JOIN Users ON (PackageBases.MaintainerUID = Users.ID) LEFT JOIN PackageCategories - ON (Packages.CategoryID = PackageCategories.ID) "; + ON (PackageBases.CategoryID = PackageCategories.ID) "; if ($SID) { /* This is not needed for the total row count query. */ $q_from_extra = "LEFT JOIN PackageVotes - ON (Packages.ID = PackageVotes.PackageID AND PackageVotes.UsersID = $myuid) + ON (PackageBases.ID = PackageVotes.PackageBaseID AND PackageVotes.UsersID = $myuid) LEFT JOIN CommentNotify ON (Packages.ID = CommentNotify.PkgID AND CommentNotify.UserID = $myuid) "; } else { @@ -603,16 +609,16 @@ function pkg_search_page($SID="") { elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "n") { /* Search by name. */ $K = "%" . addcslashes($_GET['K'], '%_') . "%"; - $q_where .= "AND (Name LIKE " . $dbh->quote($K) . ") "; + $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . ") "; } elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "x") { /* Search by name (exact match). */ - $q_where .= "AND (Name = " . $dbh->quote($_GET['K']) . ") "; + $q_where .= "AND (Packages.Name = " . $dbh->quote($_GET['K']) . ") "; } else { /* Search by name and description (default). */ $K = "%" . addcslashes($_GET['K'], '%_') . "%"; - $q_where .= "AND (Name LIKE " . $dbh->quote($K) . " OR "; + $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . " OR "; $q_where .= "Description LIKE " . $dbh->quote($K) . ") "; } } @@ -632,34 +638,35 @@ function pkg_search_page($SID="") { $order = (isset($_GET["SO"]) && $_GET["SO"] == 'd') ? 'DESC' : 'ASC'; - $q_sort = "ORDER BY Name ".$order." "; + $q_sort = "ORDER BY "; $sort_by = isset($_GET["SB"]) ? $_GET["SB"] : ''; switch ($sort_by) { case 'c': - $q_sort = "ORDER BY CategoryID ".$order.", Name ASC "; + $q_sort .= "CategoryID " . $order . ", "; break; case 'v': - $q_sort = "ORDER BY NumVotes ".$order.", Name ASC "; + $q_sort .= "NumVotes " . $order . ", "; break; case 'w': if ($SID) { - $q_sort = "ORDER BY Voted ".$order.", Name ASC "; + $q_sort .= "Voted " . $order . ", "; } break; case 'o': if ($SID) { - $q_sort = "ORDER BY Notify ".$order.", Name ASC "; + $q_sort .= "Notify " . $order . ", "; } break; case 'm': - $q_sort = "ORDER BY Maintainer ".$order.", Name ASC "; + $q_sort .= "Maintainer " . $order . ", "; break; case 'a': - $q_sort = "ORDER BY ModifiedTS ".$order.", Name ASC "; + $q_sort .= "ModifiedTS " . $order . ", "; break; default: break; } + $q_sort .= " Packages.Name " . $order . " "; $q_limit = "LIMIT ".$_GET["PP"]." OFFSET ".$_GET["O"]; @@ -758,6 +765,29 @@ function sanitize_ids($ids) { } /** + * Convert a list of package IDs into a list of corresponding package bases. + * + * @param array|int $ids Array of package IDs to convert + * + * @return array|int List of package base IDs + */ +function pkgbase_from_pkgid($ids) { + $dbh = DB::connect(); + + if (is_array($ids)) { + $q = "SELECT PackageBaseID FROM Packages "; + $q.= "WHERE ID IN (" . implode(",", $ids) . ")"; + $result = $dbh->query($q); + return $result->fetchAll(PDO::FETCH_COLUMN, 0); + } else { + $q = "SELECT PackageBaseID FROM Packages "; + $q.= "WHERE ID = " . $ids; + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_COLUMN, 0); + } +} + +/** * Flag package(s) as out-of-date * * @global string $AUR_LOCATION The AUR's URL used for notification e-mails @@ -774,15 +804,16 @@ function pkg_flag($atype, $ids) { } $ids = sanitize_ids($ids); + $base_ids = pkgbase_from_pkgid($ids); if (empty($ids)) { return array(false, __("You did not select any packages to flag.")); } $dbh = DB::connect(); - $q = "UPDATE Packages SET"; + $q = "UPDATE PackageBases SET"; $q.= " OutOfDateTS = UNIX_TIMESTAMP()"; - $q.= " WHERE ID IN (" . implode(",", $ids) . ")"; + $q.= " WHERE ID IN (" . implode(",", $base_ids) . ")"; $q.= " AND OutOfDateTS IS NULL"; $affected_pkgs = $dbh->exec($q); @@ -830,15 +861,16 @@ function pkg_unflag($atype, $ids) { } $ids = sanitize_ids($ids); + $base_ids = pkgbase_from_pkgid($ids); if (empty($ids)) { return array(false, __("You did not select any packages to unflag.")); } $dbh = DB::connect(); - $q = "UPDATE Packages SET "; + $q = "UPDATE PackageBases SET "; $q.= "OutOfDateTS = NULL "; - $q.= "WHERE ID IN (" . implode(",", $ids) . ") "; + $q.= "WHERE ID IN (" . implode(",", $base_ids) . ") "; if ($atype != "Trusted User" && $atype != "Developer") { $q.= "AND MaintainerUID = " . uid_from_sid($_COOKIE["AURSID"]); @@ -870,6 +902,7 @@ function pkg_delete ($atype, $ids, $mergepkgid) { } $ids = sanitize_ids($ids); + $base_ids = pkgbase_from_pkgid($ids); if (empty($ids)) { return array(false, __("You did not select any packages to delete.")); } @@ -878,6 +911,7 @@ function pkg_delete ($atype, $ids, $mergepkgid) { if ($mergepkgid) { $mergepkgname = pkgname_from_id($mergepkgid); + $mergepkgbase = pkgbase_from_pkgid($mergepkgid); } /* Send e-mail notifications. */ @@ -931,28 +965,32 @@ function pkg_delete ($atype, $ids, $mergepkgid) { $dbh->exec($q); /* Merge votes */ - foreach ($ids as $pkgid) { + foreach ($base_ids as $base_id) { $q = "UPDATE PackageVotes "; - $q.= "SET PackageID = " . intval($mergepkgid) . " "; - $q.= "WHERE PackageID = " . $pkgid . " "; + $q.= "SET PackageBaseID = " . intval($mergepkgbase) . " "; + $q.= "WHERE PackageBaseID = " . $base_id . " "; $q.= "AND UsersID NOT IN ("; $q.= "SELECT * FROM (SELECT UsersID "; $q.= "FROM PackageVotes "; - $q.= "WHERE PackageID = " . intval($mergepkgid); + $q.= "WHERE PackageBaseID = " . intval($mergepkgbase); $q.= ") temp)"; $dbh->exec($q); } - $q = "UPDATE Packages "; + $q = "UPDATE PackageBases "; $q.= "SET NumVotes = (SELECT COUNT(*) FROM PackageVotes "; - $q.= "WHERE PackageID = " . intval($mergepkgid) . ") "; - $q.= "WHERE ID = " . intval($mergepkgid); + $q.= "WHERE PackageBaseID = " . intval($mergepkgbase) . ") "; + $q.= "WHERE ID = " . intval($mergepkgbase); $dbh->exec($q); } $q = "DELETE FROM Packages WHERE ID IN (" . implode(",", $ids) . ")"; $result = $dbh->exec($q); + /* Deleting a package also removes the corresponding package base. */ + $q = "DELETE FROM PackageBases WHERE ID IN (" . implode(",", $base_ids) . ")"; + $result = $dbh->exec($q); + return array(true, __("The selected packages have been deleted.")); } @@ -974,7 +1012,8 @@ function pkg_adopt ($atype, $ids, $action=true) { } } - $ids = sanitize_ids($ids); + $pkg_ids = sanitize_ids($ids); + $ids = pkgbase_from_pkgid($pkg_ids); if (empty($ids)) { if ($action) { return array(false, __("You did not select any packages to adopt.")); @@ -986,7 +1025,7 @@ function pkg_adopt ($atype, $ids, $action=true) { $dbh = DB::connect(); $field = "MaintainerUID"; - $q = "UPDATE Packages "; + $q = "UPDATE PackageBases "; if ($action) { $user = uid_from_sid($_COOKIE["AURSID"]); @@ -1007,7 +1046,7 @@ function pkg_adopt ($atype, $ids, $action=true) { $dbh->exec($q); if ($action) { - pkg_notify(account_from_sid($_COOKIE["AURSID"]), $ids); + pkg_notify(account_from_sid($_COOKIE["AURSID"]), $pkg_ids); return array(true, __("The selected packages have been adopted.")); } else { return array(true, __("The selected packages have been disowned.")); @@ -1033,6 +1072,7 @@ function pkg_vote ($atype, $ids, $action=true) { } $ids = sanitize_ids($ids); + $base_ids = pkgbase_from_pkgid($ids); if (empty($ids)) { if ($action) { return array(false, __("You did not select any packages to vote for.")); @@ -1046,7 +1086,7 @@ function pkg_vote ($atype, $ids, $action=true) { $uid = uid_from_sid($_COOKIE["AURSID"]); $first = 1; - foreach ($ids as $pid) { + foreach ($base_ids as $pid) { if ($action) { $check = !isset($my_votes[$pid]); } else { @@ -1071,17 +1111,17 @@ function pkg_vote ($atype, $ids, $action=true) { /* Only add votes for packages the user hasn't already voted for. */ $op = $action ? "+" : "-"; - $q = "UPDATE Packages SET NumVotes = NumVotes $op 1 "; + $q = "UPDATE PackageBases SET NumVotes = NumVotes $op 1 "; $q.= "WHERE ID IN ($vote_ids)"; $dbh->exec($q); if ($action) { - $q = "INSERT INTO PackageVotes (UsersID, PackageID) VALUES "; + $q = "INSERT INTO PackageVotes (UsersID, PackageBaseID) VALUES "; $q.= $vote_clauses; } else { $q = "DELETE FROM PackageVotes WHERE UsersID = $uid "; - $q.= "AND PackageID IN ($vote_ids)"; + $q.= "AND PackageBaseID IN ($vote_ids)"; } $dbh->exec($q); @@ -1105,7 +1145,7 @@ function votes_for_pkgname($pkgname) { $q = "SELECT UsersID,Username,Name FROM PackageVotes "; $q.= "LEFT JOIN Users on (UsersID = Users.ID) "; - $q.= "LEFT JOIN Packages on (PackageID = Packages.ID) "; + $q.= "LEFT JOIN Packages on (PackageVotes.PackageBaseID = Packages.PackageBaseID) "; $q.= "WHERE Name = ". $dbh->quote($pkgname) . " "; $q.= "ORDER BY Username"; $result = $dbh->query($q); @@ -1133,8 +1173,10 @@ function votes_for_pkgname($pkgname) { function user_voted($uid, $pkgid) { $dbh = DB::connect(); - $q = "SELECT * FROM PackageVotes WHERE UsersID = ". $dbh->quote($uid); - $q.= " AND PackageID = " . $dbh->quote($pkgid); + $q = "SELECT * FROM PackageVotes, Packages WHERE "; + $q.= "PackageVotes.UsersID = ". $dbh->quote($uid) . " AND "; + $q.= "PackageVotes.PackageBaseID = Packages.PackageBaseID AND "; + $q.= "Packages.ID = " . $dbh->quote($pkgid); $result = $dbh->query($q); if ($result->fetch(PDO::FETCH_NUM)) { @@ -1301,10 +1343,10 @@ function pkg_change_category($pid, $atype) { return array(false, __("Invalid category ID.")); } + $base_id = pkgbase_from_pkgid($pid); + /* Verify package ownership. */ - $q = "SELECT Packages.MaintainerUID "; - $q.= "FROM Packages "; - $q.= "WHERE Packages.ID = ".$pid; + $q = "SELECT MaintainerUID FROM PackageBases WHERE ID = " . $base_id; $result = $dbh->query($q); if ($result) { $row = $result->fetch(PDO::FETCH_ASSOC); @@ -1316,9 +1358,9 @@ function pkg_change_category($pid, $atype) { $uid = uid_from_sid($_COOKIE["AURSID"]); if ($uid == $row["MaintainerUID"] || ($atype == "Developer" || $atype == "Trusted User")) { - $q = "UPDATE Packages "; + $q = "UPDATE PackageBases "; $q.= "SET CategoryID = ".intval($category_id)." "; - $q.= "WHERE ID = ".intval($pid); + $q.= "WHERE ID = ".intval($base_id); $dbh->exec($q); return array(true, __("Package category changed.")); } else { @@ -1335,7 +1377,14 @@ function pkg_change_category($pid, $atype) { */ function pkgdetails_by_pkgname($pkgname) { $dbh = DB::connect(); - $q = "SELECT * FROM Packages WHERE Name = " . $dbh->quote($pkgname); + $q = "SELECT Packages.*, PackageBases.Name AS BaseName, "; + $q.= "PackageBases.CategoryID, PackageBases.NumVotes, "; + $q.= "PackageBases.OutOfDateTS, PackageBases.SubmittedTS, "; + $q.= "PackageBases.ModifiedTS, PackageBases.SubmitterUID, "; + $q.= "PackageBases.MaintainerUID FROM Packages "; + $q.= "INNER JOIN PackageBases "; + $q.= "ON PackageBases.ID = Packages.PackageBaseID WHERE "; + $q.= "Packages.Name = " . $dbh->quote($pkgname); $result = $dbh->query($q); if ($result) { $row = $result->fetch(PDO::FETCH_ASSOC); @@ -1344,30 +1393,62 @@ function pkgdetails_by_pkgname($pkgname) { } /** + * Add package base information to the database + * + * @param string $name Name of the new package base + * @param int $category_id Category for the new package base + * @param int $uid User ID of the package uploader + * + * @return int ID of the new package base + */ +function create_pkgbase($name, $category_id, $uid) { + $dbh = DB::connect(); + $q = sprintf("INSERT INTO PackageBases (Name, CategoryID, " . + "SubmittedTS, ModifiedTS, SubmitterUID, MaintainerUID) " . + "VALUES (%s, %d, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), %d, %d)", + $dbh->quote($name), $category_id, $uid, $uid); + $dbh->exec($q); + return $dbh->lastInsertId(); +} + +/** * Add package information to the database for a specific package * + * @param int $base_id ID of the package base * @param string $pkgname Name of the new package * @param string $license License of the new package * @param string $pkgver Version of the new package - * @param int $category_id Category for the new package * @param string $pkgdesc Description of the new package * @param string $pkgurl Upstream URL for the new package + * + * @return int ID of the new package + */ +function create_pkg($base_id, $pkgname, $license, $pkgver, $pkgdesc, $pkgurl) { + $dbh = DB::connect(); + $q = sprintf("INSERT INTO Packages (PackageBaseID, Name, License, " . + "Version, Description, URL) VALUES (%d, %s, %s, %s, %s, %s)", + $base_id, $dbh->quote($pkgname), $dbh->quote($license), + $dbh->quote($pkgver), $dbh->quote($pkgdesc), + $dbh->quote($pkgurl)); + $dbh->exec($q); + return $dbh->lastInsertId(); +} + +/** + * Update package base information for a specific package base + * + * @param string $name Name of the updated package base + * @param int $base_id The package base ID of the affected package * @param int $uid User ID of the package uploader * * @return void */ -function new_pkgdetails($pkgname, $license, $pkgver, $category_id, $pkgdesc, $pkgurl, $uid) { +function update_pkgbase($base_id, $name, $uid) { $dbh = DB::connect(); - $q = sprintf("INSERT INTO Packages (Name, License, Version, CategoryID, Description, URL, SubmittedTS, ModifiedTS, SubmitterUID, MaintainerUID) VALUES (%s, %s, %s, %d, %s, %s, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(), %d, %d)", - $dbh->quote($pkgname), - $dbh->quote($license), - $dbh->quote($pkgver), - $category_id, - $dbh->quote($pkgdesc), - $dbh->quote($pkgurl), - $uid, - $uid); - + $q = sprintf("UPDATE PackageBases SET " . + "Name = %s, ModifiedTS = UNIX_TIMESTAMP(), " . + "MaintainerUID = %d, OutOfDateTS = NULL WHERE ID = %d", + $dbh->quote($name), $uid, $base_id); $dbh->exec($q); } @@ -1384,18 +1465,16 @@ function new_pkgdetails($pkgname, $license, $pkgver, $category_id, $pkgdesc, $pk * * @return void */ -function update_pkgdetails($pkgname, $license, $pkgver, $pkgdesc, $pkgurl, $uid, $pkgid) { +function update_pkg($pkgname, $license, $pkgver, $pkgdesc, $pkgurl, $pkgid) { $dbh = DB::connect(); - /* This is an overwrite of an existing package! */ - $q = sprintf("UPDATE Packages SET ModifiedTS = UNIX_TIMESTAMP(), Name = %s, Version = %s, License = %s, Description = %s, URL = %s, OutOfDateTS = NULL, MaintainerUID = %d WHERE ID = %d", - $dbh->quote($pkgname), - $dbh->quote($pkgver), - $dbh->quote($license), - $dbh->quote($pkgdesc), - $dbh->quote($pkgurl), - $uid, - $pkgid); - + $q = sprintf("UPDATE Packages SET Name = %s, Version = %s, " . + "License = %s, Description = %s, URL = %s WHERE ID = %d", + $dbh->quote($pkgname), + $dbh->quote($pkgver), + $dbh->quote($license), + $dbh->quote($pkgdesc), + $dbh->quote($pkgurl), + $pkgid); $dbh->exec($q); } @@ -1435,19 +1514,17 @@ function add_pkg_src($pkgid, $pkgsrc) { } /** - * Change the category a package belongs to + * Change the category a package base belongs to * - * @param int $pkgid The package ID to change the category for + * @param int $base_id The package base ID to change the category for * @param int $category_id The new category ID for the package * * @return void */ -function update_pkg_category($pkgid, $category_id) { +function update_pkgbase_category($base_id, $category_id) { $dbh = DB::connect(); - $q = sprintf( "UPDATE Packages SET CategoryID = %d WHERE ID = %d", - $category_id, - $pkgid); - + $q = sprintf("UPDATE PackageBases SET CategoryID = %d WHERE ID = %d", + $category_id, $base_id); $dbh->exec($q); } diff --git a/web/lib/stats.inc.php b/web/lib/stats.inc.php index e0e0b02..da3542a 100644 --- a/web/lib/stats.inc.php +++ b/web/lib/stats.inc.php @@ -11,7 +11,10 @@ function updates_table() { $dbh = DB::connect(); $key = 'recent_updates'; if(!($newest_packages = get_cache_value($key))) { - $q = 'SELECT * FROM Packages ORDER BY ModifiedTS DESC LIMIT 10'; + $q = 'SELECT Packages.Name, Version, ModifiedTS, SubmittedTS '; + $q.= 'FROM Packages INNER JOIN PackageBases ON '; + $q.= 'Packages.PackageBaseID = PackageBases.ID '; + $q.= 'ORDER BY ModifiedTS DESC LIMIT 10'; $result = $dbh->query($q); $newest_packages = new ArrayObject(); @@ -31,12 +34,12 @@ function updates_table() { * @return void */ function user_table($userid) { - $base_q = "SELECT count(*) FROM Packages WHERE Packages.MaintainerUID = " . $userid; + $base_q = "SELECT COUNT(*) FROM PackageBases WHERE MaintainerUID = " . $userid; $maintainer_unsupported_count = db_cache_value($base_q, 'user_unsupported_count:' . $userid); - $q = "SELECT count(*) FROM Packages WHERE Packages.OutOfDateTS IS NOT NULL AND Packages.MaintainerUID = " . $userid; + $q = "SELECT COUNT(*) FROM PackageBases WHERE OutOfDateTS IS NOT NULL AND MaintainerUID = " . $userid; $flagged_outdated = db_cache_value($q, 'user_flagged_outdated:' . $userid); @@ -50,10 +53,10 @@ function user_table($userid) { */ function general_stats_table() { # AUR statistics - $q = "SELECT count(*) FROM Packages"; + $q = "SELECT COUNT(*) FROM PackageBases"; $unsupported_count = db_cache_value($q, 'unsupported_count'); - $q = "SELECT count(*) FROM Packages WHERE MaintainerUID IS NULL"; + $q = "SELECT COUNT(*) FROM PackageBases WHERE MaintainerUID IS NULL"; $orphan_count = db_cache_value($q, 'orphan_count'); $q = "SELECT count(*) FROM Users"; @@ -65,16 +68,16 @@ function general_stats_table() { $targstamp = intval(strtotime("-7 days")); $yearstamp = intval(strtotime("-1 year")); - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $targstamp AND Packages.ModifiedTS = Packages.SubmittedTS"; + $q = "SELECT COUNT(*) FROM PackageBases WHERE ModifiedTS >= $targstamp AND ModifiedTS = SubmittedTS"; $add_count = db_cache_value($q, 'add_count'); - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $targstamp AND Packages.ModifiedTS != Packages.SubmittedTS"; + $q = "SELECT COUNT(*) FROM PackageBases WHERE ModifiedTS >= $targstamp AND ModifiedTS != SubmittedTS"; $update_count = db_cache_value($q, 'update_count'); - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS >= $yearstamp AND Packages.ModifiedTS != Packages.SubmittedTS"; + $q = "SELECT COUNT(*) FROM PackageBases WHERE ModifiedTS >= $yearstamp AND ModifiedTS != SubmittedTS"; $update_year_count = db_cache_value($q, 'update_year_count'); - $q = "SELECT count(*) FROM Packages WHERE Packages.ModifiedTS = Packages.SubmittedTS"; + $q = "SELECT COUNT(*) FROM PackageBases WHERE ModifiedTS = SubmittedTS"; $never_update_count = db_cache_value($q, 'never_update_count'); include('stats/general_stats_table.php'); -- 1.9.1
Move comments from the Packages table to PackageBases. Sharing comments makes sense since they almost always refer to a source package. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- schema/aur-schema.sql | 12 +++---- schema/gendummydata.py | 2 +- web/lib/pkgfuncs.inc.php | 79 ++++++++++++++++++++++--------------------- web/template/pkg_comments.php | 3 +- 4 files changed, 49 insertions(+), 47 deletions(-) diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql index a885b7a..9426a61 100644 --- a/schema/aur-schema.sql +++ b/schema/aur-schema.sql @@ -171,28 +171,28 @@ CREATE UNIQUE INDEX VoteUsersIDPackageID ON PackageVotes (UsersID, PackageBaseID -- CREATE TABLE PackageComments ( ID BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, - PackageID INTEGER UNSIGNED NOT NULL, + PackageBaseID INTEGER UNSIGNED NOT NULL, UsersID INTEGER UNSIGNED NULL DEFAULT NULL, Comments TEXT NOT NULL DEFAULT '', CommentTS BIGINT UNSIGNED NOT NULL DEFAULT 0, DelUsersID INTEGER UNSIGNED NULL DEFAULT NULL, PRIMARY KEY (ID), INDEX (UsersID), - INDEX (PackageID), + INDEX (PackageBaseID), FOREIGN KEY (UsersID) REFERENCES Users(ID) ON DELETE SET NULL, FOREIGN KEY (DelUsersID) REFERENCES Users(ID) ON DELETE CASCADE, - FOREIGN KEY (PackageID) REFERENCES Packages(ID) ON DELETE CASCADE + FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE ) ENGINE = InnoDB; -- Comment addition notifications -- CREATE TABLE CommentNotify ( - PkgID INTEGER UNSIGNED NOT NULL, + PackageBaseID INTEGER UNSIGNED NOT NULL, UserID INTEGER UNSIGNED NOT NULL, - FOREIGN KEY (PkgID) REFERENCES Packages(ID) ON DELETE CASCADE, + FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE, FOREIGN KEY (UserID) REFERENCES Users(ID) ON DELETE CASCADE ) ENGINE = InnoDB; -CREATE UNIQUE INDEX NotifyUserIDPkgID ON CommentNotify (UserID, PkgID); +CREATE UNIQUE INDEX NotifyUserIDPkgID ON CommentNotify (UserID, PackageBaseID); -- Package name blacklist -- diff --git a/schema/gendummydata.py b/schema/gendummydata.py index c2cb388..bc0ede8 100755 --- a/schema/gendummydata.py +++ b/schema/gendummydata.py @@ -216,7 +216,7 @@ for p in list(seen_pkgs.keys()): num_comments = random.randrange(PKG_CMNTS[0], PKG_CMNTS[1]) for i in range(0, num_comments): now = NOW + random.randrange(400, 86400*3) - s = ("INSERT INTO PackageComments (PackageID, UsersID," + s = ("INSERT INTO PackageComments (PackageBaseID, UsersID," " Comments, CommentTS) VALUES (%d, %d, '%s', %d);\n") s = s % (seen_pkgs[p], genUID(), genFortune(), now) out.write(s) diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index e8ac9f7..4b317f5 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -176,20 +176,20 @@ function package_required($name="") { } /** - * Get the number of non-deleted comments for a specific package + * Get the number of non-deleted comments for a specific package base * - * @param string $pkgid The package ID to get comment count for + * @param string $pkgid The package base ID to get comment count for * * @return string The number of comments left for a specific package */ -function package_comments_count($pkgid) { +function package_comments_count($base_id) { $dbh = DB::connect(); - $pkgid = intval($pkgid); - if ($pkgid > 0) { + $base_id = intval($base_id); + if ($base_id > 0) { $dbh = DB::connect(); $q = "SELECT COUNT(*) FROM PackageComments "; - $q.= "WHERE PackageID = " . $pkgid; + $q.= "WHERE PackageBaseID = " . $base_id; $q.= " AND DelUsersID IS NULL"; } $result = $dbh->query($q); @@ -203,21 +203,21 @@ function package_comments_count($pkgid) { } /** - * Get all package comment information for a specific package + * Get all package comment information for a specific package base * - * @param int $pkgid The package ID to get comments for + * @param int $pkgid The package base ID to get comments for * - * @return array All package comment information for a specific package + * @return array All package comment information for a specific package base */ -function package_comments($pkgid) { +function package_comments($base_id) { + $base_id = intval($base_id); $comments = array(); - $pkgid = intval($pkgid); - if ($pkgid > 0) { + if ($base_id > 0) { $dbh = DB::connect(); $q = "SELECT PackageComments.ID, UserName, UsersID, Comments, CommentTS "; $q.= "FROM PackageComments LEFT JOIN Users "; $q.= "ON PackageComments.UsersID = Users.ID "; - $q.= "WHERE PackageID = " . $pkgid . " "; + $q.= "WHERE PackageBaseID = " . $base_id . " "; $q.= "AND DelUsersID IS NULL "; $q.= "ORDER BY CommentTS DESC"; @@ -242,20 +242,20 @@ function package_comments($pkgid) { * Add a comment to a package page and send out appropriate notifications * * @global string $AUR_LOCATION The AUR's URL used for notification e-mails - * @param string $pkgid The package ID to add the comment on + * @param string $base_id The package base ID to add the comment on * @param string $uid The user ID of the individual who left the comment * @param string $comment The comment left on a package page * * @return void */ -function add_package_comment($pkgid, $uid, $comment) { +function add_package_comment($base_id, $uid, $comment) { global $AUR_LOCATION; $dbh = DB::connect(); $q = "INSERT INTO PackageComments "; - $q.= "(PackageID, UsersID, Comments, CommentTS) VALUES ("; - $q.= intval($pkgid) . ", " . $uid . ", "; + $q.= "(PackageBaseID, UsersID, Comments, CommentTS) VALUES ("; + $q.= intval($base_id) . ", " . $uid . ", "; $q.= $dbh->quote($comment) . ", UNIX_TIMESTAMP())"; $dbh->exec($q); @@ -267,7 +267,7 @@ function add_package_comment($pkgid, $uid, $comment) { $q.= "FROM CommentNotify, Users "; $q.= "WHERE Users.ID = CommentNotify.UserID "; $q.= "AND CommentNotify.UserID != " . $uid . " "; - $q.= "AND CommentNotify.PkgID = " . intval($pkgid); + $q.= "AND CommentNotify.PackageBaseID = " . intval($base_id); $result = $dbh->query($q); $bcc = array(); @@ -276,9 +276,8 @@ function add_package_comment($pkgid, $uid, $comment) { array_push($bcc, $row['Email']); } - $q = "SELECT Packages.* "; - $q.= "FROM Packages "; - $q.= "WHERE Packages.ID = " . intval($pkgid); + $q = "SELECT Name FROM PackageBases WHERE ID = "; + $q.= intval($base_id); $result = $dbh->query($q); $row = $result->fetch(PDO::FETCH_ASSOC); @@ -473,7 +472,8 @@ function display_package_details($id=0, $row, $SID="") { include('pkg_comment_form.php'); } - $comments = package_comments($id); + $base_id = pkgbase_from_pkgid($id); + $comments = package_comments($base_id); if (!empty($comments)) { include('pkg_comments.php'); } @@ -583,7 +583,7 @@ function pkg_search_page($SID="") { $q_from_extra = "LEFT JOIN PackageVotes ON (PackageBases.ID = PackageVotes.PackageBaseID AND PackageVotes.UsersID = $myuid) LEFT JOIN CommentNotify - ON (Packages.ID = CommentNotify.PkgID AND CommentNotify.UserID = $myuid) "; + ON (PackageBases.ID = CommentNotify.PackageBaseID AND CommentNotify.UserID = $myuid) "; } else { $q_from_extra = ""; } @@ -920,7 +920,7 @@ function pkg_delete ($atype, $ids, $mergepkgid) { $q.= "FROM CommentNotify, Users "; $q.= "WHERE Users.ID = CommentNotify.UserID "; $q.= "AND CommentNotify.UserID != " . uid_from_sid($_COOKIE['AURSID']) . " "; - $q.= "AND CommentNotify.PkgID = " . $pkgid; + $q.= "AND CommentNotify.PackageBaseID = " . pkgbase_from_pkgid($pkgid); $result = $dbh->query($q); $bcc = array(); @@ -960,8 +960,8 @@ function pkg_delete ($atype, $ids, $mergepkgid) { if ($mergepkgid) { /* Merge comments */ $q = "UPDATE PackageComments "; - $q.= "SET PackageID = " . intval($mergepkgid) . " "; - $q.= "WHERE PackageID IN (" . implode(",", $ids) . ")"; + $q.= "SET PackageBaseID = " . intval($mergepkgbase) . " "; + $q.= "WHERE PackageBaseID IN (" . implode(",", $base_ids) . ")"; $dbh->exec($q); /* Merge votes */ @@ -1188,18 +1188,18 @@ function user_voted($uid, $pkgid) { } /** - * Determine if a user wants notifications for a specific package + * Determine if a user wants notifications for a specific package base * * @param string $uid User ID to check in the database - * @param string $pkgid Package ID to check notifications for + * @param string $base_id Package base ID to check notifications for * * @return bool True if the user wants notifications, otherwise false */ -function user_notify($uid, $pkgid) { +function user_notify($uid, $base_id) { $dbh = DB::connect(); $q = "SELECT * FROM CommentNotify WHERE UserID = " . $dbh->quote($uid); - $q.= " AND PkgID = " . $dbh->quote($pkgid); + $q.= " AND PackageBaseID = " . $dbh->quote($base_id); $result = $dbh->query($q); if ($result->fetch(PDO::FETCH_NUM)) { @@ -1224,6 +1224,7 @@ function pkg_notify ($atype, $ids, $action=true) { } $ids = sanitize_ids($ids); + $base_ids = pkgbase_from_pkgid($ids); if (empty($ids)) { return array(false, __("Couldn't add to notification list.")); } @@ -1239,15 +1240,15 @@ function pkg_notify ($atype, $ids, $action=true) { * There currently shouldn't be multiple requests here, but the format * in which it's sent requires this. */ - foreach ($ids as $pid) { - $q = "SELECT Name FROM Packages WHERE ID = $pid"; + foreach ($base_ids as $bid) { + $q = "SELECT Name FROM PackageBases WHERE ID = $bid"; $result = $dbh->query($q); if ($result) { $row = $result->fetch(PDO::FETCH_NUM); - $pkgname = $row[0]; + $basename = $row[0]; } else { - $pkgname = ''; + $basename = ''; } if ($first) @@ -1258,23 +1259,23 @@ function pkg_notify ($atype, $ids, $action=true) { if ($action) { $q = "SELECT COUNT(*) FROM CommentNotify WHERE "; - $q .= "UserID = $uid AND PkgID = $pid"; + $q .= "UserID = $uid AND PackageBaseID = $bid"; /* Notification already added. Don't add again. */ $result = $dbh->query($q); if ($result->fetchColumn() == 0) { - $q = "INSERT INTO CommentNotify (PkgID, UserID) VALUES ($pid, $uid)"; + $q = "INSERT INTO CommentNotify (PackageBaseID, UserID) VALUES ($bid, $uid)"; $dbh->exec($q); } - $output .= $pkgname; + $output .= $basename; } else { - $q = "DELETE FROM CommentNotify WHERE PkgID = $pid "; + $q = "DELETE FROM CommentNotify WHERE PackageBaseID = $bid "; $q .= "AND UserID = $uid"; $dbh->exec($q); - $output .= $pkgname; + $output .= $basename; } } diff --git a/web/template/pkg_comments.php b/web/template/pkg_comments.php index 88e739e..820ba6e 100644 --- a/web/template/pkg_comments.php +++ b/web/template/pkg_comments.php @@ -1,6 +1,7 @@ <?php $uid = uid_from_sid($SID); -$count = package_comments_count($row['ID']); +$base_id = pkgbase_from_pkgid($row['ID']); +$count = package_comments_count($base_id); $pkgname = $row['Name']; ?> <div id="news"> -- 1.9.1
This will be used to create links to package base pages later. For now, this just returns a link to the corresponding package page since a package base currently only consists of a single package having the same name as the base itself. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/routing.inc.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/lib/routing.inc.php b/web/lib/routing.inc.php index 206886c..b1e5be2 100644 --- a/web/lib/routing.inc.php +++ b/web/lib/routing.inc.php @@ -58,6 +58,10 @@ function get_pkg_uri($pkgname) { } } +function get_pkgbase_uri($pkgbase_name) { + return get_pkg_uri($pkgbase_name); +} + function get_user_route() { global $USER_PATH; return $USER_PATH; -- 1.9.1
Deleting a single package without deleting the whole package base makes no sense. Comments and votes are already stored on a per-package basis, making this a straightforward extension. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/packages.php | 8 ++--- web/lib/pkgfuncs.inc.php | 82 +++++++++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 32 deletions(-) diff --git a/web/html/packages.php b/web/html/packages.php index f5ecf94..d9c3a86 100644 --- a/web/html/packages.php +++ b/web/html/packages.php @@ -72,13 +72,13 @@ if (check_token()) { } elseif (current_action("do_Delete")) { if (isset($_POST['confirm_Delete'])) { if (!isset($_POST['merge_Into']) || empty($_POST['merge_Into'])) { - list($ret, $output) = pkg_delete($atype, $ids, NULL); + list($ret, $output) = pkg_delete($atype, pkgbase_from_pkgid($ids), NULL); unset($_GET['ID']); } else { - $mergepkgid = pkgid_from_name($_POST['merge_Into']); - if ($mergepkgid) { - list($ret, $output) = pkg_delete($atype, $ids, $mergepkgid); + $merge_base_id = pkgbase_from_name($_POST['merge_Into']); + if ($merge_base_id) { + list($ret, $output) = pkg_delete($atype, pkgbase_from_pkgid($ids), $merge_base_id); unset($_GET['ID']); } else { diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 4b317f5..ef0eba9 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -788,6 +788,35 @@ function pkgbase_from_pkgid($ids) { } /** + * Retrieve ID of a package base by name + * + * @param string $name The package base name to retrieve the ID for + * + * @return int The ID of the package base + */ +function pkgbase_from_name($name) { + $dbh = DB::connect(); + $q = "SELECT ID FROM PackageBases WHERE Name = " . $dbh->quote($name); + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_COLUMN, 0); +} + +/** + * Retrieve the name of a package base given its ID + * + * @param int $base_id The ID of the package base to query + * + * @return string The name of the package base + */ +function pkgbase_name_from_id($base_id) { + $dbh = DB::connect(); + $q = "SELECT Name FROM PackageBases WHERE ID = " . intval($base_id); + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_COLUMN, 0); +} + + +/** * Flag package(s) as out-of-date * * @global string $AUR_LOCATION The AUR's URL used for notification e-mails @@ -884,15 +913,15 @@ function pkg_unflag($atype, $ids) { } /** - * Delete packages + * Delete package bases * * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to delete - * @param int $mergepkgid Package to merge the deleted ones into + * @param array $base_ids Array of package base IDs to delete + * @param int $merge_base_id Package base to merge the deleted ones into * * @return array Tuple of success/failure indicator and error message */ -function pkg_delete ($atype, $ids, $mergepkgid) { +function pkg_delete ($atype, $base_ids, $merge_base_id) { if (!$atype) { return array(false, __("You must be logged in before you can delete packages.")); } @@ -901,26 +930,24 @@ function pkg_delete ($atype, $ids, $mergepkgid) { return array(false, __("You do not have permission to delete packages.")); } - $ids = sanitize_ids($ids); - $base_ids = pkgbase_from_pkgid($ids); - if (empty($ids)) { + $base_ids = sanitize_ids($base_ids); + if (empty($base_ids)) { return array(false, __("You did not select any packages to delete.")); } $dbh = DB::connect(); - if ($mergepkgid) { - $mergepkgname = pkgname_from_id($mergepkgid); - $mergepkgbase = pkgbase_from_pkgid($mergepkgid); + if ($merge_base_id) { + $merge_base_name = pkgbase_name_from_id($merge_base_id); } /* Send e-mail notifications. */ - foreach ($ids as $pkgid) { + foreach ($base_ids as $base_id) { $q = "SELECT CommentNotify.*, Users.Email "; $q.= "FROM CommentNotify, Users "; $q.= "WHERE Users.ID = CommentNotify.UserID "; $q.= "AND CommentNotify.UserID != " . uid_from_sid($_COOKIE['AURSID']) . " "; - $q.= "AND CommentNotify.PackageBaseID = " . pkgbase_from_pkgid($pkgid); + $q.= "AND CommentNotify.PackageBaseID = " . $base_id; $result = $dbh->query($q); $bcc = array(); @@ -928,7 +955,7 @@ function pkg_delete ($atype, $ids, $mergepkgid) { array_push($bcc, $row['Email']); } if (!empty($bcc)) { - $pkgname = pkgname_from_id($pkgid); + $pkgbase_name = pkgbase_name_from_id($base_id); /* * TODO: Add native language emails for users, based on @@ -938,11 +965,11 @@ function pkg_delete ($atype, $ids, $mergepkgid) { * comment was in. */ $body = ""; - if ($mergepkgid) { - $body .= username_from_sid($_COOKIE['AURSID']) . " merged \"".$pkgname."\" into \"$mergepkgname\".\n\n"; - $body .= "You will no longer receive notifications about this package, please go to https://aur.archlinux.org" . get_pkg_uri($mergepkgname) . " and click the Notify button if you wish to recieve them again."; + if ($merge_base_id) { + $body .= username_from_sid($_COOKIE['AURSID']) . " merged \"".$pkgbase_name."\" into \"$merge_base_name\".\n\n"; + $body .= "You will no longer receive notifications about this package, please go to https://aur.archlinux.org" . get_pkgbase_uri($merge_base_name) . " and click the Notify button if you wish to recieve them again."; } else { - $body .= username_from_sid($_COOKIE['AURSID']) . " deleted \"".$pkgname."\".\n\n"; + $body .= username_from_sid($_COOKIE['AURSID']) . " deleted \"".$pkgbase_name."\".\n\n"; $body .= "You will no longer receive notifications about this package."; } $body = wordwrap($body, 70); @@ -953,43 +980,42 @@ function pkg_delete ($atype, $ids, $mergepkgid) { "Reply-to: nobody@archlinux.org\r\n" . "From: aur-notify@archlinux.org\r\n" . "X-Mailer: AUR"; - @mail('undisclosed-recipients: ;', "AUR Package deleted: " . $pkgname, $body, $headers); + @mail('undisclosed-recipients: ;', "AUR Package deleted: " . $pkgbase_name, $body, $headers); } } - if ($mergepkgid) { + if ($merge_base_id) { /* Merge comments */ $q = "UPDATE PackageComments "; - $q.= "SET PackageBaseID = " . intval($mergepkgbase) . " "; + $q.= "SET PackageBaseID = " . intval($merge_base_id) . " "; $q.= "WHERE PackageBaseID IN (" . implode(",", $base_ids) . ")"; $dbh->exec($q); /* Merge votes */ foreach ($base_ids as $base_id) { $q = "UPDATE PackageVotes "; - $q.= "SET PackageBaseID = " . intval($mergepkgbase) . " "; + $q.= "SET PackageBaseID = " . intval($merge_base_id) . " "; $q.= "WHERE PackageBaseID = " . $base_id . " "; $q.= "AND UsersID NOT IN ("; $q.= "SELECT * FROM (SELECT UsersID "; $q.= "FROM PackageVotes "; - $q.= "WHERE PackageBaseID = " . intval($mergepkgbase); + $q.= "WHERE PackageBaseID = " . intval($merge_base_id); $q.= ") temp)"; $dbh->exec($q); } $q = "UPDATE PackageBases "; $q.= "SET NumVotes = (SELECT COUNT(*) FROM PackageVotes "; - $q.= "WHERE PackageBaseID = " . intval($mergepkgbase) . ") "; - $q.= "WHERE ID = " . intval($mergepkgbase); + $q.= "WHERE PackageBaseID = " . intval($merge_base_id) . ") "; + $q.= "WHERE ID = " . intval($merge_base_id); $dbh->exec($q); } - $q = "DELETE FROM Packages WHERE ID IN (" . implode(",", $ids) . ")"; - $result = $dbh->exec($q); + $q = "DELETE FROM Packages WHERE PackageBaseID IN (" . implode(",", $base_ids) . ")"; + $dbh->exec($q); - /* Deleting a package also removes the corresponding package base. */ $q = "DELETE FROM PackageBases WHERE ID IN (" . implode(",", $base_ids) . ")"; - $result = $dbh->exec($q); + $dbh->exec($q); return array(true, __("The selected packages have been deleted.")); } -- 1.9.1
This adds full support for the new .AURINFO format used by mkaurball, including support for split packages. The old PKGBUILD parser is still available for compatibility reasons. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/pkgsubmit.php | 269 +++++++++++++++++++++++++++-------------------- web/lib/pkgfuncs.inc.php | 27 +++++ 2 files changed, 180 insertions(+), 116 deletions(-) diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 38fbb8c..13a67d8 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -82,7 +82,7 @@ if ($uid): if (!$error) { $tar = new Archive_Tar($_FILES['pfile']['tmp_name']); - # Extract PKGBUILD and .AURINFO into a string + /* Extract PKGBUILD and .AURINFO into a string. */ $pkgbuild_raw = $srcinfo_raw = ''; $dircount = 0; foreach ($tar->listContent() as $tar_file) { @@ -109,16 +109,22 @@ if ($uid): } } } + } - if (!$error && $dircount !== 1) { - $error = __("Error - source tarball may not contain files outside a directory."); - } + if (!$error && $dircount !== 1) { + $error = __("Error - source tarball may not contain files outside a directory."); + } - if (!$error && empty($pkgbuild_raw)) { + if (empty($pkgbuild_raw)) { + $pkgbuild_raw = ''; + if (!$error) { $error = __("Error trying to unpack upload - PKGBUILD does not exist."); } + } - if (!$error && empty($srcinfo_raw) && (!isset($_POST['ignore_missing_aurinfo']) || $_POST['ignore_missing_aurinfo'] != 1)) { + if (empty($srcinfo_raw)) { + $srcinfo_raw = ''; + if (!$error && (!isset($_POST['ignore_missing_aurinfo']) || $_POST['ignore_missing_aurinfo'] != 1)) { $ignore_missing_aurinfo = 1; $error = __("The source package does not contain any meta data. Please use `mkaurball` to create AUR source packages. Support for source packages without .AURINFO entries will be removed in an upcoming release! You can resubmit the package if you want to proceed anyway."); } @@ -223,6 +229,7 @@ if ($uid): } # Now, run through the pkgbuild array, and do "eval" and simple substituions. + $new_pkgbuild = array(); if (!$error) { while (list($k, $v) = each($pkgbuild)) { if (strpos($k,'eval ') !== false) { @@ -265,10 +272,10 @@ if ($uid): } } - # Parse .AURINFO and overwrite PKGBUILD fields accordingly - unset($pkg_version); - $depends = array(); - $srcinfo_pkgname_count = 0; + /* Parse .AURINFO and extract meta data. */ + $pkgbase_info = array(); + $pkginfo = array(); + $section_info = array(); foreach (explode("\n", $srcinfo_raw) as $line) { $line = trim($line); if (empty($line) || $line[0] == '#') { @@ -276,106 +283,157 @@ if ($uid): } list($key, $value) = explode(' = ', $line, 2); switch ($key) { + case 'pkgbase': case 'pkgname': - $srcinfo_pkgname_count++; - if ($srcinfo_pkgname_count > 1) { - $error = __("Error - The AUR does not support split packages!"); + if (!empty($section_info)) { + if (isset($section_info['pkgbase'])) { + $pkgbase_info = $section_info; + } elseif (isset($section_info['pkgname'])) { + $pkginfo[] = array_merge($pkgbase_info, $section_info); + } } + $section_info = array('depends' => array(), 'source' => array()); /* Fall-through case. */ + case 'epoch': case 'pkgdesc': + case 'pkgver': + case 'pkgrel': case 'url': case 'license': - $new_pkgbuild[$key] = $value; - break; - case 'pkgver': - $pkg_version = $value; + $section_info[$key] = $value; break; + case 'source': case 'depends': - $depends[] = $value; + $section_info[$key][] = $value; break; } } - # Validate package name + if (!empty($section_info)) { + if (isset($section_info['pkgbase'])) { + $pkgbase_info = $section_info; + } elseif (isset($section_info['pkgname'])) { + $pkginfo[] = array_merge($pkgbase_info, $section_info); + } + } else { + /* Use data from the PKGBUILD parser (deprecated!) */ + $pkgbase_info = $new_pkgbuild; + if (!isset($pkgbase_info['pkgbase'])) { + $pkgbase_info['pkgbase'] = $pkgbase_info['pkgname']; + } + if (empty($pkgbase_info['depends'])) { + $pkgbase_info['depends'] = array(); + } else { + $pkgbase_info['depends'] = explode(" ", $pkgbase_info['depends']); + } + if (empty($pkgbase_info['source'])) { + $pkgbase_info['source'] = array(); + } else { + $pkgbase_info['source'] = explode(" ", $pkgbase_info['source']); + } + $pkginfo[] = $pkgbase_info; + } + + /* Validate package base name. */ if (!$error) { - $pkg_name = $new_pkgbuild['pkgname']; - if ($pkg_name[0] == '(') { - $error = __("Error - The AUR does not support split packages!"); - } elseif (!preg_match("/^[a-z0-9][a-z0-9\.+_-]*$/", $pkg_name)) { + $pkgbase_name = $pkgbase_info['pkgbase']; + if (!preg_match("/^[a-z0-9][a-z0-9\.+_-]*$/", $pkgbase_name)) { $error = __("Invalid name: only lowercase letters are allowed."); } + + /* Check whether the package base already exists. */ + $base_id = pkgbase_from_name($pkgbase_name); } - # Determine the full package version with epoch - if (!$error && !isset($pkg_version)) { - if (isset($new_pkgbuild['epoch']) && (int)$new_pkgbuild['epoch'] > 0) { - $pkg_version = sprintf('%d:%s-%s', $new_pkgbuild['epoch'], $new_pkgbuild['pkgver'], $new_pkgbuild['pkgrel']); + foreach ($pkginfo as $key => $pi) { + /* Bail out early if an error has occurred. */ + if ($error) { + break; + } + + /* Validate package names. */ + $pkg_name = $pi['pkgname']; + if (!preg_match("/^[a-z0-9][a-z0-9\.+_-]*$/", $pkg_name)) { + $error = __("Invalid name: only lowercase letters are allowed."); + break; + } + + /* Determine the full package versions with epoch. */ + if (isset($pi['epoch']) && (int)$pi['epoch'] > 0) { + $pkginfo[$key]['full-version'] = sprintf('%d:%s-%s', $pi['epoch'], $pi['pkgver'], $pi['pkgrel']); } else { - $pkg_version = sprintf('%s-%s', $new_pkgbuild['pkgver'], $new_pkgbuild['pkgrel']); + $pkginfo[$key]['full-version'] = sprintf('%s-%s', $pi['pkgver'], $pi['pkgrel']); } - } - # Check for http:// or other protocol in url - if (!$error) { - $parsed_url = parse_url($new_pkgbuild['url']); + /* Check for http:// or other protocols in the URL. */ + $parsed_url = parse_url($pi['url']); if (!$parsed_url['scheme']) { $error = __("Package URL is missing a protocol (ie. http:// ,ftp://)"); + break; } - } - # TODO: This is where other additional error checking can be - # performed. Examples: #md5sums == #sources?, md5sums of any - # included files match?, install scriptlet file exists? - - # The DB schema imposes limitations on number of allowed characters - # Print error message when these limitations are exceeded - if (!$error) { - if (strlen($pkg_name) > 64) { + /* + * The DB schema imposes limitations on number of + * allowed characters. Print error message when these + * limitations are exceeded. + */ + if (strlen($pi['pkgname']) > 64) { $error = __("Error - Package name cannot be greater than %d characters", 64); + break; } - if (strlen($new_pkgbuild['url']) > 255) { + if (strlen($pi['url']) > 255) { $error = __("Error - Package URL cannot be greater than %d characters", 255); + break; } - if (strlen($new_pkgbuild['pkgdesc']) > 255) { + if (strlen($pi['pkgdesc']) > 255) { $error = __("Error - Package description cannot be greater than %d characters", 255); + break; } - if (strlen($new_pkgbuild['license']) > 40) { + if (strlen($pi['license']) > 40) { $error = __("Error - Package license cannot be greater than %d characters", 40); + break; } - if (strlen($pkg_version) > 32) { + if (strlen($pkginfo[$key]['full-version']) > 32) { $error = __("Error - Package version cannot be greater than %d characters", 32); + break; + } + + /* Check if package name is blacklisted. */ + if (!$base_id && pkgname_is_blacklisted($pi['pkgname']) && !canSubmitBlacklisted(account_from_sid($_COOKIE["AURSID"]))) { + $error = __( "%s is on the package blacklist, please check if it's available in the official repos.", $pi['pkgname']); + break; } } - if (isset($pkg_name)) { - $incoming_pkgdir = INCOMING_DIR . substr($pkg_name, 0, 2) . "/" . $pkg_name; + if (isset($pkgbase_name)) { + $incoming_pkgdir = INCOMING_DIR . substr($pkgbase_name, 0, 2) . "/" . $pkgbase_name; } + /* Upload PKGBUILD and tarball. */ if (!$error) { - # First, see if this package already exists, and if it can be overwritten - $pkg_id = pkgid_from_name($pkg_name); - if (can_submit_pkgbase($pkg_name, $_COOKIE["AURSID"])) { + /* + * First, check whether this package already exists and + * whether it can be overwritten. + */ + if (can_submit_pkgbase($pkgbase_name, $_COOKIE["AURSID"])) { if (file_exists($incoming_pkgdir)) { - # Blow away the existing file/dir and contents + /* + * Blow away the existing directory and + * its contents. + */ rm_tree($incoming_pkgdir); } - # The mode is masked by the current umask, so not as scary as it looks + /* + * The mode is masked by the current umask, so + * not as scary as it looks. + */ if (!mkdir($incoming_pkgdir, 0777, true)) { $error = __( "Could not create directory %s.", $incoming_pkgdir); } } else { $error = __( "You are not allowed to overwrite the %s%s%s package.", "<strong>", $pkg_name, "</strong>"); } - - if (!$error) { - # Check if package name is blacklisted. - if (!$pkg_id && pkgname_is_blacklisted($pkg_name)) { - if (!canSubmitBlacklisted(account_from_sid($_COOKIE["AURSID"]))) { - $error = __( "%s is on the package blacklist, please check if it's available in the official repos.", $pkg_name); - } - } - } } if (!$error) { @@ -384,96 +442,75 @@ if ($uid): } file_put_contents('PKGBUILD', $pkgbuild_raw); - move_uploaded_file($_FILES['pfile']['tmp_name'], $pkg_name . '.tar.gz'); + move_uploaded_file($_FILES['pfile']['tmp_name'], $pkgbase_name . '.tar.gz'); } - # Update the backend database + /* Update the backend database. */ if (!$error) { begin_atomic_commit(); - $pdata = pkgdetails_by_pkgname($new_pkgbuild['pkgname']); - - # Check the category to use, "1" meaning "none" (or "keep category" for - # existing packages). + /* + * Check the category to use, "1" meaning "none" (or + * "keep category" for existing packages). + */ if (isset($_POST['category'])) { - $category_id = intval($_POST['category']); - if ($category_id <= 0) { - $category_id = 1; - } - } - else { + $category_id = max(1, intval($_POST['category'])); + } else { $category_id = 1; } - if ($pdata) { - # This is an overwrite of an existing package, the database ID - # needs to be preserved so that any votes are retained. However, - # PackageDepends and PackageSources can be purged. - $pkgid = $pdata["ID"]; - $base_id = pkgbase_from_pkgid($pkgid); + if ($base_id) { + /* + * This is an overwrite of an existing package + * base, the database ID needs to be preserved + * so that any votes are retained. + */ + $was_orphan = (pkgbase_maintainer_uid($base_id) === NULL); - # Flush out old data that will be replaced with new data - remove_pkg_deps($pkgid); - remove_pkg_sources($pkgid); + update_pkgbase($base_id, $pkgbase_info['pkgbase'], $uid); - # If a new category was chosen, change it to that if ($category_id > 1) { update_pkgbase_category($base_id, $category_id); } - # Update package base and package data - update_pkgbase($base_id, $new_pkgbuild['pkgname'], $uid); - update_pkg($pkgid, $new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url']); + pkgbase_delete_packages($base_id); } else { - # This is a brand new package - $base_id = create_pkgbase($new_pkgbuild['pkgname'], $category_id, $uid); - $pkgid = create_pkg($base_id, $new_pkgbuild['pkgname'], $new_pkgbuild['license'], $pkg_version, $new_pkgbuild['pkgdesc'], $new_pkgbuild['url']); + /* This is a brand new package. */ + $was_orphan = true; + $base_id = create_pkgbase($pkgbase_name, $category_id, $uid); } - # Update package depends - if (empty($depends) && !empty($new_pkgbuild['depends'])) { - $depends = explode(" ", $new_pkgbuild['depends']); - } - if (!empty($depends)) { - foreach ($depends as $dep) { - $deppkgname = preg_replace("/(<|<=|=|>=|>).*/", "", $dep); - $depcondition = str_replace($deppkgname, "", $dep); + foreach ($pkginfo as $pi) { + $pkgid = create_pkg($base_id, $pi['pkgname'], $pi['license'], $pi['full-version'], $pi['pkgdesc'], $pi['url']); - if ($deppkgname == "") { - continue; - } - else if ($deppkgname == "#") { - break; - } + foreach ($pi['depends'] as $dep) { + $deppkgname = preg_replace("/(<|=|>).*/", "", $dep); + $depcondition = str_replace($deppkgname, "", $dep); add_pkg_dep($pkgid, $deppkgname, $depcondition); } - } - # Insert sources - if (!empty($new_pkgbuild['source'])) { - $sources = explode(" ", $new_pkgbuild['source']); - foreach ($sources as $src) { + foreach ($pi['source'] as $src) { add_pkg_src($pkgid, $src); } } - # If we just created this package, or it was an orphan and we - # auto-adopted, add submitting user to the notification list. - if (!$pdata || $pdata["MaintainerUID"] === NULL) { - pkg_notify(account_from_sid($_COOKIE["AURSID"]), array($pkgid), true); + /* + * If we just created this package, or it was an orphan + * and we auto-adopted, add submitting user to the + * notification list. + */ + if ($was_orphan) { + pkg_notify(account_from_sid($_COOKIE["AURSID"]), array($base_id), true); } - # Entire package creation process is atomic end_atomic_commit(); - header('Location: ' . get_pkg_uri($pkg_name)); + header('Location: ' . get_pkg_uri($pi[0]['pkgname'])); } chdir($cwd); } -# Logic over, let's do some output - html_header("Submit"); ?> diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index ef0eba9..3ef069c 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -815,6 +815,33 @@ function pkgbase_name_from_id($base_id) { return $result->fetch(PDO::FETCH_COLUMN, 0); } +/** + * Delete all packages belonging to a package base + * + * @param int $base_id The ID of the package base + * + * @return void + */ +function pkgbase_delete_packages($base_id) { + $dbh = DB::connect(); + $q = "DELETE FROM Packages WHERE PackageBaseID = " . intval($base_id); + $dbh->exec($q); +} + +/** + * Retrieve the maintainer of a package base given its ID + * + * @param int $base_id The ID of the package base to query + * + * @return int The user ID of the current package maintainer + */ +function pkgbase_maintainer_uid($base_id) { + $dbh = DB::connect(); + $q = "SELECT MaintainerUID FROM PackageBases WHERE ID = " . intval($base_id); + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_COLUMN, 0); +} + /** * Flag package(s) as out-of-date -- 1.9.1
This adds package base details pages, similar to the package details pages. Each package base details page contains general information (package base name, category, submitter, maintainer, ...) and links to all the corresponding packages. As on the package details pages, comments and links to several package actions are also provided. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/index.php | 16 +++ web/html/pkgbase.php | 55 ++++++++++ web/lib/pkgfuncs.inc.php | 84 ++++++++++++++++ web/lib/routing.inc.php | 16 ++- web/template/pkgbase_details.php | 210 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 380 insertions(+), 1 deletion(-) create mode 100644 web/html/pkgbase.php create mode 100644 web/template/pkgbase_details.php diff --git a/web/html/index.php b/web/html/index.php index 542d594..e79955e 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -70,6 +70,22 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { } include get_route('/' . $tokens[1]); +} elseif (!empty($tokens[1]) && '/' . $tokens[1] == get_pkgbase_route()) { + if (!empty($tokens[2])) { + /* TODO: Create a proper data structure to pass variables from + * the routing framework to the individual pages instead of + * initializing arbitrary variables here. */ + $pkgbase_name = $tokens[2]; + $base_id = pkgbase_from_name($pkgbase_name); + + if (!$base_id) { + header("HTTP/1.0 404 Not Found"); + include "./404.php"; + return; + } + } + + include get_route('/' . $tokens[1]); } elseif (!empty($tokens[1]) && '/' . $tokens[1] == get_user_route()) { if (!empty($tokens[2])) { $_REQUEST['ID'] = uid_from_username($tokens[2]); diff --git a/web/html/pkgbase.php b/web/html/pkgbase.php new file mode 100644 index 0000000..e0c9af6 --- /dev/null +++ b/web/html/pkgbase.php @@ -0,0 +1,55 @@ +<?php + +set_include_path(get_include_path() . PATH_SEPARATOR . '../lib'); + +include_once("aur.inc.php"); +set_lang(); +include_once('pkgfuncs.inc.php'); +check_sid(); + +/* + * Retrieve package base ID and name, unless initialized by the routing + * framework. + */ +if (!isset($base_id) || !isset($pkgbase_name)) { + if (isset($_GET['ID'])) { + $base_id = intval($_GET['ID']); + $pkgbase_name = pkgbase_name_from_id($_GET['ID']); + } else if (isset($_GET['N'])) { + $base_id = pkgbase_from_name($_GET['N']); + $pkgbase_name = $_GET['N']; + } else { + unset($base_id, $pkgbase_name); + } + + if ($base_id == 0 || $base_id == NULL || $pkgbase_name == NULL) { + header("HTTP/1.0 404 Not Found"); + include "./404.php"; + return; + } +} + +/* Set the title to package base name. */ +$title = $pkgbase_name; + +/* Retrieve account type. */ +if (isset($_COOKIE["AURSID"])) { + $atype = account_from_sid($_COOKIE["AURSID"]); +} else { + $atype = ""; +} + +$details = get_pkgbase_details($base_id); +html_header($title, $details); +?> + +<?php +include('pkg_search_form.php'); +if (isset($_COOKIE["AURSID"])) { + display_pkgbase_details($base_id, $details, $_COOKIE["AURSID"]); +} else { + display_pkgbase_details($base_id, $details, null); +} + +html_footer(AUR_VERSION); + diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 3ef069c..b92eb9c 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -445,6 +445,41 @@ function get_package_details($id=0) { } /** + * Get the package base details + * + * @param string $id The package base ID to get description for + * + * @return array The package base's details OR error message + **/ +function get_pkgbase_details($base_id) { + $dbh = DB::connect(); + + $q = "SELECT PackageBases.ID, PackageBases.Name, "; + $q.= "PackageBases.CategoryID, PackageBases.NumVotes, "; + $q.= "PackageBases.OutOfDateTS, PackageBases.SubmittedTS, "; + $q.= "PackageBases.ModifiedTS, PackageBases.SubmitterUID, "; + $q.= "PackageBases.MaintainerUID, PackageCategories.Category "; + $q.= "FROM PackageBases, PackageCategories "; + $q.= "WHERE PackageBases.CategoryID = PackageCategories.ID "; + $q.= "AND PackageBases.ID = " . intval($base_id); + $result = $dbh->query($q); + + $row = array(); + + if (!$result) { + $row['error'] = __("Error retrieving package details."); + } + else { + $row = $result->fetch(PDO::FETCH_ASSOC); + if (empty($row)) { + $row['error'] = __("Package details could not be found."); + } + } + + return $row; +} + +/** * Display the package details page * * @global string $AUR_LOCATION The AUR's URL used for notification e-mails @@ -480,6 +515,41 @@ function display_package_details($id=0, $row, $SID="") { } } +/** + * Display the package base details page + * + * @global string $AUR_LOCATION The AUR's URL used for notification e-mails + * @global bool $USE_VIRTUAL_URLS True if using URL rewriting, otherwise false + * @param string $id The package base ID to get details page for + * @param array $row Package base details retrieved by get_pkgbase_details + * @param string $SID The session ID of the visitor + * + * @return void + */ +function display_pkgbase_details($base_id, $row, $SID="") { + global $AUR_LOCATION; + global $USE_VIRTUAL_URLS; + + $dbh = DB::connect(); + + if (isset($row['error'])) { + print "<p>" . $row['error'] . "</p>\n"; + } + else { + include('pkgbase_details.php'); + + if ($SID) { + include('actions_form.php'); + include('pkg_comment_form.php'); + } + + $comments = package_comments($base_id); + if (!empty($comments)) { + include('pkg_comments.php'); + } + } +} + /* pkg_search_page(SID) * outputs the body of search/search results page @@ -816,6 +886,20 @@ function pkgbase_name_from_id($base_id) { } /** + * Get the names of all packages belonging to a package base + * + * @param int $base_id The ID of the package base + * + * @return array The names of all packages belonging to the package base + */ +function pkgbase_get_pkgnames($base_id) { + $dbh = DB::connect(); + $q = "SELECT Name FROM Packages WHERE PackageBaseID = " . intval($base_id); + $result = $dbh->query($q); + return $result->fetchAll(PDO::FETCH_COLUMN, 0); +} + +/** * Delete all packages belonging to a package base * * @param int $base_id The ID of the package base diff --git a/web/lib/routing.inc.php b/web/lib/routing.inc.php index b1e5be2..1b2aa52 100644 --- a/web/lib/routing.inc.php +++ b/web/lib/routing.inc.php @@ -4,6 +4,7 @@ $ROUTES = array( '' => 'home.php', '/index.php' => 'home.php', '/packages' => 'packages.php', + '/pkgbase' => 'pkgbase.php', '/register' => 'account.php', '/account' => 'account.php', '/accounts' => 'account.php', @@ -18,6 +19,7 @@ $ROUTES = array( ); $PKG_PATH = '/packages'; +$PKGBASE_PATH = '/pkgbase'; $USER_PATH = '/account'; function get_route($path) { @@ -47,6 +49,11 @@ function get_pkg_route() { return $PKG_PATH; } +function get_pkgbase_route() { + global $PKGBASE_PATH; + return $PKGBASE_PATH; +} + function get_pkg_uri($pkgname) { global $USE_VIRTUAL_URLS; global $PKG_PATH; @@ -59,7 +66,14 @@ function get_pkg_uri($pkgname) { } function get_pkgbase_uri($pkgbase_name) { - return get_pkg_uri($pkgbase_name); + global $USE_VIRTUAL_URLS; + global $PKGBASE_PATH; + + if ($USE_VIRTUAL_URLS) { + return $PKGBASE_PATH . '/' . urlencode($pkgbase_name) . '/'; + } else { + return '/' . get_route($PKGBASE_PATH) . '?N=' . urlencode($pkgbase_name); + } } function get_user_route() { diff --git a/web/template/pkgbase_details.php b/web/template/pkgbase_details.php new file mode 100644 index 0000000..a77ecd3 --- /dev/null +++ b/web/template/pkgbase_details.php @@ -0,0 +1,210 @@ +<?php +$atype = account_from_sid($SID); +$uid = uid_from_sid($SID); + +$base_id = intval($row['ID']); + +$catarr = pkgCategories(); + +$submitter = username_from_id($row["SubmitterUID"]); +$maintainer = username_from_id($row["MaintainerUID"]); + +$votes = $row['NumVotes']; + +# In case of wanting to put a custom message +$msg = __('unknown'); + +# Print the timestamps for last updates +$updated_time = ($row["ModifiedTS"] == 0) ? $msg : gmdate("Y-m-d H:i", intval($row["ModifiedTS"])); +$submitted_time = ($row["SubmittedTS"] == 0) ? $msg : gmdate("Y-m-d H:i", intval($row["SubmittedTS"])); +$out_of_date_time = ($row["OutOfDateTS"] == 0) ? $msg : gmdate("Y-m-d", intval($row["OutOfDateTS"])); + +$urlpath = URL_DIR . substr($row['Name'], 0, 2) . "/" . $row['Name']; + +$pkgs = pkgbase_get_pkgnames($base_id); +?> +<div id="pkgdetails" class="box"> + <h2><?= __('Package Base Details') . ': ' . htmlspecialchars($row['Name']) ?></h2> + <div id="detailslinks" class="listing"> + <div id="actionlist"> + <h4><?= __('Package Actions') ?></h4> + <ul class="small"> + <li><a href="<?= $urlpath ?>/PKGBUILD"><?= __('View PKGBUILD') ?></a></li> + <li><a href="<?= $urlpath . '/' . $pkgs[0] ?>.tar.gz"><?= __('Download tarball') ?></a></li> + <li><span class="flagged"><?php if ($row["OutOfDateTS"] !== NULL) { echo __('Flagged out-of-date')." (${out_of_date_time})"; } ?></span></li> + <?php if ($USE_VIRTUAL_URLS && $uid): ?> + <?php if ($row["OutOfDateTS"] === NULL): ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'flag/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_Flag" value="<?= __('Flag package out-of-date') ?>" /> + </form> + </li> + <?php elseif (($row["OutOfDateTS"] !== NULL) && + ($uid == $row["MaintainerUID"] || $atype == "Trusted User" || $atype == "Developer")): ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'unflag/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_UnFlag" value="<?= __('Unflag package') ?>" /> + </form> + </li> + <?php endif; ?> + <?php if (user_voted($uid, $row['ID'])): ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'unvote/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_UnVote" value="<?= __('Remove vote') ?>" /> + </form> + </li> + <?php else: ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'vote/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_Vote" value="<?= __('Vote for this package') ?>" /> + </form> + </li> + <?php endif; ?> + <?php if (user_notify($uid, $row['ID'])): ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'unnotify/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_UnNotify" value="<?= __('Disable notifications') ?>" /> + </form> + </li> + <?php else: ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'notify/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_Notify" value="<?= __('Notify of new comments') ?>" /> + </form> + </li> + <?php endif; ?> + <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> + <li><a href="<?= get_pkg_uri($pkgs[0]) . 'delete/'; ?>"><?= __('Delete Package'); ?></a></li> + <li><a href="<?= get_pkg_uri($pkgs[0]) . 'merge/'; ?>"><?= __('Merge Package'); ?></a></li> + <?php endif; ?> + <?php endif; ?> + + <?php if ($uid && $row["MaintainerUID"] === NULL): ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'adopt/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_Adopt" value="<?= __('Adopt Package') ?>" /> + </form> + </li> + <?php elseif ($uid && $uid == $row["MaintainerUID"] || + $atype == "Trusted User" || $atype == "Developer"): ?> + <li> + <form action="<?= get_pkg_uri($pkgs[0]) . 'disown/'; ?>" method="post"> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="submit" class="button text-button" name="do_Disown" value="<?= __('Disown Package') ?>" /> + </form> + </li> + <?php endif; ?> + </ul> + </div> + </div> + + <table id="pkginfo"> + <tr> + <th><?= __('Category') . ': ' ?></th> +<?php +if ($SID && ($uid == $row["MaintainerUID"] || + ($atype == "Developer" || $atype == "Trusted User"))): +?> + <td> + <form method="post" action="<?= htmlspecialchars(get_pkg_uri($row['Name']), ENT_QUOTES); ?>"> + <div> + <input type="hidden" name="action" value="do_ChangeCategory" /> + <?php if ($SID): ?> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <?php endif; ?> + <select name="category_id"> +<?php + foreach ($catarr as $cid => $catname): +?> + <option value="<?= $cid ?>"<?php if ($cid == $row["CategoryID"]) { ?> selected="selected" <?php } ?>><?= $catname ?></option> + <?php endforeach; ?> + </select> + <input type="submit" value="<?= __('Change category') ?>"/> + </div> + </form> +<?php else: ?> + <td> + <a href="<?= get_uri('/packages/'); ?>?C=<?= $row['CategoryID'] ?>"><?= $row['Category'] ?></a> +<?php endif; ?> + </td> + </tr> + <tr> + <th><?= __('Submitter') .': ' ?></th> +<?php +if ($row["SubmitterUID"]): + if ($SID): + if (!$USE_VIRTUAL_URLS): +?> + <td><a href="<?= get_uri('/account/'); ?>?Action=AccountInfo&ID=<?= htmlspecialchars($row['SubmitterUID'], ENT_QUOTES) ?>" title="<?= __('View account information for')?> <?= htmlspecialchars($submitter) ?>"><?= htmlspecialchars($submitter) ?></a></td> + <?php else: ?> + <td><a href="<?= get_uri('/account/') . htmlspecialchars($submitter, ENT_QUOTES) ?>" title="<?= __('View account information for %s', htmlspecialchars($submitter)) ?>"><?= htmlspecialchars($submitter) ?></a></td> + <?php endif; ?> +<?php else: ?> + <td><?= htmlspecialchars($submitter) ?></td> + <?php endif; ?> +<?php else: ?> + <td><?= __('None') ?></td> +<?php endif; ?> + </tr> + <tr> + <th><?= __('Maintainer') .': ' ?></th> +<?php +if ($row["MaintainerUID"]): + if ($SID): + if (!$USE_VIRTUAL_URLS): +?> + <td><a href="<?= get_uri('/account/'); ?>?Action=AccountInfo&ID=<?= htmlspecialchars($row['MaintainerUID'], ENT_QUOTES) ?>" title="<?= __('View account information for')?> <?= htmlspecialchars($maintainer) ?>"><?= htmlspecialchars($maintainer) ?></a></td> + <?php else: ?> + <td><a href="<?= get_uri('/account/') . htmlspecialchars($maintainer, ENT_QUOTES) ?>" title="<?= __('View account information for %s', htmlspecialchars($maintainer)) ?>"><?= htmlspecialchars($maintainer) ?></a></td> + <?php endif; ?> + <?php else: ?> + <td><?= htmlspecialchars($maintainer) ?></td> + <?php endif; ?> +<?php else: ?> + <td><?= __('None') ?></td> +<?php endif; ?> + </tr> + <tr> + <th><?= __('Votes') . ': ' ?></th> +<?php if ($atype == "Developer" || $atype == "Trusted User"): ?> +<?php if ($USE_VIRTUAL_URLS): ?> + <td><a href="<?= get_pkg_uri($row['Name']); ?>voters/"><?= $votes ?></a></td> +<?php else: ?> + <td><a href="<?= get_uri('/voters/'); ?>?N=<?= htmlspecialchars($row['Name'], ENT_QUOTES) ?>"><?= $votes ?></a></td> +<?php endif; ?> +<?php else: ?> + <td><?= $votes ?></td> +<?php endif; ?> + </tr> + <tr> + <th><?= __('First Submitted') . ': ' ?></th> + <td><?= $submitted_time ?></td> + </tr> + <tr> + <th><?= __('Last Updated') . ': ' ?></th> + <td><?= $updated_time ?></td> + </tr> + </table> + + <div id="metadata"> + <div id="pkgs" class="listing"> + <h3><?= __('Packages') . " (" . count($pkgs) . ")"?></h3> +<?php if (count($pkgs) > 0): ?> + <ul> +<?php + while (list($k, $pkg) = each($pkgs)): +?> + <li><a href="<?= htmlspecialchars(get_pkg_uri($pkg), ENT_QUOTES); ?>" title="<?= __('View packages details for').' '. htmlspecialchars($pkg) ?>"><?= htmlspecialchars($pkg) ?></a></li> + <?php endwhile; ?> + </ul> +<?php endif; ?> + </div> + </div> +</div> -- 1.9.1
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/template/pkg_details.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/template/pkg_details.php b/web/template/pkg_details.php index bd08282..d4e4e4e 100644 --- a/web/template/pkg_details.php +++ b/web/template/pkg_details.php @@ -112,6 +112,10 @@ $sources = package_sources($row["ID"]); <table id="pkginfo"> <tr> + <th><?= __('Package Base') . ': ' ?></th> + <td class="wrap"><a href="<?= htmlspecialchars(get_pkgbase_uri($row['BaseName']), ENT_QUOTES); ?>"><?= htmlspecialchars($row['BaseName']); ?></a></td> + </tr> + <tr> <th><?= __('Description') . ': ' ?></th> <td class="wrap"><?= htmlspecialchars($row['Description']); ?></td> </tr> -- 1.9.1
A package should only be overwritten if it already belongs to the package base that is trying to overwrite it. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/pkgsubmit.php | 44 +++++++++++++++++++++++--------------------- web/lib/aur.inc.php | 19 +++++++++++++++++++ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 13a67d8..cf5e03b 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -410,33 +410,35 @@ if ($uid): } /* Upload PKGBUILD and tarball. */ - if (!$error) { - /* - * First, check whether this package already exists and - * whether it can be overwritten. - */ - if (can_submit_pkgbase($pkgbase_name, $_COOKIE["AURSID"])) { - if (file_exists($incoming_pkgdir)) { - /* - * Blow away the existing directory and - * its contents. - */ - rm_tree($incoming_pkgdir); - } + if (!$error && !can_submit_pkgbase($pkgbase_name, $_COOKIE["AURSID"])) { + $error = __( "You are not allowed to overwrite the %s%s%s package.", "<strong>", $pkgbase_name, "</strong>"); + } - /* - * The mode is masked by the current umask, so - * not as scary as it looks. - */ - if (!mkdir($incoming_pkgdir, 0777, true)) { - $error = __( "Could not create directory %s.", $incoming_pkgdir); + if (!$error) { + foreach ($pkginfo as $pi) { + if (!can_submit_pkg($pi['pkgname'], $base_id)) { + $error = __( "You are not allowed to overwrite the %s%s%s package.", "<strong>", $pi['pkgname'], "</strong>"); + break; } - } else { - $error = __( "You are not allowed to overwrite the %s%s%s package.", "<strong>", $pkg_name, "</strong>"); } } if (!$error) { + /* + * Blow away the existing directory and its contents. + */ + if (file_exists($incoming_pkgdir)) { + rm_tree($incoming_pkgdir); + } + + /* + * The mode is masked by the current umask, so not as + * scary as it looks. + */ + if (!mkdir($incoming_pkgdir, 0777, true)) { + $error = __( "Could not create directory %s.", $incoming_pkgdir); + } + if (!chdir($incoming_pkgdir)) { $error = __("Could not change directory to %s.", $incoming_pkgdir); } diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index e786e50..16aa261 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -313,6 +313,25 @@ function can_submit_pkgbase($name="", $sid="") { } /** + * Determine if a package can be overwritten by some package base + * + * @param string $name Name of the package to be submitted + * @param int $base_id The ID of the package base + * + * @return bool True if the package can be overwritten, false if not + */ +function can_submit_pkg($name, $base_id) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) FROM Packages WHERE "; + $q.= "Name = " . $dbh->quote($name) . " AND "; + $q.= "PackageBaseID <> " . intval($base_id); + $result = $dbh->query($q); + + if (!$result) return false; + return ($result->fetchColumn() == 0); +} + +/** * Recursively delete a directory * * @param string $dirname Name of the directory to be removed -- 1.9.1
This is legacy code. Move it to a separate source file in order to clean up the submission code. The code will be removed altogether in an upcoming release. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/pkgsubmit.php | 142 +--------------------------------------- web/lib/pkgbuild-parser.inc.php | 139 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 140 insertions(+), 141 deletions(-) create mode 100644 web/lib/pkgbuild-parser.inc.php diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index cf5e03b..38c2dde 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -130,147 +130,7 @@ if ($uid): } } - # if no error, get list of directory contents and process PKGBUILD - # TODO: This needs to be completely rewritten to support stuff like arrays - # and variable substitution among other things. - if (!$error) { - # process PKGBUILD - remove line concatenation - # - $pkgbuild = array(); - $line_no = 0; - $lines = array(); - $continuation_line = 0; - $current_line = ""; - $paren_depth = 0; - foreach (explode("\n", $pkgbuild_raw) as $line) { - $line = trim($line); - # Remove comments - $line = preg_replace('/\s*#.*/', '', $line); - - $char_counts = count_chars($line, 0); - $paren_depth += $char_counts[ord('(')] - $char_counts[ord(')')]; - if (substr($line, strlen($line)-1) == "\\") { - # continue appending onto existing line_no - # - $current_line .= substr($line, 0, strlen($line)-1); - $continuation_line = 1; - } elseif ($paren_depth > 0) { - # assumed continuation - # continue appending onto existing line_no - # - $current_line .= $line . " "; - $continuation_line = 1; - } else { - # maybe the last line in a continuation, or a standalone line? - # - if ($continuation_line) { - # append onto existing line_no - # - $current_line .= $line; - $lines[$line_no] = $current_line; - $current_line = ""; - } else { - # it's own line_no - # - $lines[$line_no] = $line; - } - $continuation_line = 0; - $line_no++; - } - } - - # Now process the lines and put any var=val lines into the - # 'pkgbuild' array. - while (list($k, $line) = each($lines)) { - # Neutralize parameter substitution - $line = preg_replace('/\${(\w+)#(\w*)}?/', '$1$2', $line); - - $lparts = Array(); - # Match variable assignment only. - if (preg_match('/^\s*[_\w]+=[^=].*/', $line, $matches)) { - $lparts = explode("=", $matches[0], 2); - } - - if (!empty($lparts)) { - # this is a variable/value pair, strip - # out array parens and any quoting, - # except in pkgdesc for pkgname or - # pkgdesc, only remove start/end pairs - # of " or ' - if ($lparts[0] == "pkgname" || $lparts[0] == "pkgdesc") { - if ($lparts[1]{0} == '"' && - $lparts[1]{strlen($lparts[1])-1} == '"') { - $pkgbuild[$lparts[0]] = substr($lparts[1], 1, -1); - } - elseif - ($lparts[1]{0} == "'" && - $lparts[1]{strlen($lparts[1])-1} == "'") { - $pkgbuild[$lparts[0]] = substr($lparts[1], 1, -1); - } else { - $pkgbuild[$lparts[0]] = $lparts[1]; - } - } else { - $pkgbuild[$lparts[0]] = str_replace(array("(",")","\"","'"), "", - $lparts[1]); - } - } - } - - # some error checking on PKGBUILD contents - just make sure each - # variable has a value. This does not do any validity checking - # on the values, or attempts to fix line continuation/wrapping. - $req_vars = array("url", "pkgdesc", "license", "pkgrel", "pkgver", "arch", "pkgname"); - foreach ($req_vars as $var) { - if (!array_key_exists($var, $pkgbuild)) { - $error = __('Missing %s variable in PKGBUILD.', $var); - break; - } - } - } - - # Now, run through the pkgbuild array, and do "eval" and simple substituions. - $new_pkgbuild = array(); - if (!$error) { - while (list($k, $v) = each($pkgbuild)) { - if (strpos($k,'eval ') !== false) { - $k = preg_replace('/^eval[\s]*/', "", $k); - ##"eval" replacements - $pattern_eval = '/{\$({?)([\w]+)(}?)}/'; - while (preg_match($pattern_eval,$v,$regs)) { - $pieces = explode(",",$pkgbuild["$regs[2]"]); - ## nongreedy matching! - preserving the order of "eval" - $pattern = '/([\S]*?){\$'.$regs[1].$regs[2].$regs[3].'}([\S]*)/'; - while (preg_match($pattern,$v,$regs_replace)) { - $replacement = ""; - for ($i = 0; $i < sizeof($pieces); $i++) { - $replacement .= $regs_replace[1].$pieces[$i].$regs_replace[2]." "; - } - $v=preg_replace($pattern, $replacement, $v, 1); - } - } - } - - # Simple variable replacement - $pattern_var = '/\$({?)([_\w]+)(}?)/'; - $offset = 0; - while (preg_match($pattern_var, $v, $regs, PREG_OFFSET_CAPTURE, $offset)) { - $var = $regs[2][0]; - $pos = $regs[0][1]; - $len = strlen($regs[0][0]); - - if (isset($new_pkgbuild[$var])) { - $replacement = substr($new_pkgbuild[$var], strpos($new_pkgbuild[$var], " ")); - } - else { - $replacement = ''; - } - - $v = substr_replace($v, $replacement, $pos, $len); - $offset = $pos + strlen($replacement); - } - $new_pkgbuild[$k] = $v; - } - } + include('pkgbuild-parser.inc.php'); /* Parse .AURINFO and extract meta data. */ $pkgbase_info = array(); diff --git a/web/lib/pkgbuild-parser.inc.php b/web/lib/pkgbuild-parser.inc.php new file mode 100644 index 0000000..0bd4cfe --- /dev/null +++ b/web/lib/pkgbuild-parser.inc.php @@ -0,0 +1,139 @@ +# <?php +if (!$error) { + # process PKGBUILD - remove line concatenation + # + $pkgbuild = array(); + $line_no = 0; + $lines = array(); + $continuation_line = 0; + $current_line = ""; + $paren_depth = 0; + foreach (explode("\n", $pkgbuild_raw) as $line) { + $line = trim($line); + # Remove comments + $line = preg_replace('/\s*#.*/', '', $line); + + $char_counts = count_chars($line, 0); + $paren_depth += $char_counts[ord('(')] - $char_counts[ord(')')]; + if (substr($line, strlen($line)-1) == "\\") { + # continue appending onto existing line_no + # + $current_line .= substr($line, 0, strlen($line)-1); + $continuation_line = 1; + } elseif ($paren_depth > 0) { + # assumed continuation + # continue appending onto existing line_no + # + $current_line .= $line . " "; + $continuation_line = 1; + } else { + # maybe the last line in a continuation, or a standalone line? + # + if ($continuation_line) { + # append onto existing line_no + # + $current_line .= $line; + $lines[$line_no] = $current_line; + $current_line = ""; + } else { + # it's own line_no + # + $lines[$line_no] = $line; + } + $continuation_line = 0; + $line_no++; + } + } + + # Now process the lines and put any var=val lines into the + # 'pkgbuild' array. + while (list($k, $line) = each($lines)) { + # Neutralize parameter substitution + $line = preg_replace('/\${(\w+)#(\w*)}?/', '$1$2', $line); + + $lparts = Array(); + # Match variable assignment only. + if (preg_match('/^\s*[_\w]+=[^=].*/', $line, $matches)) { + $lparts = explode("=", $matches[0], 2); + } + + if (!empty($lparts)) { + # this is a variable/value pair, strip + # out array parens and any quoting, + # except in pkgdesc for pkgname or + # pkgdesc, only remove start/end pairs + # of " or ' + if ($lparts[0] == "pkgname" || $lparts[0] == "pkgdesc") { + if ($lparts[1]{0} == '"' && + $lparts[1]{strlen($lparts[1])-1} == '"') { + $pkgbuild[$lparts[0]] = substr($lparts[1], 1, -1); + } + elseif + ($lparts[1]{0} == "'" && + $lparts[1]{strlen($lparts[1])-1} == "'") { + $pkgbuild[$lparts[0]] = substr($lparts[1], 1, -1); + } else { + $pkgbuild[$lparts[0]] = $lparts[1]; + } + } else { + $pkgbuild[$lparts[0]] = str_replace(array("(",")","\"","'"), "", + $lparts[1]); + } + } + } + + # some error checking on PKGBUILD contents - just make sure each + # variable has a value. This does not do any validity checking + # on the values, or attempts to fix line continuation/wrapping. + $req_vars = array("url", "pkgdesc", "license", "pkgrel", "pkgver", "arch", "pkgname"); + foreach ($req_vars as $var) { + if (!array_key_exists($var, $pkgbuild)) { + $error = __('Missing %s variable in PKGBUILD.', $var); + break; + } + } +} + +# Now, run through the pkgbuild array, and do "eval" and simple substituions. +$new_pkgbuild = array(); +if (!$error) { + while (list($k, $v) = each($pkgbuild)) { + if (strpos($k,'eval ') !== false) { + $k = preg_replace('/^eval[\s]*/', "", $k); + ##"eval" replacements + $pattern_eval = '/{\$({?)([\w]+)(}?)}/'; + while (preg_match($pattern_eval,$v,$regs)) { + $pieces = explode(",",$pkgbuild["$regs[2]"]); + ## nongreedy matching! - preserving the order of "eval" + $pattern = '/([\S]*?){\$'.$regs[1].$regs[2].$regs[3].'}([\S]*)/'; + while (preg_match($pattern,$v,$regs_replace)) { + $replacement = ""; + for ($i = 0; $i < sizeof($pieces); $i++) { + $replacement .= $regs_replace[1].$pieces[$i].$regs_replace[2]." "; + } + $v=preg_replace($pattern, $replacement, $v, 1); + } + } + } + + # Simple variable replacement + $pattern_var = '/\$({?)([_\w]+)(}?)/'; + $offset = 0; + while (preg_match($pattern_var, $v, $regs, PREG_OFFSET_CAPTURE, $offset)) { + $var = $regs[2][0]; + $pos = $regs[0][1]; + $len = strlen($regs[0][0]); + + if (isset($new_pkgbuild[$var])) { + $replacement = substr($new_pkgbuild[$var], strpos($new_pkgbuild[$var], " ")); + } + else { + $replacement = ''; + } + + $v = substr_replace($v, $replacement, $pos, $len); + $offset = $pos + strlen($replacement); + } + $new_pkgbuild[$k] = $v; + } +} -- 1.9.1
Instead of always parsing the PKGBUILD, only invoke the parser when there is no meta data (.AURINFO) available. This speeds up the general case (packages including meta data). Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/pkgsubmit.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/html/pkgsubmit.php b/web/html/pkgsubmit.php index 38c2dde..2432510 100644 --- a/web/html/pkgsubmit.php +++ b/web/html/pkgsubmit.php @@ -130,8 +130,6 @@ if ($uid): } } - include('pkgbuild-parser.inc.php'); - /* Parse .AURINFO and extract meta data. */ $pkgbase_info = array(); $pkginfo = array(); @@ -177,6 +175,8 @@ if ($uid): } } else { /* Use data from the PKGBUILD parser (deprecated!) */ + include('pkgbuild-parser.inc.php'); + $pkgbase_info = $new_pkgbuild; if (!isset($pkgbase_info['pkgbase'])) { $pkgbase_info['pkgbase'] = $pkgbase_info['pkgname']; -- 1.9.1
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- UPGRADING | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/UPGRADING b/UPGRADING index 9736ef0..a33ea63 100644 --- a/UPGRADING +++ b/UPGRADING @@ -18,6 +18,130 @@ ALTER TABLE PackageComments ADD FOREIGN KEY (UsersID) REFERENCES Users(ID) ON DELETE SET NULL; ---- +3. Create the PackageBases table: + +---- +CREATE TABLE PackageBases ( + ID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, + Name VARCHAR(64) NOT NULL, + CategoryID TINYINT UNSIGNED NOT NULL DEFAULT 1, + NumVotes INTEGER UNSIGNED NOT NULL DEFAULT 0, + OutOfDateTS BIGINT UNSIGNED NULL DEFAULT NULL, + SubmittedTS BIGINT UNSIGNED NOT NULL, + ModifiedTS BIGINT UNSIGNED NOT NULL, + SubmitterUID INTEGER UNSIGNED NULL DEFAULT NULL, + MaintainerUID INTEGER UNSIGNED NULL DEFAULT NULL, + PRIMARY KEY (ID), + UNIQUE (Name), + INDEX (CategoryID), + INDEX (NumVotes), + INDEX (SubmitterUID), + INDEX (MaintainerUID), + FOREIGN KEY (CategoryID) REFERENCES PackageCategories(ID) ON DELETE NO ACTION, + -- deleting a user will cause packages to be orphaned, not deleted + FOREIGN KEY (SubmitterUID) REFERENCES Users(ID) ON DELETE SET NULL, + FOREIGN KEY (MaintainerUID) REFERENCES Users(ID) ON DELETE SET NULL +) ENGINE = InnoDB; +---- + +4. Migrate data from Packages to PackageBases: + +---- +INSERT INTO PackageBases SELECT ID, Name, CategoryID, NumVotes, OutOfDateTS, + SubmittedTS, ModifiedTS, SubmitterUID, MaintainerUID FROM Packages; +---- + +5. Delete unneeded foreign keys from Packages: + +First, drop the foreign keys on CategoryID, SubmitterUID and MaintainerUID. The +following queries should work in most cases: + +---- +ALTER TABLE Packages + DROP FOREIGN KEY Packages_ibfk_1, + DROP FOREIGN KEY Packages_ibfk_2, + DROP FOREIGN KEY Packages_ibfk_3; +---- + +You can use `SHOW CREATE TABLE Packages;` to check whether you should use +different names for your setup. + +6. Delete unneeded fields from Packages: + +---- +ALTER TABLE Packages + DROP COLUMN CategoryID, + DROP COLUMN NumVotes, + DROP COLUMN OutOfDateTS, + DROP COLUMN SubmittedTS, + DROP COLUMN ModifiedTS, + DROP COLUMN SubmitterUID, + DROP COLUMN MaintainerUID; +---- + +7. Add package base references to the Packages table: + +---- +ALTER TABLE Packages + ADD COLUMN PackageBaseID INTEGER UNSIGNED NULL, + ADD FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE; +UPDATE Packages SET PackageBaseID = ID; +ALTER TABLE Packages MODIFY PackageBaseID INTEGER UNSIGNED NOT NULL; +---- + +8. Delete foreign keys from PackageVotes, PackageComments and CommentNotify: + +---- +ALTER TABLE PackageVotes + DROP FOREIGN KEY PackageVotes_ibfk_1, + DROP FOREIGN KEY PackageVotes_ibfk_2; +ALTER TABLE PackageComments + DROP FOREIGN KEY PackageComments_ibfk_3; +ALTER TABLE CommentNotify + DROP FOREIGN KEY CommentNotify_ibfk_1, + DROP FOREIGN KEY CommentNotify_ibfk_2; +---- + +We highly recommend to use `SHOW CREATE TABLE PackageVotes;` etc. to check +whether you should use different names for your setup. + +9. Delete indexes from PackageVotes and CommentNotify: + +---- +ALTER TABLE PackageVotes DROP INDEX VoteUsersIDPackageID; +ALTER TABLE CommentNotify DROP INDEX NotifyUserIDPkgID; +---- + +10. Migrate PackageVotes, PackageComments and CommentNotify to refer to package +bases: + +---- +ALTER TABLE PackageVotes ADD COLUMN PackageBaseID INTEGER UNSIGNED NOT NULL; +UPDATE PackageVotes SET PackageBaseID = PackageID; +ALTER TABLE PackageVotes DROP COLUMN PackageID; +ALTER TABLE PackageComments ADD COLUMN PackageBaseID INTEGER UNSIGNED NOT NULL; +UPDATE PackageComments SET PackageBaseID = PackageID; +ALTER TABLE PackageComments DROP COLUMN PackageID; +ALTER TABLE CommentNotify ADD COLUMN PackageBaseID INTEGER UNSIGNED NOT NULL; +UPDATE CommentNotify SET PackageBaseID = PkgID; +ALTER TABLE CommentNotify DROP COLUMN PkgID; +---- + +11. Recreate missing foreign keys and indexes: + +---- +ALTER TABLE PackageVotes + ADD FOREIGN KEY (UsersID) REFERENCES Users(ID) ON DELETE CASCADE, + ADD FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE; +ALTER TABLE PackageComments + ADD FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE; +ALTER TABLE CommentNotify + ADD FOREIGN KEY (PackageBaseID) REFERENCES PackageBases(ID) ON DELETE CASCADE, + ADD FOREIGN KEY (UserID) REFERENCES Users(ID) ON DELETE CASCADE; +CREATE UNIQUE INDEX VoteUsersIDPackageID ON PackageVotes (UsersID, PackageBaseID); +CREATE UNIQUE INDEX NotifyUserIDPkgID ON CommentNotify (UserID, PackageBaseID); +---- + From 2.2.0 to 2.3.0 ------------------- -- 1.9.1
Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/lib/pkgfuncs.inc.php | 11 ++++++++++- web/template/pkg_search_form.php | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index b92eb9c..a63ee6f 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -681,10 +681,19 @@ function pkg_search_page($SID="") { $K = "%" . addcslashes($_GET['K'], '%_') . "%"; $q_where .= "AND (Packages.Name LIKE " . $dbh->quote($K) . ") "; } - elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "x") { + elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "b") { + /* Search by package base name. */ + $K = "%" . addcslashes($_GET['K'], '%_') . "%"; + $q_where .= "AND (PackageBases.Name LIKE " . $dbh->quote($K) . ") "; + } + elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "N") { /* Search by name (exact match). */ $q_where .= "AND (Packages.Name = " . $dbh->quote($_GET['K']) . ") "; } + elseif (isset($_GET["SeB"]) && $_GET["SeB"] == "B") { + /* Search by package base name (exact match). */ + $q_where .= "AND (PackageBases.Name = " . $dbh->quote($_GET['K']) . ") "; + } else { /* Search by name and description (default). */ $K = "%" . addcslashes($_GET['K'], '%_') . "%"; diff --git a/web/template/pkg_search_form.php b/web/template/pkg_search_form.php index 588b4d4..ececf06 100644 --- a/web/template/pkg_search_form.php +++ b/web/template/pkg_search_form.php @@ -4,7 +4,9 @@ include_once('pkgfuncs.inc.php'); $searchby = array( 'nd' => __('Name, Description'), 'n' => __('Name Only'), - 'x' => __('Exact name'), + 'b' => __('Package Base'), + 'N' => __('Exact Name'), + 'B' => __('Exact Package Base'), 'm' => __('Maintainer'), 's' => __('Submitter') ); -- 1.9.1
Package actions now operate on package bases instead of packages. Move all actions to the correct locations. This also fixes some issues with comment notifications. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de> --- web/html/index.php | 34 +++++++-------- web/html/packages.php | 75 --------------------------------- web/html/pkgbase.php | 82 ++++++++++++++++++++++++++++++++++++- web/html/pkgdel.php | 10 ++--- web/html/pkgmerge.php | 10 ++--- web/lib/pkgfuncs.inc.php | 64 ++++++++++++++--------------- web/template/pkg_comment_form.php | 4 +- web/template/pkg_comments.php | 7 ++-- web/template/pkg_details.php | 30 +++++++------- web/template/pkg_search_results.php | 4 +- web/template/pkgbase_details.php | 26 ++++++------ 11 files changed, 175 insertions(+), 171 deletions(-) diff --git a/web/html/index.php b/web/html/index.php index e79955e..fe74857 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -20,6 +20,22 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { include "./404.php"; return; } + } + + include get_route('/' . $tokens[1]); +} elseif (!empty($tokens[1]) && '/' . $tokens[1] == get_pkgbase_route()) { + if (!empty($tokens[2])) { + /* TODO: Create a proper data structure to pass variables from + * the routing framework to the individual pages instead of + * initializing arbitrary variables here. */ + $pkgbase_name = $tokens[2]; + $base_id = pkgbase_from_name($pkgbase_name); + + if (!$base_id) { + header("HTTP/1.0 404 Not Found"); + include "./404.php"; + return; + } if (!empty($tokens[3])) { /* TODO: Remove support for legacy URIs and move these @@ -65,23 +81,7 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { return; } - $_POST['IDs'] = array(pkgid_from_name($tokens[2]) => '1'); - } - } - - include get_route('/' . $tokens[1]); -} elseif (!empty($tokens[1]) && '/' . $tokens[1] == get_pkgbase_route()) { - if (!empty($tokens[2])) { - /* TODO: Create a proper data structure to pass variables from - * the routing framework to the individual pages instead of - * initializing arbitrary variables here. */ - $pkgbase_name = $tokens[2]; - $base_id = pkgbase_from_name($pkgbase_name); - - if (!$base_id) { - header("HTTP/1.0 404 Not Found"); - include "./404.php"; - return; + $_POST['IDs'] = array(pkgbase_from_name($tokens[2]) => '1'); } } diff --git a/web/html/packages.php b/web/html/packages.php index d9c3a86..876e2c0 100644 --- a/web/html/packages.php +++ b/web/html/packages.php @@ -42,77 +42,6 @@ if (isset($_COOKIE["AURSID"])) { $atype = ""; } -# Grab the list of Package IDs to be operated on -$ids = array(); -if (isset($_POST['IDs'])) { - foreach ($_POST['IDs'] as $id => $i) { - $id = intval($id); - if ($id > 0) { - $ids[] = $id; - } - } -} - -# Determine what action to do -$ret = false; -$output = ""; -if (check_token()) { - if (current_action("do_Flag")) { - list($ret, $output) = pkg_flag($atype, $ids); - } elseif (current_action("do_UnFlag")) { - list($ret, $output) = pkg_unflag($atype, $ids); - } elseif (current_action("do_Adopt")) { - list($ret, $output) = pkg_adopt($atype, $ids, true); - } elseif (current_action("do_Disown")) { - list($ret, $output) = pkg_adopt($atype, $ids, false); - } elseif (current_action("do_Vote")) { - list($ret, $output) = pkg_vote($atype, $ids, true); - } elseif (current_action("do_UnVote")) { - list($ret, $output) = pkg_vote($atype, $ids, false); - } elseif (current_action("do_Delete")) { - if (isset($_POST['confirm_Delete'])) { - if (!isset($_POST['merge_Into']) || empty($_POST['merge_Into'])) { - list($ret, $output) = pkg_delete($atype, pkgbase_from_pkgid($ids), NULL); - unset($_GET['ID']); - } - else { - $merge_base_id = pkgbase_from_name($_POST['merge_Into']); - if ($merge_base_id) { - list($ret, $output) = pkg_delete($atype, pkgbase_from_pkgid($ids), $merge_base_id); - unset($_GET['ID']); - } - else { - $output = __("Cannot find package to merge votes and comments into."); - } - } - } - else { - $output = __("The selected packages have not been deleted, check the confirmation checkbox."); - } - } elseif (current_action("do_Notify")) { - list($ret, $output) = pkg_notify($atype, $ids); - } elseif (current_action("do_UnNotify")) { - list($ret, $output) = pkg_notify($atype, $ids, false); - } elseif (current_action("do_DeleteComment")) { - list($ret, $output) = pkg_delete_comment($atype); - } elseif (current_action("do_ChangeCategory")) { - list($ret, $output) = pkg_change_category($pkgid, $atype); - } - - if (isset($_REQUEST['comment'])) { - $uid = uid_from_sid($_COOKIE["AURSID"]); - add_package_comment($pkgid, $uid, $_REQUEST['comment']); - $ret = true; - } - - if ($ret) { - /* Redirect back to package page on success. */ - header('Location: ' . get_pkg_uri($pkgname)); - exit(); - } -} - -# Get package details after package actions have been attempted, FS#34508 $details = array(); if (isset($pkgname)) { $details = get_package_details($pkgid); @@ -121,10 +50,6 @@ if (isset($pkgname)) { html_header($title, $details); ?> -<?php if ($output): ?> - <p class="pkgoutput"><?= $output ?></p> -<?php endif; ?> - <?php if (isset($pkgid)) { include('pkg_search_form.php'); diff --git a/web/html/pkgbase.php b/web/html/pkgbase.php index e0c9af6..42705ed 100644 --- a/web/html/pkgbase.php +++ b/web/html/pkgbase.php @@ -22,7 +22,7 @@ if (!isset($base_id) || !isset($pkgbase_name)) { unset($base_id, $pkgbase_name); } - if ($base_id == 0 || $base_id == NULL || $pkgbase_name == NULL) { + if (isset($base_id) && ($base_id == 0 || $base_id == NULL || $pkgbase_name == NULL)) { header("HTTP/1.0 404 Not Found"); include "./404.php"; return; @@ -39,10 +39,90 @@ if (isset($_COOKIE["AURSID"])) { $atype = ""; } +/* Grab the list of package base IDs to be operated on. */ +$ids = array(); +if (isset($_POST['IDs'])) { + foreach ($_POST['IDs'] as $id => $i) { + $id = intval($id); + if ($id > 0) { + $ids[] = $id; + } + } +} + +/* Perform package base actions. */ +$ret = false; +$output = ""; +if (check_token()) { + if (current_action("do_Flag")) { + list($ret, $output) = pkg_flag($atype, $ids); + } elseif (current_action("do_UnFlag")) { + list($ret, $output) = pkg_unflag($atype, $ids); + } elseif (current_action("do_Adopt")) { + list($ret, $output) = pkg_adopt($atype, $ids, true); + } elseif (current_action("do_Disown")) { + list($ret, $output) = pkg_adopt($atype, $ids, false); + } elseif (current_action("do_Vote")) { + list($ret, $output) = pkg_vote($atype, $ids, true); + } elseif (current_action("do_UnVote")) { + list($ret, $output) = pkg_vote($atype, $ids, false); + } elseif (current_action("do_Delete")) { + if (isset($_POST['confirm_Delete'])) { + if (!isset($_POST['merge_Into']) || empty($_POST['merge_Into'])) { + list($ret, $output) = pkg_delete($atype, $ids, NULL); + unset($_GET['ID']); + } + else { + $merge_base_id = pkgbase_from_name($_POST['merge_Into']); + if ($merge_base_id) { + list($ret, $output) = pkg_delete($atype, $ids, $merge_base_id); + unset($_GET['ID']); + } + else { + $output = __("Cannot find package to merge votes and comments into."); + } + } + } + else { + $output = __("The selected packages have not been deleted, check the confirmation checkbox."); + } + } elseif (current_action("do_Notify")) { + list($ret, $output) = pkg_notify($atype, $ids); + } elseif (current_action("do_UnNotify")) { + list($ret, $output) = pkg_notify($atype, $ids, false); + } elseif (current_action("do_DeleteComment")) { + list($ret, $output) = pkg_delete_comment($atype); + } elseif (current_action("do_ChangeCategory")) { + list($ret, $output) = pkg_change_category($base_id, $atype); + } + + if (isset($_REQUEST['comment'])) { + $uid = uid_from_sid($_COOKIE["AURSID"]); + add_package_comment($base_id, $uid, $_REQUEST['comment']); + $ret = true; + } + + if ($ret) { + if (isset($base_id)) { + /* Redirect back to package base page on success. */ + header('Location: ' . get_pkgbase_uri($pkgbase_name)); + exit(); + } else { + /* Redirect back to package search page. */ + header('Location: ' . get_pkg_route()); + exit(); + } + } +} + $details = get_pkgbase_details($base_id); html_header($title, $details); ?> +<?php if ($output): ?> +<p class="pkgoutput"><?= $output ?></p> +<?php endif; ?> + <?php include('pkg_search_form.php'); if (isset($_COOKIE["AURSID"])) { diff --git a/web/html/pkgdel.php b/web/html/pkgdel.php index 7f244eb..d1026ce 100644 --- a/web/html/pkgdel.php +++ b/web/html/pkgdel.php @@ -18,17 +18,17 @@ if (isset($_COOKIE["AURSID"])) { if ($atype == "Trusted User" || $atype == "Developer"): ?> <div class="box"> - <h2><?= __('Delete Package: %s', htmlspecialchars($pkgname)) ?></h2> + <h2><?= __('Delete Package: %s', htmlspecialchars($pkgbase_name)) ?></h2> <p> <?= __('Use this form to delete the package (%s%s%s) from the AUR. ', - '<strong>', htmlspecialchars($pkgname), '</strong>'); ?> + '<strong>', htmlspecialchars($pkgbase_name), '</strong>'); ?> <?= __('Deletion of a package is permanent. '); ?> <?= __('Select the checkbox to confirm action.') ?> </p> - <form action="<?= get_uri('/packages/'); ?>" method="post"> + <form action="<?= get_uri('/pkgbase/'); ?>" method="post"> <fieldset> - <input type="hidden" name="IDs[<?= $pkgid ?>]" value="1" /> - <input type="hidden" name="ID" value="<?= $pkgid ?>" /> + <input type="hidden" name="IDs[<?= $base_id ?>]" value="1" /> + <input type="hidden" name="ID" value="<?= $base_id ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <p><input type="checkbox" name="confirm_Delete" value="1" /> <?= __("Confirm package deletion") ?></p> diff --git a/web/html/pkgmerge.php b/web/html/pkgmerge.php index 834d0c9..9ffd5e7 100644 --- a/web/html/pkgmerge.php +++ b/web/html/pkgmerge.php @@ -18,18 +18,18 @@ if (isset($_COOKIE["AURSID"])) { if ($atype == "Trusted User" || $atype == "Developer"): ?> <div class="box"> - <h2><?= __('Merge Package: %s', htmlspecialchars($pkgname)) ?></h2> + <h2><?= __('Merge Package: %s', htmlspecialchars($pkgbase_name)) ?></h2> <p> <?= __('Use this form to merge the package (%s%s%s) into another package. ', - '<strong>', htmlspecialchars($pkgname), '</strong>'); ?> + '<strong>', htmlspecialchars($pkgbase_name), '</strong>'); ?> <?= __('Once the package has been merged it cannot be reversed. '); ?> <?= __('Enter the package name you wish to merge the package into. '); ?> <?= __('Select the checkbox to confirm action.') ?> </p> - <form action="<?= get_uri('/packages/'); ?>" method="post"> + <form action="<?= get_uri('/pkgbase/'); ?>" method="post"> <fieldset> - <input type="hidden" name="IDs[<?= $pkgid ?>]" value="1" /> - <input type="hidden" name="ID" value="<?= $pkgid ?>" /> + <input type="hidden" name="IDs[<?= $base_id ?>]" value="1" /> + <input type="hidden" name="ID" value="<?= $base_id ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <p><label for="merge_Into" ><?= __("Merge into:") ?></label> <input type="text" id="merge_Into" name="merge_Into" /></p> diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index a63ee6f..4e37d2f 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -500,6 +500,9 @@ function display_package_details($id=0, $row, $SID="") { print "<p>" . $row['error'] . "</p>\n"; } else { + $base_id = pkgbase_from_pkgid($id); + $pkgbase_name = pkgbase_name_from_id($base_id); + include('pkg_details.php'); if ($SID) { @@ -507,7 +510,6 @@ function display_package_details($id=0, $row, $SID="") { include('pkg_comment_form.php'); } - $base_id = pkgbase_from_pkgid($id); $comments = package_comments($base_id); if (!empty($comments)) { include('pkg_comments.php'); @@ -536,6 +538,8 @@ function display_pkgbase_details($base_id, $row, $SID="") { print "<p>" . $row['error'] . "</p>\n"; } else { + $pkgbase_name = pkgbase_name_from_id($base_id); + include('pkgbase_details.php'); if ($SID) { @@ -641,7 +645,8 @@ function pkg_search_page($SID="") { $q_select .= "Users.Username AS Maintainer, PackageCategories.Category, Packages.Name, Packages.Version, Packages.Description, - PackageBases.NumVotes, Packages.ID, PackageBases.OutOfDateTS "; + PackageBases.NumVotes, Packages.ID, Packages.PackageBaseID, + PackageBases.OutOfDateTS "; $q_from = "FROM Packages LEFT JOIN PackageBases ON (PackageBases.ID = Packages.PackageBaseID) @@ -941,20 +946,19 @@ function pkgbase_maintainer_uid($base_id) { * * @global string $AUR_LOCATION The AUR's URL used for notification e-mails * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to flag/unflag + * @param array $base_ids Array of package base IDs to flag/unflag * * @return array Tuple of success/failure indicator and error message */ -function pkg_flag($atype, $ids) { +function pkg_flag($atype, $base_ids) { global $AUR_LOCATION; if (!$atype) { return array(false, __("You must be logged in before you can flag packages.")); } - $ids = sanitize_ids($ids); - $base_ids = pkgbase_from_pkgid($ids); - if (empty($ids)) { + $base_ids = pkgbase_from_pkgid($base_ids); + if (empty($base_ids)) { return array(false, __("You did not select any packages to flag.")); } @@ -972,10 +976,10 @@ function pkg_flag($atype, $ids) { $f_name = username_from_sid($_COOKIE['AURSID']); $f_email = email_from_sid($_COOKIE['AURSID']); $f_uid = uid_from_sid($_COOKIE['AURSID']); - $q = "SELECT Packages.Name, Users.Email, Packages.ID "; - $q.= "FROM Packages, Users "; - $q.= "WHERE Packages.ID IN (" . implode(",", $ids) .") "; - $q.= "AND Users.ID = Packages.MaintainerUID "; + $q = "SELECT PackageBases.Name, Users.Email "; + $q.= "FROM PackageBases, Users "; + $q.= "WHERE PackageBases.ID IN (" . implode(",", $base_ids) .") "; + $q.= "AND Users.ID = PackageBases.MaintainerUID "; $q.= "AND Users.ID != " . $f_uid; $result = $dbh->query($q); if ($result) { @@ -1000,18 +1004,17 @@ function pkg_flag($atype, $ids) { * Unflag package(s) as out-of-date * * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to flag/unflag + * @param array $base_ids Array of package base IDs to flag/unflag * * @return array Tuple of success/failure indicator and error message */ -function pkg_unflag($atype, $ids) { +function pkg_unflag($atype, $base_ids) { if (!$atype) { return array(false, __("You must be logged in before you can unflag packages.")); } - $ids = sanitize_ids($ids); - $base_ids = pkgbase_from_pkgid($ids); - if (empty($ids)) { + $base_ids = pkgbase_from_pkgid($base_ids); + if (empty($base_ids)) { return array(false, __("You did not select any packages to unflag.")); } @@ -1144,12 +1147,12 @@ function pkg_delete ($atype, $base_ids, $merge_base_id) { * Adopt or disown packages * * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to adopt/disown + * @param array $base_ids Array of package base IDs to adopt/disown * @param bool $action Adopts if true, disowns if false. Adopts by default * * @return array Tuple of success/failure indicator and error message */ -function pkg_adopt ($atype, $ids, $action=true) { +function pkg_adopt ($atype, $base_ids, $action=true) { if (!$atype) { if ($action) { return array(false, __("You must be logged in before you can adopt packages.")); @@ -1158,9 +1161,8 @@ function pkg_adopt ($atype, $ids, $action=true) { } } - $pkg_ids = sanitize_ids($ids); - $ids = pkgbase_from_pkgid($pkg_ids); - if (empty($ids)) { + $base_ids = sanitize_ids($base_ids); + if (empty($base_ids)) { if ($action) { return array(false, __("You did not select any packages to adopt.")); } else { @@ -1180,7 +1182,7 @@ function pkg_adopt ($atype, $ids, $action=true) { } $q.= "SET $field = $user "; - $q.= "WHERE ID IN (" . implode(",", $ids) . ") "; + $q.= "WHERE ID IN (" . implode(",", $base_ids) . ") "; if ($action && $atype == "User") { /* Regular users may only adopt orphan packages. */ @@ -1203,12 +1205,12 @@ function pkg_adopt ($atype, $ids, $action=true) { * Vote and un-vote for packages * * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to vote/un-vote + * @param array $base_ids Array of package base IDs to vote/un-vote * @param bool $action Votes if true, un-votes if false. Votes by default * * @return array Tuple of success/failure indicator and error message */ -function pkg_vote ($atype, $ids, $action=true) { +function pkg_vote ($atype, $base_ids, $action=true) { if (!$atype) { if ($action) { return array(false, __("You must be logged in before you can vote for packages.")); @@ -1217,9 +1219,8 @@ function pkg_vote ($atype, $ids, $action=true) { } } - $ids = sanitize_ids($ids); - $base_ids = pkgbase_from_pkgid($ids); - if (empty($ids)) { + $base_ids = sanitize_ids($base_ids); + if (empty($base_ids)) { if ($action) { return array(false, __("You did not select any packages to vote for.")); } else { @@ -1360,18 +1361,17 @@ function user_notify($uid, $base_id) { * Toggle notification of packages * * @param string $atype Account type, output of account_from_sid - * @param array $ids Array of package IDs to toggle, formatted as $package_id + * @param array $base_ids Array of package base IDs to toggle * * @return array Tuple of success/failure indicator and error message */ -function pkg_notify ($atype, $ids, $action=true) { +function pkg_notify ($atype, $base_ids, $action=true) { if (!$atype) { return; } - $ids = sanitize_ids($ids); - $base_ids = pkgbase_from_pkgid($ids); - if (empty($ids)) { + $base_ids = sanitize_ids($base_ids); + if (empty($base_ids)) { return array(false, __("Couldn't add to notification list.")); } diff --git a/web/template/pkg_comment_form.php b/web/template/pkg_comment_form.php index 8e74fe6..8a74dc1 100644 --- a/web/template/pkg_comment_form.php +++ b/web/template/pkg_comment_form.php @@ -1,6 +1,6 @@ <div id="generic-form" class="box"> <h2><?= __("Add Comment"); ?></h2> - <form action="<?= get_pkg_uri($row['Name']) ?>" method="post"> + <form action="<?= get_pkgbase_uri($pkgbase_name) ?>" method="post"> <fieldset> <?php if (isset($_REQUEST['comment']) && check_token()) { @@ -8,7 +8,7 @@ if (isset($_REQUEST['comment']) && check_token()) { } ?> <div> - <input type="hidden" name="ID" value="<?= intval($row['ID']) ?>" /> + <input type="hidden" name="ID" value="<?= intval($base_id) ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> </div> <p> diff --git a/web/template/pkg_comments.php b/web/template/pkg_comments.php index 820ba6e..1f47bb3 100644 --- a/web/template/pkg_comments.php +++ b/web/template/pkg_comments.php @@ -2,11 +2,10 @@ $uid = uid_from_sid($SID); $base_id = pkgbase_from_pkgid($row['ID']); $count = package_comments_count($base_id); -$pkgname = $row['Name']; ?> <div id="news"> <h3> - <a href="<?= htmlentities(get_pkg_uri($pkgname), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all %s comments' , $count) ?>"><?= __('Latest Comments') ?></a> + <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all %s comments' , $count) ?>"><?= __('Latest Comments') ?></a> <span class="arrow"></span> </h3> @@ -16,7 +15,7 @@ $pkgname = $row['Name']; endif; ?> <h4> <?php if (canDeleteCommentArray($row, $atype, $uid)): ?> - <form method="post" action="<?= htmlspecialchars(get_pkg_uri($pkgname), ENT_QUOTES); ?>"> + <form method="post" action="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name), ENT_QUOTES); ?>"> <fieldset style="display:inline;"> <input type="hidden" name="action" value="do_DeleteComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> @@ -49,7 +48,7 @@ $pkgname = $row['Name']; <?php if ($count > 10 && !isset($_GET['comments'])): ?> <div id="news"> <h3> - <a href="<?= htmlentities(get_pkg_uri($pkgname), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all %s comments', $count) ?>"><?= __('All comments', $count) ?></a> + <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all %s comments', $count) ?>"><?= __('All comments', $count) ?></a> </h3> </div> <?php endif; ?> diff --git a/web/template/pkg_details.php b/web/template/pkg_details.php index d4e4e4e..5268d3b 100644 --- a/web/template/pkg_details.php +++ b/web/template/pkg_details.php @@ -20,7 +20,7 @@ $updated_time = ($row["ModifiedTS"] == 0) ? $msg : gmdate("Y-m-d H:i", intval($r $submitted_time = ($row["SubmittedTS"] == 0) ? $msg : gmdate("Y-m-d H:i", intval($row["SubmittedTS"])); $out_of_date_time = ($row["OutOfDateTS"] == 0) ? $msg : gmdate("Y-m-d", intval($row["OutOfDateTS"])); -$urlpath = URL_DIR . substr($row['Name'], 0, 2) . "/" . $row['Name']; +$urlpath = URL_DIR . substr($row['BaseName'], 0, 2) . "/" . $row['BaseName']; $deps = package_dependencies($row["ID"]); $requiredby = package_required($row["Name"]); @@ -35,12 +35,12 @@ $sources = package_sources($row["ID"]); <h4><?= __('Package Actions') ?></h4> <ul class="small"> <li><a href="<?= $urlpath ?>/PKGBUILD"><?= __('View PKGBUILD') ?></a></li> - <li><a href="<?= $urlpath . '/' . $row['Name'] ?>.tar.gz"><?= __('Download tarball') ?></a></li> + <li><a href="<?= $urlpath . '/' . $row['BaseName'] ?>.tar.gz"><?= __('Download tarball') ?></a></li> <li><span class="flagged"><?php if ($row["OutOfDateTS"] !== NULL) { echo __('Flagged out-of-date')." (${out_of_date_time})"; } ?></span></li> <?php if ($USE_VIRTUAL_URLS && $uid): ?> <?php if ($row["OutOfDateTS"] === NULL): ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'flag/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'flag/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Flag" value="<?= __('Flag package out-of-date') ?>" /> </form> @@ -48,7 +48,7 @@ $sources = package_sources($row["ID"]); <?php elseif (($row["OutOfDateTS"] !== NULL) && ($uid == $row["MaintainerUID"] || $atype == "Trusted User" || $atype == "Developer")): ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'unflag/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'unflag/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_UnFlag" value="<?= __('Unflag package') ?>" /> </form> @@ -56,14 +56,14 @@ $sources = package_sources($row["ID"]); <?php endif; ?> <?php if (user_voted($uid, $row['ID'])): ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'unvote/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'unvote/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_UnVote" value="<?= __('Remove vote') ?>" /> </form> </li> <?php else: ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'vote/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'vote/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Vote" value="<?= __('Vote for this package') ?>" /> </form> @@ -71,28 +71,28 @@ $sources = package_sources($row["ID"]); <?php endif; ?> <?php if (user_notify($uid, $row['ID'])): ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'unnotify/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'unnotify/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_UnNotify" value="<?= __('Disable notifications') ?>" /> </form> </li> <?php else: ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'notify/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'notify/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Notify" value="<?= __('Notify of new comments') ?>" /> </form> </li> <?php endif; ?> <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> - <li><a href="<?= get_pkg_uri($row['Name']) . 'delete/'; ?>"><?= __('Delete Package'); ?></a></li> - <li><a href="<?= get_pkg_uri($row['Name']) . 'merge/'; ?>"><?= __('Merge Package'); ?></a></li> + <li><a href="<?= get_pkgbase_uri($row['BaseName']) . 'delete/'; ?>"><?= __('Delete Package'); ?></a></li> + <li><a href="<?= get_pkgbase_uri($row['BaseName']) . 'merge/'; ?>"><?= __('Merge Package'); ?></a></li> <?php endif; ?> <?php endif; ?> <?php if ($uid && $row["MaintainerUID"] === NULL): ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'adopt/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'adopt/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Adopt" value="<?= __('Adopt Package') ?>" /> </form> @@ -100,7 +100,7 @@ $sources = package_sources($row["ID"]); <?php elseif ($uid && $uid == $row["MaintainerUID"] || $atype == "Trusted User" || $atype == "Developer"): ?> <li> - <form action="<?= get_pkg_uri($row['Name']) . 'disown/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['BaseName']) . 'disown/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Disown" value="<?= __('Disown Package') ?>" /> </form> @@ -130,7 +130,7 @@ if ($SID && ($uid == $row["MaintainerUID"] || ($atype == "Developer" || $atype == "Trusted User"))): ?> <td> - <form method="post" action="<?= htmlspecialchars(get_pkg_uri($row['Name']), ENT_QUOTES); ?>"> + <form method="post" action="<?= htmlspecialchars(get_pkgbase_uri($row['BaseName']), ENT_QUOTES); ?>"> <div> <input type="hidden" name="action" value="do_ChangeCategory" /> <?php if ($SID): ?> @@ -196,9 +196,9 @@ if ($row["MaintainerUID"]): <th><?= __('Votes') . ': ' ?></th> <?php if ($atype == "Developer" || $atype == "Trusted User"): ?> <?php if ($USE_VIRTUAL_URLS): ?> - <td><a href="<?= get_pkg_uri($row['Name']); ?>voters/"><?= $votes ?></a></td> + <td><a href="<?= get_pkgbase_uri($row['BaseName']); ?>voters/"><?= $votes ?></a></td> <?php else: ?> - <td><a href="<?= get_uri('/voters/'); ?>?N=<?= htmlspecialchars($row['Name'], ENT_QUOTES) ?>"><?= $votes ?></a></td> + <td><a href="<?= get_uri('/voters/'); ?>?N=<?= htmlspecialchars($row['BaseName'], ENT_QUOTES) ?>"><?= $votes ?></a></td> <?php endif; ?> <?php else: ?> <td><?= $votes ?></td> diff --git a/web/template/pkg_search_results.php b/web/template/pkg_search_results.php index 16f574a..c9da5f9 100644 --- a/web/template/pkg_search_results.php +++ b/web/template/pkg_search_results.php @@ -28,7 +28,7 @@ if (!$result): ?> <?php endif; ?> </div> - <form id="pkglist-results-form" method="post" action="<?= get_uri('/packages/'); ?>?<?= htmlentities($_SERVER['QUERY_STRING']) ?>"> + <form id="pkglist-results-form" method="post" action="<?= get_uri('/pkgbase/'); ?>?<?= htmlentities($_SERVER['QUERY_STRING']) ?>"> <table class="results"> <thead> <tr> @@ -52,7 +52,7 @@ if (!$result): ?> <?php while (list($indx, $row) = each($searchresults)): ?> <tr class="<?= ($indx % 2 == 0) ? 'odd' : 'even' ?>"> <?php if ($SID): ?> - <td><input type="checkbox" name="IDs[<?= $row["ID"] ?>]" value="1" /></td> + <td><input type="checkbox" name="IDs[<?= $row["PackageBaseID"] ?>]" value="1" /></td> <?php endif; ?> <td><?= htmlspecialchars($row["Category"]) ?></td> <td><a href="<?= htmlspecialchars(get_pkg_uri($row["Name"]), ENT_QUOTES); ?>"><?= htmlspecialchars($row["Name"]) ?></a></td> diff --git a/web/template/pkgbase_details.php b/web/template/pkgbase_details.php index a77ecd3..8da23c4 100644 --- a/web/template/pkgbase_details.php +++ b/web/template/pkgbase_details.php @@ -30,12 +30,12 @@ $pkgs = pkgbase_get_pkgnames($base_id); <h4><?= __('Package Actions') ?></h4> <ul class="small"> <li><a href="<?= $urlpath ?>/PKGBUILD"><?= __('View PKGBUILD') ?></a></li> - <li><a href="<?= $urlpath . '/' . $pkgs[0] ?>.tar.gz"><?= __('Download tarball') ?></a></li> + <li><a href="<?= $urlpath . '/' . $row['Name'] ?>.tar.gz"><?= __('Download tarball') ?></a></li> <li><span class="flagged"><?php if ($row["OutOfDateTS"] !== NULL) { echo __('Flagged out-of-date')." (${out_of_date_time})"; } ?></span></li> <?php if ($USE_VIRTUAL_URLS && $uid): ?> <?php if ($row["OutOfDateTS"] === NULL): ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'flag/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'flag/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Flag" value="<?= __('Flag package out-of-date') ?>" /> </form> @@ -43,7 +43,7 @@ $pkgs = pkgbase_get_pkgnames($base_id); <?php elseif (($row["OutOfDateTS"] !== NULL) && ($uid == $row["MaintainerUID"] || $atype == "Trusted User" || $atype == "Developer")): ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'unflag/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'unflag/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_UnFlag" value="<?= __('Unflag package') ?>" /> </form> @@ -51,14 +51,14 @@ $pkgs = pkgbase_get_pkgnames($base_id); <?php endif; ?> <?php if (user_voted($uid, $row['ID'])): ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'unvote/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'unvote/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_UnVote" value="<?= __('Remove vote') ?>" /> </form> </li> <?php else: ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'vote/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'vote/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Vote" value="<?= __('Vote for this package') ?>" /> </form> @@ -66,28 +66,28 @@ $pkgs = pkgbase_get_pkgnames($base_id); <?php endif; ?> <?php if (user_notify($uid, $row['ID'])): ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'unnotify/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'unnotify/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_UnNotify" value="<?= __('Disable notifications') ?>" /> </form> </li> <?php else: ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'notify/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'notify/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Notify" value="<?= __('Notify of new comments') ?>" /> </form> </li> <?php endif; ?> <?php if ($atype == "Trusted User" || $atype == "Developer"): ?> - <li><a href="<?= get_pkg_uri($pkgs[0]) . 'delete/'; ?>"><?= __('Delete Package'); ?></a></li> - <li><a href="<?= get_pkg_uri($pkgs[0]) . 'merge/'; ?>"><?= __('Merge Package'); ?></a></li> + <li><a href="<?= get_pkgbase_uri($row['Name']) . 'delete/'; ?>"><?= __('Delete Package'); ?></a></li> + <li><a href="<?= get_pkgbase_uri($row['Name']) . 'merge/'; ?>"><?= __('Merge Package'); ?></a></li> <?php endif; ?> <?php endif; ?> <?php if ($uid && $row["MaintainerUID"] === NULL): ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'adopt/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'adopt/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Adopt" value="<?= __('Adopt Package') ?>" /> </form> @@ -95,7 +95,7 @@ $pkgs = pkgbase_get_pkgnames($base_id); <?php elseif ($uid && $uid == $row["MaintainerUID"] || $atype == "Trusted User" || $atype == "Developer"): ?> <li> - <form action="<?= get_pkg_uri($pkgs[0]) . 'disown/'; ?>" method="post"> + <form action="<?= get_pkgbase_uri($row['Name']) . 'disown/'; ?>" method="post"> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> <input type="submit" class="button text-button" name="do_Disown" value="<?= __('Disown Package') ?>" /> </form> @@ -113,7 +113,7 @@ if ($SID && ($uid == $row["MaintainerUID"] || ($atype == "Developer" || $atype == "Trusted User"))): ?> <td> - <form method="post" action="<?= htmlspecialchars(get_pkg_uri($row['Name']), ENT_QUOTES); ?>"> + <form method="post" action="<?= htmlspecialchars(get_pkgbase_uri($row['Name']), ENT_QUOTES); ?>"> <div> <input type="hidden" name="action" value="do_ChangeCategory" /> <?php if ($SID): ?> @@ -175,7 +175,7 @@ if ($row["MaintainerUID"]): <th><?= __('Votes') . ': ' ?></th> <?php if ($atype == "Developer" || $atype == "Trusted User"): ?> <?php if ($USE_VIRTUAL_URLS): ?> - <td><a href="<?= get_pkg_uri($row['Name']); ?>voters/"><?= $votes ?></a></td> + <td><a href="<?= get_pkgbase_uri($row['Name']); ?>voters/"><?= $votes ?></a></td> <?php else: ?> <td><a href="<?= get_uri('/voters/'); ?>?N=<?= htmlspecialchars($row['Name'], ENT_QUOTES) ?>"><?= $votes ?></a></td> <?php endif; ?> -- 1.9.1
participants (1)
-
Lukas Fleischer