aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/Model
diff options
context:
space:
mode:
Diffstat (limited to 'Digitigrade/Model')
-rw-r--r--Digitigrade/Model/Actor.php38
-rw-r--r--Digitigrade/Model/BlockRelation.php82
-rw-r--r--Digitigrade/Model/FollowRelation.php2
-rw-r--r--Digitigrade/Model/Notification.php2
4 files changed, 122 insertions, 2 deletions
diff --git a/Digitigrade/Model/Actor.php b/Digitigrade/Model/Actor.php
index b4e9392..f2eecae 100644
--- a/Digitigrade/Model/Actor.php
+++ b/Digitigrade/Model/Actor.php
@@ -2,6 +2,7 @@
namespace Digitigrade\Model;
use Digitigrade\Notification\PendingFollowActionedNotif;
+use Digitigrade\Notification\UnblockNotif;
use Digitigrade\Notification\UnfollowNotif;
use Digitigrade\RpcException;
use Digitigrade\RpcReceiver;
@@ -142,6 +143,16 @@ class Actor extends PushableModel implements RpcReceiver {
(new PendingFollowActionedNotif($args[0], $this, 'reject'))->processNotifications();
return;
+ case 'block':
+ $rel = BlockRelation::create($args[0], $this);
+ $rel->processNotifications();
+ return;
+
+ case 'unblock':
+ BlockRelation::findByActors($args[0], $this)->remove();
+ (new UnblockNotif($args[0], $this))->processNotifications();
+ return;
+
default:
throw new \RuntimeException("behaviour for actor rpc method $method not (yet?) implemented");
}
@@ -233,6 +244,31 @@ class Actor extends PushableModel implements RpcReceiver {
return array_intersect($followers, $followees);
}
+ /**
+ * Blocks another actor.
+ * @param Actor $target the actor to block
+ */
+ public function block(self $target) {
+ $target->rpcCall('block', [$this]);
+ }
+
+ /**
+ * Unblocks another actor.
+ * @param Actor $target the actor to unblock
+ */
+ public function unblock(self $target) {
+ $target->rpcCall('unblock', [$this]);
+ }
+
+ /**
+ * @param Actor $target the other actor
+ * @return boolean whether this actor blocks the target actor
+ */
+ public function blocks(Actor $target): bool {
+ $relation = BlockRelation::findByActors($this, $target);
+ return $relation != null;
+ }
+
public function findHomeInstance(): Instance {
if ($this->isLocal) {
// can't do this because we don't keep track of ourself in the instance table
@@ -282,6 +318,8 @@ class Actor extends PushableModel implements RpcReceiver {
'unfollow' => path_to_uri("/actor/$this->id/unfollow"),
'acceptedFollow' => path_to_uri("/actor/$this->id/acceptedFollow"),
'rejectedFollow' => path_to_uri("/actor/$this->id/rejectedFollow"),
+ 'block' => path_to_uri("/actor/$this->id/block"),
+ 'unblock' => path_to_uri("/actor/$this->id/unblock"),
]
];
}
diff --git a/Digitigrade/Model/BlockRelation.php b/Digitigrade/Model/BlockRelation.php
new file mode 100644
index 0000000..ca7166c
--- /dev/null
+++ b/Digitigrade/Model/BlockRelation.php
@@ -0,0 +1,82 @@
+<?php
+namespace Digitigrade\Model;
+
+use Digitigrade\Model;
+use Digitigrade\Notification\Notifyable;
+
+class BlockRelation extends Model implements Notifyable {
+ public Actor $subject;
+ public Actor $object;
+
+ /**
+ * Creates and saves a new blocking relationship
+ * @param Actor $subject the actor who doesn't want to see the other one
+ * @param Actor $object the actor being blocked
+ * @return self
+ */
+ public static function create(Actor $subject, Actor $object): self {
+ $rel = new self();
+ $rel->subject = $subject;
+ $rel->object = $object;
+ $rel->save();
+ return $rel;
+ }
+
+ protected function getUpdateWhereClause(\PDO $db): ?string {
+ if (self::findWhere('subject = ? and object = ?', [$this->subject->id, $this->object->id]) != null) {
+ return 'subject = ' . $this->subject->id . ' and object = ' . $this->object->id;
+ }
+ return null;
+ }
+
+ public static function findByActors(Actor $subject, Actor $object): ?self {
+ return self::findWhere('subject = ? and object = ?', [$subject->id, $object->id]);
+ }
+
+ /**
+ * @return self[]
+ */
+ public static function findAllWithSubject(Actor $subject): array {
+ return self::findAllWhere('subject = ?', [$subject->id]);
+ }
+
+ /**
+ * @return self[]
+ */
+ public static function findAllWithObject(Actor $object): array {
+ return self::findAllWhere('object = ?', [$object->id]);
+ }
+
+ public function toJsonReference(): mixed {
+ return [$this->subject->id, $this->object->id];
+ }
+
+ public static function fromJsonReference(mixed $reference): ?self {
+ return self::findByActors(
+ Actor::find($reference[0]),
+ Actor::find($reference[1])
+ );
+ }
+
+ public function getNotificationTitle(): string {
+ return sprintf(__("notifications.block"), $this->subject->displayName);
+ }
+ public function getNotificationTitleLink(): ?string {
+ return '/@/' . $this->subject->getFullHandle();
+ }
+ public function getNotificationImageUrl(): ?string {
+ return $this->subject->avatar ?? '/static/default-avatar.png';
+ }
+ public function getNotificationImageLink(): ?string {
+ return $this->getNotificationTitleLink();
+ }
+ public function getNotificationBody(): ?string {
+ return null;
+ }
+
+ public function processNotifications() {
+ if (!$this->object->isLocal)
+ return;
+ Notification::fromNotifyable($this, UserAccount::findByLinkedActor($this->object))->send();
+ }
+} \ No newline at end of file
diff --git a/Digitigrade/Model/FollowRelation.php b/Digitigrade/Model/FollowRelation.php
index 7cab761..ecb625a 100644
--- a/Digitigrade/Model/FollowRelation.php
+++ b/Digitigrade/Model/FollowRelation.php
@@ -54,7 +54,7 @@ class FollowRelation extends Model implements Notifyable {
return [$this->subject->id, $this->object->id];
}
- public static function fromJsonReference(mixed $reference): self {
+ public static function fromJsonReference(mixed $reference): ?self {
return self::findByActors(
Actor::find($reference[0]),
Actor::find($reference[1])
diff --git a/Digitigrade/Model/Notification.php b/Digitigrade/Model/Notification.php
index ee9d64a..50e9991 100644
--- a/Digitigrade/Model/Notification.php
+++ b/Digitigrade/Model/Notification.php
@@ -28,7 +28,7 @@ class Notification extends Model {
return $notif;
}
- public function toNotifyable(): Notifyable {
+ public function toNotifyable(): ?Notifyable {
return $this->itemType::fromJsonReference(json_decode($this->itemData));
}