aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/Model
diff options
context:
space:
mode:
authorwinter2025-01-28 16:59:43 +0000
committerwinter2025-01-28 16:59:43 +0000
commit09a42d23cd067dc5c2a7d4f03e8f074a9317f6c8 (patch)
treec01ea939a0c72c2a4ed5b6479d7739f3dbaaf01f /Digitigrade/Model
parent4c66a437d3125ef1a03bac96b80c82e9da060a81 (diff)
implement extensions on existing objects
Diffstat (limited to 'Digitigrade/Model')
-rw-r--r--Digitigrade/Model/Actor.php36
-rw-r--r--Digitigrade/Model/FetchableModel.php2
-rw-r--r--Digitigrade/Model/Interaction.php31
-rw-r--r--Digitigrade/Model/Note.php24
4 files changed, 88 insertions, 5 deletions
diff --git a/Digitigrade/Model/Actor.php b/Digitigrade/Model/Actor.php
index 62d1b39..2b9a867 100644
--- a/Digitigrade/Model/Actor.php
+++ b/Digitigrade/Model/Actor.php
@@ -1,6 +1,7 @@
<?php
namespace Digitigrade\Model;
+use Digitigrade\Db;
use Digitigrade\Notification\PendingFollowActionedNotif;
use Digitigrade\Notification\UnblockNotif;
use Digitigrade\Notification\UnfollowNotif;
@@ -76,6 +77,37 @@ class Actor extends PushableModel implements RpcReceiver {
return null;
}
+ protected function hydrate() {
+ $this->endpoints = ActorEndpoints::findWhere('actor_id = ?', [$this->id]);
+ $this->extensions = $this->findExtensions();
+ }
+
+ protected function dehydrate() {
+ $this->saveExtensions();
+ }
+
+ private function findExtensions() {
+ $pdo = Db::getInstance()->getPdo();
+ $stmt = $pdo->prepare('SELECT uri, data FROM actor_extension WHERE actor_id = ?');
+ $stmt->execute([$this->id]);
+ $items = [];
+ while ($row = $stmt->fetch()) {
+ $items[$row['uri']] = json_decode($row['data']);
+ }
+ return $items;
+ }
+
+ private function saveExtensions() {
+ $pdo = Db::getInstance()->getPdo();
+ foreach ($this->extensions as $uri => $obj) {
+ $stmt = $pdo->prepare(
+ 'INSERT INTO actor_extension(actor_id, uri, data) VALUES (?, ?, ?) ' .
+ 'ON CONFLICT (actor_id, uri) DO UPDATE SET data = EXCLUDED.data'
+ );
+ $stmt->execute([$this->id, $uri, json_encode($obj)]);
+ }
+ }
+
public static function findLocalByHandle(string $handle): ?self {
return self::findWhere('is_local = true AND handle = ?', [$handle]);
}
@@ -323,8 +355,4 @@ class Actor extends PushableModel implements RpcReceiver {
]
];
}
-
- public function hydrate() {
- $this->endpoints = ActorEndpoints::findWhere('actor_id = ?', [$this->id]);
- }
}
diff --git a/Digitigrade/Model/FetchableModel.php b/Digitigrade/Model/FetchableModel.php
index e14cc2e..6d21f40 100644
--- a/Digitigrade/Model/FetchableModel.php
+++ b/Digitigrade/Model/FetchableModel.php
@@ -38,7 +38,7 @@ abstract class FetchableModel extends Model implements RemoteFetchable {
if (!($reflType instanceof \ReflectionNamedType))
continue;
$type = $reflType->getName();
- if (is_subclass_of($type, FetchableModel::class) && is_string($data->{$propName})) {
+ if (is_subclass_of($type, FetchableModel::class) && isset($data->{$propName}) && is_string($data->{$propName})) {
// try to avoid recursion
// TODO: make a better effort at avoiding recursion (e.g. when it's more than one step nested)
if ($data->{$propName} == $uri) {
diff --git a/Digitigrade/Model/Interaction.php b/Digitigrade/Model/Interaction.php
index 902dbc0..e651f45 100644
--- a/Digitigrade/Model/Interaction.php
+++ b/Digitigrade/Model/Interaction.php
@@ -1,6 +1,7 @@
<?php
namespace Digitigrade\Model;
+use Digitigrade\Db;
use Digitigrade\Model\HomeTimelineItem;
use Digitigrade\Notification\Notifyable;
use Digitigrade\Timeline\ReasonReshared;
@@ -44,6 +45,36 @@ class Interaction extends PushableModel implements Notifyable {
return hostname_from_uri($this->author->uri) == hostname_from_uri($this->uri);
}
+ protected function hydrate() {
+ $this->extensions = $this->findExtensions();
+ }
+
+ protected function dehydrate() {
+ $this->saveExtensions();
+ }
+
+ private function findExtensions() {
+ $pdo = Db::getInstance()->getPdo();
+ $stmt = $pdo->prepare('SELECT uri, data FROM interaction_extension WHERE interaction_id = ?');
+ $stmt->execute([$this->id]);
+ $items = [];
+ while ($row = $stmt->fetch()) {
+ $items[$row['uri']] = json_decode($row['data']);
+ }
+ return $items;
+ }
+
+ private function saveExtensions() {
+ $pdo = Db::getInstance()->getPdo();
+ foreach ($this->extensions as $uri => $obj) {
+ $stmt = $pdo->prepare(
+ 'INSERT INTO interaction_extension(interaction_id, uri, data) VALUES (?, ?, ?) ' .
+ 'ON CONFLICT (interaction_id, uri) DO UPDATE SET data = EXCLUDED.data'
+ );
+ $stmt->execute([$this->id, $uri, json_encode($obj)]);
+ }
+ }
+
public static function findAllWithAuthor(Actor $author): array {
return self::findAllWhere('author = ?', [$author->id]);
}
diff --git a/Digitigrade/Model/Note.php b/Digitigrade/Model/Note.php
index 01bc861..0164e7d 100644
--- a/Digitigrade/Model/Note.php
+++ b/Digitigrade/Model/Note.php
@@ -81,10 +81,12 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
$this->formattedContent = $this->findFormattedContents();
$this->mentions = $this->findMentions();
$this->attachments = NoteAttachment::findAllWhere('note_id = ?', [$this->id]);
+ $this->extensions = $this->findExtensions();
}
protected function dehydrate() {
$this->saveMentions();
+ $this->saveExtensions();
}
protected function validate(): bool {
@@ -109,6 +111,17 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
return $actors;
}
+ private function findExtensions(): array {
+ $pdo = Db::getInstance()->getPdo();
+ $stmt = $pdo->prepare('SELECT uri, data FROM note_extension WHERE note_id = ?');
+ $stmt->execute([$this->id]);
+ $items = [];
+ while ($row = $stmt->fetch()) {
+ $items[$row['uri']] = json_decode($row['data']);
+ }
+ return $items;
+ }
+
private function saveMentions() {
$pdo = Db::getInstance()->getPdo();
foreach ($this->mentions as $mention) {
@@ -117,6 +130,17 @@ class Note extends PushableModel implements TimelineIncludeable, Notifyable {
}
}
+ private function saveExtensions() {
+ $pdo = Db::getInstance()->getPdo();
+ foreach ($this->extensions as $uri => $obj) {
+ $stmt = $pdo->prepare(
+ 'INSERT INTO note_extension(note_id, uri, data) VALUES (?, ?, ?) ' .
+ 'ON CONFLICT (note_id, uri) DO UPDATE SET data = EXCLUDED.data'
+ );
+ $stmt->execute([$this->id, $uri, json_encode($obj)]);
+ }
+ }
+
public static function findAllWithAuthor(Actor $author, ?int $limit = null, int $offset = 0, bool $includeDeleted = false): array {
$where = 'author = ?';
if (!$includeDeleted) {