diff --git a/app/Database/Migrations/2022-07-28-143030_add_activities_trigger_after_insert.php b/app/Database/Migrations/2022-07-28-143030_add_activities_trigger_after_insert.php deleted file mode 100644 index 1325c1b0..00000000 --- a/app/Database/Migrations/2022-07-28-143030_add_activities_trigger_after_insert.php +++ /dev/null @@ -1,50 +0,0 @@ -db->prefixTable(config('Fediverse')->tablesPrefix . 'activities'); - $notificationsTable = $this->db->prefixTable('notifications'); - $createQuery = <<db->query($createQuery); - } - - public function down(): void - { - $activitiesTable = $this->db->prefixTable(config('Fediverse')->tablesPrefix . 'activities'); - $this->db->query("DROP TRIGGER IF EXISTS `{$activitiesTable}_after_insert`"); - } -} diff --git a/app/Database/Migrations/2022-08-14-141726_add_activities_trigger_after_update.php b/app/Database/Migrations/2022-08-14-141726_add_activities_trigger_after_update.php deleted file mode 100644 index 882566f4..00000000 --- a/app/Database/Migrations/2022-08-14-141726_add_activities_trigger_after_update.php +++ /dev/null @@ -1,59 +0,0 @@ -db->prefixTable(config('Fediverse')->tablesPrefix . 'activities'); - $notificationsTable = $this->db->prefixTable('notifications'); - $createQuery = <<db->query($createQuery); - } - - public function down(): void - { - $activitiesTable = $this->db->prefixTable(config('Fediverse')->tablesPrefix . 'activities'); - $this->db->query("DROP TRIGGER IF EXISTS `{$activitiesTable}_after_update`"); - } -} diff --git a/modules/Admin/Controllers/NotificationController.php b/modules/Admin/Controllers/NotificationController.php index c3191c84..f4bc5558 100644 --- a/modules/Admin/Controllers/NotificationController.php +++ b/modules/Admin/Controllers/NotificationController.php @@ -10,13 +10,13 @@ declare(strict_types=1); namespace Modules\Admin\Controllers; -use App\Entities\Notification; use App\Entities\Podcast; -use App\Models\NotificationModel; use App\Models\PodcastModel; use CodeIgniter\Exceptions\PageNotFoundException; use CodeIgniter\HTTP\RedirectResponse; use CodeIgniter\I18n\Time; +use Modules\Fediverse\Entities\Notification; +use Modules\Fediverse\Models\NotificationModel; use Modules\Fediverse\Models\PostModel; class NotificationController extends BaseController diff --git a/modules/Admin/Language/en/Notifications.php b/modules/Admin/Language/en/Notifications.php index 1772ba76..2b139d51 100644 --- a/modules/Admin/Language/en/Notifications.php +++ b/modules/Admin/Language/en/Notifications.php @@ -13,7 +13,7 @@ return [ 'reply' => '{actor_username} replied to your post', 'favourite' => '{actor_username} favourited your post', 'reblog' => '{actor_username} shared your post', - 'follow' => '{actor_username} started following {target_actor_username}', + 'follow' => '{actor_username} started following you', 'no_notifications' => 'No notifications', 'mark_all_as_read' => 'Mark all as read', ]; diff --git a/modules/Auth/Entities/User.php b/modules/Auth/Entities/User.php index 5a7d9a6c..312bde68 100644 --- a/modules/Auth/Entities/User.php +++ b/modules/Auth/Entities/User.php @@ -11,9 +11,9 @@ declare(strict_types=1); namespace Modules\Auth\Entities; use App\Entities\Podcast; -use App\Models\NotificationModel; use App\Models\PodcastModel; use App\Models\UserModel; +use Modules\Fediverse\Models\NotificationModel; use Myth\Auth\Entities\User as MythAuthUser; use RuntimeException; diff --git a/app/Database/Migrations/2022-07-26-091451_add_notifications.php b/modules/Fediverse/Database/Migrations/2018-01-01-130000_add_notifications.php similarity index 93% rename from app/Database/Migrations/2022-07-26-091451_add_notifications.php rename to modules/Fediverse/Database/Migrations/2018-01-01-130000_add_notifications.php index cddfcdc9..7fa59da2 100644 --- a/app/Database/Migrations/2022-07-26-091451_add_notifications.php +++ b/modules/Fediverse/Database/Migrations/2018-01-01-130000_add_notifications.php @@ -65,11 +65,11 @@ class AddNotifications extends Migration $this->forge->addForeignKey('target_actor_id', $tablesPrefix . 'actors', 'id', '', 'CASCADE'); $this->forge->addForeignKey('post_id', $tablesPrefix . 'posts', 'id', '', 'CASCADE'); $this->forge->addForeignKey('activity_id', $tablesPrefix . 'activities', 'id', '', 'CASCADE'); - $this->forge->createTable('notifications'); + $this->forge->createTable($tablesPrefix . 'notifications'); } public function down(): void { - $this->forge->dropTable('notifications'); + $this->forge->dropTable(config('Fediverse')->tablesPrefix . 'notifications'); } } diff --git a/app/Entities/Notification.php b/modules/Fediverse/Entities/Notification.php similarity index 94% rename from app/Entities/Notification.php rename to modules/Fediverse/Entities/Notification.php index b878228f..cfd74184 100644 --- a/app/Entities/Notification.php +++ b/modules/Fediverse/Entities/Notification.php @@ -8,12 +8,9 @@ declare(strict_types=1); * @link https://castopod.org/ */ -namespace App\Entities; +namespace Modules\Fediverse\Entities; use Michalsn\Uuid\UuidEntity; -use Modules\Fediverse\Entities\Activity; -use Modules\Fediverse\Entities\Actor; -use Modules\Fediverse\Entities\Post; use Modules\Fediverse\Models\ActorModel; use Modules\Fediverse\Models\PostModel; use RuntimeException; diff --git a/modules/Fediverse/Models/ActivityModel.php b/modules/Fediverse/Models/ActivityModel.php index 31b9659e..dcb1f0ad 100644 --- a/modules/Fediverse/Models/ActivityModel.php +++ b/modules/Fediverse/Models/ActivityModel.php @@ -32,6 +32,16 @@ class ActivityModel extends BaseUuidModel */ protected $uuidFields = ['id', 'post_id']; + /** + * @var string[] + */ + protected $afterInsert = ['notify']; + + /** + * @var string[] + */ + protected $afterUpdate = ['notify']; + /** * @var string[] */ @@ -116,4 +126,71 @@ class ActivityModel extends BaseUuidModel ->orderBy('scheduled_at', 'ASC') ->findAll(); } + + /** + * @param array> $data + * @return array> + */ + protected function notify(array $data): array + { + $activity = (new self())->getActivityById(is_array($data['id']) ? $data['id'][0] : $data['id']); + + if (! $activity instanceof Activity) { + return $data; + } + + if ($activity->target_actor_id === $activity->actor_id) { + return $data; + } + + // notify only if incoming activity (with status set to NULL) is created + if ($activity->status !== null) { + return $data; + } + + if ($activity->type === 'Follow') { + (new NotificationModel())->insert([ + 'actor_id' => $activity->actor_id, + 'target_actor_id' => $activity->target_actor_id, + 'activity_id' => $activity->id, + 'type' => 'follow', + 'created_at' => $activity->created_at, + ]); + } elseif ($activity->type === 'Undo_Follow') { + (new NotificationModel())->builder() + ->delete([ + 'actor_id' => $activity->actor_id, + 'target_actor_id' => $activity->target_actor_id, + 'type' => 'follow', + ]); + } elseif (in_array($activity->type, ['Create', 'Like', 'Announce'], true) && $activity->post_id !== null) { + (new NotificationModel())->insert([ + 'actor_id' => $activity->actor_id, + 'target_actor_id' => $activity->target_actor_id, + 'post_id' => $activity->post_id, + 'activity_id' => $activity->id, + 'type' => match ($activity->type) { + 'Create' => 'reply', + 'Like' => 'like', + 'Announce' => 'share', + }, + 'created_at' => $activity->created_at, + ]); + } elseif (in_array($activity->type, ['Undo_Like', 'Undo_Announce'], true) && $activity->post_id !== null) { + (new NotificationModel())->builder() + ->delete([ + 'actor_id' => $activity->actor_id, + 'target_actor_id' => $activity->target_actor_id, + 'post_id' => service('uuid') + ->fromString($activity->post_id) + ->getBytes(), + 'type' => match ($activity->type) { + 'Undo_Like' => 'like', + 'Undo_Announce' => 'share', + }, + ]); + } + + return $data; + } } diff --git a/app/Models/NotificationModel.php b/modules/Fediverse/Models/NotificationModel.php similarity index 61% rename from app/Models/NotificationModel.php rename to modules/Fediverse/Models/NotificationModel.php index 10ce851a..24732d7d 100644 --- a/app/Models/NotificationModel.php +++ b/modules/Fediverse/Models/NotificationModel.php @@ -3,17 +3,16 @@ declare(strict_types=1); /** - * @copyright 2021 Ad Aures + * @copyright 2022 Ad Aures * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @link https://castopod.org/ */ -namespace App\Models; +namespace Modules\Fediverse\Models; -use App\Entities\Notification; -use Michalsn\Uuid\UuidModel; +use Modules\Fediverse\Entities\Notification; -class NotificationModel extends UuidModel +class NotificationModel extends BaseUuidModel { /** * @var string @@ -43,5 +42,14 @@ class NotificationModel extends UuidModel /** * @var string[] */ - protected $allowedFields = ['read_at']; + protected $allowedFields = [ + 'actor_id', + 'target_actor_id', + 'post_id', + 'activity_id', + 'type', + 'read_at', + 'created_at', + 'updated_at', + ]; } diff --git a/themes/cp_admin/podcast/notifications.php b/themes/cp_admin/podcast/notifications.php index e5a4454e..3b960d0b 100644 --- a/themes/cp_admin/podcast/notifications.php +++ b/themes/cp_admin/podcast/notifications.php @@ -53,7 +53,6 @@ ], null, false), 'follow' => lang('Notifications.follow', [ 'actor_username' => $actorUsernameHtml, - 'target_actor_username' => $targetActorUsernameHtml, ], null, false), default => '', };