I am working on a messaging functionality on my website between two users and I have managed to make the messaging system work quite alright. But I have a little issue which I can't find a solution to it. I want to be able to show, A list of all message received from other users when the user clicks on this route /conversations. But right now what it does is that it display a list of all users in the users table when I click on the route /conversations which I don't want.
Here are my routes in web
Route::get('/conversations', 'ConversationsController#index')->name('conversations');
Route::get('/conversations/{user}', 'ConversationsController#show')->name('conversations.show');
Route::post('/conversations/{user}', 'ConversationsController#store');
Here is my list of conversations route for index
<div class="contact-edit" id="ci">
<h3>MEssages</h3>
#include('conversations.users', ['users'=>$users, 'unread'=>$unread])
</div>
Here is the conversation.users
<div class="col-md-3">
<div class="list-group">
#foreach($users as $user)
<a class = "list-group-item d-flex justify-content-between align-items-center" href="{{route('conversations.show', $user->id)}}">
{{ $user->name }}
#if(isset($unread[$user->id]))
<span class="badge-pill badge-primary">{{$unread[$user->id]}}</span>
#endif
</a>
#endforeach
</div>
Here is my route opening the conversations tab
Ecrire un message
Here is my conversation controller
class ConversationsController extends Controller
{
private $r;
private $auth;
public function __construct(ConversationRepository $conversationRepository, AuthManager $auth)
{
$this->r = $conversationRepository;
$this->middleware('auth');
$this->auth = $auth;
}
public function index (User $user){
$me = Auth::user();
//dd(Auth::user());
return view('conversations/index', [
'users'=>$this->r->getConversations(Auth::user()->id),
'unread' => $this->r->unreadCount(Auth::user()->id)
]);
}
public function show (User $user){
$me = Auth::user();
$messages = $this->r->getMessagesFor($me->id, $user->id)->paginate(5);
$unread = $this->r->unreadCount($me->id);
if (isset($unread[$user->id])) {
$this->r->readAllFrom($user->id, $me->id);
unset($unread[$user->id]);
}
return view('conversations/show', [
'users'=>$this->r->getConversations($me->id),
'user'=>$user,
'messages'=>$messages,
'unread' => $unread
]);
}
public function store (User $user, StoreMessageRequest $request){
$message = $this->r->createMessage(
$request->get('content'),
Auth::user()->id,
$user->id
);
$user->notify(new MessageReceived($message));
return redirect(route('conversations.show', ['id'=>$user->id]));
}
}
And here is my conversation repository
class ConversationRepository
{
private $user;
private $message;
public function __construct(User $user, Message $message)
{
$this->user = $user;
$this->message = $message;
}
public function getConversations(int $userId)
{
$conversations = $this->user->newQuery()
->select('name','surname','photo','id')
->where('id', '!=', $userId)
->whereType('jobber')
->get();
return $conversations;
}
public function createMessage(string $content, int $from, int $to)
{
return $this->message->newQuery()->create([
'content'=>$content,
'from_id'=>$from,
'to_id'=>$to,
'created_at'=>\Carbon\Carbon::now()
]);
}
public function getMessagesFor(int $from, int $to) : Builder
{
return $this->message->newQuery()
->whereRaw("((from_id = $from AND to_id = $to )OR(from_id = $to AND to_id = $from))")
->orderBy('created_at', 'DESC')
->with([
'from'=> function ($query){ return $query->select('name', 'id');}
]);
}
//Recupere le nombre de message non lu pour chaque conversation
public function unreadCount (int $userId)
{
return $this->message->newQuery()
->where('to_id', $userId)
->groupBy('from_id')
->selectRaw('from_id, COUNT(id) as count')
->whereRaw('read_at IS NULL')
->get()
->pluck('count', 'from_id');
}
THis is my user model
public function messages()
{
return $this->hasMany('App\Message', 'from_id', 'to_id', 'content');
}
This is message model
public function user()
{
return $this->belongsTo('App\User');
}
Any help will be welcome
I'm not sure I am understanding what you want to do but here is a possible solution assuming you want to get all messages that are to you.
In your repository:
$this->message->where('to_id',Auth::user()->id)->get();
Related
I have a relationship between post and tag in post show page I'm trying to display post related to the post show content but excluding the main show content it's not working and I'm not getting error.
class PostShow extends Component
{
public $post;
public $body;
public $slug;
public $comment;
public function mount(Post $post) {
$this->post = $post;
}
protected $rules = [
'comment' => 'string|required|min:3|max:5000',
];
protected $listeners = [
'commentWasAdded'
];
public function commentWasAdded() {
$this->post->refresh();
}
public function render() {
$post = Post::where('slug', '=', $slug)->first();
$related = Post::whereHas('tags', function ($q) use ($post) {
return $q->whereIn('name', $post->tags->pluck('name'));
})
->where('id', '!=', $post->id) // So you won't fetch same post
->get();
return view('livewire.post-show',[
'related' => $related,
]);
}
}
I'm currently trying to make a favorite functionality to my laravel application. I'm trying to access the post table with eloquent, but it says property posts(the function in the favorite model) does not exist.
Update: I updated the query. If I dump $favorite I get two items, which is correct, but now I get this error message instead:Property [posts] does not exist on the Eloquent builder instance. (View: C:\xampp\laravelprojects\Skakahand\resources\views\profile\index.blade.php)
<div class="favorite-section">
<p>Mina favoriter</p>
{{$favorite->posts->title}}
</div>
This is my controller:
public function index(User $user)
{
$favorite = Favorite::where('user_id', auth()->user()->id)
->get();
return view('profile.index',[
'user' => $user,
'favorite' => $favorite
]);
}
Favorite model:
class Favorite extends Model
{
use HasFactory;
protected $fillable = [
'user_id'
];
public function users()
{
return $this->belongsTo(User::class);
}
public function posts()
{
return $this->belongsTo(Post::class);
}
}
and post model:
class Post extends Model
{
use HasFactory;
/* use Sluggable; */
protected $fillable = [
'title',
'body',
'category',
'decision',
'number',
'place',
'image_path',
'slug',
'price',
'user_id',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function favorites(){
return $this->hasMany(Favorite::class);
}
}
First correct Model like this
class Favorite extends Model
{
use HasFactory;
protected $fillable = [
'user_id',
'post_id',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function post()
{
return $this->belongsTo(Post::class);
}
}
In controller change code like this for for avoid lazy loads
public function index(User $user)
{
$favorites = Favorite::where('user_id', auth()->user()->id)
->with('post')
->get();
return view('profile.index',[
'user' => $user,
'favorites' => $favorites
]);
}
in blade use code like
<div class="favorite-section">
<p>Mina favoriter</p>
<ul>
#foreach($favorites as $favorite)
<li>{{ $favorite->post->title ?? '' }} </li>
#endforeach
</ul>
</div>
just include ->with() for relationship,
your query should look like this
$favorite = Favorite::where('user_id', auth()->user()->id)->with('post')
->get();
return view('profile.index',compact('favorite','user'));
Now I try to connect an Ionic3 test app with laravel 5.4 API data.
Ionic code is click here
So, my goal is to show list page in Ionic3 app.
But there are nothing to show.
Could you some advice where I modify code?
Thank you in advence.
Laravel 5.4 API
namespace App\Http\Controllers;
use App\Customer;
use Illuminate\Http\Request;
class CustomerController extends Controller
{
public function index()
{
$customer = Customer::all();
return response()->json($customer);
}
public function store(Request $request)
{
$this->validate($request, [
'name'=>'required',
'email' =>'required',
'tel' =>'required',
]);
$customer = Customer::create($request->all());
return response()->json($customer);
}
public function show($id)
{
$customer = Customer::find($id);
return response()->json($customer);
}
public function update(Request $request, $id)
{
$customer = new Customer;
$customer->name = $request->input('name');
$customer->email = $request->input('email');
$customer->tel = $request->input('tel');
$customer->address = $request->input('address');
$customer->note = $request->input('note');
$customer->save();
return response()->json($customer);
}
public function destroy($id)
{
$customer = Customer::find($id);
$customer->delete();
return response()->json($customer);
}
}
I'm trying to save my Pivot but nothing happened, it doesnt prompt any error I dunno where to debug cause there is no prompt, any idea ? attached here is my code.
Controller note: Email and Name is updating properly.
public function update(Request $request, User $User)
{
$user=auth()->user();
$User->name = $request->get('name');
$User->email = $request->get('email');
$User->warehouse_id = $request->get('warehouse_id');
$User->role_id = $request->get('role_id');
$User->save();
$User->roles()->updateExistingPivot($request->get('role_id'), ['role_id' => $request->get('role_id')]);
$User->warehouse()->updateExistingPivot($request->get('warehouse_id'), ['warehouse_id' => $request->get('warehouse_id')]);
return redirect()->route('user.index');
}
Model for relationship
Warehouse
class Warehouse extends Model
{
protected $fillable = ['warehouse','warehouse_description','created_by'];
public $primaryKey='id';
public function users()
{
return $this->belongsToMany(User::class);
}
}
User
public function roles()
{
return $this->belongsToMany(Role::class);
}
public function warehouse()
{
return $this->belongsToMany(Warehouse::class);
}
Role
class Role extends Model
{
protected $fillable = ['role'];
public $primaryKey='id';
public function users()
{
return $this->belongsToMany(User::class);
}
}
What I did was putting isnerting the previews id before yusing updateExistingPivot
Here is my Controller
public function update(Request $request, User $User)
{
$User->name = $request->get('name');
$User->email = $request->get('email');
$User->warehouse_id = $request->get('warehouse_id');
$User->role_id = $request->get('role_id');
$User->roles()->updateExistingPivot($User->role_id, ['role_id' => $request->get('role_id')]);
$User->warehouse()->updateExistingPivot($User->warehouse_id, ['warehouse_id' => $request->get('warehouse_id')]);
$User->save();
return redirect()->route('user.index');
}
Here is my MessageController.php file
class MessageController extends Controller
{
protected $authUser;
public function __construct()
{
$this->middleware('auth');
Talk::setAuthUserId(Auth::user()->id);
View::composer('partials.peoplelist', function($view) {
$threads = Talk::threads();
$view->with(compact('threads'));
});
}
public function chatHistory($id)
{
$conversations = Talk::getMessagesByUserId($id);
$user = '';
$messages = [];
if(!$conversations) {
$user = User::find($id);
} else {
$user = $conversations->withUser;
$messages = $conversations->messages;
}
return view('messages.conversations', compact('messages', 'user'));
}
public function ajaxSendMessage(Request $request)
{
if ($request->ajax()) {
$rules = [
'message-data'=>'required',
'_id'=>'required'
];
$this->validate($request, $rules);
$body = $request->input('message-data');
$userId = $request->input('_id');
if ($message = Talk::sendMessageByUserId($userId, $body)) {
$html = view('ajax.newMessageHtml', compact('message'))->render();
return view('messages.conversations', compact('messages', 'user'));
}
}
}
public function ajaxDeleteMessage(Request $request, $id)
{
if ($request->ajax()) {
if(Talk::deleteMessage($id)) {
return response()->json(['status'=>'success'], 200);
}
return response()->json(['status'=>'errors', 'msg'=>'something went wrong'], 401);
}
}
i am trying to send a message from this form
<form action="{{url('/message_send')}}" method="post" id="talkSendMessage">
<textarea name="message-data" id="message-data" placeholder ="Type your message" rows="3"></textarea>
<input type="hidden" name="_id" value="{{#request()->route('id')}}">
<button type="submit">Send</button>
</form>
but it doesnt work, an error saying NotFoundHttpException in RouteCollection.php line 161: and here is my routes.php file
Route::get('message/{id}', 'MessageController#chatHistory')->name('message.read');
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
Route::post('message_send', 'MessageController#ajaxSendMessage')->name('message.new');
Route::delete('message/delete/{id}', 'MessageController#ajaxDeleteMessage')->name('message.delete');
});
I dont understand where the error is coming from??
You have missed the prefix you defined in your route group.
Route::group(['prefix'=>'ajax', 'as'=>'ajax::'], function() {
You have to add the prefix as well to the form's action,
<form action="{{url('/ajax/message_send')}}" method="post" id="talkSendMessage">