mirror of
https://github.com/Poniverse/Pony.fm.git
synced 2024-11-25 22:47:59 +01:00
#25: Implemented all basic notification types.
- blocks off the unfinished URL endpoints for email notifications
This commit is contained in:
parent
78b22cdfd0
commit
ff5d8220ef
8 changed files with 85 additions and 43 deletions
|
@ -20,12 +20,17 @@
|
||||||
|
|
||||||
namespace Poniverse\Ponyfm\Http\Controllers;
|
namespace Poniverse\Ponyfm\Http\Controllers;
|
||||||
|
|
||||||
|
use App;
|
||||||
use DB;
|
use DB;
|
||||||
use Poniverse\Ponyfm\Models\Email;
|
use Poniverse\Ponyfm\Models\Email;
|
||||||
use Poniverse\Ponyfm\Models\EmailSubscription;
|
use Poniverse\Ponyfm\Models\EmailSubscription;
|
||||||
|
|
||||||
|
// TODO: #25 - finish these endpoints and secure them properly
|
||||||
|
|
||||||
class NotificationsController extends Controller {
|
class NotificationsController extends Controller {
|
||||||
public function getEmailClick($emailKey) {
|
public function getEmailClick($emailKey) {
|
||||||
|
App::abort(403, "This isn't implemented yet!");
|
||||||
|
|
||||||
$emailKey = decrypt($emailKey);
|
$emailKey = decrypt($emailKey);
|
||||||
/** @var Email $email */
|
/** @var Email $email */
|
||||||
$email = Email::findOrFail($emailKey);
|
$email = Email::findOrFail($emailKey);
|
||||||
|
@ -40,6 +45,8 @@ class NotificationsController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getEmailUnsubscribe($subscriptionKey) {
|
public function getEmailUnsubscribe($subscriptionKey) {
|
||||||
|
App::abort(403, "This isn't implemented yet!");
|
||||||
|
|
||||||
$subscriptionId = decrypt($subscriptionKey);
|
$subscriptionId = decrypt($subscriptionKey);
|
||||||
$subscription = EmailSubscription::findOrFail($subscriptionId);
|
$subscription = EmailSubscription::findOrFail($subscriptionId);
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,6 @@ use Log;
|
||||||
use Mail;
|
use Mail;
|
||||||
use Poniverse\Ponyfm\Contracts\Favouritable;
|
use Poniverse\Ponyfm\Contracts\Favouritable;
|
||||||
use Poniverse\Ponyfm\Mail\BaseNotification;
|
use Poniverse\Ponyfm\Mail\BaseNotification;
|
||||||
use Poniverse\Ponyfm\Mail\ContentFavourited;
|
|
||||||
use Poniverse\Ponyfm\Mail\NewComment;
|
|
||||||
use Poniverse\Ponyfm\Mail\NewFollower;
|
|
||||||
use Poniverse\Ponyfm\Mail\NewPlaylist;
|
|
||||||
use Poniverse\Ponyfm\Mail\NewTrack;
|
|
||||||
use Poniverse\Ponyfm\Models\Activity;
|
use Poniverse\Ponyfm\Models\Activity;
|
||||||
use Poniverse\Ponyfm\Models\Comment;
|
use Poniverse\Ponyfm\Models\Comment;
|
||||||
use Poniverse\Ponyfm\Models\Email;
|
use Poniverse\Ponyfm\Models\Email;
|
||||||
|
@ -66,7 +61,9 @@ class PonyfmDriver extends AbstractDriver
|
||||||
*/
|
*/
|
||||||
private function sendEmails(Activity $activity, $recipients) {
|
private function sendEmails(Activity $activity, $recipients) {
|
||||||
foreach ($recipients as $recipient) {
|
foreach ($recipients as $recipient) {
|
||||||
|
/** @var Notification $notification */
|
||||||
$notification = $activity->notifications->where('user_id', $recipient->id)->first();
|
$notification = $activity->notifications->where('user_id', $recipient->id)->first();
|
||||||
|
/** @var Email $email */
|
||||||
$email = $notification->email()->create([]);
|
$email = $notification->email()->create([]);
|
||||||
|
|
||||||
Log::debug("Attempting to send an email about notification {$notification->id} to {$recipient->email}.");
|
Log::debug("Attempting to send an email about notification {$notification->id} to {$recipient->email}.");
|
||||||
|
@ -88,9 +85,11 @@ class PonyfmDriver extends AbstractDriver
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
||||||
|
if (NULL !== $recipientsQuery) {
|
||||||
$this->insertNotifications($activity, $recipientsQuery->get());
|
$this->insertNotifications($activity, $recipientsQuery->get());
|
||||||
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_PUBLISHED_TRACK)->get());
|
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_PUBLISHED_TRACK)->get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
@ -106,10 +105,15 @@ class PonyfmDriver extends AbstractDriver
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
||||||
|
if (NULL !== $recipientsQuery) {
|
||||||
$this->insertNotifications($activity, $recipientsQuery->get());
|
$this->insertNotifications($activity, $recipientsQuery->get());
|
||||||
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_PUBLISHED_PLAYLIST)->get());
|
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_PUBLISHED_PLAYLIST)->get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritdoc
|
||||||
|
*/
|
||||||
public function newFollower(User $userBeingFollowed, User $follower)
|
public function newFollower(User $userBeingFollowed, User $follower)
|
||||||
{
|
{
|
||||||
$activity = Activity::create([
|
$activity = Activity::create([
|
||||||
|
@ -121,9 +125,11 @@ class PonyfmDriver extends AbstractDriver
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
||||||
|
if (NULL !== $recipientsQuery) {
|
||||||
$this->insertNotifications($activity, $recipientsQuery->get());
|
$this->insertNotifications($activity, $recipientsQuery->get());
|
||||||
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_NEW_FOLLOWER)->get());
|
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_NEW_FOLLOWER)->get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
@ -139,9 +145,11 @@ class PonyfmDriver extends AbstractDriver
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
||||||
|
if (NULL !== $recipientsQuery) {
|
||||||
$this->insertNotifications($activity, $recipientsQuery->get());
|
$this->insertNotifications($activity, $recipientsQuery->get());
|
||||||
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_NEW_COMMENT)->get());
|
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_NEW_COMMENT)->get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
|
@ -157,7 +165,9 @@ class PonyfmDriver extends AbstractDriver
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
$recipientsQuery = $this->getRecipients(__FUNCTION__, func_get_args());
|
||||||
|
if (NULL !== $recipientsQuery) {
|
||||||
$this->insertNotifications($activity, $recipientsQuery->get());
|
$this->insertNotifications($activity, $recipientsQuery->get());
|
||||||
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_CONTENT_FAVOURITED)->get());
|
$this->sendEmails($activity, $recipientsQuery->withEmailSubscriptionFor(Activity::TYPE_CONTENT_FAVOURITED)->get());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
|
|
||||||
namespace Poniverse\Ponyfm\Library\Notifications;
|
namespace Poniverse\Ponyfm\Library\Notifications;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
use Poniverse\Ponyfm\Contracts\Favouritable;
|
use Poniverse\Ponyfm\Contracts\Favouritable;
|
||||||
use Poniverse\Ponyfm\Contracts\NotificationHandler;
|
use Poniverse\Ponyfm\Contracts\NotificationHandler;
|
||||||
use Poniverse\Ponyfm\Jobs\SendNotifications;
|
use Poniverse\Ponyfm\Jobs\SendNotifications;
|
||||||
use Poniverse\Ponyfm\Library\Notifications\Drivers\EmailDriver;
|
|
||||||
use Poniverse\Ponyfm\Library\Notifications\Drivers\NativeDriver;
|
use Poniverse\Ponyfm\Library\Notifications\Drivers\NativeDriver;
|
||||||
use Poniverse\Ponyfm\Library\Notifications\Drivers\PonyfmDriver;
|
use Poniverse\Ponyfm\Library\Notifications\Drivers\PonyfmDriver;
|
||||||
use Poniverse\Ponyfm\Models\Activity;
|
use Poniverse\Ponyfm\Models\Activity;
|
||||||
|
@ -39,7 +39,8 @@ use Poniverse\Ponyfm\Models\User;
|
||||||
* @package Poniverse\Ponyfm\Library\Notifications
|
* @package Poniverse\Ponyfm\Library\Notifications
|
||||||
*
|
*
|
||||||
* This class returns a list of users who are to receive a particular notification.
|
* This class returns a list of users who are to receive a particular notification.
|
||||||
* It is instantiated on a per-driver basis.
|
* It is instantiated on a per-driver basis. Its methods return Eloquent query
|
||||||
|
* objects for the PonyfmDriver.
|
||||||
*/
|
*/
|
||||||
class RecipientFinder implements NotificationHandler
|
class RecipientFinder implements NotificationHandler
|
||||||
{
|
{
|
||||||
|
@ -67,11 +68,6 @@ class RecipientFinder implements NotificationHandler
|
||||||
case PonyfmDriver::class:
|
case PonyfmDriver::class:
|
||||||
return $track->user->followers();
|
return $track->user->followers();
|
||||||
|
|
||||||
case EmailDriver::class:
|
|
||||||
return $track->user->followers()->whereHas('emailSubscriptions', function($query) {
|
|
||||||
$query->where('activity_type', Activity::TYPE_PUBLISHED_TRACK);
|
|
||||||
})->get();
|
|
||||||
|
|
||||||
case NativeDriver::class:
|
case NativeDriver::class:
|
||||||
$followerIds = [];
|
$followerIds = [];
|
||||||
$subIds = [];
|
$subIds = [];
|
||||||
|
@ -99,7 +95,8 @@ class RecipientFinder implements NotificationHandler
|
||||||
{
|
{
|
||||||
switch ($this->notificationDriver) {
|
switch ($this->notificationDriver) {
|
||||||
case PonyfmDriver::class:
|
case PonyfmDriver::class:
|
||||||
return $playlist->user->followers;
|
return $playlist->user->followers();
|
||||||
|
|
||||||
case NativeDriver::class:
|
case NativeDriver::class:
|
||||||
$followerIds = [];
|
$followerIds = [];
|
||||||
$subIds = [];
|
$subIds = [];
|
||||||
|
@ -127,8 +124,8 @@ class RecipientFinder implements NotificationHandler
|
||||||
{
|
{
|
||||||
switch ($this->notificationDriver) {
|
switch ($this->notificationDriver) {
|
||||||
case PonyfmDriver::class:
|
case PonyfmDriver::class:
|
||||||
case EmailDriver::class:
|
return $this->queryForUser($userBeingFollowed);
|
||||||
return [$userBeingFollowed];
|
|
||||||
case NativeDriver::class:
|
case NativeDriver::class:
|
||||||
return Subscription::where('user_id', '=', $userBeingFollowed->id)->get();
|
return Subscription::where('user_id', '=', $userBeingFollowed->id)->get();
|
||||||
default:
|
default:
|
||||||
|
@ -145,8 +142,8 @@ class RecipientFinder implements NotificationHandler
|
||||||
case PonyfmDriver::class:
|
case PonyfmDriver::class:
|
||||||
return
|
return
|
||||||
$comment->user->id === $comment->resource->user->id
|
$comment->user->id === $comment->resource->user->id
|
||||||
? []
|
? NULL
|
||||||
: [$comment->resource->user];
|
: $this->queryForUser($comment->resource->user);
|
||||||
case NativeDriver::class:
|
case NativeDriver::class:
|
||||||
return Subscription::where('user_id', '=', $comment->resource->user->id)->get();
|
return Subscription::where('user_id', '=', $comment->resource->user->id)->get();
|
||||||
default:
|
default:
|
||||||
|
@ -163,12 +160,23 @@ class RecipientFinder implements NotificationHandler
|
||||||
case PonyfmDriver::class:
|
case PonyfmDriver::class:
|
||||||
return
|
return
|
||||||
$favouriter->id === $entityBeingFavourited->user->id
|
$favouriter->id === $entityBeingFavourited->user->id
|
||||||
? []
|
? NULL
|
||||||
: [$entityBeingFavourited->user];
|
: $this->queryForUser($entityBeingFavourited->user);
|
||||||
case NativeDriver::class:
|
case NativeDriver::class:
|
||||||
return Subscription::where('user_id', '=', $entityBeingFavourited->user->id)->get();
|
return Subscription::where('user_id', '=', $entityBeingFavourited->user->id)->get();
|
||||||
default:
|
default:
|
||||||
return $this->fail();
|
return $this->fail();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function that returns an Eloquent query instance that will return
|
||||||
|
* a specific user when executed.
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @return \Eloquent|Builder
|
||||||
|
*/
|
||||||
|
private function queryForUser(User $user):Builder {
|
||||||
|
return User::where('id', '=', $user->id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,8 @@ class ContentFavourited extends BaseNotification
|
||||||
'content-favourited',
|
'content-favourited',
|
||||||
$this->activityRecord->text, [
|
$this->activityRecord->text, [
|
||||||
'creatorName' => $creatorName,
|
'creatorName' => $creatorName,
|
||||||
'resourceType' => $this->activityRecord->getResourceType(),
|
'resourceType' => $this->activityRecord->getResourceTypeString(),
|
||||||
'resourceTitle' => $this->activityRecord->resource->resource->title,
|
'resourceTitle' => $this->activityRecord->resource->title,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ class NewComment extends BaseNotification
|
||||||
|
|
||||||
// Profile comments get a different template and subject line from
|
// Profile comments get a different template and subject line from
|
||||||
// other types of comments.
|
// other types of comments.
|
||||||
if ($this->activityRecord->getResourceType() === User::class) {
|
if ($this->activityRecord->getResourceTypeString() === User::class) {
|
||||||
return $this->renderEmail(
|
return $this->renderEmail(
|
||||||
'new-comment-profile',
|
'new-comment-profile',
|
||||||
$this->activityRecord->text, [
|
$this->activityRecord->text, [
|
||||||
|
@ -44,7 +44,7 @@ class NewComment extends BaseNotification
|
||||||
'new-comment-content',
|
'new-comment-content',
|
||||||
$this->activityRecord->text, [
|
$this->activityRecord->text, [
|
||||||
'creatorName' => $creatorName,
|
'creatorName' => $creatorName,
|
||||||
'resourceType' => $this->activityRecord->getResourceType(),
|
'resourceType' => $this->activityRecord->getResourceTypeString(),
|
||||||
'resourceTitle' => $this->activityRecord->resource->resource->title,
|
'resourceTitle' => $this->activityRecord->resource->resource->title,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,11 +217,11 @@ class Activity extends Model
|
||||||
* @return string
|
* @return string
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
public function getResourceType():string
|
public function getResourceTypeString():string
|
||||||
{
|
{
|
||||||
switch($this->activity_type) {
|
switch($this->activity_type) {
|
||||||
case static::TYPE_NEW_COMMENT:
|
case static::TYPE_NEW_COMMENT:
|
||||||
if ($this->resource_type === User::class) {
|
if ($this->isProfileComment()) {
|
||||||
return $this->resource->getResourceType();
|
return $this->resource->getResourceType();
|
||||||
} else {
|
} else {
|
||||||
return $this->resource->resource->getResourceType();
|
return $this->resource->resource->getResourceType();
|
||||||
|
@ -232,6 +232,14 @@ class Activity extends Model
|
||||||
throw new \Exception("Unknown activity type {$this->activity_type} - cannot determine resource type.");
|
throw new \Exception("Unknown activity type {$this->activity_type} - cannot determine resource type.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isProfileComment():bool {
|
||||||
|
return static::TYPE_NEW_COMMENT === $this->activity_type &&
|
||||||
|
User::class === $this->resource->getResourceClass();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The string this method generates is used for email subject lines as well
|
* The string this method generates is used for email subject lines as well
|
||||||
* as on-site notifications.
|
* as on-site notifications.
|
||||||
|
@ -256,17 +264,16 @@ class Activity extends Model
|
||||||
return "{$this->initiatingUser->display_name} is now following you!";
|
return "{$this->initiatingUser->display_name} is now following you!";
|
||||||
|
|
||||||
case static::TYPE_NEW_COMMENT:
|
case static::TYPE_NEW_COMMENT:
|
||||||
// Is this a profile comment?
|
if ($this->isProfileComment()) {
|
||||||
if ($this->resource_type === User::class) {
|
|
||||||
return "{$this->initiatingUser->display_name} left a comment on your profile!";
|
return "{$this->initiatingUser->display_name} left a comment on your profile!";
|
||||||
|
|
||||||
// Must be a content comment.
|
// If it's not a profile comment, it must be a content comment.
|
||||||
} else {
|
} else {
|
||||||
return "{$this->initiatingUser->display_name} left a comment on your {$this->getResourceType()}, {$this->resource->resource->title}!";
|
return "{$this->initiatingUser->display_name} left a comment on your {$this->getResourceTypeString()}, \"{$this->resource->resource->title}\"!";
|
||||||
}
|
}
|
||||||
|
|
||||||
case static::TYPE_CONTENT_FAVOURITED:
|
case static::TYPE_CONTENT_FAVOURITED:
|
||||||
return "{$this->initiatingUser->display_name} favourited your {$this->getResourceType()}, {$this->resource->title}!";
|
return "{$this->initiatingUser->display_name} favourited your {$this->getResourceTypeString()}, \"{$this->resource->title}\"!";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new \Exception('This activity\'s activity type is unknown!');
|
throw new \Exception('This activity\'s activity type is unknown!');
|
||||||
|
|
|
@ -144,6 +144,15 @@ class Comment extends Model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the class name of the object that this is a comment on.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getResourceClass():string {
|
||||||
|
return get_class($this->resource);
|
||||||
|
}
|
||||||
|
|
||||||
public function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
DB::transaction(function () {
|
DB::transaction(function () {
|
||||||
|
|
|
@ -77,6 +77,7 @@ Route::get('p{id}/dl.{extension}', 'PlaylistsController@getDownload');
|
||||||
|
|
||||||
Route::get('notifications', 'AccountController@getNotifications');
|
Route::get('notifications', 'AccountController@getNotifications');
|
||||||
|
|
||||||
|
|
||||||
Route::get('notifications/email/unsubscribe/{subscriptionKey}', 'NotificationsController@getEmailUnsubscribe')->name('email:unsubscribe');
|
Route::get('notifications/email/unsubscribe/{subscriptionKey}', 'NotificationsController@getEmailUnsubscribe')->name('email:unsubscribe');
|
||||||
Route::get('notifications/email/click/{emailKey}', 'NotificationsController@getEmailClick')->name('email:click');
|
Route::get('notifications/email/click/{emailKey}', 'NotificationsController@getEmailClick')->name('email:click');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue