Team-Tea-Time / laravel-forum

A slim, lean forum package designed for quick and easy integration in Laravel projects
https://laravel-forum.teamteatime.net/
MIT License
601 stars 165 forks source link

Implement thread subscribtion #162

Closed rtfmfm closed 7 years ago

rtfmfm commented 7 years ago

Hi! I want to add the ability for users subscribe to a threads and receive email notification for new posts in the thread. My idea is to add a button around the thread name. When the user clicks it, it will add users's id and thread's id in new sql table (forum_subscriptions) with columns thread_id and user_id. Then on every new post in the thread, after the store function I would perform check and send email to every user which is subscribed for this thread.

Thinking on the above I'm facing few questions:

  1. Is there a better approach to achieve this?
  2. Where to write both functions (1. write thread_id and user_id in forum_subscriptions; 2. check and email sending) without editing forum controllers inside vendor folder?
  3. Every syntax example will be appreciated ;-)

Thank you in advance!

Riari commented 7 years ago

Your approach seems fine in principle :)

One thing I would consider first is whether or not you might eventually want to enable users to subscribe to content besides forum threads, in which case, you'll want to adopt a different naming convention and make your DB table schema support multiple content types - i.e. have a subscriptions table with user_id, model, and model_id columns. You could then write a more centralised system that will allow adding/removing subscriptions for a given user on the specified model. I can give you more detail on this if you like.

For your second question re: where to write the functions; for the 'subscribe' action, you can just write your own route and controller method. For notifying subscribers of new posts, I'd suggest using Eloquent model events, i.e. observe the created event on Riari\Forum\Models\Post, get the users subscribed to the thread and queue emails to them. That way, you don't have to extend/override any forum controllers.

rtfmfm commented 7 years ago

Hello Riari, thank you for your prompt reply! I'm totally new with Laravel and from my point of view, your advice looks too complicated for me. I do not really understand what "content" you have in mind. Of course, I'll be happy to hear more about this.

For the second question. I understand the idea with the route which will point to my controller method. The second part with the model events is new for me, but I'll dive in the documentation for the solution.

Thank you for your help!

Riari commented 7 years ago

On the first point, with "content" I'm referring to any content your users might submit. Photo albums, user blogs, etc. Whatever your site might comprise, a subscription system doesn't have to be specific to the forum. If anything, I'd argue that it shouldn't be specific to the forum even if that's all it covers initially. Hence the suggestion of developing it to support any model instead of just threads :)

rtfmfm commented 7 years ago

Hello Riari, can you tell me how to send information back to the view without changing the forum controllers in the vendor folder. I want to change the button depending on the user subscription or not.

Thank you in advance!

Riari commented 7 years ago

You do have the option of overriding the controllers without touching the vendor directory. See http://teamteatime.net/docs/laravel-forum/3.x/front-end/configuration.md

You could also go via Eloquent; write some query scopes on your Subscription model to enable retrieving subscriptions by user and thread. E.g. Subscription::forUser($user)->onModel('Thread', $thread)->first(); or Subscription::forUser($user)->onThread($thread)->first(); (depending on how your subscriptions table is set up) - you can do such a call directly in the views, which may not be ideal and some would suggest it's bad practice, but it's not that different from doing the call in a controller action and assigning the result to a variable in the view. It would look something like this:

@if (Subscription::forUser(auth()->user())->onThread($thread)->first())
    display an 'Unsubscribe' button
@else
    display a 'Subscribe' button
@endif
rtfmfm commented 7 years ago

Hello Riari, I achieve what I wanted. Thank you very much for your help. I would not succeed without your guidelines and code examples. I'm sure there are many things that can be improved and polished in my code, but this will happen with the time. Thank you !!!

Riari commented 7 years ago

No problem :)