aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/Model/Note.php
diff options
context:
space:
mode:
Diffstat (limited to 'Digitigrade/Model/Note.php')
-rw-r--r--Digitigrade/Model/Note.php36
1 files changed, 34 insertions, 2 deletions
diff --git a/Digitigrade/Model/Note.php b/Digitigrade/Model/Note.php
index a4df99d..d5d4e69 100644
--- a/Digitigrade/Model/Note.php
+++ b/Digitigrade/Model/Note.php
@@ -2,6 +2,8 @@
namespace Digitigrade\Model;
use Digitigrade\Db;
+use Digitigrade\FormattingProvider\CommonMark;
+use Digitigrade\FormattingProvider\SanitisedHtml;
use Digitigrade\Model\HomeTimelineItem;
use Digitigrade\Notification\Notifyable;
use Digitigrade\Timeline\TimelineIncludeable;
@@ -91,6 +93,7 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
$this->saveMentions();
$this->saveAttachments();
$this->saveExtensions();
+ $this->saveFormattedContents();
}
protected function validate(): bool {
@@ -102,7 +105,11 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
$pdo = Db::getInstance()->getPdo();
$stmt = $pdo->prepare('SELECT mimetype, body FROM note_formatted_content WHERE note_id = ?');
$stmt->execute([$this->id]);
- return $stmt->fetchAll(\PDO::FETCH_ASSOC);
+ $rows = $stmt->fetchAll();
+ return array_combine(
+ array_map(fn($row) => $row['mimetype'], $rows),
+ array_map(fn($row) => $row['body'], $rows)
+ );
}
private function findMentions(): array {
@@ -126,6 +133,17 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
return $items;
}
+ private function saveFormattedContents() {
+ $pdo = Db::getInstance()->getPdo();
+ foreach ($this->formattedContent as $mimetype => $body) {
+ $stmt = $pdo->prepare(
+ 'INSERT INTO note_formatted_content(note_id, mimetype, body) VALUES (?, ?, ?)' .
+ 'ON CONFLICT (note_id, mimetype) DO UPDATE SET body = EXCLUDED.body'
+ );
+ $stmt->execute([$this->id, $mimetype, $body]);
+ }
+ }
+
private function saveMentions() {
$pdo = Db::getInstance()->getPdo();
foreach ($this->mentions as $mention) {
@@ -230,7 +248,21 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
* @return ?string the marked up content
*/
public function getFormattedContent(string $mimetype): ?string {
- return array_filter($this->formattedContent, fn($item) => $item['mimetype'] == $mimetype)[0]['body'] ?? null;
+ return $this->formattedContent[$mimetype] ?? null;
+ }
+
+ /**
+ * Gets the best available formatted content (or plain if there aren't any)
+ * and converts it to sanitised HTML
+ * @return string HTML that is hopefully safe to include directly
+ */
+ public function getBestContentAsHtml(): string {
+ if (isset($this->formattedContent['text/html'])) {
+ return SanitisedHtml::getInstance()->renderToHtml($this->formattedContent['text/html']);
+ } elseif (isset($this->formattedContent['text/markdown'])) {
+ return CommonMark::getInstance()->renderToHtml($this->formattedContent['text/markdown']);
+ }
+ return htmlspecialchars($this->plainContent);
}
public function renderAsHtml() {