Skip to content

Forum Topic Subscription System #314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 12, 2018
18 changes: 5 additions & 13 deletions app/Http/Controllers/ForumController.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,14 @@

namespace App\Http\Controllers;

use App\Events\MessageSent;
use App\Repositories\ChatRepository;
use App\Repositories\TaggedUserRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use App\Forum;
use App\Post;
use App\Topic;
use App\User;
use App\Message;
use App\Like;
use App\TopicSubscription;
use App\Achievements\UserMadeFirstPost;
use App\Achievements\UserMade25Posts;
use App\Achievements\UserMade50Posts;
Expand All @@ -35,7 +32,8 @@
use App\Achievements\UserMade700Posts;
use App\Achievements\UserMade800Posts;
use App\Achievements\UserMade900Posts;
use App\Mail\NewReply;
use App\Repositories\ChatRepository;
use App\Repositories\TaggedUserRepository;
use Decoda\Decoda;
use \Toastr;

Expand Down Expand Up @@ -288,20 +286,14 @@ public function reply(Request $request, $slug, $id)
// Save
$forum->save();

// Find the user who initated the topic
$topicCreator = User::findOrFail($topic->first_post_user_id);

// Post To Chatbox
$appurl = config('app.url');
$postUrl = "{$appurl}/forums/topic/{$topic->slug}.{$topic->id}?page={$post->getPageNumber()}#post-{$post->id}";
$profileUrl = "{$appurl}/{$user->username}.{$user->id}";

$this->chat->systemMessage("[url=$profileUrl]{$user->username}[/url] has left a reply on topic [url={$postUrl}]{$topic->name}[/url]");

// Mail Topic Creator Of New Reply
if ($post->user_id != $topic->first_post_user_id) {
Mail::to($topicCreator->email)->send(new NewReply($user, $topic));
}
// Notify All Subscribers Of New Reply
$topic->notifySubscribers($post);

//Achievements
$user->unlock(new UserMadeFirstPost(), 1);
Expand Down
64 changes: 64 additions & 0 deletions app/Http/Controllers/SubscriptionController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php
/**
* NOTICE OF LICENSE
*
* UNIT3D is open-sourced software licensed under the GNU General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
* @author HDVinnie
*/

namespace App\Http\Controllers;

use App\Topic;
use App\TopicSubscription;
use \Toastr;

class SubscriptionController extends Controller
{
/**
* Subscribe To A Topic
*
* @param Topic $topic
* @return Illuminate\Http\RedirectResponse
*/
public function subscribe(Topic $topic)
{
if (!auth()->user()->isSubscribed($topic->id)) {

$subscription = new TopicSubscription();
$subscription->user_id = auth()->user()->id;
$subscription->topic_id = $topic->id;
$subscription->save();

return redirect()->route('forum_topic', ['slug' => $topic->slug, 'id' => $topic->id])
->with(Toastr::success('You are now subscribed to topic, ' . $topic->name . '. You will now receive site notifications when a reply is left.', 'Yay!', ['options']));
} else {
return redirect()->route('forum_topic', ['slug' => $topic->slug, 'id' => $topic->id])
->with(Toastr::error('You are already subscribed to this topic', 'Whoops!', ['options']));
}
}

/**
* Unsubscribe To A Topic
*
* @param Topic $topic
* @return Illuminate\Http\RedirectResponse
*/
public function unsubscribe(Topic $topic)
{
if (auth()->user()->isSubscribed($topic->id)) {

$subscription = auth()->user()->subscriptions()->where('topic_id', $topic->id)->first();
$subscription->delete();

return redirect()->route('forum_topic', ['slug' => $topic->slug, 'id' => $topic->id])
->with(Toastr::info('You are no longer subscribed to topic, ' . $topic->name. '. You will no longer receive site notifications when a reply is left.', 'Yay!', ['options']));
} else {
return redirect()->route('forum_topic', ['slug' => $topic->slug, 'id' => $topic->id])
->with(Toastr::error('You are not subscribed this topic to begin with...', 'Whoops!', ['options']));
}
}
}
49 changes: 0 additions & 49 deletions app/Mail/NewReply.php

This file was deleted.

66 changes: 66 additions & 0 deletions app/Notifications/NewTopicPost.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php
/**
* NOTICE OF LICENSE
*
* UNIT3D is open-sourced software licensed under the GNU General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
* @author HDVinnie
*/

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Request;

use App\Post;

class NewTopicPost extends Notification implements ShouldQueue
{
use Queueable;

public $post;

/**
* Create a new notification instance.
*
* @param Post $post
* @return void
*/
public function __construct(Post $post)
{
$this->post = $post;
}

/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['database'];
}

/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
$appurl = config('app.url');
return [
'title' => "Subscribed Topic Has A New Post",
'body' => $this->post->user->username . " has left a new post on " . $this->post->topic->name,
'url' => "{$appurl}/forums/topic/{$this->post->topic->slug}.{$this->post->topic->id}?page={$this->post->getPageNumber()}#post-{$this->post->id}"
];
}
}
20 changes: 20 additions & 0 deletions app/Topic.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ public function posts()
return $this->hasMany(Post::class);
}

/**
* Has Many Subscriptions
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function subscriptions()
{
return $this->hasMany(TopicSubscription::class);
}

/**
* Notify Subscribers Of A Topic When New Post Is Made
*
* @return string
*/
public function notifySubscribers($post)
{
$this->subscriptions->where('user_id', '!=', $post->user_id)->each->notify($post);
}

/**
* Does User Have Permission To View Topic
*
Expand Down
53 changes: 53 additions & 0 deletions app/TopicSubscription.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
/**
* NOTICE OF LICENSE
*
* UNIT3D is open-sourced software licensed under the GNU General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
* @author HDVinnie
*/

namespace App;

use Illuminate\Database\Eloquent\Model;
use App\Notifications\NewTopicPost;


class TopicSubscription extends Model
{
/**
* Belongs To A User
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo(User::class)->withDefault([
'username' => 'System',
'id' => '1'
]);
}

/**
* Belongs To A Topic
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function topic()
{
return $this->belongsTo(Topic::class);
}

/**
* Notify Subscribers Of A Topic When New Post Is Made
*
* @return string
*/
public function notify($post)
{
$this->user->notify(new NewTopicPost($post));
}
}
21 changes: 21 additions & 0 deletions app/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,27 @@ public function likes()
return $this->hasMany(Like::class);
}

/**
* Has Many Subscriptions
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function subscriptions()
{
return $this->hasMany(TopicSubscription::class);
}

/**
* Does Subscription Exist
*
* @param $topic_id
* @return string
*/
public function isSubscribed($topic_id)
{
return (bool)$this->subscriptions()->where('topic_id', $topic_id)->first(['id']);
}

/**
* Get All Followers Of A User
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* NOTICE OF LICENSE
*
* UNIT3D is open-sourced software licensed under the GNU General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
* @author HDVinnie
*/

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTopicSubscriptionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('topic_subscriptions', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('topic_id');
$table->timestamps();
$table->unique(['user_id', 'topic_id']);
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('topic_subscriptions');
}
}
Loading