Skip to content

Commit 881f00c

Browse files
committed
Comment edit work in progress
1 parent bbf717a commit 881f00c

File tree

4 files changed

+276
-0
lines changed

4 files changed

+276
-0
lines changed

src/controllers/Comment/Edit.php

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
<?php
2+
3+
namespace BNETDocs\Controllers\Comment;
4+
5+
use \BNETDocs\Libraries\Authentication;
6+
use \BNETDocs\Libraries\CSRF;
7+
use \BNETDocs\Libraries\Comment;
8+
use \BNETDocs\Libraries\EventTypes;
9+
use \BNETDocs\Libraries\Exceptions\CommentNotFoundException;
10+
use \BNETDocs\Libraries\Logger;
11+
use \BNETDocs\Libraries\User;
12+
use \BNETDocs\Models\Comment\Edit as CommentEditModel;
13+
14+
use \CarlBennett\MVC\Libraries\Common;
15+
use \CarlBennett\MVC\Libraries\Controller;
16+
use \CarlBennett\MVC\Libraries\Router;
17+
use \CarlBennett\MVC\Libraries\View;
18+
19+
use \InvalidArgumentException;
20+
use \UnexpectedValueException;
21+
22+
class Edit extends Controller {
23+
24+
public function &run(Router &$router, View &$view, array &$args) {
25+
26+
$data = $router->getRequestQueryArray();
27+
$model = new CommentEditModel();
28+
$model->comment = null;
29+
$model->csrf_id = mt_rand();
30+
$model->csrf_token = CSRF::generate($model->csrf_id);
31+
$model->error = null;
32+
$model->id = (isset($data["id"]) ? $data["id"] : null);
33+
$model->parent_id = null;
34+
$model->parent_type = null;
35+
$model->user = Authentication::$user;
36+
37+
try { $model->comment = new Comment($model->id); }
38+
catch (CommentNotFoundException $e) { $model->comment = null; }
39+
catch (InvalidArgumentException $e) { $model->comment = null; }
40+
41+
$model->acl_allowed = ($model->user && (
42+
$model->user->getAcl(User::OPTION_ACL_COMMENT_DELETE) ||
43+
$model->user->getId() == $model->comment->getUserId()
44+
));
45+
46+
if ($model->comment === null) {
47+
$model->error = "NOT_FOUND";
48+
} else {
49+
$model->content = $model->comment->getContent(true);
50+
$model->parent_type = $model->comment->getParentType();
51+
$model->parent_id = $model->comment->getParentId();
52+
53+
if ($router->getRequestMethod() == "POST") {
54+
$this->tryDelete($router, $model);
55+
}
56+
}
57+
58+
$view->render($model);
59+
60+
$model->_responseCode = ($model->acl_allowed ? 200 : 403);
61+
$model->_responseHeaders["Content-Type"] = $view->getMimeType();
62+
$model->_responseTTL = 0;
63+
64+
return $model;
65+
}
66+
67+
protected function tryDelete(Router &$router, CommentDeleteModel &$model) {
68+
if (!isset($model->user)) {
69+
$model->error = "NOT_LOGGED_IN";
70+
return;
71+
}
72+
if (!$model->acl_allowed) {
73+
$model->error = "ACL_NOT_SET";
74+
return;
75+
}
76+
77+
$data = $router->getRequestBodyArray();
78+
$csrf_id = (isset($data["csrf_id" ]) ? $data["csrf_id" ] : null);
79+
$csrf_token = (isset($data["csrf_token"]) ? $data["csrf_token"] : null);
80+
$csrf_valid = CSRF::validate($csrf_id, $csrf_token);
81+
82+
if (!$csrf_valid) {
83+
$model->error = "INVALID_CSRF";
84+
return;
85+
}
86+
CSRF::invalidate($csrf_id);
87+
88+
$model->error = false;
89+
90+
$id = (int) $model->id;
91+
$parent_type = (int) $model->parent_type;
92+
$parent_id = (int) $model->parent_id;
93+
$user_id = $model->user->getId();
94+
95+
$log_key = null;
96+
switch ($parent_type) {
97+
case Comment::PARENT_TYPE_DOCUMENT:
98+
$log_key = EventTypes::COMMENT_DELETED_DOCUMENT; break;
99+
case Comment::PARENT_TYPE_COMMENT:
100+
$log_key = EventTypes::COMMENT_DELETED_COMMENT; break;
101+
case Comment::PARENT_TYPE_NEWS_POST:
102+
$log_key = EventTypes::COMMENT_DELETED_NEWS; break;
103+
case Comment::PARENT_TYPE_PACKET:
104+
$log_key = EventTypes::COMMENT_DELETED_PACKET; break;
105+
case Comment::PARENT_TYPE_SERVER:
106+
$log_key = EventTypes::COMMENT_DELETED_SERVER; break;
107+
case Comment::PARENT_TYPE_USER:
108+
$log_key = EventTypes::COMMENT_DELETED_USER; break;
109+
default: throw new UnexpectedValueException(
110+
'Parent type: ' . $parent_type
111+
);
112+
}
113+
114+
try {
115+
116+
$success = Comment::delete($id, $parent_type, $parent_id);
117+
118+
} catch (QueryException $e) {
119+
120+
// SQL error occurred. We can show a friendly message to the user while
121+
// also notifying this problem to staff.
122+
Logger::logException($e);
123+
124+
$success = false;
125+
126+
}
127+
128+
if (!$success) {
129+
$model->error = "INTERNAL_ERROR";
130+
} else {
131+
$model->error = false;
132+
}
133+
134+
Logger::logEvent(
135+
$log_key,
136+
$user_id,
137+
getenv("REMOTE_ADDR"),
138+
json_encode([
139+
"error" => $model->error,
140+
"comment_id" => $id,
141+
"parent_type" => $parent_type,
142+
"parent_id" => $parent_id
143+
])
144+
);
145+
}
146+
147+
}

