Added commenting system
This commit is contained in:
141
htdocs/comments.php
Normal file
141
htdocs/comments.php
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
define("SITE_ROOT", realpath(dirname(__file__)));
|
||||||
|
require_once SITE_ROOT . "/lib/init.php";
|
||||||
|
$S->requireUser();
|
||||||
|
|
||||||
|
$ajax = (int)$_REQUEST["ajax"];
|
||||||
|
$signature_id = (int)$_REQUEST["signature_id"];
|
||||||
|
$stats = new CrashStats($filter);
|
||||||
|
|
||||||
|
if (false === $r = $stats->getSignature($signature_id))
|
||||||
|
{
|
||||||
|
print "<p>No such signature</p>";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderComments($comments)
|
||||||
|
{
|
||||||
|
global $S;
|
||||||
|
foreach($comments as $c):
|
||||||
|
$from = $c->name . " <" . $c->email . ">" . " " . date("r", $c->commented);
|
||||||
|
$comment = Markdown::defaultTransform($c->comment);
|
||||||
|
$del = "";
|
||||||
|
if ($S->user->is_admin || $S->user_id == $c->user_id)
|
||||||
|
{
|
||||||
|
$del = "<a class=\"del_comment\" data-id=\"{$c->id}\">Delete comment</a> ";
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="ui-corner-all" style="margin: 2em 0; background-color: #252525;">
|
||||||
|
<div style="padding: 5px; border-bottom: 1px solid #444; vertical-align: middle;">
|
||||||
|
<?php echo $del . htmlentities($from) ?>
|
||||||
|
</div>
|
||||||
|
<div style="padding: 5px"><?php echo $comment ?></div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_POST["action"] == "add_comment")
|
||||||
|
{
|
||||||
|
if (trim($_POST["comment"]))
|
||||||
|
{
|
||||||
|
$stats->addSignatureComment($signature_id, $_POST["comment"]);
|
||||||
|
}
|
||||||
|
renderComments($stats->getSignatureComments($signature_id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($_POST["action"] == "del_comment")
|
||||||
|
{
|
||||||
|
$stats->delSignatureComment($signature_id, $_POST["delete_id"]);
|
||||||
|
renderComments($stats->getSignatureComments($signature_id));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$comments = $stats->getSignatureComments($signature_id);
|
||||||
|
if (!$ajax) Layout::header();
|
||||||
|
?>
|
||||||
|
<script>
|
||||||
|
var signature_id = <?php echo $signature_id ?>;
|
||||||
|
|
||||||
|
function updateDelLinks(){
|
||||||
|
$(".del_comment").each(function() {
|
||||||
|
var $link = $(this);
|
||||||
|
var id = $link.data("id");
|
||||||
|
|
||||||
|
$link.button({
|
||||||
|
text: false,
|
||||||
|
icons: { primary: "ui-icon-close" },
|
||||||
|
})
|
||||||
|
.on("click", function(){
|
||||||
|
if (true || confirm("Delete comment?")) {
|
||||||
|
|
||||||
|
data = {
|
||||||
|
ajax: 1,
|
||||||
|
action: "del_comment",
|
||||||
|
signature_id: signature_id,
|
||||||
|
delete_id: id,
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "comments.php",
|
||||||
|
data: data,
|
||||||
|
success: function(res) {
|
||||||
|
$("#comments_scroller").html(res);
|
||||||
|
$('#comments_scroller').scrollTop($('#comments_scroller')[0].scrollHeight);
|
||||||
|
updateDelLinks();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$(function(){
|
||||||
|
$("#add_comment").button()
|
||||||
|
.on("click", function(){
|
||||||
|
|
||||||
|
data = {
|
||||||
|
ajax: 1,
|
||||||
|
action: "add_comment",
|
||||||
|
signature_id: signature_id,
|
||||||
|
comment: $("#comment_input").val(),
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "comments.php",
|
||||||
|
data: data,
|
||||||
|
success: function(res) {
|
||||||
|
$("#comments_scroller").html(res);
|
||||||
|
$('#comments_scroller').scrollTop($('#comments_scroller')[0].scrollHeight);
|
||||||
|
updateDelLinks();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#comments_scroller').scrollTop($('#comments_scroller')[0].scrollHeight);
|
||||||
|
|
||||||
|
updateDelLinks();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--div id="comments_frame" style="height: 100%;"-->
|
||||||
|
<div id="comments_scroller" style="height: 300px; overflow-y: auto;"><?php echo renderComments($comments) ?></div>
|
||||||
|
<div id="new_comment" style="height: 100px;">
|
||||||
|
<a id="add_comment">Add comment</a>
|
||||||
|
<textarea id="comment_input" class="ui-widget-content" style="display: block; width: 100%; height: 100%; margin-top: 5px;"></textarea>
|
||||||
|
</div>
|
||||||
|
<div style="height: 30px;"></div>
|
||||||
|
<!--/div-->
|
||||||
|
|
||||||
|
<?php
|
||||||
|
|
||||||
|
if (!$ajax) Layout::footer();
|
||||||
@@ -25,7 +25,7 @@ class CrashStats
|
|||||||
{
|
{
|
||||||
$ret = array();
|
$ret = array();
|
||||||
$where = $this->filter->getWhere();
|
$where = $this->filter->getWhere();
|
||||||
$q = "select count(r.id) as nr, s.id as signature_id, s.signature as signature_text from reports r join signature s on r.signature_id = s.id $where group by signature_id order by nr desc";
|
$q = "select count(r.id) as nr, s.id as signature_id, s.signature as signature_text, s.has_comments from reports r join signature s on r.signature_id = s.id $where group by signature_id order by nr desc";
|
||||||
$q .= kl_str_sql(" limit !i", 100);
|
$q .= kl_str_sql(" limit !i", 100);
|
||||||
if (false !== $cached = Memc::getq($q)) return $cached;
|
if (false !== $cached = Memc::getq($q)) return $cached;
|
||||||
|
|
||||||
@@ -153,4 +153,41 @@ class CrashStats
|
|||||||
Memc::setq($q, $ret);
|
Memc::setq($q, $ret);
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateCommentCount($id)
|
||||||
|
{
|
||||||
|
$q = kl_str_sql("update signature set has_comments=(select count(*) as count from comment where signature_id=!i) where id=!i", $id, $id);
|
||||||
|
DBH::$db->query($q);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSignatureComment($id, $text)
|
||||||
|
{
|
||||||
|
global $S;
|
||||||
|
$q = kl_str_sql("insert into comment (signature_id, user_id, comment) values (!i, !i, !s)", $id, $S->user_id, $text);
|
||||||
|
DBH::$db->query($q);
|
||||||
|
self::updateCommentCount($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSignatureComments($id)
|
||||||
|
{
|
||||||
|
$ret = array();
|
||||||
|
$q = kl_str_sql("select c.*, u.name, u.email from comment c join users u on c.user_id = u.user_id where signature_id=!i order by id asc;", $id);
|
||||||
|
if (!$res = DBH::$db->query($q)) return;
|
||||||
|
|
||||||
|
while ($row = DBH::$db->fetchRow($res))
|
||||||
|
{
|
||||||
|
$c = new stdClass;
|
||||||
|
DBH::$db->loadFromDbRow($c, $res, $row);
|
||||||
|
$ret[] = $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
function delSignatureComment($id, $del_id)
|
||||||
|
{
|
||||||
|
$q = kl_str_sql("delete from comment where id=!i", $del_id);
|
||||||
|
DBH::$db->query($q);
|
||||||
|
self::updateCommentCount($id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
1514
htdocs/lib/Markdown.php
Normal file
1514
htdocs/lib/Markdown.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -59,5 +59,14 @@ create table reports(
|
|||||||
create table signature(
|
create table signature(
|
||||||
id integer not null auto_increment primary key,
|
id integer not null auto_increment primary key,
|
||||||
hash varchar(32) not null unique,
|
hash varchar(32) not null unique,
|
||||||
signature text
|
signature text,
|
||||||
|
has_comments integer
|
||||||
|
);
|
||||||
|
|
||||||
|
create table comment(
|
||||||
|
id integer not null auto_increment primary key,
|
||||||
|
signature_id integer,
|
||||||
|
user_id integer,
|
||||||
|
commented timestamp not null default current_timestamp,
|
||||||
|
comment text
|
||||||
);
|
);
|
||||||
@@ -4,21 +4,6 @@ define("SITE_ROOT", realpath(dirname(__file__)));
|
|||||||
require_once SITE_ROOT . "/lib/init.php";
|
require_once SITE_ROOT . "/lib/init.php";
|
||||||
$S->requireUser();
|
$S->requireUser();
|
||||||
|
|
||||||
/*
|
|
||||||
$report = CrashReport::getReport((int)$_GET["id"]);
|
|
||||||
if (!$report)
|
|
||||||
{
|
|
||||||
print "<p>No such report</p>";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
$full = ReportParser::parse($report->id);
|
|
||||||
//print_r (array_keys($full));
|
|
||||||
|
|
||||||
print "<p> Reported: " . date("r", (int)$report->reported). "</p>";
|
|
||||||
*/
|
|
||||||
|
|
||||||
$stats = new CrashStats($filter);
|
$stats = new CrashStats($filter);
|
||||||
|
|
||||||
if (false === $r = $stats->getSignature((int)$_GET["signature_id"]))
|
if (false === $r = $stats->getSignature((int)$_GET["signature_id"]))
|
||||||
|
|||||||
@@ -14,6 +14,35 @@ $filter->render();
|
|||||||
$(function() {
|
$(function() {
|
||||||
$( "#tabs" ).tabs();
|
$( "#tabs" ).tabs();
|
||||||
$("div.ui-tabs-panel").css('padding','0px');
|
$("div.ui-tabs-panel").css('padding','0px');
|
||||||
|
|
||||||
|
var tag = $("<div></div>");
|
||||||
|
var $dialog = tag.dialog({
|
||||||
|
autoOpen: false,
|
||||||
|
width: 800,
|
||||||
|
height: 500,
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".comment_link").each(function() {
|
||||||
|
var $link = $(this);
|
||||||
|
var signature_id = $link.data("signature-id");
|
||||||
|
|
||||||
|
$link.on("click", function() {
|
||||||
|
$dialog.dialog("option", "title", "Crash signature " + signature_id);
|
||||||
|
$dialog.dialog("open");
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: "comments.php?ajax=1&signature_id=" + signature_id,
|
||||||
|
success: function(res) {
|
||||||
|
tag.html(res);
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
tag.html("<p>Failed to fetch the comment section for this signature</p>");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<br/>
|
<br/>
|
||||||
@@ -41,6 +70,7 @@ $filter->render();
|
|||||||
<table class="jtable noborder" style="width: 100%">
|
<table class="jtable noborder" style="width: 100%">
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 3%">Nr</th>
|
<th style="width: 3%">Nr</th>
|
||||||
|
<th style="width: 7%"> </th>
|
||||||
<th style="width: 10%">Module</th>
|
<th style="width: 10%">Module</th>
|
||||||
<th style="width: 80%">Stack Top</th>
|
<th style="width: 80%">Stack Top</th>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -55,6 +85,7 @@ $filter->render();
|
|||||||
?>
|
?>
|
||||||
<tr class="rowhighlight">
|
<tr class="rowhighlight">
|
||||||
<td style="text-align: right"><a href="<?php echo rl_s($r) ?>"><?php echo htmlentities($r->nr) ?></a></td>
|
<td style="text-align: right"><a href="<?php echo rl_s($r) ?>"><?php echo htmlentities($r->nr) ?></a></td>
|
||||||
|
<td><a href="#" class="comment_link" data-signature-id="<?php echo htmlentities($r->signature_id) ?>">Comments</a></td>
|
||||||
<td><a href="<?php echo rl_s($r) ?>"><?php echo htmlentities($parts[0]) ?></a></td>
|
<td><a href="<?php echo rl_s($r) ?>"><?php echo htmlentities($parts[0]) ?></a></td>
|
||||||
<td><a href="<?php echo rl_s($r) ?>"><?php echo $txt ?></a></td>
|
<td><a href="<?php echo rl_s($r) ?>"><?php echo $txt ?></a></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user