diff options
Diffstat (limited to 'Digitigrade/Model')
| -rw-r--r-- | Digitigrade/Model/Actor.php | 38 | ||||
| -rw-r--r-- | Digitigrade/Model/BlockRelation.php | 82 | ||||
| -rw-r--r-- | Digitigrade/Model/FollowRelation.php | 2 | ||||
| -rw-r--r-- | Digitigrade/Model/Notification.php | 2 |
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)); } |