src/models/Comment/Edit.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace BNETDocs\Models\Comment;
4+
5+
use \CarlBennett\MVC\Libraries\Model;
6+
7+
class Edit extends Model {
8+
9+
public $acl_allowed;
10+
public $comment;
11+
public $csrf_id;
12+
public $csrf_token;
13+
public $error;
14+
public $id;
15+
public $parent_id;
16+
public $parent_type;
17+
public $user;
18+
19+
}

src/templates/Comment/Edit.phtml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
namespace BNETDocs\Templates\Comment;
4+
5+
use \CarlBennett\MVC\Libraries\Pair;
6+
7+
$title = "Edit Comment";
8+
$description = "This form allows an individual to edit a comment.";
9+
10+
$this->opengraph->attach(new Pair("url", "/comment/edit"));
11+
$this->opengraph->attach(new Pair("type", "article"));
12+
13+
switch ($this->getContext()->error) {
14+
case "ACL_NOT_SET":
15+
$message = "You do not have the privilege to edit this comment.";
16+
break;
17+
case "NOT_FOUND":
18+
$message = "Cannot find comment by that id.";
19+
break;
20+
case "NOT_LOGGED_IN":
21+
$message = "You must be logged in to edit comments.";
22+
break;
23+
case "INVALID_CSRF":
24+
$message = "The Cross-Site Request Forgery token was invalid. Either the "
25+
. "edit comment form expired, or this may have been a malicious "
26+
. "attempt to edit a comment.";
27+
break;
28+
case "INTERNAL_ERROR":
29+
$message = "An internal error occurred while processing your request. "
30+
. "Our staff has been notified of the issue. Try again later.";
31+
break;
32+
default:
33+
$message = $this->getContext()->error;
34+
}
35+
36+
$c = $this->getContext()->comment;
37+
if ($c) {
38+
$c_id = $c->getId();
39+
$c_user = $c->getUser();
40+
$c_user_id = $c->getUserId();
41+
$c_user_name = $c_user->getName();
42+
$c_user_url = $c_user->getURI();
43+
$c_user_avatar = $c_user->getAvatarURI(22);
44+
}
45+
46+
$this->additional_css[] = "/a/comments.css";
47+
$this->additional_css[] = "/a/forms.css";
48+
require("./header.inc.phtml");
49+
?>
50+
<article>
51+
<?php if (is_null($this->getContext()->error) && !is_null($c)) { ?>
52+
<header>Edit Comment</header>
53+
<form method="POST">
54+
<input type="hidden" name="comment_id" value="<?php echo $c_id; ?>"/>
55+
<input type="hidden" name="csrf_id" value="<?php echo $this->getContext()->csrf_id; ?>"/>
56+
<input type="hidden" name="csrf_token" value="<?php echo $this->getContext()->csrf_token; ?>"/>
57+
<section>
58+
<table class="comments"><tbody>
59+
<tr><td><a href="<?php echo $c_user_url; ?>"><img class="avatar" src="<?php echo $c_user_avatar; ?>"/> <?php echo filter_var($c_user_name, FILTER_SANITIZE_STRING); ?></a><br/><time class="comment_timestamp" datetime="<?php echo $c->getCreatedDateTime()->format("c"); ?>"><?php echo $c->getCreatedDateTime()->format("D M j, Y g:ia T"); ?></time></td><td><textarea id="comment-content" name="content" cols="80" rows="5"><?php echo $c->getContent(false); ?></textarea></td></tr>
60+
</tbody></table><hr/>
61+
<p>
62+
<input class="float-right bg-green" type="submit" value="Edit Comment" tabindex="2" autofocus="autofocus"/>
63+
<a class="button button-bg-red" href="javascript:history.go(-1);" id="cancel-btn">Cancel</a>
64+
</p>
65+
<script type="text/javascript">
66+
if (history.length == 1) {
67+
document.getElementById('cancel-btn').className += ' button-disabled';
68+
}
69+
</script>
70+
</section>
71+
</form>
72+
<?php } else if ($this->getContext()->error === false) { ?>
73+
<header class="green">Comment Edited</header>
74+
<section class="green">
75+
<p>You have successfully edited the comment!</p>
76+
<p>Use the navigation to the left to move to another page.</p>
77+
</section>
78+
<?php } else { ?>
79+
<header class="red">Edit Comment</header>
80+
<section class="red">
81+
<p>An error occurred while attempting to delete the comment.</p>
82+
<p><?php echo $message; ?></p>
83+
<p>Use the navigation to the left to move to another page.</p>
84+
</section>
85+
<?php } ?>
86+
</article>
87+
<?php require("./footer.inc.phtml"); ?>

src/views/Comment/EditHtml.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace BNETDocs\Views\Comment;
4+
5+
use \BNETDocs\Models\Comment\Edit as CommentEditModel;
6+
7+
use \CarlBennett\MVC\Libraries\Exceptions\IncorrectModelException;
8+
use \CarlBennett\MVC\Libraries\Model;
9+
use \CarlBennett\MVC\Libraries\Template;
10+
use \CarlBennett\MVC\Libraries\View;
11+
12+
class EditHtml extends View {
13+
public function getMimeType() {
14+
return 'text/html;charset=utf-8';
15+
}
16+
17+
public function render( Model &$model ) {
18+
if ( !$model instanceof CommentEditModel ) {
19+
throw new IncorrectModelException();
20+
}
21+
( new Template( $model, 'Comment/Edit' ))->render();
22+
}
23+
}

0 commit comments

Comments
 (0)