Skip to content

Commit f17c5b1

Browse files
committed
Allow viewing comments via API
This is in preparation for allowing comments in sections of the site without having to POST/PUT to that section's endpoints. In other words, this gives comments their own unique endpoint that can be accessed over Ajax calls.
1 parent f3a621d commit f17c5b1

File tree

10 files changed

+219
-3
lines changed

10 files changed

+219
-3
lines changed

src/controllers/API/Comment.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
namespace BNETDocs\Controllers\API;
4+
5+
use \BNETDocs\Libraries\Comment as CommentLib;
6+
use \BNETDocs\Libraries\Common;
7+
use \BNETDocs\Libraries\Controller;
8+
use \BNETDocs\Libraries\Exceptions\CommentNotFoundException;
9+
use \BNETDocs\Libraries\Exceptions\QueryException;
10+
use \BNETDocs\Libraries\Exceptions\UnspecifiedViewException;
11+
use \BNETDocs\Libraries\Router;
12+
use \BNETDocs\Libraries\UserSession;
13+
use \BNETDocs\Models\API\Comment as APICommentModel;
14+
use \BNETDocs\Views\API\CommentJSON as APICommentJSONView;
15+
use \DateTime;
16+
use \DateTimeZone;
17+
18+
class Comment extends Controller {
19+
20+
public function run(Router &$router) {
21+
switch ($router->getRequestPathExtension()) {
22+
case "json": case "":
23+
$view = new APICommentJSONView();
24+
break;
25+
default:
26+
throw new UnspecifiedViewException();
27+
}
28+
$model = new APICommentModel();
29+
$model->user_session = UserSession::load($router);
30+
31+
switch ($router->getRequestMethod()) {
32+
case "GET": $code = $this->handleGet($router, $model); break;
33+
case "OPTIONS": $code = $this->handleOptions($router, $model); break;
34+
case "PUT": $code = $this->handlePut($router, $model); break;
35+
default: $code = $this->handleUnknown($router, $model); break;
36+
}
37+
38+
ob_start();
39+
$view->render($model);
40+
$router->setResponseCode($code);
41+
$router->setResponseTTL(0);
42+
$router->setResponseHeader("Content-Type", $view->getMimeType());
43+
$router->setResponseContent(ob_get_contents());
44+
ob_end_clean();
45+
}
46+
47+
protected function handleGet(Router &$router, APICommentModel &$model) {
48+
$query = $router->getRequestQueryArray();
49+
$p_id = (isset($query["parent_id" ]) ? $query["parent_id" ] : null);
50+
$p_type = (isset($query["parent_type"]) ? $query["parent_type"] : null);
51+
52+
if ($p_id !== null) $p_id = (int) $p_id;
53+
if ($p_type !== null) $p_type = (int) $p_type;
54+
55+
$comments = CommentLib::getAll($p_type, $p_id);
56+
$error = ($comments === null ? true : false);
57+
58+
$model->response = [
59+
"comments" => $comments,
60+
"error" => $error,
61+
"parent_id" => $p_id,
62+
"parent_type" => $p_type,
63+
];
64+
65+
return ($error ? 400 : 200);
66+
}
67+
68+
protected function handleOptions(Router &$router, APICommentModel &$model) {
69+
$router->setResponseHeader("Allow", "GET,OPTIONS,PUT");
70+
$model->response = ["error" => false,
71+
"allow" => ["GET","OPTIONS","PUT"]];
72+
return 200;
73+
}
74+
75+
protected function handlePut(Router &$router, APICommentModel &$model) {
76+
return 403;
77+
}
78+
79+
protected function handleUnknown(Router &$router, APICommentModel &$model) {
80+
$router->setResponseHeader("Allow", "GET,OPTIONS,PUT");
81+
$model->response = ["error" => "Method Not Allowed",
82+
"allow" => ["GET","OPTIONS","PUT"]];
83+
return 405;
84+
}
85+
86+
}

