Mark as read after accept friend's request - php

I have a simple function to accept a friend's request:
public function acceptFriend($id){
$user = User::find($id);
$sender = Auth::user();
$sender->acceptFriendRequest($user);
return redirect()->back();
}
It work's correctly but if other user send a friend's request, he send a notification. I want to mark as read it after accept request but I have a problem.I don't know how I can do query building to check this one notify. I know I can make a new function and like attirute use notify id but user of my website can accept request not only in notify list but in user's profile too.
I thought about read information form "data" column from "notifications" table but I have a problem. I try a few of query buildings:
$hello = auth()->user()->unreadNotifications->where('notifiable_id', Auth::user()->id)
->where('data->arr->id', '12')->first();
or
$hello = auth()->user()->unreadNotifications->where('notifiable_id', Auth::user()->id)
->where('data', '%12%')->first();
But it doesn;t works. "12" is id of sender,
The table structure is the normal notifications structure:
Schema::create('notifications', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->string('type');
$table->morphs('notifiable');
$table->text('data');
$table->timestamp('read_at')->nullable();
$table->timestamps();
});
The data column will contain an array such as:
{
"title":"Something",
"arr":{
"id":12,
"name":"HelloWorld",
"avatar":null
}
}

You will need the Query Builder equivalent of a LIKE query.
->where('data', '%12%') will generate SQL: data = '%12%' returning no results.
->where('data', 'like', '%12%') will generate SQL: data like '%12%' which should work.

Related

Laravel display the query parameter in the url

I have users table and each user have a column for 'qr_url' and it's a random 170 characters length string generated with Str::random
I have a page that displays all the users and for each user there is a button named inquiry to check if the user exists in the database
I have a route name inquiry that check if this qr_url already for a user or not
Route::get('/users/inquiry/{query}', [UserController::class, 'inquiry'])->name('users.inquiry');
in the inquiry() function I receive this query that contain the qr_url
public function inquiry($query)
{
$user = User::where('qr_url', '=', $query)->first();
return view('users/inquiry', compact('user'));
}
I need to know how can I make the URL looks like that
http://example.com/Home/GetResultByQR?query=theqr_url
Hello guy you should use request()->get('query'). For example:
public function inquiry()
{
$user = User::where('qr_url', '=', request()->get('query'))->first();
return view('users/inquiry', compact('user'));
}

Laravel 6 - Affiliate Tracking User Registeration

As u guys can see in Image Above, i want to create referral_system that user can register and input referral_user from affiliate users.
And Referral_Code is unique for every user.
My Problem is I cant track Whom that code is.
My User Schema
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('referrer_id')->nullable();
$table->foreign('referrer_id')->references('id')->on('users');
$table->string('referral_code')->unique()->nullable();
$table->string('referred_by')->nullable();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
My User Model
public function referrer()
{
return $this->belongsTo(User::class);
}
public function referrals()
{
return $this->hasMany(User::class);
}
In My UserController
$referrer = User::where('name', auth()->user()->name)->first();
$user = new User();
$user->name = $request->name;
$user->referral_code = substr(uniqid(), 0, 8); // for unique id
$user->email = $request->email;
$user->referrer_id = $referrer ? $referrer->id : null;
$user->role = $request->role;
$user->password = bcrypt($request->password);
$user->save();
return response()->json([
'created' => true,
]);
Hope u guys will give me some idea and if u notice mistake in my code, pls correct me, I'll appreciate of all ur help.
Thanks...
I believe you're confusing Laravel relationships. hasOne, belongsTo, etc are not designed to be worked with in the same model. Basically what you're saying in Users model is that "User has a User where user_id = id" which makes no sense.
I have no idea how you've designed your sql tables, I recommend you to split your entities in distinct parts and have pivot tables which binds them: users, affiliates, referrals
- users table have : "id"
- affiliates table have: "id", "refferal_code"
- refferals table have : "id", "affiliate_id", "user_id", "refferal_code"
You tie a user with an affiliate through refferals table, through their IDs.
Then create relationships between those. You may want to read more about Eloquent relationships as well. Hope this answer helps you.

Laravel retrieve data with condition from many-to-many condition

