Skip to content

Commit 6330e18

Browse files
committed
Initial commit of packet editor (NOT WORKING YET)
1 parent c18a9f2 commit 6330e18

File tree

4 files changed

+296
-0
lines changed

4 files changed

+296
-0
lines changed

src/controllers/Packet/Edit.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
namespace BNETDocs\Controllers\Packet;
4+
5+
use \BNETDocs\Libraries\CSRF;
6+
use \BNETDocs\Libraries\Exceptions\PacketNotFoundException;
7+
use \BNETDocs\Libraries\Logger;
8+
use \BNETDocs\Libraries\Packet;
9+
use \BNETDocs\Libraries\User;
10+
use \BNETDocs\Models\Packet\Edit as PacketEditModel;
11+
use \CarlBennett\MVC\Libraries\Common;
12+
use \CarlBennett\MVC\Libraries\Controller;
13+
use \CarlBennett\MVC\Libraries\DatabaseDriver;
14+
use \CarlBennett\MVC\Libraries\Router;
15+
use \CarlBennett\MVC\Libraries\View;
16+
use \DateTime;
17+
use \DateTimeZone;
18+
use \InvalidArgumentException;
19+
20+
class Edit extends Controller {
21+
22+
public function &run(Router &$router, View &$view, array &$args) {
23+
24+
$data = $router->getRequestQueryArray();
25+
$model = new PacketEditModel();
26+
$model->content = null;
27+
$model->csrf_id = mt_rand();
28+
$model->csrf_token = CSRF::generate($model->csrf_id, 900); // 15 mins
29+
$model->packet = null;
30+
$model->packet_id = (isset($data["id"]) ? $data["id"] : null);
31+
$model->error = null;
32+
$model->markdown = null;
33+
$model->published = null;
34+
$model->title = null;
35+
$model->user = (
36+
isset($_SESSION['user_id']) ? new User($_SESSION['user_id']) : null
37+
);
38+
39+
$model->acl_allowed = ($model->user && $model->user->getAcl(
40+
User::OPTION_ACL_PACKET_MODIFY
41+
));
42+
43+
try { $model->packet = new Packet($model->packet_id); }
44+
catch (PacketNotFoundException $e) { $model->packet = null; }
45+
catch (InvalidArgumentException $e) { $model->packet = null; }
46+
47+
if ($model->packet === null) {
48+
$model->error = "NOT_FOUND";
49+
} else {
50+
$flags = $model->packet->getOptionsBitmask();
51+
52+
$model->content = $model->packet->getContent(false);
53+
$model->markdown = ($flags & Packet::OPTION_MARKDOWN);
54+
$model->published = ($flags & Packet::OPTION_PUBLISHED);
55+
$model->title = $model->packet->getTitle();
56+
57+
if ($router->getRequestMethod() == "POST") {
58+
$this->handlePost($router, $model);
59+
}
60+
}
61+
62+
$view->render($model);
63+
64+
$model->_responseCode = ($model->acl_allowed ? 200 : 403);
65+
$model->_responseHeaders["Content-Type"] = $view->getMimeType();
66+
$model->_responseTTL = 0;
67+
68+
return $model;
69+
70+
}
71+
72+
protected function handlePost(Router &$router, PacketEditModel &$model) {
73+
if (!$model->acl_allowed) {
74+
$model->error = "ACL_NOT_SET";
75+
return;
76+
}
77+
if (!isset(Common::$database)) {
78+
Common::$database = DatabaseDriver::getDatabaseObject();
79+
}
80+
81+
$data = $router->getRequestBodyArray();
82+
$csrf_id = (isset($data["csrf_id" ]) ? $data["csrf_id" ] : null);
83+
$csrf_token = (isset($data["csrf_token"]) ? $data["csrf_token"] : null);
84+
$csrf_valid = CSRF::validate($csrf_id, $csrf_token);
85+
$category = (isset($data["category" ]) ? $data["category" ] : null);
86+
$title = (isset($data["title" ]) ? $data["title" ] : null);
87+
$markdown = (isset($data["markdown" ]) ? $data["markdown" ] : null);
88+
$content = (isset($data["content" ]) ? $data["content" ] : null);
89+
$publish = (isset($data["publish" ]) ? $data["publish" ] : null);
90+
$save = (isset($data["save" ]) ? $data["save" ] : null);
91+
92+
$model->category = $category;
93+
$model->title = $title;
94+
$model->markdown = $markdown;
95+
$model->content = $content;
96+
97+
if (!$csrf_valid) {
98+
$model->error = "INVALID_CSRF";
99+
return;
100+
}
101+
CSRF::invalidate($csrf_id);
102+
103+
if (empty($title)) {
104+
$model->error = "EMPTY_TITLE";
105+
} else if (empty($content)) {
106+
$model->error = "EMPTY_CONTENT";
107+
}
108+
109+
$user_id = $model->user->getId();
110+
111+
try {
112+
113+
$model->packet->setTitle($model->title);
114+
$model->packet->setMarkdown($model->markdown);
115+
$model->packet->setContent($model->content);
116+
$model->packet->setPublished($publish);
117+
118+
$model->packet->setEditedCount(
119+
$model->packet->getEditedCount() + 1
120+
);
121+
$model->packet->setEditedDateTime(
122+
new DateTime("now", new DateTimeZone("UTC"))
123+
);
124+
125+
$success = $model->packet->save();
126+
127+
} catch (QueryException $e) {
128+
129+
// SQL error occurred. We can show a friendly message to the user while
130+
// also notifying this problem to staff.
131+
Logger::logException($e);
132+
133+
$success = false;
134+
135+
}
136+
137+
if (!$success) {
138+
$model->error = "INTERNAL_ERROR";
139+
} else {
140+
$model->error = false;
141+
}
142+
143+
Logger::logEvent(
144+
"packet_edited",
145+
$user_id,
146+
getenv("REMOTE_ADDR"),
147+
json_encode([
148+
"error" => $model->error,
149+
"packet_id" => $model->packet_id,
150+
"options_bitmask" => $model->packet->getOptionsBitmask(),
151+
"title" => $model->packet->getTitle(),
152+
"content" => $model->packet->getContent(false),
153+
])
154+
);
155+
}
156+
157+
}

