Laravel eloquent arrays to remove matching - php

I have to two eloquent returned arrays :
$services = \App\Service::all();
$userService = \App\UserService::where('user_id', Auth::user()->id)->get();
What i tried is that :
#foreach($services as $service){
#foreach($userServices as $userService){
#if($userService->service_id != $service->id)
<option value="{{ $service->id }}">{{ $service->name }}</option>
#endif
#endforeach
#endforeach
But its repeating the options, And creating mess.
What will be a good approach ?

You can try this out:
$userServices = \App\UserService::where('user_id', Auth::user()->id)
->pluck('service_id')->toArray();
$services = \App\Service::whereNotIn('id',$userServices)->get();
//Now you can loop through services
#foreach($services as $service){
<option value="{{ $service->id }}">{{ $service->name }}</option>
#endforeach
Hope it helps...

You need to use nested relations in your model. Like this;
class Service extends Model
{
public function user_service()
{
return $this->hasMany(UserService::class, 'user_id');
}
}
And Controller
$user_id = Auth::user()->id;
$services = Service::with(['user_service' => function ($query) use ($user_id) {
$query->where('user_id', $user_id);
}])->get();
return view('page', compact('services'));

i have read the code
$services = \App\Service::all();
$userService = \App\UserService::where('user_id', Auth::user()->id)->get();
and
#foreach($services as $service){
#foreach($userServices as $userService){
#if($userService->service_id != $service->id)
<option value="{{ $service->id }}">{{ $service->name }}</option>
#endif
#endforeach
#endforeach
Userservice is sufficient to what you want to do, no need to retrieve data twice. you can simply find all service for the logged user in you query
$user_id = Auth::user()->id;
return Service::with(['user_service' => function ($query) use ($user_id) {
$query->where('user_id', $user_id);
}])->get();
or try to make a inner joins with raw query.

If you don't want to change your approach just change != to ==
#if($userService->service_id == $service->id)
Or if you want a good approach try eloquent.
Your models seems to be many to many relationship
Visit this link https://laravel.com/docs/5.4/eloquent-relationships#many-to-many

Related

Laravel Auth::user()->id returns null on livewire form