src/libraries/Comment.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
use \DateTime;
1414
use \DateTimeZone;
1515
use \InvalidArgumentException;
16+
use \JsonSerializable;
1617
use \PDO;
1718
use \PDOException;
1819
use \StdClass;
1920

20-
class Comment {
21+
class Comment implements JsonSerializable {
2122

2223
const PARENT_TYPE_DOCUMENT = 0;
2324
const PARENT_TYPE_COMMENT = 1;
@@ -173,6 +174,31 @@ public function getUserId() {
173174
return $this->user_id;
174175
}
175176

177+
public function jsonSerialize() {
178+
$created_datetime = $this->getCreatedDateTime();
179+
if (!is_null($created_datetime)) $created_datetime = [
180+
"iso" => $created_datetime->format("r"),
181+
"unix" => $created_datetime->getTimestamp(),
182+
];
183+
184+
$edited_datetime = $this->getEditedDateTime();
185+
if (!is_null($edited_datetime)) $edited_datetime = [
186+
"iso" => $edited_datetime->format("r"),
187+
"unix" => $edited_datetime->getTimestamp(),
188+
];
189+
190+
return [
191+
"content" => $this->getContent(true),
192+
"created_datetime" => $created_datetime,
193+
"edited_count" => $this->getEditedCount(),
194+
"edited_datetime" => $edited_datetime,
195+
"id" => $this->getId(),
196+
"parent_id" => $this->getParentId(),
197+
"parent_type" => $this->getParentType(),
198+
"user" => $this->getUser(),
199+
];
200+
}
201+
176202
protected static function normalize(StdClass &$data) {
177203
$data->content = (string) $data->content;
178204
$data->created_datetime = (string) $data->created_datetime;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace BNETDocs\Libraries\Exceptions;
4+
5+
use \BNETDocs\Libraries\Exceptions\BNETDocsException;
6+
use \BNETDocs\Libraries\Logger;
7+
use \Exception;
8+
9+
class CommentNotFoundException extends BNETDocsException {
10+
11+
public function __construct($query, Exception &$prev_ex = null) {
12+
parent::__construct("Comment not found", 21, $prev_ex);
13+
Logger::logMetric("query", $query);
14+
}
15+
16+
}

src/libraries/Exceptions/Reference.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,4 @@ All of the following errors are subclassed from the `BNETDocsException` class.
2525
| 18 | `PacketTransportLayerNotFoundException` | Packet transport layer not found |
2626
| 19 | `PacketDirectionInvalidException` | Packet direction is invalid |
2727
| 20 | `ProductNotFoundException` | Product not found |
28+
| 21 | `CommentNotFoundException` | Comment not found |

src/libraries/Router.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace BNETDocs\Libraries;
44

5+
use \BNETDocs\Controllers\API\Comment as APICommentController;
56
use \BNETDocs\Controllers\Credits as CreditsController;
67
use \BNETDocs\Controllers\Document\Index as DocumentIndexController;
78
use \BNETDocs\Controllers\Document\Popular as DocumentPopularController;
@@ -253,6 +254,17 @@ public function route(Pair &$redirect = null) {
253254
}
254255
$controller = new RedirectController($url, $code);
255256
break;
257+
case "api":
258+
switch ($subpath) {
259+
case "comment":
260+
$controller = new APICommentController();
261+
break;
262+
default:
263+
throw new ControllerNotFoundException(
264+
$path . "/" . $subpath
265+
);
266+
}
267+
break;
256268
case "credits": case "credits.htm": case "credits.html":
257269
$controller = new CreditsController();
258270
break;

src/libraries/User.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,12 @@
1212
use \DateTime;
1313
use \DateTimeZone;
1414
use \InvalidArgumentException;
15+
use \JsonSerializable;
1516
use \PDO;
1617
use \PDOException;
1718
use \StdClass;
1819

19-
class User {
20+
class User implements JsonSerializable {
2021

2122
const OPTION_ACL_DOCUMENT_CREATE = 0x00000001;
2223
const OPTION_ACL_DOCUMENT_MODIFY = 0x00000002;
@@ -304,6 +305,27 @@ public function isStaff() {
304305
));
305306
}
306307

308+
public function jsonSerialize() {
309+
$created_datetime = $this->getCreatedDateTime();
310+
if (!is_null($created_datetime)) $created_datetime = [
311+
"iso" => $created_datetime->format("r"),
312+
"unix" => $created_datetime->getTimestamp(),
313+
];
314+
315+
$verified_datetime = $this->getVerifiedDateTime();
316+
if (!is_null($verified_datetime)) $verified_datetime = [
317+
"iso" => $verified_datetime->format("r"),
318+
"unix" => $verified_datetime->getTimestamp(),
319+
];
320+
321+
return [
322+
"created_datetime" => $created_datetime,
323+
"id" => $this->getId(),
324+
"name" => $this->getName(),
325+
"verified_datetime" => $verified_datetime,
326+
];
327+
}
328+
307329
protected static function normalize(StdClass &$data) {
308330
$data->created_datetime = (string) $data->created_datetime;
309331
$data->email = (string) $data->email;

src/models/API/Comment.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace BNETDocs\Models\API;
4+
5+
use \BNETDocs\Libraries\Model;
6+
7+
class Comment extends Model {
8+
9+
public $response;
10+
public $user_session;
11+
12+
public function __construct() {
13+
parent::__construct();
14+
$this->response = null;
15+
$this->user_session = null;
16+
}
17+
18+
}

src/templates/News/View.phtml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ if ($object) {
4949

5050
$this->additional_css[] = "/a/news.css";
5151
$this->additional_css[] = "/a/comments.css";
52+
if ($logged_in) $this->additional_css[] = "/a/forms.css";
5253
require("./header.inc.phtml");
5354
?>
5455
<article>
@@ -91,6 +92,15 @@ require("./header.inc.phtml");
9192
</tbody></table>
9293
<?php } ?>
9394
</section>
95+
<?php if ($logged_in) { ?>
96+
<section>
97+
<form method="POST" action="?">
98+
<p class="center"><label for="comment-content">Comment on this post:</label></p>
99+
<p class="center"><textarea id="comment-content" name="comment-content" cols="80" rows="5"></textarea></p>
100+
<p class="center"><input type="submit" value="Comment"/></p>
101+
</form>
102+
</section>
103+
<?php } ?>
94104
<?php } else { ?>
95105
<header class="red"><?php echo htmlspecialchars($title, ENT_HTML5, "UTF-8"); ?></header>
96106
<section class="red"><?php echo htmlspecialchars($description, ENT_HTML5, "UTF-8"); ?></section>

src/views/API/CommentJSON.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace BNETDocs\Views\API;
4+
5+
use \BNETDocs\Libraries\Common;
6+
use \BNETDocs\Libraries\Exceptions\IncorrectModelException;
7+
use \BNETDocs\Libraries\Model;
8+
use \BNETDocs\Libraries\View;
9+
use \BNETDocs\Models\API\Comment as CommentModel;
10+
use \ReflectionExtension;
11+
12+
class CommentJSON extends View {
13+
14+
public function getMimeType() {
15+
return "application/json;charset=utf-8";
16+
}
17+
18+
public function render(Model &$model) {
19+
if (!$model instanceof CommentModel) {
20+
throw new IncorrectModelException();
21+
}
22+
echo json_encode($model->response, Common::prettyJSONIfBrowser());
23+
}
24+
25+
}

src/views/ServersJSON.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function render(Model &$model) {
4949
"status_bitmask" => $server->getStatusBitmask(),
5050
"type_id" => $server->getTypeId(),
5151
"updated_datetime" => $updated_datetime,
52-
"user_id" => $server->getUserId()
52+
"user" => $server->getUser()
5353
];
5454
}
5555

0 commit comments

Comments
 (0)