src/models/Packet/Edit.php

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

src/templates/Packet/Edit.phtml

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace BNETDocs\Templates\Packet;
4+
5+
use \CarlBennett\MVC\Libraries\Common;
6+
use \CarlBennett\MVC\Libraries\Pair;
7+
8+
$title = "Edit Packet";
9+
$description = "This form allows an individual to edit a packet.";
10+
11+
$this->opengraph->attach(new Pair("url", "/packet/edit"));
12+
$this->opengraph->attach(new Pair("type", "article"));
13+
14+
switch ($this->getContext()->error) {
15+
case "ACL_NOT_SET":
16+
$message = "You do not have the privilege to edit packets.";
17+
break;
18+
case "NOT_FOUND":
19+
$message = "Cannot find packet by that id.";
20+
break;
21+
case "INVALID_CSRF":
22+
$message = "The Cross-Site Request Forgery token was invalid. Either the"
23+
. "edit packet form expired, or this may have been a malicious attempt"
24+
. "to create a packet.";
25+
break;
26+
case "EMPTY_TITLE":
27+
$message = "The title of the packet is required.";
28+
break;
29+
case "EMPTY_CONTENT":
30+
$message = "The content of the packet is required.";
31+
break;
32+
case "INTERNAL_ERROR":
33+
$message = "An internal error occurred while processing your request. "
34+
. "Our staff has been notified of the issue. Try again later.";
35+
break;
36+
default:
37+
$message = $this->getContext()->error;
38+
}
39+
40+
$this->additional_css[] = "/a/forms.css";
41+
require("./header.inc.phtml");
42+
?>
43+
<article>
44+
<?php if ($this->getContext()->error !== false) { ?>
45+
<header>Edit Packet</header>
46+
<?php if (!empty($message)) { ?>
47+
<section class="red"><p><?php echo $message; ?></p></section>
48+
<?php } ?>
49+
<?php if ($this->getContext()->error != "NOT_FOUND") { ?>
50+
<form method="POST" action="?id=<?php echo
51+
htmlspecialchars($this->getContext()->packet_id, ENT_HTML5, "UTF-8"); ?>">
52+
<input type="hidden" name="csrf_id" value="<?php echo
53+
htmlspecialchars($this->getContext()->csrf_id, ENT_HTML5, "UTF-8");
54+
?>"/>
55+
<input type="hidden" name="csrf_token" value="<?php echo
56+
htmlspecialchars($this->getContext()->csrf_token, ENT_HTML5, "UTF-8");
57+
?>"/>
58+
<section>
59+
<label for="title">Title:</label><br/>
60+
<input type="text" name="title" id="title" tabindex="1" required
61+
autofocus="autofocus" value="<?php echo
62+
filter_var($this->getContext()->title, FILTER_SANITIZE_STRING);
63+
?>"/>
64+
</section>
65+
<section>
66+
<label for="content">Content:</label>
67+
<span style="float:right;">
68+
<label for="markdown" title="Use markdown or use raw HTML">Markdown</label>
69+
<input type="checkbox" name="markdown" id="markdown" tabindex="3"
70+
title="Use markdown or use raw HTML" value="1"<?php
71+
if ($this->getContext()->markdown)
72+
echo " checked=\"checked\"";
73+
?>/>
74+
</span>
75+
<textarea name="content" id="content" tabindex="2" required
76+
style="height:200px;"><?php echo
77+
htmlspecialchars($this->getContext()->content, ENT_HTML5, "UTF-8");
78+
?></textarea>
79+
</section>
80+
<section>
81+
<input type="submit" name="publish" value="Publish" tabindex="4"/>
82+
<input type="submit" name="save" value="Unpublish" tabindex="5"/>
83+
</section>
84+
</form>
85+
<?php } ?>
86+
<?php } else { ?>
87+
<header class="green">Edit Packet</header>
88+
<section class="green">
89+
<p>Your packet has been edited.</p>
90+
<p>Use the navigation to the left to move to another page.</p>
91+
</section>
92+
<?php } ?>
93+
</article>
94+
<?php require("./footer.inc.phtml"); ?>

src/views/Packet/EditHtml.php

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

0 commit comments

Comments
 (0)