I'm try to get Auth::user()->id as my form value. It can shows on the label but it return value null.
View :
<option value="{{ Auth::user()->id }}" data-keterangan="">{{ Auth::user()->id }}</option>
Http/Livewire :
$this->validate([
'customer_code'=>'required|string',
'customer_name'=>'required|string',
'phone_number'=>'required|string'
]);
StokItem::updateOrCreate([
'customer_code'=>$this->customer_code,
'customer_name'=>$this->customer_name,
'phone_number'=>$this->phone_number
]);
Model :
protected $fillable = ['id','customer_code','customer_name','phone_number','produk_code','produk_name','produk_uom','qty','kode_kondisi_barang','jenis_kondisi_barang','remark','url_foto','status'];
You cannot do auth()->name(), you need to call the authenticated user by doing auth()->user() then after that get the column you have in your database eg auth()->user()->name
(https://laravel.com/docs/8.x/helpers#method-auth)
In your Livewire Component, you should do something like this
public $id = '';
public $name = '';
public $no_hp = '';
public function mount()
{
$this->id = auth()->id();
$this->name = auth()->user()->name;
$this->no_hp = auth()->user()->no_hp;
}
Make sure your user is authenticate
#auth
<option value="{{ Auth::user()->id }}" data-keterangan="">{{ Auth::user()->id }}</option>
#endauth

Undefined variable: editor (View: /home/marco/prova/resources/views/home.blade.php)

I have a problem, blade not find the variable: editor.
This is the function of my Controller.
public function HomeText()
{
$data = [];
$data['editor'] = Editore::get();
return view('home')->with($data);
}
And these are the instructions in the file blade.php:
<select class="form-control select_editore">
#foreach ($editor as $editore)
<option>
{{ $editore->id_editore, $editore->nome_editore }}
</option>
#endforeach
</select>
What is the error?
I hope that you help me!
I'm newbie with Laravel,
I want to understand where I'm wrong.
Change it to this if you want to use an array:
return view('home', $data);
If you want to use ->with(), do this:
->with('editor', $data['editor'])
Change this:
public function HomeText()
{
$data = [];
$data['editor'] = Editore::get();
return view('home')->with($data);
}
to this:
public function HomeText()
{
$editor = Editore::all();
return view('home',compact('editor'));
}
and in your blade file
change
<option>{{ $editore->id_editore, $editore->nome_editore }}</option>
to
<option>{{ $editore->id_editore}}, {{$editore->nome_editore }}</option>
you may want to change the way you pass the variable to this
public function HomeText()
{
$data = [];
$data['editor'] = Editore::get(); // or all()
return view('home', $data);
}
then you may now use $editor in your blade ..
In your way of coding you can’t call $editor directly.
You have to use, $data[‘editor’] as $editore
<select class="form-control select_editore">
#foreach ($data[‘editor’] as $editore)
<option>
{{ $editore->id_editore, $editore->nome_editore }}
</option>
#endforeach

How to pass variable from foreach to view?

I'm trying to pass a variable from foreach to my view. So I can access this using in my select form. Because I have two tables M:M relationship between departments and user. I need to get all the department_name where the user_id belong. For me able to send a data via department_name Here what I did please take a look.
DB Diagram:
department_user
As you can see here user_id is the id of the user and document_id is where the users belong.
Model:
Department:
public function users()
{
return $this->belongsToMany('\App\Models\User', 'department_user');
}
User:
public function departments()
{
return $this->belongsToMany('App\Models\Department', 'department_user');
}
Controller:
public function getDocuments()
{
$departmentRecipient = DB::table('departments')->get();
foreach ($departmentRecipient as $department)
{
$department->users = DB::table('department_user')
->where('department_id', '=', $department->id)
->pluck('user_id');
}
return view('document.create')->with('department', $department);
}
I'm getting all the users_id when I die and dump my variable departmentRecipient.
View:
<div class = "form-group">
<label for = "recipient" class = "control-label">Recipient:</label>
<select name = "recipient[]" multiple class = "form-control select2-multi" id = "myUserList">
#foreach ($department as $list)
<option value = "{{ $list->user_id }}">{{ $list->department_name }}</option>
#endforeach
</select>
</div>
I wanted to foreach the $department in my Controller to my select form. But it always says.
Trying to get property of non-object (View: C:\Users\JohnFrancis\LaravelFrancis\resources\views\document\create.blade.php)
Goal:
Use the following loop to iterate through the department users and add them to pivot table.
foreach($request->department as $departmentId)
{
foreach(Department::find($departmentId->id)->users()->get() as $user1) //find the users belonging to the current department
{
$document->sentToUsers()->sync([ $user1->id => ['sender_id' => $user->id]],false );
}
}
Also remove the following code form your getDocuments() as it is redundant:
foreach ($departmentRecipient as $department)
{
$department->users = DB::table('department_user')
->where('department_id', '=', $department->id)
->pluck('user_id');
}
I don't see user_id property in your dumped value of $departmentRecipient object, that is why you are getting the error you mentioned. However, there is a users array inside of $departmentRecipient object, which you made inside your foreach loop. You are plucking every user_id which are in individual department and setting in a property named users of $departmentRecipient object, and so you are getting an array inside users property. Here I have a solution for you,
public function getDocuments()
{
$departmentRecipient = DB::table('departments')->get();
$departmentUsers = array();
foreach ($departmentRecipient as $department)
{
$users = DB::table('department_user')
->where('department_id', '=', $department->id)
->pluck('user_id');
foreach ($users as $userId) {
$departmentUsers[$userId] = $department->department_name;
}
}
return view('document.create')->with('department', $department)->with('departmentUsers', $departmentUsers);
}
and inside of your view loop through the variable $departmentUsers, like this,
#foreach ($departmentUsers as $userId => $departmentName)
<option value = "{{ $userId }}">{{ $departmentName }}</option>
#endforeach
This will work but as your department contains multiple users so you will get individual department name multiple time in your select2 dropdown. If you share more of what is your goal by select2 then may be I can help you to solve your problem in other way.
Moreover if you are interested to use of Eloquent then you can get rid of lots of foreach looping.
In your case you can have multiple users against each department. So to make it work correctly with your forearch code. You need to make sure you are getting one user record against each depart. So modify following line of code in controller.
$department->users = DB::table('department_user')->where('department_id', '=', $department->id)->pluck('user_id');
But you want to display all users of department then you have to change foreach loop code into view.
Try This Code
App/Department
public function users()
{
return $this->belongsToMany('App\Entities\User', 'department_user', 'user_id', 'department_id');
}
App/User
public function departments()
{
return $this->belongsToMany('App\Models\Department', 'department_user');
}
Controller
use App/User;
public function getDocuments($userId,User $User)
{
$getSpecificUser = $User->with('departments')->find($userid);
return view('document.create')->compact('getSpecificUser');
}
View
#foreach ($getSpecificUser as $getUser)
#if(empty($getUser->departments) === false)
#foreach ($getUser->departments as $departments)
<option value = "{{ $getUser->id }}">{{ $departments->department_name }}</option>
#endforeach
#endif
#endforeach

Laravel 5.2 correct way to use variables in blade

So I know about passing variables via the controller for instance if its a query array I will do
public function index()
{
$query = Request::get('q');
if ($query) {
$users = User::where('username', 'LIKE', "%$query%")->get();
}
return view('view', compact('users'));
}
And when on the blade I will do
#if( ! empty($users))
#foreach($users as $user)
{{ $user->username }}
#endforeach
#endif
Now my question is how do I set a variable using a variable from the foreach? at the moment I am using PHP inside of the blade template file but I feel this is messy, here is what I have
#if( ! empty($users))
#foreach($users as $user)
<?php
$lastOnline = \Carbon\Carbon::createFromTimeStamp(strtotime($user->last_online))->diffForHumans();
$fiveMinsAgo = \Carbon\Carbon::now()->subMinute(5);
?>
{{ $user->username }}
#if ($user->last_online <= $fiveMinsAgo)
{{ $lastOnline }}
#else
Online Now
#endif
#endforeach
#endif
found a solution to my issue if anyone else is ever looking for it.
public function getLastOnlineAttribute($value)
{
$fiveMinsAgo = \Carbon\Carbon::now()->subMinute(5);
$thirtMinsAgo = \Carbon\Carbon::now()->subMinute(30);
$lastOnline = \Carbon\Carbon::createFromTimeStamp(strtotime($value))->diffForHumans();
if ($value <= $fiveMinsAgo) {
echo 'Last Active: '.$lastOnline.'';
}
else {
echo 'Online Now';
}
}
Basically add this into your model for the variable (eg, if its a $user->last_online it would go into the user model) , it is called a eloquent mutator if you are ever looking for more info, https://laravel.com/docs/master/eloquent-mutators
It grabs your data for the variable for instance {{ $user->last_online }}
Note that the Underscore is transformed into a CamelCase in the function name, the output is set at $value, you can then set variables inside of the function and mould the output however you wish, then in the blade you can get rid of all the extra crap and just use {{ $user->last_online }}

Bookmark an article in Laravel

I am trying to create a functionality for a user to be able to bookmark and article and remove the article from his bookmarks as well. The functionality to bookmark an article works just fine, but when I try to remove the article from the bookmarks then it does not work and instead it inserts the same record but with the article_id being NULL.
Here is my controller:
public function postBookmark() {
$user_id = Auth::user()->id;
$article_id = Input::get('id');
$bookmark = Bookmark::where('user_id', '=', $user_id)->where('article_id', '=', $article_id);
$article = Article::where('id', '=', $article_id);
$article = $article->first();
// I want to check if the article has been already bookmarked by the same user
// but this if statement always returns true
if(!empty($bookmark)) {
$bookmark = Bookmark::create(array(
'user_id' => $user_id,
'article_id' => $article_id,
));
if($bookmark) {
return View::make('article.view')
->with('article', $article)
->with('bookmarked', true);
}
} else {
// Does not work
$bookmark->delete();
return View::make('article.view')
->with('article', $article)
->with('bookmarked', false);
}
return Redirect::route('article-all')
->with('global', 'We were unable to bookmark the article. Please, try again later.');
}
And here is part of my view:
{{ Form::open(array('action' => 'BookmarkController#postBookmark')) }}
<input
type="checkbox"
name="id"
onClick="this.form.submit()"
value="{{ $article->id }}"
id="bookmark"
{{ $bookmarked ? 'checked' : '' }}
/>
<label for="bookmark">Bookmark</label>
{{ Form::close() }}
I do also have a route with a post method for this functionality. I would highly appreciate if anyone could give any idea of why it does not work.
You are not executing your bookmark query.
The $boomark variable in your code example is a Illuminate\Database\Eloquent\Builder object and empty($boomark) will return always false because there is a object stored.
To execute a query you can use get() for example. In your case you want only one result, then you use first() to retrieve the first found bookmark object.
Change:
$bookmark = Bookmark::where('user_id', '=', $user_id)->where('article_id', '=', $article_id);
To this:
$bookmark = Bookmark::where('user_id', '=', $user_id)->where('article_id', '=', $article_id)->first();
Then it should work fine.
If you really want, changing the condition if(!empty($bookmark)) to if ($bookmark->count()) { might do the trick, but it will do another query with COUNT() to the DB and it is not really a good way of doing it.
The problem is with if(!empty($bookmark)), because $bookmark has a QueryBuilder instance, it will never be empty.
The preferred way would be using Eloquent model relations. With relationships you could check by Article::has('bookmark') for instance.
Thanks for the help. I ended up using both of your solutions.
public function postBookmark() {
$user_id = Auth::id();
$article_id = Input::get('id');
$bookmark = User::find($user_id)->bookmarks()->where('article_id', '=', $article_id)->first();
if(empty($bookmark)) {
$bookmark = Bookmark::create(array(
'user_id' => $user_id,
'article_id' => $article_id,
));
if($bookmark) {
return Redirect::route('article-get', array('article_id' => $article_id));
}
} else {
$bookmark->delete();
return Redirect::route('article-get', array('article_id' => $article_id));
}
return Redirect::route('article-all')
->with('global', 'We were unable to bookmark the article. Please, try again later.');
}
Nonetheless, what I really needed to fix was my view. For some reason the id of my input was not being submitted properly, so I ended up creating a hidden field for it as well.
{{ Form::open(array('action' => 'BookmarkController#postBookmark')) }}
<input
type="checkbox"
name="id"
onClick="this.form.submit()"
value="{{ $article->id }}"
id="bookmark"
{{ $bookmarked ? 'checked' : '' }}
/>
<input
type="hidden"
name="id"
value="{{ $article->id }}"
/>
<label for="bookmark">Bookmark</label>
{{ Form::close() }}

Categories