[COMPONENT][Notification] Make logic more generic and robust

Fixed various bugs

Some important concepts to bear in mind:

* Notification: Associated with activities, won't be reconstructed
together with objects, can be thought of as transient

* Attention: Associated with objects, will be reconstructed with them, can
be thought as persistent

* Notifications and Attentions have no direct implications.

* Mentions are a specific form of attentions in notes, leads to the creation of Attentions.

Finally,

Potential PHP issue detected and reported: https://github.com/php/php-src/issues/8199
`static::method()` from a non static context (such as a class method) calls `__call`, rather than
the expected `__callStatic`. Can be fixed by using `(static fn() => static::method())()`, but the
usage of the magic method is strictly unnecessary in this case.
This commit is contained in:
2022-03-13 18:23:19 +00:00
parent e1cceac150
commit 888c3798b7
32 changed files with 438 additions and 494 deletions

View File

@@ -37,6 +37,7 @@ use App\Util\Common;
use App\Util\Exception\DuplicateFoundException;
use App\Util\Exception\NotFoundException;
use App\Util\Exception\ServerException;
use Component\Notification\Entity\Attention;
use Component\Subscription\Controller\Subscribers as SubscribersController;
use Component\Subscription\Controller\Subscriptions as SubscriptionsController;
@@ -97,20 +98,21 @@ class Subscription extends Component
$subscription = DB::findOneBy(table: Entity\ActorSubscription::class, criteria: $opts, return_null: true);
$activity = null;
if (\is_null($subscription)) {
DB::persist(Entity\ActorSubscription::create($opts));
DB::persist($subscription = Entity\ActorSubscription::create($opts));
$activity = Activity::create([
'actor_id' => $subscriber_id,
'verb' => 'subscribe',
'object_type' => 'actor',
'object_type' => Actor::schemaName(),
'object_id' => $subscribed_id,
'source' => $source,
]);
DB::persist($activity);
DB::persist(Attention::create(['object_type' => Activity::schemaName(), 'object_id' => $activity->getId(), 'target_id' => $subscribed_id]));
Event::handle('NewNotification', [
\is_int($subject) ? $subject : Actor::getById($subscriber_id),
$activity,
['object' => [$activity->getObjectId()]],
[$subscribed_id],
_m('{subject} subscribed to {object}.', ['{subject}' => $activity->getActorId(), '{object}' => $activity->getObjectId()]),
]);
}
@@ -146,21 +148,22 @@ class Subscription extends Component
if (!\is_null($subscription)) {
// Remove Subscription
DB::remove($subscription);
$previous_follow_activity = DB::findBy('activity', ['verb' => 'subscribe', 'object_type' => 'actor', 'object_id' => $subscribed_id], order_by: ['created' => 'DESC'])[0];
$previous_follow_activity = DB::findBy(Activity::class, ['verb' => 'subscribe', 'object_type' => Actor::schemaName(), 'object_id' => $subscribed_id], order_by: ['created' => 'DESC'])[0];
// Store Activity
$activity = Activity::create([
'actor_id' => $subscriber_id,
'verb' => 'undo',
'object_type' => 'activity',
'object_type' => Activity::schemaName(),
'object_id' => $previous_follow_activity->getId(),
'source' => $source,
]);
DB::persist($activity);
DB::persist(Attention::create(['object_type' => Activity::schemaName(), 'object_id' => $activity->getId(), 'target_id' => $subscribed_id]));
Event::handle('NewNotification', [
\is_int($subject) ? $subject : Actor::getById($subscriber_id),
$activity,
['object' => [$previous_follow_activity->getObjectId()]],
[],
_m('{subject} unsubscribed from {object}.', ['{subject}' => $activity->getActorId(), '{object}' => $previous_follow_activity->getObjectId()]),
]);
}