I have three tables:
email_accounts (list of business emails)
-------------
id
email
sender_name
users
------
id
name
email
email_accounts_users
--------------------
email_account_id
user_id
And the eloquent relationship is declared as:
User
------
public function emailAccounts()
{
return $this->belongsToMany(EmailAccount::class,'email_accounts_users');
}
EmailAccount
------------
public function users()
{
return $this->belongsToMany(User::class,'email_accounts_users');
}
I am trying to fetch rows from email_accounts that belongs to current user.
This could be correctly fetched as:
$email_acc = \DB::table('email_accounts')
->join('email_accounts_users', 'email_accounts_users.email_account_id', 'email_accounts.id')
->join('users', 'users.id', 'email_accounts_users.user_id')
->select('email_accounts.*')
->where('user_id',auth()->user()->id)
->get();
dd($email_acc);
However, I am trying to get with laravel eloquent model.
So, I tried as follows:
$email_acc = EmailAccount::with(['users' => function(){
$query->where('users_id',auth()->user()->id)
}])->get();
dd($email_acc);
However, its returning all the emails from email_accounts, rather its filtering the data from users table and sending only the currently logged in user. from users table.
However, my requirement is to fetch emails form email_accounts that belong to currently logged in users.
Like
Try This
$email_acc = EmailAccount::whereHas('users', function($query) {
$query->where('id',auth()->user()->id);
})
->get();
dd($email_acc);
It will return empty collection if the record doesn't exixts
or you can also fetch using logged in user instance
$user = auth()->user();
return $user->emailAccounts;
Make sure you defined a perfect relationship
Read Querying Relationship Existence
Specify foreign keys as follows
public function emailAccounts()
{
return $this->belongsToMany(EmailAccount::class,'email_accounts_users', 'id', 'email_account_id' );
}
EmailAccount
------------
public function users()
{
return $this->belongsToMany(User::class,'email_accounts_users', 'id', 'user_id');
}

using a foreign key or not?

