Commit e08555a4 authored by Yassine Doghri's avatar Yassine Doghri
Browse files

fix(notifications): notify actors after activities insert / update using model callback methods

--> Remove sql triggers because most shared hosting plans prevent using them
parent 460f52f7
Loading
Loading
Loading
Loading
Loading
+0 −50
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

/**
 * Class AddActivitiesTriggerAfterInsert Creates activities trigger in database
 *
 * @copyright  2020 Ad Aures
 * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
 * @link       https://castopod.org/
 */

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddActivitiesTriggerAfterInsert extends Migration
{
    public function up(): void
    {
        $activitiesTable = $this->db->prefixTable(config('Fediverse')->tablesPrefix . 'activities');
        $notificationsTable = $this->db->prefixTable('notifications');
        $createQuery = <<<CODE_SAMPLE
        CREATE TRIGGER `{$activitiesTable}_after_insert`
        AFTER INSERT ON `{$activitiesTable}`
        FOR EACH ROW
        BEGIN
        -- only create notification if new incoming activity with NULL status is created
        IF NEW.target_actor_id AND NEW.target_actor_id != NEW.actor_id AND NEW.status IS NULL THEN
            IF NEW.type = 'Follow' THEN
                INSERT INTO `{$notificationsTable}` (`actor_id`, `target_actor_id`, `activity_id`, `type`, `created_at`, `updated_at`)
                VALUES (NEW.actor_id, NEW.target_actor_id, NEW.id, 'follow', NEW.created_at, NEW.created_at);
            ELSEIF NEW.type = 'Undo_Follow' THEN
                DELETE FROM `{$notificationsTable}`
                WHERE `actor_id` = NEW.actor_id
                AND `target_actor_id` = NEW.target_actor_id
                AND `type` = 'follow';
            END IF;
        END IF;
        END
        CODE_SAMPLE;
        $this->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`");
    }
}
+0 −59
Original line number Diff line number Diff line
<?php

declare(strict_types=1);

/**
 * Class AddActivitiesTriggerAfterUpdate Creates activities trigger in database
 *
 * @copyright  2020 Ad Aures
 * @license    https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
 * @link       https://castopod.org/
 */

namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddActivitiesTriggerAfterUpdate extends Migration
{
    public function up(): void
    {
        $activitiesTable = $this->db->prefixTable(config('Fediverse')->tablesPrefix . 'activities');
        $notificationsTable = $this->db->prefixTable('notifications');
        $createQuery = <<<CODE_SAMPLE
        CREATE TRIGGER `{$activitiesTable}_after_update`
        AFTER UPDATE ON `{$activitiesTable}`
        FOR EACH ROW
        BEGIN
        -- only create notification if new incoming activity with NULL status is created
        IF NEW.target_actor_id AND NEW.target_actor_id != NEW.actor_id AND NEW.status IS NULL THEN
            IF NEW.type IN ('Create', 'Like', 'Announce') AND OLD.post_id IS NULL AND NEW.post_id IS NOT NULL THEN
                SET @type = (CASE
                                WHEN NEW.type = 'Create' THEN 'reply'
                                WHEN NEW.type = 'Like' THEN 'like'
                                WHEN NEW.type = 'Announce' THEN 'share'
                            END);
                INSERT INTO `{$notificationsTable}` (`actor_id`, `target_actor_id`,`post_id`, `activity_id`, `type`, `created_at`, `updated_at`)
                VALUES (NEW.actor_id, NEW.target_actor_id,NEW.post_id, NEW.id, @type, NEW.created_at, NEW.created_at);
            ELSEIF NEW.type IN ('Undo_Like', 'Undo_Announce') THEN
                DELETE FROM `{$notificationsTable}`
                WHERE `actor_id` = NEW.actor_id
                AND `target_actor_id` = NEW.target_actor_id
                AND `type` = (CASE
                                    WHEN NEW.type = 'Undo_Like' THEN 'like'
                                    WHEN NEW.type = 'Undo_Announce' THEN 'share'
                                END)
                AND `post_id` = NEW.post_id;
            END IF;
        END IF;
        END
        CODE_SAMPLE;
        $this->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`");
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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',
];
+1 −1
Original line number Diff line number Diff line
@@ -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;

Loading