[PATCH] Add page for seeing all of a user's comments
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- web/html/account.php | 69 +++++++++++++++++++++++++++++- web/html/css/aurweb.css | 17 ++++++++ web/html/index.php | 2 + web/html/pkgbase.php | 7 ++- web/lib/acctfuncs.inc.php | 41 ++++++++++++++++++ web/lib/credentials.inc.php | 2 + web/template/account_edit_form.php | 1 + 7 files changed, 136 insertions(+), 3 deletions(-) diff --git a/web/html/account.php b/web/html/account.php index c30a89a..955aa4d 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -8,7 +8,7 @@ include_once('acctfuncs.inc.php'); # access Account specific functions $action = in_request("Action"); $need_userinfo = array( - "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount" + "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount", "ListComments" ); if (in_array($action, $need_userinfo)) { @@ -54,6 +54,8 @@ if ($action == "UpdateAccount") { if ($action == "AccountInfo") { html_header(__('Account') . ' ' . $row['Username']); +} elseif ($action == "ListComments") { + html_header(__('Comments for') . ' ' . $row['Username']); } else { html_header(__('Accounts')); } @@ -61,7 +63,11 @@ if ($action == "AccountInfo") { # Main page processing here # echo "<div class=\"box\">\n"; -echo " <h2>".__("Accounts")."</h2>\n"; +if ($action == "ListComments") { + echo " <h2>".__("Comments for").' '.$row['Username']."</h2>\n"; +} else { + echo " <h2>".__("Accounts")."</h2>\n"; +} if (isset($_COOKIE["AURSID"])) { if ($action == "SearchAccounts") { @@ -166,6 +172,65 @@ if (isset($_COOKIE["AURSID"])) { $row["Username"]); } + } elseif ($action == "ListComments") { + if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)) { + # display the comment list if they're a TU/dev + # + + /* Sanitize paging variables. */ + if (isset($_GET["O"])) { + $_GET["O"] = max(intval($_GET["O"]), 0); + } else { + $_GET["O"] = 0; + } + + if (isset($_GET["PP"])) { + $_GET["PP"] = bound(intval($_GET["PP"]), 5, 250); + } else { + $_GET["PP"] = 10; + } + + $total = account_comments_count($row["ID"]); + + /* Calculate the results to use. */ + $first = $_GET['O'] + 1; + + /* Calculation of pagination links. */ + $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50; + $current = ceil($first / $per_page); + $pages = ceil($total / $per_page); + $templ_pages = array(); + + if ($current > 1) { + $templ_pages['« ' . __('First')] = 0; + $templ_pages['‹ ' . __('Previous')] = ($current - 2) * $per_page; + } + + if ($current - 5 > 1) + $templ_pages["..."] = false; + + for ($i = max($current - 5, 1); $i <= min($pages, $current + 5); $i++) { + $templ_pages[$i] = ($i - 1) * $per_page; + } + + if ($current + 5 < $pages) + $templ_pages["... "] = false; + + if ($current < $pages) { + $templ_pages[__('Next') . ' ›'] = $current * $per_page; + $templ_pages[__('Last') . ' »'] = ($pages - 1) * $per_page; + } + + $username = $row["Username"]; + $userid = $row["ID"]; + $comments = account_comments($row["ID"], $_GET["PP"], $_GET["O"]); + + include('account_comments.php'); + + } else { + print __("You are not allowed to access this area."); + } + } else { if (has_credential(CRED_ACCOUNT_SEARCH)) { # display the search page if they're a TU/dev diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index f5e1037..ce54a28 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -148,3 +148,20 @@ label.confirmation, color: red; font-weight: bold; } + +.commentlist-nav .page { + margin: 0 .25em; +} + +#commentlist-results .commentlist-nav { + float: right; + margin-top: -2.2em; +} + +.commentlist-nav .prev { + margin-right: 1em; +} + +.commentlist-nav .next { + margin-right: 1em; +} diff --git a/web/html/index.php b/web/html/index.php index 2c53cdd..b2cd840 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -142,6 +142,8 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { $_REQUEST['Action'] = "UpdateAccount"; } elseif ($tokens[3] == 'delete') { $_REQUEST['Action'] = "DeleteAccount"; + } elseif ($tokens[3] == 'comments') { + $_REQUEST['Action'] = "ListComments"; } else { header("HTTP/1.0 404 Not Found"); include "./404.php"; diff --git a/web/html/pkgbase.php b/web/html/pkgbase.php index cf9a6c6..8a0c363 100644 --- a/web/html/pkgbase.php +++ b/web/html/pkgbase.php @@ -43,6 +43,7 @@ if (isset($_POST['IDs'])) { /* Perform package base actions. */ $via = isset($_POST['via']) ? $_POST['via'] : NULL; +$return_to = isset($_POST['return_to']) ? $_POST['return_to'] : NULL; $ret = false; $output = ""; $fragment = ""; @@ -133,7 +134,11 @@ if (check_token()) { /* Redirect back to package request page on success. */ header('Location: ' . get_pkgreq_route()); exit(); - } if (isset($base_id)) { + } elseif ((current_action("do_DeleteComment") || + current_action("do_UndeleteComment")) && $return_to) { + header('Location: ' . $return_to); + exit(); + } elseif (isset($base_id)) { /* Redirect back to package base page on success. */ header('Location: ' . get_pkgbase_uri($pkgbase_name) . $fragment); exit(); diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index df57375..9536139 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -1403,3 +1403,44 @@ function accept_terms($uid, $termrev) { $dbh->exec($q); } } + +function account_comments($uid, $limit, $offset=0) { + $dbh = DB::connect(); + $q = "SELECT PackageComments.ID, Comments, "; + $q.= "PackageBaseId, CommentTS, DelTS, EditedTS, B.UserName AS EditUserName, "; + $q.= "C.UserName as DelUserName, RenderedComment, "; + $q.= "PB.ID as PackageBaseID, PB.Name as PackageBaseName "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN PackageBases PB ON PackageComments.PackageBaseID = PB.ID "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "LEFT JOIN Users B ON PackageComments.EditedUsersID = B.ID "; + $q.= "LEFT JOIN Users C ON PackageComments.DelUsersID = C.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid) . " "; + $q.= "ORDER BY CommentTS DESC"; + + if ($limit > 0) { + $q.=" LIMIT " . $limit; + } + + if ($offset > 0) { + $q.=" OFFSET " . $offset; + } + + $result = $dbh->query($q); + if (!$result) { + return null; + } + + return $result->fetchAll(); +} + +function account_comments_count($uid) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid); + + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_NUM)[0]; +} diff --git a/web/lib/credentials.inc.php b/web/lib/credentials.inc.php index d8698a8..5d90cfc 100644 --- a/web/lib/credentials.inc.php +++ b/web/lib/credentials.inc.php @@ -5,6 +5,7 @@ define("CRED_ACCOUNT_EDIT", 2); define("CRED_ACCOUNT_EDIT_DEV", 3); define("CRED_ACCOUNT_LAST_LOGIN", 4); define("CRED_ACCOUNT_SEARCH", 5); +define("CRED_ACCOUNT_LIST_COMMENTS", 28); define("CRED_COMMENT_DELETE", 6); define("CRED_COMMENT_UNDELETE", 27); define("CRED_COMMENT_VIEW_DELETED", 22); @@ -59,6 +60,7 @@ function has_credential($credential, $approved_users=array()) { case CRED_ACCOUNT_EDIT: case CRED_ACCOUNT_LAST_LOGIN: case CRED_ACCOUNT_SEARCH: + case CRED_ACCOUNT_LIST_COMMENTS: case CRED_COMMENT_DELETE: case CRED_COMMENT_UNDELETE: case CRED_COMMENT_VIEW_DELETED: diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index 6eff81b..38d5274 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -2,6 +2,7 @@ <p> <?= __('Click %shere%s if you want to permanently delete this account.', '<a href="' . get_user_uri($N) . 'delete/' . '">', '</a>') ?> <?= __('Click %shere%s for user details.', '<a href="' . get_user_uri($N) . '">', '</a>') ?> + <?= __('Click %shere%s to list the comments made by this account.', '<a href="' . get_user_uri($N) . 'comments/' . '">', '</a>') ?> </p> <form id="edit-profile-form" action="<?= get_user_uri($N) . 'update/'; ?>" method="post"> -- 2.18.0
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- v2: Actually add the new template, d'oh. web/html/account.php | 69 +++++++++++++++- web/html/css/aurweb.css | 17 ++++ web/html/index.php | 2 + web/html/pkgbase.php | 7 +- web/lib/acctfuncs.inc.php | 41 ++++++++++ web/lib/credentials.inc.php | 2 + web/template/account_comments.php | 125 +++++++++++++++++++++++++++++ web/template/account_edit_form.php | 1 + 8 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 web/template/account_comments.php diff --git a/web/html/account.php b/web/html/account.php index c30a89a..955aa4d 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -8,7 +8,7 @@ include_once('acctfuncs.inc.php'); # access Account specific functions $action = in_request("Action"); $need_userinfo = array( - "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount" + "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount", "ListComments" ); if (in_array($action, $need_userinfo)) { @@ -54,6 +54,8 @@ if ($action == "UpdateAccount") { if ($action == "AccountInfo") { html_header(__('Account') . ' ' . $row['Username']); +} elseif ($action == "ListComments") { + html_header(__('Comments for') . ' ' . $row['Username']); } else { html_header(__('Accounts')); } @@ -61,7 +63,11 @@ if ($action == "AccountInfo") { # Main page processing here # echo "<div class=\"box\">\n"; -echo " <h2>".__("Accounts")."</h2>\n"; +if ($action == "ListComments") { + echo " <h2>".__("Comments for").' '.$row['Username']."</h2>\n"; +} else { + echo " <h2>".__("Accounts")."</h2>\n"; +} if (isset($_COOKIE["AURSID"])) { if ($action == "SearchAccounts") { @@ -166,6 +172,65 @@ if (isset($_COOKIE["AURSID"])) { $row["Username"]); } + } elseif ($action == "ListComments") { + if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)) { + # display the comment list if they're a TU/dev + # + + /* Sanitize paging variables. */ + if (isset($_GET["O"])) { + $_GET["O"] = max(intval($_GET["O"]), 0); + } else { + $_GET["O"] = 0; + } + + if (isset($_GET["PP"])) { + $_GET["PP"] = bound(intval($_GET["PP"]), 5, 250); + } else { + $_GET["PP"] = 10; + } + + $total = account_comments_count($row["ID"]); + + /* Calculate the results to use. */ + $first = $_GET['O'] + 1; + + /* Calculation of pagination links. */ + $per_page = ($_GET['PP'] > 0) ? $_GET['PP'] : 50; + $current = ceil($first / $per_page); + $pages = ceil($total / $per_page); + $templ_pages = array(); + + if ($current > 1) { + $templ_pages['« ' . __('First')] = 0; + $templ_pages['‹ ' . __('Previous')] = ($current - 2) * $per_page; + } + + if ($current - 5 > 1) + $templ_pages["..."] = false; + + for ($i = max($current - 5, 1); $i <= min($pages, $current + 5); $i++) { + $templ_pages[$i] = ($i - 1) * $per_page; + } + + if ($current + 5 < $pages) + $templ_pages["... "] = false; + + if ($current < $pages) { + $templ_pages[__('Next') . ' ›'] = $current * $per_page; + $templ_pages[__('Last') . ' »'] = ($pages - 1) * $per_page; + } + + $username = $row["Username"]; + $userid = $row["ID"]; + $comments = account_comments($row["ID"], $_GET["PP"], $_GET["O"]); + + include('account_comments.php'); + + } else { + print __("You are not allowed to access this area."); + } + } else { if (has_credential(CRED_ACCOUNT_SEARCH)) { # display the search page if they're a TU/dev diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index f5e1037..ce54a28 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -148,3 +148,20 @@ label.confirmation, color: red; font-weight: bold; } + +.commentlist-nav .page { + margin: 0 .25em; +} + +#commentlist-results .commentlist-nav { + float: right; + margin-top: -2.2em; +} + +.commentlist-nav .prev { + margin-right: 1em; +} + +.commentlist-nav .next { + margin-right: 1em; +} diff --git a/web/html/index.php b/web/html/index.php index 2c53cdd..b2cd840 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -142,6 +142,8 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { $_REQUEST['Action'] = "UpdateAccount"; } elseif ($tokens[3] == 'delete') { $_REQUEST['Action'] = "DeleteAccount"; + } elseif ($tokens[3] == 'comments') { + $_REQUEST['Action'] = "ListComments"; } else { header("HTTP/1.0 404 Not Found"); include "./404.php"; diff --git a/web/html/pkgbase.php b/web/html/pkgbase.php index cf9a6c6..8a0c363 100644 --- a/web/html/pkgbase.php +++ b/web/html/pkgbase.php @@ -43,6 +43,7 @@ if (isset($_POST['IDs'])) { /* Perform package base actions. */ $via = isset($_POST['via']) ? $_POST['via'] : NULL; +$return_to = isset($_POST['return_to']) ? $_POST['return_to'] : NULL; $ret = false; $output = ""; $fragment = ""; @@ -133,7 +134,11 @@ if (check_token()) { /* Redirect back to package request page on success. */ header('Location: ' . get_pkgreq_route()); exit(); - } if (isset($base_id)) { + } elseif ((current_action("do_DeleteComment") || + current_action("do_UndeleteComment")) && $return_to) { + header('Location: ' . $return_to); + exit(); + } elseif (isset($base_id)) { /* Redirect back to package base page on success. */ header('Location: ' . get_pkgbase_uri($pkgbase_name) . $fragment); exit(); diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index df57375..9536139 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -1403,3 +1403,44 @@ function accept_terms($uid, $termrev) { $dbh->exec($q); } } + +function account_comments($uid, $limit, $offset=0) { + $dbh = DB::connect(); + $q = "SELECT PackageComments.ID, Comments, "; + $q.= "PackageBaseId, CommentTS, DelTS, EditedTS, B.UserName AS EditUserName, "; + $q.= "C.UserName as DelUserName, RenderedComment, "; + $q.= "PB.ID as PackageBaseID, PB.Name as PackageBaseName "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN PackageBases PB ON PackageComments.PackageBaseID = PB.ID "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "LEFT JOIN Users B ON PackageComments.EditedUsersID = B.ID "; + $q.= "LEFT JOIN Users C ON PackageComments.DelUsersID = C.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid) . " "; + $q.= "ORDER BY CommentTS DESC"; + + if ($limit > 0) { + $q.=" LIMIT " . $limit; + } + + if ($offset > 0) { + $q.=" OFFSET " . $offset; + } + + $result = $dbh->query($q); + if (!$result) { + return null; + } + + return $result->fetchAll(); +} + +function account_comments_count($uid) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid); + + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_NUM)[0]; +} diff --git a/web/lib/credentials.inc.php b/web/lib/credentials.inc.php index d8698a8..5d90cfc 100644 --- a/web/lib/credentials.inc.php +++ b/web/lib/credentials.inc.php @@ -5,6 +5,7 @@ define("CRED_ACCOUNT_EDIT", 2); define("CRED_ACCOUNT_EDIT_DEV", 3); define("CRED_ACCOUNT_LAST_LOGIN", 4); define("CRED_ACCOUNT_SEARCH", 5); +define("CRED_ACCOUNT_LIST_COMMENTS", 28); define("CRED_COMMENT_DELETE", 6); define("CRED_COMMENT_UNDELETE", 27); define("CRED_COMMENT_VIEW_DELETED", 22); @@ -59,6 +60,7 @@ function has_credential($credential, $approved_users=array()) { case CRED_ACCOUNT_EDIT: case CRED_ACCOUNT_LAST_LOGIN: case CRED_ACCOUNT_SEARCH: + case CRED_ACCOUNT_LIST_COMMENTS: case CRED_COMMENT_DELETE: case CRED_COMMENT_UNDELETE: case CRED_COMMENT_VIEW_DELETED: diff --git a/web/template/account_comments.php b/web/template/account_comments.php new file mode 100644 index 0000000..aedcc55 --- /dev/null +++ b/web/template/account_comments.php @@ -0,0 +1,125 @@ +<div id="commentlist-results"> +<?php if (count($templ_pages) > 1): ?> +<p class="commentlist-nav"> + <?php foreach ($templ_pages as $pagenr => $pagestart): ?> + <?php if ($pagestart === false): ?> + <span class="page"><?= $pagenr ?></span> + <?php elseif ($pagestart + 1 == $first): ?> + <span class="page"><?= $pagenr ?></span> + <?php else: ?> + <a class="page" href="<?= get_uri('/account/' . $username . '/comments/'); ?>?<?= mkurl('O=' . $pagestart) ?>"><?= $pagenr ?></a> + <?php endif; ?> + <?php endforeach; ?> +</p> +<?php endif; ?> +</div> + +<?php while (list($indx, $row) = each($comments)): ?> + <?php + $date_fmtd = date('Y-m-d H:i', $row['CommentTS']); + $pkg_uri = '<a href=' . htmlspecialchars(get_pkg_uri($row['PackageBaseName']), ENT_QUOTES) . '>' . htmlspecialchars($row['PackageBaseName']) . '</a></td>'; + $heading = __('Commented on package %s on %s', $pkg_uri, $date_fmtd); + + $is_deleted = $row['DelTS']; + $is_edited = $row['EditedTS']; + + if ($userid && $is_deleted) { + $date_fmtd = date('Y-m-d H:i', $row['DelTS']); + $heading .= ' <span class="edited">('; + if ($row['DelUserName']) { + $user_fmtd = html_format_username($row['DelUserName']); + $heading .= __('deleted on %s by %s', $date_fmtd, $user_fmtd); + } else { + $heading .= __('deleted on %s', $date_fmtd); + } + $heading .= ')</span>'; + } elseif ($userid && $is_edited) { + $date_fmtd = date('Y-m-d H:i', $row['EditedTS']); + $heading .= ' <span class="edited">('; + if ($row['EditUserName']) { + $user_fmtd = html_format_username($row['EditUserName']); + $heading .= __('edited on %s by %s', $date_fmtd, $user_fmtd); + } else { + $heading .= __('edited on %s', $date_fmtd); + } + $heading .= ')</span>'; + } + ?> + <h4 id="<?= isset($pinned) ? "pinned-" : "comment-" ?><?= $row['ID'] ?>"<?php if ($is_deleted): ?> class="comment-deleted"<?php endif; ?>> + <?= $heading ?> + <?php if ($is_deleted && has_credential(CRED_COMMENT_UNDELETE)): ?> + <form class="undelete-comment-form" method="post" action="<?= htmlspecialchars(get_pkgbase_uri($row['PackageBaseName']), ENT_QUOTES); ?>"> + <fieldset style="display:inline;"> + <input type="hidden" name="action" value="do_UndeleteComment" /> + <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> + <input type="image" class="undelete-comment" src="/images/action-undo.min.svg" width="11" height="11" alt="<?= __('Undelete comment') ?>" title="<?= __('Undelete comment') ?>" name="submit" value="1" /> + </fieldset> + </form> + <?php endif;?> + + <?php if (!$is_deleted && can_delete_comment_array(array('UsersID' => $userid))): ?> + <form class="delete-comment-form" method="post" action="<?= htmlspecialchars(get_pkgbase_uri($row['PackageBaseName']), ENT_QUOTES); ?>"> + <fieldset style="display:inline;"> + <input type="hidden" name="action" value="do_DeleteComment" /> + <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> + <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> + <input type="image" class="delete-comment" src="/images/x.min.svg" width="11" height="11" alt="<?= __('Delete comment') ?>" title="<?= __('Delete comment') ?>" name="submit" value="1" /> + </fieldset> + </form> + <?php endif; ?> + + <?php if (!$is_deleted && can_edit_comment_array(array('UsersID' => $userid))): ?> + <a href="<?= htmlspecialchars(get_pkgbase_uri($row['PackageBaseName']) . 'edit-comment/?comment_id=' . $row['ID'], ENT_QUOTES) ?>" class="edit-comment" title="<?= __('Edit comment') ?>"><img src="/images/pencil.min.svg" alt="<?= __('Edit comment') ?>" width="11" height="11"></a> + <?php endif; ?> + </h4> + + <div id="<?= isset($pinned) ? "pinned-" : "comment-" ?><?= $row['ID'] ?>-content" class="article-content<?php if ($is_deleted): ?> comment-deleted<?php endif; ?>"> + <div> + <?php if (!empty($row['RenderedComment'])): ?> + <?= $row['RenderedComment'] ?> + <?php else: ?> + <p> + <?= parse_comment($row['Comments']) ?> + </p> + <?php endif; ?> + </div> + </div> +<?php endwhile; ?> +<script> +$(document).ready(function() { + $('.edit-comment').click(function () { + var parent_element = this.parentElement, + parent_id = parent_element.id, + comment_id = parent_id.substr(parent_id.indexOf('-') + 1), + edit_form = $(parent_element).next(), + _this = $(this); + add_busy_indicator(_this); + $.getJSON('<?= get_uri('/rpc') ?>', { + type: 'get-comment-form', + arg: comment_id, + base_id: <?= intval($row["PackageBaseID"]) ?>, + base_name: <?= json_encode($row['PackageBaseName']) ?> + }, function (data) { + remove_busy_indicator(_this); + if (data.success) { + edit_form.html(data.form); + edit_form.find('textarea').focus(); + } else { + alert(data.error); + } + }); + return false; + }); + + function add_busy_indicator(sibling) { + sibling.after('<img src="/images/ajax-loader.gif" class="ajax-loader" width="16" height="11" alt="Busy…" />'); + } + + function remove_busy_indicator(sibling) { + sibling.next().remove(); + } +}); +</script> diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index 6eff81b..38d5274 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -2,6 +2,7 @@ <p> <?= __('Click %shere%s if you want to permanently delete this account.', '<a href="' . get_user_uri($N) . 'delete/' . '">', '</a>') ?> <?= __('Click %shere%s for user details.', '<a href="' . get_user_uri($N) . '">', '</a>') ?> + <?= __('Click %shere%s to list the comments made by this account.', '<a href="' . get_user_uri($N) . 'comments/' . '">', '</a>') ?> </p> <form id="edit-profile-form" action="<?= get_user_uri($N) . 'update/'; ?>" method="post"> -- 2.18.0
On Tue, 17 Jul 2018 at 14:31:26, Johannes Löthberg wrote:
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- v2: Actually add the new template, d'oh.
web/html/account.php | 69 +++++++++++++++- web/html/css/aurweb.css | 17 ++++ web/html/index.php | 2 + web/html/pkgbase.php | 7 +- web/lib/acctfuncs.inc.php | 41 ++++++++++ web/lib/credentials.inc.php | 2 + web/template/account_comments.php | 125 +++++++++++++++++++++++++++++ web/template/account_edit_form.php | 1 + 8 files changed, 261 insertions(+), 3 deletions(-) create mode 100644 web/template/account_comments.php [...]
Thanks a lot for implementing this! There is a lot of code duplication going on, though. Is there any reason we cannot use a shared template for the package comments and the user comments pages? It seems like one only needs to choose a different result set? Best regards, Lukas
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- Since v2: Refactor things a bit to use the same pkg_comments.php for both per-package and per-user comment listings web/html/account.php | 20 +++++- web/html/css/aurweb.css | 42 +++++++++++++ web/html/index.php | 2 + web/html/pkgbase.php | 10 ++- web/lib/acctfuncs.inc.php | 42 +++++++++++++ web/lib/aur.inc.php | 53 ++++++++++++++++ web/lib/credentials.inc.php | 2 + web/lib/pkgbasefuncs.inc.php | 10 ++- web/lib/pkgfuncs.inc.php | 4 ++ web/template/account_details.php | 3 + web/template/account_edit_form.php | 1 + web/template/pkg_comments.php | 99 ++++++++++++++++++++++-------- 12 files changed, 258 insertions(+), 30 deletions(-) diff --git a/web/html/account.php b/web/html/account.php index c30a89a..885952b 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -8,7 +8,7 @@ include_once('acctfuncs.inc.php'); # access Account specific functions $action = in_request("Action"); $need_userinfo = array( - "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount" + "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount", "ListComments" ); if (in_array($action, $need_userinfo)) { @@ -166,6 +166,24 @@ if (isset($_COOKIE["AURSID"])) { $row["Username"]); } + } elseif ($action == "ListComments") { + if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)) { + # display the comment list if they're a TU/dev + + $total_comment_count = account_comments_count($row["ID"]); + [$pagination_templs, $per_page, $offset] = calculate_pagination($total_comment_count); + + $username = $row["Username"]; + $uid = $row["ID"]; + $comments = account_comments($row["ID"], $per_page, $offset); + + $comment_section = "account"; + include('pkg_comments.php'); + + } else { + print __("You are not allowed to access this area."); + } + } else { if (has_credential(CRED_ACCOUNT_SEARCH)) { # display the search page if they're a TU/dev diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index f5e1037..593c9ae 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -148,3 +148,45 @@ label.confirmation, color: red; font-weight: bold; } + +.package-comments { + margin-top: 1.5em; +} + +.comments-header { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +/* arrowed headings */ +.comments-header h3 span.text { + display: block; + background: #1794D1; + font-size: 15px; + padding: 2px 10px; + color: white; +} + +.comments-header .comments-header-nav { + align-self: flex-end; +} + +.comment-header { + clear: both; + font-size: 1em; + margin-top: 1.5em; + border-bottom: 1px dotted #bbb; +} + +.comments div { + margin-bottom: 1em; +} + +.comments div p { + margin-bottom: 0.5em; +} + +.comments .more { + font-weight: normal; +} diff --git a/web/html/index.php b/web/html/index.php index 2c53cdd..b2cd840 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -142,6 +142,8 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { $_REQUEST['Action'] = "UpdateAccount"; } elseif ($tokens[3] == 'delete') { $_REQUEST['Action'] = "DeleteAccount"; + } elseif ($tokens[3] == 'comments') { + $_REQUEST['Action'] = "ListComments"; } else { header("HTTP/1.0 404 Not Found"); include "./404.php"; diff --git a/web/html/pkgbase.php b/web/html/pkgbase.php index cf9a6c6..46ad77e 100644 --- a/web/html/pkgbase.php +++ b/web/html/pkgbase.php @@ -43,6 +43,7 @@ if (isset($_POST['IDs'])) { /* Perform package base actions. */ $via = isset($_POST['via']) ? $_POST['via'] : NULL; +$return_to = isset($_POST['return_to']) ? $_POST['return_to'] : NULL; $ret = false; $output = ""; $fragment = ""; @@ -133,7 +134,14 @@ if (check_token()) { /* Redirect back to package request page on success. */ header('Location: ' . get_pkgreq_route()); exit(); - } if (isset($base_id)) { + } elseif ((current_action("do_DeleteComment") || + current_action("do_UndeleteComment")) && $return_to) { + header('Location: ' . $return_to); + exit(); + } elseif (current_action("do_PinComment") && $return_to) { + header('Location: ' . $return_to); + exit(); + } elseif (isset($base_id)) { /* Redirect back to package base page on success. */ header('Location: ' . get_pkgbase_uri($pkgbase_name) . $fragment); exit(); diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index df57375..192d879 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -1403,3 +1403,45 @@ function accept_terms($uid, $termrev) { $dbh->exec($q); } } + +function account_comments($uid, $limit, $offset=0) { + $dbh = DB::connect(); + $q = "SELECT PackageComments.ID, Comments, UsersID, "; + $q.= "PackageBaseId, CommentTS, DelTS, EditedTS, B.UserName AS EditUserName, "; + $q.= "PinnedTS, "; + $q.= "C.UserName as DelUserName, RenderedComment, "; + $q.= "PB.ID as PackageBaseID, PB.Name as PackageBaseName "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN PackageBases PB ON PackageComments.PackageBaseID = PB.ID "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "LEFT JOIN Users B ON PackageComments.EditedUsersID = B.ID "; + $q.= "LEFT JOIN Users C ON PackageComments.DelUsersID = C.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid) . " "; + $q.= "ORDER BY CommentTS DESC"; + + if ($limit > 0) { + $q.=" LIMIT " . $limit; + } + + if ($offset > 0) { + $q.=" OFFSET " . $offset; + } + + $result = $dbh->query($q); + if (!$result) { + return null; + } + + return $result->fetchAll(); +} + +function account_comments_count($uid) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid); + + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_NUM)[0]; +} diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index feb4006..89da81a 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -705,3 +705,56 @@ function aur_location() { } return $location; } + +/** + * Calculate pagination templates + * + * @return array The array of pagination templates, per page, and offset values + */ +function calculate_pagination($total_comment_count) { + /* Sanitize paging variables. */ + if (isset($_GET["O"])) { + $_GET["O"] = max(intval($_GET["O"]), 0); + } else { + $_GET["O"] = 0; + } + $offset = $_GET["O"]; + + if (isset($_GET["PP"])) { + $_GET["PP"] = bound(intval($_GET["PP"]), 1, 250); + } else { + $_GET["PP"] = 10; + } + $per_page = $_GET["PP"]; + + // Page offsets start at zero, so page 2 has offset 1, which means that we + // need to add 1 to the offset to get the current page. + $current_page = ceil($offset / $per_page) + 1; + $num_pages = ceil($total_comment_count / $per_page); + $pagination_templs = array(); + + if ($current_page > 1) { + $previous_page = $current_page - 1; + $previous_offset = ($previous_page - 1) * $per_page; + $pagination_templs['« ' . __('First')] = 0; + $pagination_templs['‹ ' . __('Previous')] = $previous_offset; + } + + if ($current_page - 5 > 1) { + $pagination_templs["..."] = false; + } + + for ($i = max($current_page - 5, 1); $i <= min($num_pages, $current_page + 5); $i++) { + $pagination_templs[$i] = ($i - 1) * $per_page; + } + + if ($current_page + 5 < $num_pages) + $pagination_templs["... "] = false; + + if ($current_page < $num_pages) { + $pagination_templs[__('Next') . ' ›'] = $current_page * $per_page; + $pagination_templs[__('Last') . ' »'] = ($num_pages - 1) * $per_page; + } + + return [$pagination_templs, $per_page, $offset]; +} diff --git a/web/lib/credentials.inc.php b/web/lib/credentials.inc.php index d8698a8..5d90cfc 100644 --- a/web/lib/credentials.inc.php +++ b/web/lib/credentials.inc.php @@ -5,6 +5,7 @@ define("CRED_ACCOUNT_EDIT", 2); define("CRED_ACCOUNT_EDIT_DEV", 3); define("CRED_ACCOUNT_LAST_LOGIN", 4); define("CRED_ACCOUNT_SEARCH", 5); +define("CRED_ACCOUNT_LIST_COMMENTS", 28); define("CRED_COMMENT_DELETE", 6); define("CRED_COMMENT_UNDELETE", 27); define("CRED_COMMENT_VIEW_DELETED", 22); @@ -59,6 +60,7 @@ function has_credential($credential, $approved_users=array()) { case CRED_ACCOUNT_EDIT: case CRED_ACCOUNT_LAST_LOGIN: case CRED_ACCOUNT_SEARCH: + case CRED_ACCOUNT_LIST_COMMENTS: case CRED_COMMENT_DELETE: case CRED_COMMENT_UNDELETE: case CRED_COMMENT_VIEW_DELETED: diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php index 72c33b6..953a581 100644 --- a/web/lib/pkgbasefuncs.inc.php +++ b/web/lib/pkgbasefuncs.inc.php @@ -44,7 +44,7 @@ function pkgbase_comments_count($base_id, $include_deleted, $only_pinned=false) * * @return array All package comment information for a specific package base */ -function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false) { +function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false, $offset=0) { $base_id = intval($base_id); $limit = intval($limit); if (!$base_id) { @@ -71,6 +71,9 @@ function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false if ($limit > 0) { $q.=" LIMIT " . $limit; } + if ($offset > 0) { + $q.=" OFFSET " . $offset; + } $result = $dbh->query($q); if (!$result) { return null; @@ -273,6 +276,7 @@ function pkgbase_display_details($base_id, $row, $SID="") { include('pkgbase_details.php'); if ($SID) { + $comment_section = "package"; include('pkg_comment_box.php'); } @@ -281,13 +285,17 @@ function pkgbase_display_details($base_id, $row, $SID="") { $limit_pinned = isset($_GET['pinned']) ? 0 : 5; $pinned = pkgbase_comments($base_id, $limit_pinned, false, true); if (!empty($pinned)) { + $comment_section = "package"; include('pkg_comments.php'); } unset($pinned); + $limit = isset($_GET['comments']) ? 0 : 10; $comments = pkgbase_comments($base_id, $limit, $include_deleted); + if (!empty($comments)) { + $comment_section = "package"; include('pkg_comments.php'); } } diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index ad25474..140b8fc 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -624,13 +624,17 @@ function pkg_display_details($id=0, $row, $SID="") { $limit_pinned = isset($_GET['pinned']) ? 0 : 5; $pinned = pkgbase_comments($base_id, $limit_pinned, false, true); if (!empty($pinned)) { + $comment_section = "package"; include('pkg_comments.php'); } unset($pinned); + $limit = isset($_GET['comments']) ? 0 : 10; $comments = pkgbase_comments($base_id, $limit, $include_deleted); + if (!empty($comments)) { + $comment_section = "package"; include('pkg_comments.php'); } } diff --git a/web/template/account_details.php b/web/template/account_details.php index 024bd9c..fa6b528 100644 --- a/web/template/account_details.php +++ b/web/template/account_details.php @@ -82,6 +82,9 @@ <?php if (can_edit_account($row)): ?> <li><a href="<?= get_user_uri($row['Username']); ?>edit"><?= __("Edit this user's account") ?></a></li> <?php endif; ?> + <?php if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)): ?> + <li><a href="<?= get_user_uri($row['Username']); ?>comments"><?= __("List this user's comments") ?></a></li> + <?php endif; ?> </ul></td> </tr> </table> diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index 6eff81b..38d5274 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -2,6 +2,7 @@ <p> <?= __('Click %shere%s if you want to permanently delete this account.', '<a href="' . get_user_uri($N) . 'delete/' . '">', '</a>') ?> <?= __('Click %shere%s for user details.', '<a href="' . get_user_uri($N) . '">', '</a>') ?> + <?= __('Click %shere%s to list the comments made by this account.', '<a href="' . get_user_uri($N) . 'comments/' . '">', '</a>') ?> </p> <form id="edit-profile-form" action="<?= get_user_uri($N) . 'update/'; ?>" method="post"> diff --git a/web/template/pkg_comments.php b/web/template/pkg_comments.php index 3e5e5cc..3001a34 100644 --- a/web/template/pkg_comments.php +++ b/web/template/pkg_comments.php @@ -1,28 +1,69 @@ <?php -if (!isset($count)) { - $count = pkgbase_comments_count($base_id, $include_deleted); +if ($comment_section == "package") { + if (!isset($count)) { + $count = pkgbase_comments_count($base_id, $include_deleted); + } } ?> -<div id="news"> - <h3> - <?php if (!isset($comments)): ?> - <?php $comments = $pinned ?> - <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all comments' , $count) ?> (<?= $count ?>)"><?= __('Pinned Comments') ?></a> - <span class="arrow"></span> - <?php else: ?> - <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all comments' , $count) ?> (<?= $count ?>)"><?= __('Latest Comments') ?></a> - <span class="arrow"></span> + + +<?php if ($comment_section == "package"): ?> +<div class="comments package-comments"> +<?php else: ?> +<div class="comments"> +<?php endif; ?> + <div class="comments-header"> + <h3> + <?php if ($comment_section == "package"): ?> + <?php if (!isset($comments)): ?> + <?php $comments = $pinned ?> + <span class="text"><?= __('Pinned Comments') ?></span> + <span class="arrow"></span> + <?php else: ?> + <span class="text"><?= __('Latest Comments') ?></span> + <span class="arrow"></span> + <?php endif; ?> + <?php elseif ($comment_section == "account"): ?> + <?= __("Comments for") ?> <a href="<?= htmlentities(get_uri('/account/' . $username), ENT_QUOTES) ?>"><?= $username ?></a> + <?php endif; ?> + </h3> + + <?php if (isset($pagination_templs) && count($pagination_templs) > 1): ?> + <p class="comments-header-nav"> + <?php foreach ($pagination_templs as $pagenr => $pagestart): ?> + <?php if ($pagestart === false): ?> + <span class="page"><?= $pagenr ?></span> + <?php elseif ($pagestart === $offset): ?> + <span class="page"><?= $pagenr ?></span> + <?php else: ?> + <?php if ($comment_section == "package"): ?> + <a class="page" href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('O=' . $pagestart) ?>"><?= $pagenr ?></a> + <?php else: ?> + <a class="page" href="<?= get_uri('/account/' . $username . '/comments/') . '?' . mkurl('O=' . $pagestart) ?>"><?= $pagenr ?></a> + <?php endif; ?> + <?php endif; ?> + <?php endforeach; ?> + </p> <?php endif; ?> - </h3> + </div> <?php foreach ($comments as $indx => $row): ?> <?php + if ($comment_section == "account") { + $pkgbase_name = $row["PackageBaseName"]; + } + $date_fmtd = date('Y-m-d H:i', $row['CommentTS']); - if ($row['UserName']) { - $user_fmtd = html_format_username($row['UserName']); - $heading = __('%s commented on %s', $user_fmtd, $date_fmtd); - } else { - $heading = __('Anonymous comment on %s', $date_fmtd); + if ($comment_section == "package") { + if ($row['UserName']) { + $user_fmtd = html_format_username($row['UserName']); + $heading = __('%s commented on %s', $user_fmtd, $date_fmtd); + } else { + $heading = __('Anonymous comment on %s', $date_fmtd); + } + } elseif ($comment_section == "account") { + $pkg_uri = '<a href=' . htmlspecialchars(get_pkg_uri($row['PackageBaseName']), ENT_QUOTES) . '>' . htmlspecialchars($row['PackageBaseName']) . '</a></td>'; + $heading = __('Commented on package %s on %s', $pkg_uri, $date_fmtd); } $is_deleted = $row['DelTS']; @@ -50,8 +91,13 @@ if (!isset($count)) { } $heading .= ')</span>'; } + + $comment_classes = "comment-header"; + if ($is_deleted) { + $comment_classes .= " comment-deleted"; + } ?> - <h4 id="<?= isset($pinned) ? "pinned-" : "comment-" ?><?= $row['ID'] ?>"<?php if ($is_deleted): ?> class="comment-deleted"<?php endif; ?>> + <h4 id="<?= isset($pinned) ? "pinned-" : "comment-" ?><?= $row['ID'] ?>" class="<?= $comment_classes ?>"> <?= $heading ?> <?php if ($is_deleted && has_credential(CRED_COMMENT_UNDELETE)): ?> <form class="undelete-comment-form" method="post" action="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name), ENT_QUOTES); ?>"> @@ -59,6 +105,7 @@ if (!isset($count)) { <input type="hidden" name="action" value="do_UndeleteComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="undelete-comment" src="/images/action-undo.min.svg" width="11" height="11" alt="<?= __('Undelete comment') ?>" title="<?= __('Undelete comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -70,6 +117,7 @@ if (!isset($count)) { <input type="hidden" name="action" value="do_DeleteComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="delete-comment" src="/images/x.min.svg" width="11" height="11" alt="<?= __('Delete comment') ?>" title="<?= __('Delete comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -79,13 +127,14 @@ if (!isset($count)) { <a href="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name) . 'edit-comment/?comment_id=' . $row['ID'], ENT_QUOTES) ?>" class="edit-comment" title="<?= __('Edit comment') ?>"><img src="/images/pencil.min.svg" alt="<?= __('Edit comment') ?>" width="11" height="11"></a> <?php endif; ?> - <?php if (!$is_deleted && !$is_pinned && can_pin_comment_array($row) && !(pkgbase_comments_count($base_id, false, true) >= 5)): ?> + <?php if (!$is_deleted && !$is_pinned && can_pin_comment_array($row) && !(pkgbase_comments_count($row["PackageBaseID"], false, true) >= 5)): ?> <form class="pin-comment-form" method="post" action="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name), ENT_QUOTES); ?>"> <fieldset style="display:inline;"> <input type="hidden" name="action" value="do_PinComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> - <input type="hidden" name="package_base" value="<?= $base_id ?>" /> + <input type="hidden" name="package_base" value="<?= $row["PackageBaseID"] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="pin-comment" src="/images/pin.min.svg" width="11" height="11" alt="<?= __('Pin comment') ?>" title="<?= __('Pin comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -97,6 +146,7 @@ if (!isset($count)) { <input type="hidden" name="action" value="do_UnpinComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="pin-comment" src="/images/unpin.min.svg" width="11" height="11" alt="<?= __('Unpin comment') ?>" title="<?= __('Unpin comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -114,13 +164,8 @@ if (!isset($count)) { </div> </div> <?php endforeach; ?> - -<?php if ($count > 10 && !isset($_GET['comments']) && !isset($pinned)): ?> - <h3> - <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all comments') ?> (<?= $count ?>)"><?= __('All comments', $count) ?></a> - </h3> -<?php endif; ?> </div> + <script> $(document).ready(function() { $('.edit-comment').click(function () { @@ -133,7 +178,7 @@ $(document).ready(function() { $.getJSON('<?= get_uri('/rpc') ?>', { type: 'get-comment-form', arg: comment_id, - base_id: <?= intval($base_id) ?>, + base_id: <?= intval($row["PackageBaseID"]) ?>, pkgbase_name: <?= json_encode($pkgbase_name) ?> }, function (data) { remove_busy_indicator(_this); -- 2.18.0
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- web/lib/pkgbasefuncs.inc.php | 5 +++-- web/lib/pkgfuncs.inc.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php index 953a581..eb22c38 100644 --- a/web/lib/pkgbasefuncs.inc.php +++ b/web/lib/pkgbasefuncs.inc.php @@ -291,9 +291,10 @@ function pkgbase_display_details($base_id, $row, $SID="") { unset($pinned); - $limit = isset($_GET['comments']) ? 0 : 10; - $comments = pkgbase_comments($base_id, $limit, $include_deleted); + $total_comment_count = pkgbase_comments_count($base_id, $include_deleted); + [$pagination_templs, $per_page, $offset] = calculate_pagination($total_comment_count); + $comments = pkgbase_comments($base_id, $per_page, $include_deleted, false, $offset); if (!empty($comments)) { $comment_section = "package"; include('pkg_comments.php'); diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 140b8fc..c9aef36 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -630,9 +630,10 @@ function pkg_display_details($id=0, $row, $SID="") { unset($pinned); - $limit = isset($_GET['comments']) ? 0 : 10; - $comments = pkgbase_comments($base_id, $limit, $include_deleted); + $total_comment_count = pkgbase_comments_count($base_id, $include_deleted); + [$pagination_templs, $per_page, $offset] = calculate_pagination($total_comment_count); + $comments = pkgbase_comments($base_id, $per_page, $include_deleted, false, $offset); if (!empty($comments)) { $comment_section = "package"; include('pkg_comments.php'); -- 2.18.0
On Sun, 22 Jul 2018 at 17:54:36, Johannes Löthberg wrote:
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- web/lib/pkgbasefuncs.inc.php | 5 +++-- web/lib/pkgfuncs.inc.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) [...]
Great! Does this also mean we actually get paginated package comments or does this only make pagination possible by manually adding GET parameters to the URL? Best regards, Lukas
Quoting Lukas Fleischer (2018-08-05 18:32:56)
On Sun, 22 Jul 2018 at 17:54:36, Johannes Löthberg wrote:
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- web/lib/pkgbasefuncs.inc.php | 5 +++-- web/lib/pkgfuncs.inc.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) [...]
Great! Does this also mean we actually get paginated package comments or does this only make pagination possible by manually adding GET parameters to the URL?
Proper pagination for everything. -- Sincerely, Johannes Löthberg PGP Key ID: 0x50FB9B273A9D0BB5 PGP Key FP: 5134 EF9E AF65 F95B 6BB1 608E 50FB 9B27 3A9D 0BB5 https://theos.kyriasis.com/~kyrias/
On Sun, 22 Jul 2018 at 17:54:35, Johannes Löthberg wrote:
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- Since v2: Refactor things a bit to use the same pkg_comments.php for both per-package and per-user comment listings
web/html/account.php | 20 +++++- web/html/css/aurweb.css | 42 +++++++++++++ web/html/index.php | 2 + web/html/pkgbase.php | 10 ++- web/lib/acctfuncs.inc.php | 42 +++++++++++++ web/lib/aur.inc.php | 53 ++++++++++++++++ web/lib/credentials.inc.php | 2 + web/lib/pkgbasefuncs.inc.php | 10 ++- web/lib/pkgfuncs.inc.php | 4 ++ web/template/account_details.php | 3 + web/template/account_edit_form.php | 1 + web/template/pkg_comments.php | 99 ++++++++++++++++++++++-------- 12 files changed, 258 insertions(+), 30 deletions(-)
Sorry for reviewing this so late. The patch is pretty invasive, though, and we should make sure we are not missing anything.
@@ -166,6 +166,24 @@ if (isset($_COOKIE["AURSID"])) { $row["Username"]); }
+ } elseif ($action == "ListComments") { + if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)) { + # display the comment list if they're a TU/dev + + $total_comment_count = account_comments_count($row["ID"]); + [$pagination_templs, $per_page, $offset] = calculate_pagination($total_comment_count);
Interesting. I don't think we are using this syntax anywhere so far and it might be a good idea to use list() instead, even if it is just for consistency. Thoughts?
+ + $username = $row["Username"]; + $uid = $row["ID"]; + $comments = account_comments($row["ID"], $per_page, $offset);
We can replace the first parameter with $uid here.
diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index f5e1037..593c9ae 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -148,3 +148,45 @@ label.confirmation, color: red; font-weight: bold; } + +.package-comments { + margin-top: 1.5em; +} + +.comments-header { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +/* arrowed headings */ +.comments-header h3 span.text { + display: block; + background: #1794D1; + font-size: 15px; + padding: 2px 10px; + color: white; +} + +.comments-header .comments-header-nav { + align-self: flex-end; +} + +.comment-header { + clear: both; + font-size: 1em; + margin-top: 1.5em; + border-bottom: 1px dotted #bbb; +} + +.comments div { + margin-bottom: 1em; +} + +.comments div p { + margin-bottom: 0.5em; +} + +.comments .more { + font-weight: normal; +}
What is the rationale for adding those new styles? Can't we just display comments the way they are currently displayed under the package details?
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index df57375..192d879 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -1403,3 +1403,45 @@ function accept_terms($uid, $termrev) { $dbh->exec($q); } } + +function account_comments($uid, $limit, $offset=0) { + $dbh = DB::connect(); + $q = "SELECT PackageComments.ID, Comments, UsersID, "; + $q.= "PackageBaseId, CommentTS, DelTS, EditedTS, B.UserName AS EditUserName, "; + $q.= "PinnedTS, "; + $q.= "C.UserName as DelUserName, RenderedComment, "; + $q.= "PB.ID as PackageBaseID, PB.Name as PackageBaseName "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN PackageBases PB ON PackageComments.PackageBaseID = PB.ID "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "LEFT JOIN Users B ON PackageComments.EditedUsersID = B.ID "; + $q.= "LEFT JOIN Users C ON PackageComments.DelUsersID = C.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid) . " "; + $q.= "ORDER BY CommentTS DESC"; + + if ($limit > 0) { + $q.=" LIMIT " . $limit;
Please add intval() around $limit here. Even if we know that the current callers always pass integer values, it does not hurt to enforce the conversion here to prevent from potential security issues in the future.
+ } + + if ($offset > 0) { + $q.=" OFFSET " . $offset;
Same here. Add intval($offset).
+ } + + $result = $dbh->query($q); + if (!$result) { + return null; + } + + return $result->fetchAll(); +} + +function account_comments_count($uid) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid); + + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_NUM)[0];
Is this equivalent to "return $result->fetchColumn();"?
+} diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index feb4006..89da81a 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -705,3 +705,56 @@ function aur_location() { } return $location; } + +/** + * Calculate pagination templates + * + * @return array The array of pagination templates, per page, and offset values + */ +function calculate_pagination($total_comment_count) { [...]
Nice! I wonder whether we can use this helper function elsewhere, such as for paginating package search results?
diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php index 72c33b6..953a581 100644 --- a/web/lib/pkgbasefuncs.inc.php +++ b/web/lib/pkgbasefuncs.inc.php [...] @@ -71,6 +71,9 @@ function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false if ($limit > 0) { $q.=" LIMIT " . $limit; } + if ($offset > 0) { + $q.=" OFFSET " . $offset;
Same as above, please add intval(). Everything else looks good so far. And there's FS#59512 [1] (which you are probably already aware of) to be addressed in a re-roll. Thanks a lot put working on this! Regards, Lukas [1] https://bugs.archlinux.org/task/59512
Quoting Lukas Fleischer (2018-08-05 18:31:46)
+ [$pagination_templs, $per_page, $offset] = calculate_pagination($total_comment_count);
Interesting. I don't think we are using this syntax anywhere so far and it might be a good idea to use list() instead, even if it is just for consistency. Thoughts?
While I prefer the short syntax since it's both less noisy and more consistent with the short array creation syntax, it doesn't matter much, so I'll change it.
+ + $username = $row["Username"]; + $uid = $row["ID"]; + $comments = account_comments($row["ID"], $per_page, $offset);
We can replace the first parameter with $uid here.
Fixed.
diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index f5e1037..593c9ae 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -148,3 +148,45 @@ label.confirmation, color: red; font-weight: bold; } + +.package-comments { + margin-top: 1.5em; +} + +.comments-header { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +/* arrowed headings */ +.comments-header h3 span.text { + display: block; + background: #1794D1; + font-size: 15px; + padding: 2px 10px; + color: white; +} + +.comments-header .comments-header-nav { + align-self: flex-end; +} + +.comment-header { + clear: both; + font-size: 1em; + margin-top: 1.5em; + border-bottom: 1px dotted #bbb; +} + +.comments div { + margin-bottom: 1em; +} + +.comments div p { + margin-bottom: 0.5em; +} + +.comments .more { + font-weight: normal; +}
What is the rationale for adding those new styles? Can't we just display comments the way they are currently displayed under the package details?
I had to add more divs to be able to style the pagination links in a reasonable manner, which means that the archweb.css styles no longer apply.
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index df57375..192d879 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -1403,3 +1403,45 @@ function accept_terms($uid, $termrev) { $dbh->exec($q); } } + +function account_comments($uid, $limit, $offset=0) { + $dbh = DB::connect(); + $q = "SELECT PackageComments.ID, Comments, UsersID, "; + $q.= "PackageBaseId, CommentTS, DelTS, EditedTS, B.UserName AS EditUserName, "; + $q.= "PinnedTS, "; + $q.= "C.UserName as DelUserName, RenderedComment, "; + $q.= "PB.ID as PackageBaseID, PB.Name as PackageBaseName "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN PackageBases PB ON PackageComments.PackageBaseID = PB.ID "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "LEFT JOIN Users B ON PackageComments.EditedUsersID = B.ID "; + $q.= "LEFT JOIN Users C ON PackageComments.DelUsersID = C.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid) . " "; + $q.= "ORDER BY CommentTS DESC"; + + if ($limit > 0) { + $q.=" LIMIT " . $limit;
Please add intval() around $limit here. Even if we know that the current callers always pass integer values, it does not hurt to enforce the conversion here to prevent from potential security issues in the future.
+ } + + if ($offset > 0) { + $q.=" OFFSET " . $offset;
Same here. Add intval($offset).
Both fixed.
+ } + + $result = $dbh->query($q); + if (!$result) { + return null; + } + + return $result->fetchAll(); +} + +function account_comments_count($uid) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid); + + $result = $dbh->query($q); + return $result->fetch(PDO::FETCH_NUM)[0];
Is this equivalent to "return $result->fetchColumn();"?
Yeah, fixed.
+} diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index feb4006..89da81a 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -705,3 +705,56 @@ function aur_location() { } return $location; } + +/** + * Calculate pagination templates + * + * @return array The array of pagination templates, per page, and offset values + */ +function calculate_pagination($total_comment_count) { [...]
Nice! I wonder whether we can use this helper function elsewhere, such as for paginating package search results?
Yep, that's the plan.
diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php index 72c33b6..953a581 100644 --- a/web/lib/pkgbasefuncs.inc.php +++ b/web/lib/pkgbasefuncs.inc.php [...] @@ -71,6 +71,9 @@ function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false if ($limit > 0) { $q.=" LIMIT " . $limit; } + if ($offset > 0) { + $q.=" OFFSET " . $offset;
Same as above, please add intval().
Fixed.
Everything else looks good so far. And there's FS#59512 [1] (which you are probably already aware of) to be addressed in a re-roll. Thanks a lot put working on this!
Yeah, I hadn't even thought about letting regular users list their own comments, but there's no real reason not to, so fixed. -- Sincerely, Johannes Löthberg PGP Key ID: 0x50FB9B273A9D0BB5 PGP Key FP: 5134 EF9E AF65 F95B 6BB1 608E 50FB 9B27 3A9D 0BB5 https://theos.kyriasis.com/~kyrias/
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- Since v3: - Switched to older list() syntax instead of []. - Fix use of row variable where not needed. - Added missing intvals in account_comments. - Switched to fetchColumn instead of fetch(PDO::FETCH_NUM)[0]. - Allowed regular users to see their comments list. (FS#59512) web/html/account.php | 20 +++++- web/html/css/aurweb.css | 42 +++++++++++++ web/html/index.php | 2 + web/html/pkgbase.php | 10 ++- web/lib/acctfuncs.inc.php | 42 +++++++++++++ web/lib/aur.inc.php | 53 ++++++++++++++++ web/lib/credentials.inc.php | 2 + web/lib/pkgbasefuncs.inc.php | 10 ++- web/lib/pkgfuncs.inc.php | 4 ++ web/template/account_details.php | 3 + web/template/account_edit_form.php | 1 + web/template/pkg_comments.php | 99 ++++++++++++++++++++++-------- 12 files changed, 258 insertions(+), 30 deletions(-) diff --git a/web/html/account.php b/web/html/account.php index c30a89a..9695c9b 100644 --- a/web/html/account.php +++ b/web/html/account.php @@ -8,7 +8,7 @@ include_once('acctfuncs.inc.php'); # access Account specific functions $action = in_request("Action"); $need_userinfo = array( - "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount" + "DisplayAccount", "DeleteAccount", "AccountInfo", "UpdateAccount", "ListComments" ); if (in_array($action, $need_userinfo)) { @@ -166,6 +166,24 @@ if (isset($_COOKIE["AURSID"])) { $row["Username"]); } + } elseif ($action == "ListComments") { + if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)) { + # display the comment list if they're a TU/dev + + $total_comment_count = account_comments_count($row["ID"]); + list($pagination_templs, $per_page, $offset) = calculate_pagination($total_comment_count); + + $username = $row["Username"]; + $uid = $row["ID"]; + $comments = account_comments($uid, $per_page, $offset); + + $comment_section = "account"; + include('pkg_comments.php'); + + } else { + print __("You are not allowed to access this area."); + } + } else { if (has_credential(CRED_ACCOUNT_SEARCH)) { # display the search page if they're a TU/dev diff --git a/web/html/css/aurweb.css b/web/html/css/aurweb.css index f5e1037..593c9ae 100644 --- a/web/html/css/aurweb.css +++ b/web/html/css/aurweb.css @@ -148,3 +148,45 @@ label.confirmation, color: red; font-weight: bold; } + +.package-comments { + margin-top: 1.5em; +} + +.comments-header { + display: flex; + justify-content: space-between; + align-items: flex-start; +} + +/* arrowed headings */ +.comments-header h3 span.text { + display: block; + background: #1794D1; + font-size: 15px; + padding: 2px 10px; + color: white; +} + +.comments-header .comments-header-nav { + align-self: flex-end; +} + +.comment-header { + clear: both; + font-size: 1em; + margin-top: 1.5em; + border-bottom: 1px dotted #bbb; +} + +.comments div { + margin-bottom: 1em; +} + +.comments div p { + margin-bottom: 0.5em; +} + +.comments .more { + font-weight: normal; +} diff --git a/web/html/index.php b/web/html/index.php index 2c53cdd..b2cd840 100644 --- a/web/html/index.php +++ b/web/html/index.php @@ -142,6 +142,8 @@ if (!empty($tokens[1]) && '/' . $tokens[1] == get_pkg_route()) { $_REQUEST['Action'] = "UpdateAccount"; } elseif ($tokens[3] == 'delete') { $_REQUEST['Action'] = "DeleteAccount"; + } elseif ($tokens[3] == 'comments') { + $_REQUEST['Action'] = "ListComments"; } else { header("HTTP/1.0 404 Not Found"); include "./404.php"; diff --git a/web/html/pkgbase.php b/web/html/pkgbase.php index cf9a6c6..46ad77e 100644 --- a/web/html/pkgbase.php +++ b/web/html/pkgbase.php @@ -43,6 +43,7 @@ if (isset($_POST['IDs'])) { /* Perform package base actions. */ $via = isset($_POST['via']) ? $_POST['via'] : NULL; +$return_to = isset($_POST['return_to']) ? $_POST['return_to'] : NULL; $ret = false; $output = ""; $fragment = ""; @@ -133,7 +134,14 @@ if (check_token()) { /* Redirect back to package request page on success. */ header('Location: ' . get_pkgreq_route()); exit(); - } if (isset($base_id)) { + } elseif ((current_action("do_DeleteComment") || + current_action("do_UndeleteComment")) && $return_to) { + header('Location: ' . $return_to); + exit(); + } elseif (current_action("do_PinComment") && $return_to) { + header('Location: ' . $return_to); + exit(); + } elseif (isset($base_id)) { /* Redirect back to package base page on success. */ header('Location: ' . get_pkgbase_uri($pkgbase_name) . $fragment); exit(); diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php index df57375..dc44484 100644 --- a/web/lib/acctfuncs.inc.php +++ b/web/lib/acctfuncs.inc.php @@ -1403,3 +1403,45 @@ function accept_terms($uid, $termrev) { $dbh->exec($q); } } + +function account_comments($uid, $limit, $offset=0) { + $dbh = DB::connect(); + $q = "SELECT PackageComments.ID, Comments, UsersID, "; + $q.= "PackageBaseId, CommentTS, DelTS, EditedTS, B.UserName AS EditUserName, "; + $q.= "PinnedTS, "; + $q.= "C.UserName as DelUserName, RenderedComment, "; + $q.= "PB.ID as PackageBaseID, PB.Name as PackageBaseName "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN PackageBases PB ON PackageComments.PackageBaseID = PB.ID "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "LEFT JOIN Users B ON PackageComments.EditedUsersID = B.ID "; + $q.= "LEFT JOIN Users C ON PackageComments.DelUsersID = C.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid) . " "; + $q.= "ORDER BY CommentTS DESC"; + + if ($limit > 0) { + $q.=" LIMIT " . intval($limit); + } + + if ($offset > 0) { + $q.=" OFFSET " . intval($offset); + } + + $result = $dbh->query($q); + if (!$result) { + return null; + } + + return $result->fetchAll(); +} + +function account_comments_count($uid) { + $dbh = DB::connect(); + $q = "SELECT COUNT(*) "; + $q.= "FROM PackageComments "; + $q.= "LEFT JOIN Users A ON PackageComments.UsersID = A.ID "; + $q.= "WHERE A.ID = " . $dbh->quote($uid); + + $result = $dbh->query($q); + return $result->fetchColumn(); +} diff --git a/web/lib/aur.inc.php b/web/lib/aur.inc.php index feb4006..e9530fc 100644 --- a/web/lib/aur.inc.php +++ b/web/lib/aur.inc.php @@ -705,3 +705,56 @@ function aur_location() { } return $location; } + +/** + * Calculate pagination templates + * + * @return array The array of pagination templates, per page, and offset values + */ +function calculate_pagination($total_comment_count) { + /* Sanitize paging variables. */ + if (isset($_GET["O"])) { + $_GET["O"] = max(intval($_GET["O"]), 0); + } else { + $_GET["O"] = 0; + } + $offset = $_GET["O"]; + + if (isset($_GET["PP"])) { + $_GET["PP"] = bound(intval($_GET["PP"]), 1, 250); + } else { + $_GET["PP"] = 10; + } + $per_page = $_GET["PP"]; + + // Page offsets start at zero, so page 2 has offset 1, which means that we + // need to add 1 to the offset to get the current page. + $current_page = ceil($offset / $per_page) + 1; + $num_pages = ceil($total_comment_count / $per_page); + $pagination_templs = array(); + + if ($current_page > 1) { + $previous_page = $current_page - 1; + $previous_offset = ($previous_page - 1) * $per_page; + $pagination_templs['« ' . __('First')] = 0; + $pagination_templs['‹ ' . __('Previous')] = $previous_offset; + } + + if ($current_page - 5 > 1) { + $pagination_templs["..."] = false; + } + + for ($i = max($current_page - 5, 1); $i <= min($num_pages, $current_page + 5); $i++) { + $pagination_templs[$i] = ($i - 1) * $per_page; + } + + if ($current_page + 5 < $num_pages) + $pagination_templs["... "] = false; + + if ($current_page < $num_pages) { + $pagination_templs[__('Next') . ' ›'] = $current_page * $per_page; + $pagination_templs[__('Last') . ' »'] = ($num_pages - 1) * $per_page; + } + + return array($pagination_templs, $per_page, $offset); +} diff --git a/web/lib/credentials.inc.php b/web/lib/credentials.inc.php index d8698a8..c125119 100644 --- a/web/lib/credentials.inc.php +++ b/web/lib/credentials.inc.php @@ -5,6 +5,7 @@ define("CRED_ACCOUNT_EDIT", 2); define("CRED_ACCOUNT_EDIT_DEV", 3); define("CRED_ACCOUNT_LAST_LOGIN", 4); define("CRED_ACCOUNT_SEARCH", 5); +define("CRED_ACCOUNT_LIST_COMMENTS", 28); define("CRED_COMMENT_DELETE", 6); define("CRED_COMMENT_UNDELETE", 27); define("CRED_COMMENT_VIEW_DELETED", 22); @@ -48,6 +49,7 @@ function has_credential($credential, $approved_users=array()) { $atype = account_from_sid($_COOKIE['AURSID']); switch ($credential) { + case CRED_ACCOUNT_LIST_COMMENTS: case CRED_PKGBASE_FLAG: case CRED_PKGBASE_NOTIFY: case CRED_PKGBASE_VOTE: diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php index 72c33b6..953a581 100644 --- a/web/lib/pkgbasefuncs.inc.php +++ b/web/lib/pkgbasefuncs.inc.php @@ -44,7 +44,7 @@ function pkgbase_comments_count($base_id, $include_deleted, $only_pinned=false) * * @return array All package comment information for a specific package base */ -function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false) { +function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false, $offset=0) { $base_id = intval($base_id); $limit = intval($limit); if (!$base_id) { @@ -71,6 +71,9 @@ function pkgbase_comments($base_id, $limit, $include_deleted, $only_pinned=false if ($limit > 0) { $q.=" LIMIT " . $limit; } + if ($offset > 0) { + $q.=" OFFSET " . $offset; + } $result = $dbh->query($q); if (!$result) { return null; @@ -273,6 +276,7 @@ function pkgbase_display_details($base_id, $row, $SID="") { include('pkgbase_details.php'); if ($SID) { + $comment_section = "package"; include('pkg_comment_box.php'); } @@ -281,13 +285,17 @@ function pkgbase_display_details($base_id, $row, $SID="") { $limit_pinned = isset($_GET['pinned']) ? 0 : 5; $pinned = pkgbase_comments($base_id, $limit_pinned, false, true); if (!empty($pinned)) { + $comment_section = "package"; include('pkg_comments.php'); } unset($pinned); + $limit = isset($_GET['comments']) ? 0 : 10; $comments = pkgbase_comments($base_id, $limit, $include_deleted); + if (!empty($comments)) { + $comment_section = "package"; include('pkg_comments.php'); } } diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index ad25474..140b8fc 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -624,13 +624,17 @@ function pkg_display_details($id=0, $row, $SID="") { $limit_pinned = isset($_GET['pinned']) ? 0 : 5; $pinned = pkgbase_comments($base_id, $limit_pinned, false, true); if (!empty($pinned)) { + $comment_section = "package"; include('pkg_comments.php'); } unset($pinned); + $limit = isset($_GET['comments']) ? 0 : 10; $comments = pkgbase_comments($base_id, $limit, $include_deleted); + if (!empty($comments)) { + $comment_section = "package"; include('pkg_comments.php'); } } diff --git a/web/template/account_details.php b/web/template/account_details.php index 024bd9c..fa6b528 100644 --- a/web/template/account_details.php +++ b/web/template/account_details.php @@ -82,6 +82,9 @@ <?php if (can_edit_account($row)): ?> <li><a href="<?= get_user_uri($row['Username']); ?>edit"><?= __("Edit this user's account") ?></a></li> <?php endif; ?> + <?php if (has_credential(CRED_ACCOUNT_LIST_COMMENTS)): ?> + <li><a href="<?= get_user_uri($row['Username']); ?>comments"><?= __("List this user's comments") ?></a></li> + <?php endif; ?> </ul></td> </tr> </table> diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php index 6eff81b..38d5274 100644 --- a/web/template/account_edit_form.php +++ b/web/template/account_edit_form.php @@ -2,6 +2,7 @@ <p> <?= __('Click %shere%s if you want to permanently delete this account.', '<a href="' . get_user_uri($N) . 'delete/' . '">', '</a>') ?> <?= __('Click %shere%s for user details.', '<a href="' . get_user_uri($N) . '">', '</a>') ?> + <?= __('Click %shere%s to list the comments made by this account.', '<a href="' . get_user_uri($N) . 'comments/' . '">', '</a>') ?> </p> <form id="edit-profile-form" action="<?= get_user_uri($N) . 'update/'; ?>" method="post"> diff --git a/web/template/pkg_comments.php b/web/template/pkg_comments.php index 3e5e5cc..3001a34 100644 --- a/web/template/pkg_comments.php +++ b/web/template/pkg_comments.php @@ -1,28 +1,69 @@ <?php -if (!isset($count)) { - $count = pkgbase_comments_count($base_id, $include_deleted); +if ($comment_section == "package") { + if (!isset($count)) { + $count = pkgbase_comments_count($base_id, $include_deleted); + } } ?> -<div id="news"> - <h3> - <?php if (!isset($comments)): ?> - <?php $comments = $pinned ?> - <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all comments' , $count) ?> (<?= $count ?>)"><?= __('Pinned Comments') ?></a> - <span class="arrow"></span> - <?php else: ?> - <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all comments' , $count) ?> (<?= $count ?>)"><?= __('Latest Comments') ?></a> - <span class="arrow"></span> + + +<?php if ($comment_section == "package"): ?> +<div class="comments package-comments"> +<?php else: ?> +<div class="comments"> +<?php endif; ?> + <div class="comments-header"> + <h3> + <?php if ($comment_section == "package"): ?> + <?php if (!isset($comments)): ?> + <?php $comments = $pinned ?> + <span class="text"><?= __('Pinned Comments') ?></span> + <span class="arrow"></span> + <?php else: ?> + <span class="text"><?= __('Latest Comments') ?></span> + <span class="arrow"></span> + <?php endif; ?> + <?php elseif ($comment_section == "account"): ?> + <?= __("Comments for") ?> <a href="<?= htmlentities(get_uri('/account/' . $username), ENT_QUOTES) ?>"><?= $username ?></a> + <?php endif; ?> + </h3> + + <?php if (isset($pagination_templs) && count($pagination_templs) > 1): ?> + <p class="comments-header-nav"> + <?php foreach ($pagination_templs as $pagenr => $pagestart): ?> + <?php if ($pagestart === false): ?> + <span class="page"><?= $pagenr ?></span> + <?php elseif ($pagestart === $offset): ?> + <span class="page"><?= $pagenr ?></span> + <?php else: ?> + <?php if ($comment_section == "package"): ?> + <a class="page" href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('O=' . $pagestart) ?>"><?= $pagenr ?></a> + <?php else: ?> + <a class="page" href="<?= get_uri('/account/' . $username . '/comments/') . '?' . mkurl('O=' . $pagestart) ?>"><?= $pagenr ?></a> + <?php endif; ?> + <?php endif; ?> + <?php endforeach; ?> + </p> <?php endif; ?> - </h3> + </div> <?php foreach ($comments as $indx => $row): ?> <?php + if ($comment_section == "account") { + $pkgbase_name = $row["PackageBaseName"]; + } + $date_fmtd = date('Y-m-d H:i', $row['CommentTS']); - if ($row['UserName']) { - $user_fmtd = html_format_username($row['UserName']); - $heading = __('%s commented on %s', $user_fmtd, $date_fmtd); - } else { - $heading = __('Anonymous comment on %s', $date_fmtd); + if ($comment_section == "package") { + if ($row['UserName']) { + $user_fmtd = html_format_username($row['UserName']); + $heading = __('%s commented on %s', $user_fmtd, $date_fmtd); + } else { + $heading = __('Anonymous comment on %s', $date_fmtd); + } + } elseif ($comment_section == "account") { + $pkg_uri = '<a href=' . htmlspecialchars(get_pkg_uri($row['PackageBaseName']), ENT_QUOTES) . '>' . htmlspecialchars($row['PackageBaseName']) . '</a></td>'; + $heading = __('Commented on package %s on %s', $pkg_uri, $date_fmtd); } $is_deleted = $row['DelTS']; @@ -50,8 +91,13 @@ if (!isset($count)) { } $heading .= ')</span>'; } + + $comment_classes = "comment-header"; + if ($is_deleted) { + $comment_classes .= " comment-deleted"; + } ?> - <h4 id="<?= isset($pinned) ? "pinned-" : "comment-" ?><?= $row['ID'] ?>"<?php if ($is_deleted): ?> class="comment-deleted"<?php endif; ?>> + <h4 id="<?= isset($pinned) ? "pinned-" : "comment-" ?><?= $row['ID'] ?>" class="<?= $comment_classes ?>"> <?= $heading ?> <?php if ($is_deleted && has_credential(CRED_COMMENT_UNDELETE)): ?> <form class="undelete-comment-form" method="post" action="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name), ENT_QUOTES); ?>"> @@ -59,6 +105,7 @@ if (!isset($count)) { <input type="hidden" name="action" value="do_UndeleteComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="undelete-comment" src="/images/action-undo.min.svg" width="11" height="11" alt="<?= __('Undelete comment') ?>" title="<?= __('Undelete comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -70,6 +117,7 @@ if (!isset($count)) { <input type="hidden" name="action" value="do_DeleteComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="delete-comment" src="/images/x.min.svg" width="11" height="11" alt="<?= __('Delete comment') ?>" title="<?= __('Delete comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -79,13 +127,14 @@ if (!isset($count)) { <a href="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name) . 'edit-comment/?comment_id=' . $row['ID'], ENT_QUOTES) ?>" class="edit-comment" title="<?= __('Edit comment') ?>"><img src="/images/pencil.min.svg" alt="<?= __('Edit comment') ?>" width="11" height="11"></a> <?php endif; ?> - <?php if (!$is_deleted && !$is_pinned && can_pin_comment_array($row) && !(pkgbase_comments_count($base_id, false, true) >= 5)): ?> + <?php if (!$is_deleted && !$is_pinned && can_pin_comment_array($row) && !(pkgbase_comments_count($row["PackageBaseID"], false, true) >= 5)): ?> <form class="pin-comment-form" method="post" action="<?= htmlspecialchars(get_pkgbase_uri($pkgbase_name), ENT_QUOTES); ?>"> <fieldset style="display:inline;"> <input type="hidden" name="action" value="do_PinComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> - <input type="hidden" name="package_base" value="<?= $base_id ?>" /> + <input type="hidden" name="package_base" value="<?= $row["PackageBaseID"] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="pin-comment" src="/images/pin.min.svg" width="11" height="11" alt="<?= __('Pin comment') ?>" title="<?= __('Pin comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -97,6 +146,7 @@ if (!isset($count)) { <input type="hidden" name="action" value="do_UnpinComment" /> <input type="hidden" name="comment_id" value="<?= $row['ID'] ?>" /> <input type="hidden" name="token" value="<?= htmlspecialchars($_COOKIE['AURSID']) ?>" /> + <input type="hidden" name="return_to" value="<?= htmlspecialchars($_SERVER["REQUEST_URI"], ENT_QUOTES) ?>" /> <input type="image" class="pin-comment" src="/images/unpin.min.svg" width="11" height="11" alt="<?= __('Unpin comment') ?>" title="<?= __('Unpin comment') ?>" name="submit" value="1" /> </fieldset> </form> @@ -114,13 +164,8 @@ if (!isset($count)) { </div> </div> <?php endforeach; ?> - -<?php if ($count > 10 && !isset($_GET['comments']) && !isset($pinned)): ?> - <h3> - <a href="<?= htmlentities(get_pkgbase_uri($pkgbase_name), ENT_QUOTES) . '?' . mkurl('comments=all') ?>" title="<?= __('View all comments') ?> (<?= $count ?>)"><?= __('All comments', $count) ?></a> - </h3> -<?php endif; ?> </div> + <script> $(document).ready(function() { $('.edit-comment').click(function () { @@ -133,7 +178,7 @@ $(document).ready(function() { $.getJSON('<?= get_uri('/rpc') ?>', { type: 'get-comment-form', arg: comment_id, - base_id: <?= intval($base_id) ?>, + base_id: <?= intval($row["PackageBaseID"]) ?>, pkgbase_name: <?= json_encode($pkgbase_name) ?> }, function (data) { remove_busy_indicator(_this); -- 2.18.0
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- Since v3: - Switched to list() syntax instead of newer []. web/lib/pkgbasefuncs.inc.php | 5 +++-- web/lib/pkgfuncs.inc.php | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/web/lib/pkgbasefuncs.inc.php b/web/lib/pkgbasefuncs.inc.php index 953a581..b39bca5 100644 --- a/web/lib/pkgbasefuncs.inc.php +++ b/web/lib/pkgbasefuncs.inc.php @@ -291,9 +291,10 @@ function pkgbase_display_details($base_id, $row, $SID="") { unset($pinned); - $limit = isset($_GET['comments']) ? 0 : 10; - $comments = pkgbase_comments($base_id, $limit, $include_deleted); + $total_comment_count = pkgbase_comments_count($base_id, $include_deleted); + list($pagination_templs, $per_page, $offset) = calculate_pagination($total_comment_count); + $comments = pkgbase_comments($base_id, $per_page, $include_deleted, false, $offset); if (!empty($comments)) { $comment_section = "package"; include('pkg_comments.php'); diff --git a/web/lib/pkgfuncs.inc.php b/web/lib/pkgfuncs.inc.php index 140b8fc..ced1f8e 100644 --- a/web/lib/pkgfuncs.inc.php +++ b/web/lib/pkgfuncs.inc.php @@ -630,9 +630,10 @@ function pkg_display_details($id=0, $row, $SID="") { unset($pinned); - $limit = isset($_GET['comments']) ? 0 : 10; - $comments = pkgbase_comments($base_id, $limit, $include_deleted); + $total_comment_count = pkgbase_comments_count($base_id, $include_deleted); + list($pagination_templs, $per_page, $offset) = calculate_pagination($total_comment_count); + $comments = pkgbase_comments($base_id, $per_page, $include_deleted, false, $offset); if (!empty($comments)) { $comment_section = "package"; include('pkg_comments.php'); -- 2.18.0
On Mon, 06 Aug 2018 at 02:02:57, Johannes Löthberg wrote:
Signed-off-by: Johannes Löthberg <johannes@kyriasis.com> --- Since v3: - Switched to older list() syntax instead of []. - Fix use of row variable where not needed. - Added missing intvals in account_comments. - Switched to fetchColumn instead of fetch(PDO::FETCH_NUM)[0]. - Allowed regular users to see their comments list. (FS#59512)
web/html/account.php | 20 +++++- web/html/css/aurweb.css | 42 +++++++++++++ web/html/index.php | 2 + web/html/pkgbase.php | 10 ++- web/lib/acctfuncs.inc.php | 42 +++++++++++++ web/lib/aur.inc.php | 53 ++++++++++++++++ web/lib/credentials.inc.php | 2 + web/lib/pkgbasefuncs.inc.php | 10 ++- web/lib/pkgfuncs.inc.php | 4 ++ web/template/account_details.php | 3 + web/template/account_edit_form.php | 1 + web/template/pkg_comments.php | 99 ++++++++++++++++++++++-------- 12 files changed, 258 insertions(+), 30 deletions(-) [...]
Merged both patches into pu, thanks!
participants (2)
-
Johannes Löthberg
-
Lukas Fleischer