I have a table named 'Feedbacks' with 5 fields:
('id', 'user_id', 'instruction', 'description', 'fk_eleve')
The admin can create several recordings, here is a screenshot.
Here, I have a recording which is Menier Jeremy it's the student
In my rubric 'Eleves' (english: Student) we can see several recordings:
Here, Menier Jeremy has like email address test#gmail.com.
Menier Jeremy wants to connect...
There are 2 rubrics for now:
- Student Profil and Feedback
the user Menier Jeremy can see his profil
However, when the user wants to see his 'feedback'.
Unfortunately, I get the following error message:
SQLSTATE [42S22]: Column not found:
1054 Field Field 'email' unknown in where (SQL: select count (*) as aggregate fromreturnswhere email= test#gmail.com)
I have a problem with the email ?
public function index(Request $request)
{
$user = $request->user();
$feedbacks = Feedback::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
$query->where('email', $user->email);
})
->when($request->has('search'), function (Builder $query) use ($request) {
$query->join('eleves', 'feedbacks.fk_eleve', '=', 'eleves.id')
->orderBy('eleves.nom', 'asc')
->where('eleves.nom', 'like', '%'.$request->input('search').'%');
})
->paginate(5);
return view('admin.feedbacks.index', compact('feedbacks'))
->with('display_search', $user->hasRole('admin'));
}
Do know you where is the problem?
Thank you a lot
Edit code #Watercayman
When, the user Jeremy Menier is connected, I see several recordings:
I have to retrieve only ID n° 1
public function index(Request $request)
{
$user = $request->user();
$feedbacks = Feedback::query()
->when($user->hasRole('admin') !== true, function (Builder $query) use ($user) {
\Auth::user()->load('feedbacks');
$feedbacksForThisUser = \Auth::user()->feedbacks;
})
->when($request->has('search'), function (Builder $query) use ($request) {
$query->join('eleves', 'feedbacks.fk_eleve', '=', 'eleves.id')->orderBy('eleves.nom', 'asc')->where('eleves.nom','like','%'.$request->input('search').'%');
})
->paginate(5);
return view('admin.feedbacks.index', compact('feedbacks'))
->with('display_search', $user->hasRole('admin'));
}
My model User:
public function feedbacks()
{
return $this->hasMany('App\Feedback', 'user_id', 'id');
}
My model Feedback
public function user()
{
return $this->belongsTo('App\User', 'id', 'user_id');
}
Sure, you can get the email for the users that have provided feedback using the FK. But I don't think you need all of the query you are using. I think you can make this much simpler. Because the user has a relation with the Feedback model (I assume through an Eleve model), you can simply eager load the relationship using the name search if you wish:
// Note I have removed the query() method you had in your original query
$feedbacks = Feedback::with('eleves', function ($query) use($request)
$query->orderBy('eleves.nom','asc')->where('eleves.nom','like','%'.$request->input('search').'%');
})->paginate(5);
To simplify the explanation I've removed the where from the query. To demonstrate I'll just use an if check before the query - you can make this more complex if you wish, but it is a little easier to see this way.
Something like:
if($request->has('search'){ do the query above }
else { $feedbacks = Feedback::with('eleves')->paginate(5); }
Then, because you have pulled the relations, you can then just get the email from any eleves that have been loaded:
$feedback->first()->eleve->email
So if you use the $feedbacks in a loop in your blade file:
#foreach($feedbacks as $feedback)
{{ $feedback->eleve->email }}
#endforeach
OK, I think because of the edit, the question is pretty different than what was first asked, so I'll add another answer rather than try to convey this in the comments.
I think you are asking that when the user tries to see his feedbacks, you are getting the SQL error. If the user is selecting the feedback option, it may only be the single user that is looking for his own feedbacks. I suggest you change your query to the reverse (pull the feedbacks from the user instead of pulling all the feedbacks and then getting user to match):
\Auth::user()->load('feedbacks');
$feedbacksForThisUser = \Auth::user()->feedbacks;
Or if you want to get another user's feedbacks (and the user has permission to see them), just query on that user:
$user = User::with('feedbacks')->find($idOfUserYouWantToSee);
$feedbacks = $user->feedbacks;
Same thing goes for if you want to search for feedbacks from a user with a specific name:
$user = User::with('feedbacks')->where('nom','like','%'.$request->input('search').'%')->first();
$feedbacksForSearchedUser = $user->feedbacks;
The key is to forget about the emails - the relationship will link all feedbacks to the user. You don't need to join, or query on the email. You always have it on the $user object. (i.e. $user->email will always work).
If you want to see ALL feedbacks from ALL users, this isn't really any harder, just query all users and eager load the feedbacks relationship:
$users = User::with("feedbacks")->get();
Then in your blade:
#foreach($users as $user)
// If you want to display only a special set of users to the Auth::User(), then do an if-check here
#if(\Auth::user()->hasPerm("someperm") && $user->isInSomeCategory)
#foreach($user->feedbacks as $feedback)
{{ $feedback->text // or whatever the field you want to show }}
#endforeach
#endif // The if check is totally optional in this - just giving you an example
#endforeach
EDIT: to show a simple index()
public function index(Request $request)
{
if(!\Auth::user()->hasRole('admin')) {
\Auth::user()->load('feedbacks');
$feedback = \Auth::user()->feedbacks;
}
elseif($request->has('search')) {
$user = User::with('feedbacks')->where('nom','like','%'.$request->input('search').'%')->first();
$feedbacks = $user->feedbacks;
}
return view('admin.feedbacks.index', compact('feedbacks'));
}
Note: to make this as simple as possible, I also removed:
->with('display_search', $user->hasRole('admin'));
You can check this on the Blade page because \Auth::user() is already loaded automatically.

How to delete data in multiple table database without using any relationship in Laravel

I have 2 table in my database.
first is table post
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->date('PostDate');
$table->string('PostTitle', 200);
$table->string('GroupID', 100)->nullable();
$table->integer('LanguageID')->default(1);
$table->timestamps();
});
second is table post_categories
Schema::create('post_categories', function (Blueprint $table) {
$table->integer('post_id');
$table->integer('category_id');
$table->timestamps();
});
Every time I store post data into database, it will stored as two rows.. because I have two active language. In my post_categories table, there has category_id column.. So, if the post data with id = 1 has 2 categories.. and the post data with id = 2 has 3 categories, it will create 5 rows in post_categories table.
But when I want to delete the post, I will check from the group ID first.. So, I will delete 2 rows too..
But the problem is, I can not delete the data in post_categories.. I have using foreach but the data won't be deleted..
This is my delete Controller:
public function destroy($id)
{
$post = Post::findOrFail($id);
Post::where('GroupID', $post->GroupID)->delete();
$postGroups = Post::where('GroupID', $post->GroupID)->get();
foreach ($postGroups as $postGroup) {
DB::table('post_categories')->where('post_id', $postGroup->id)->delete();
}
return response()->json([
"error" => "0",
"message" => "Success"
]);
}
I can delete all the post with same group ID, but I can not delete the post_categories data that has same post_id.
You've already chosen the answer, but in your case it's much better to use whereIn():
$post = Post::findOrFail($id);
$postGroups = Post::where('GroupID', $post->GroupID)->get();
DB::table('post_categories')->whereIn('post_id', $postGroups->pluck('id'))->delete();
Post::where('GroupID', $post->GroupID)->delete();
Delete the categories before deleting the post.
public function destroy($id)
{
$post = Post::findOrFail($id);
$postGroups = Post::where('GroupID', $post->GroupID)->get();
foreach ($postGroups as $postGroup) {
DB::table('post_categories')->where('post_id', $postGroup->id)->delete();
}
Post::where('GroupID', $post->GroupID)->delete();
return response()->json([
"error" => "0",
"message" => "Success"
]);
}
In order to have a better code experience, I recommend using a table structure like posts, posts_categories and posts_languages. This last one will contain the data regarding the content in multiple languages, and will be related to posts

Categories