Removing duplicates from laravel eloquent - php

Inside my controller I have following function,
public function index($locale, Company $company, Department $department, Request $request)
{
$this->authorize('viewUsers', [Department::class, $company, $department]);
$users = $department->usersWithSubcontractors()
// ->notApiUser()
->select(
'users.id',
'first_name',
'last_name',
'job_title',
'email',
'phone_number',
'unique_id',
'phone_country_calling_code',
'country_id',
'company_name',
'is_subcontractor',
)->addSelect([
'current_jobtitle' => JobTitle::selectRaw('IFNULL(project_specific_job_titles.title, job_titles.title)')
->join('project_track_records', 'project_track_records.user_id', 'users.id', 'inner')
->join('project_specific_job_titles', 'project_track_records.project_specific_job_title_id', 'project_specific_job_titles.id', 'inner')
->whereColumn('job_titles.id', 'project_specific_job_titles.job_title_id')
->whereDate('project_track_records.start_date', '<=', Carbon::now())
->whereDate('project_track_records.end_date', '>=', Carbon::now())
->limit(1),
'dept_user_id' => DepartmentUser::selectRaw('id')->wherecolumn('users.id','department_user.user_id')->limit(1),
'department_jobtitle' => JobTitle::selectRaw('title')->whereColumn('job_titles.id', 'department_user.job_title_id'),
])->when(request('q'), function ($q) {
$q->where(function ($q) {
$q->whereRaw("CONCAT_WS(' ', `first_name`, `last_name`) like '%" . request('q') . "%'");
});
})->when($request->get('employeeType'), function ($q) use ($request) {
$q->whereIn('users.is_subcontractor', $request->get('employeeType'));
})->paginate(\request('per_page', config('repository.pagination.limit')));
$users->load('country');
$users->append(['profile_image']);
$users->makeVisible(['unique_id']);
$users->map(fn ($item) => $item->certificate_matrix = (new GetCertificationMatrixQueryAction())->execute($item->id, $department->id));
if ($request->filled('certificateStatus')) {
$valid = in_array('valid', $request->get('certificateStatus'));
$expire_soon = in_array('expire soon', $request->get('certificateStatus'));
$expired = in_array('expired', $request->get('certificateStatus'));
if ($valid) $users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && !$certificate->expire_soon && !$certificate->expired)->count() === $item->certificate_matrix->count())->values());
if ($expire_soon && !$expired) $users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && $certificate->expire_soon)->count() > 0)->values());
if ($expired && !$expire_soon) $users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && $certificate->expired)->count() > 0)->values());
}
if ($request->filled('matrixStatus')) {
$compliant = in_array('compliant', $request->get('matrixStatus'));
$non_compliant = in_array('non-compliant', $request->get('matrixStatus'));
if ($non_compliant && !$compliant)
$users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status === 0 || $certificate->expire_soon || !$certificate->expired)->count() > 0)->values());
if ($compliant && !$non_compliant)
$users->setCollection($users->filter(fn ($item) => $item->certificate_matrix->filter(fn ($certificate) => $certificate->matrix_status && !$certificate->expire_soon && !$certificate->expired)->count() == $item->certificate_matrix->count())->values());
}
return response()->json($users);
}
Issue with this list is that, this eloquent gives me duplicate entries. How can I remove duplicates from this eloquent results list? I tried gruop the result by, dept_user_id but this gives me unknown column error....
I'm trying to remove this, as it this gives me duplicate key error on the vue end..

Related

Laravel Eloquent How to apply condition on "with" datas on the output?

here my code :
$prestations = Prestation::with(
[
'service' => function($service) use($searchService) {
$service->select(['id','name'])->where('name', 'regexp', "/$searchService/i");
},
'facility' => function($facility) use($searchPartenaire) {
$facility->select(['id','name'])->where('name', 'regexp', "/$searchPartenaire/i");
}
]
)
->where('name', 'regexp', "/$search/i")
->orderBy($orderBy, $orderDirection)
->simplePaginate(50);
$res = [
'results' => $prestations,
'total' => Prestation::all()->count(),
];
The problem is that in the output of all datas where "service" and "facility" names are not equal on the $searchService and $searchPartenaire the values are replaced by "null".
So i don't want to have values in the output where the search variables are not equals.
Thank you.
you can try like this
$prestations = Prestation::with('service','facility');
$prestations->whereHas('service', function ($query) use ($searchPartenaire) {
$query->Where('name', 'like', '%' . $searchPartenaire . '%');
});
$prestations->whereHas('facility', function ($query) use ($searchPartenaire) {
$query->Where('name', 'like', '%' . $searchPartenaire . '%');
});
$prestations->where('name', 'like', '%'.$search.'%')
->orderBy($orderBy, $orderDirection)
->simplePaginate(50);
return $res = [
'results' => $prestations,
'total' => Prestation::all()->count(),
];
1st create instances of Prestation $prestations = Prestation::with('service','facility')
then apply the condtion this is good approach in seach
Here my code after Kamlesh Paul suggestion :
$prestations = Prestation::with('service','facility');
$prestations->whereHas('service', function ($query) use ($searchService) {
$query->where('name', 'regexp', "/$searchService/i");
});
$prestations->whereHas('facility', function ($query) use ($searchPartenaire) {
$query->where('name', 'regexp', "/$searchPartenaire/i");
});
$prestations->where('name', 'regexp', "/$search/i")
->orderBy($orderBy, $orderDirection)
->simplePaginate(50);
$res = [
'results' => $prestations,
'total' => Prestation::all()->count(),
];
return $res;
But there is an infinite calls of http request, i think that the problem is when the where don't find an equal name, anyone have a suggest ?
Thank's.
I finnaly found a solution very similar :
$prestations = Prestation::with('service','facility')
->whereHas('service', function ($query) use ($searchService) {
$query->where('name', 'regexp', "/$searchService/i");
})
->whereHas('facility', function ($query) use ($searchPartenaire) {
$query->where('name', 'regexp', "/$searchPartenaire/i");
})
->where('name', 'regexp', "/$search/i")
->orderBy($orderBy, $orderDirection)
->simplePaginate(50);
$res = [
'results' => $prestations,
'total' => Prestation::all()->count(),
];
Thank's for your help.

How to fix ''Property [id] does not exist in this statement"

I want to select from 2 table a data to all users and merge this data to object that I want to return
example
{
user:{
id:1,
name:bla,
saved cards:[
{id:1, name:test},
{id:2, name:test2}
]
},
{id:2, name:bla1,
saved cards:[
{id:1, name:test},
{id:2, name:test2},
{id:3, name:test3}
]
}
}
public function getalluser(Request $request)
{
$User_data = User::where('users.role', '=', 0)
->get();
$count = count($User_data);
for ($i = 0; $i < $count; $i++) {
$json_data[] = [
'user' => User::where('users.role', '=', 0)
->where( 'users.id', $User_data->id[$i])
->leftJoin('webrole', 'users.role', '=', 'webrole.id')
->get(),
'saved cards' => User::where('users.role', '=', 0)
->where( 'credit_cards.user_id', $User_data->id[$i])
->leftJoin('credit_cards', 'users.id', '=', 'credit_cards.user_id')
->get()
];
}
return response()->json($User_data);
}
foreach($User_data as $data) {
$json_data[] = [
'user' => User::where('users.role', '=', 0)
->where( 'users.id', $data->id)
->leftJoin('webrole', 'users.role', '=', 'webrole.id')
->get(),
'saved cards' => User::where('users.role', '=', 0)
->where( 'credit_cards.user_id', $data->id)
->leftJoin('credit_cards', 'users.id', '=', 'credit_cards.user_id')
->get()
];
}

How to see matches of search in SQL?

I have a search line where a user enters query divided by commas. I need to find at least 1 matches in the SQL-table. But I need to mark the matches in each found object too. How can I do this?
Working search (Laravel Eloquent (PostgreSQL) without marking matches):
public function searchOfAuthor(Request $request)
{
$search = array_map('trim', explode(',', $request->get('search')));
$columns = [
'city',
'phone',
'email',
'skype',
'icq',
'vk'
];
$authors = AuthorMask::where(function ($query) use ($columns, $search) {
foreach ($search as $searchKey) {
if (!empty($searchKey)) {
$query->orWhere('name', 'ILIKE', '%'.$searchKey.'%');
foreach ($columns as $column) {
$query->orWhere($column, 'ILIKE', $searchKey);
}
}
}
})
->with('author')
->orderByRaw('company_id = ? desc', Auth::user()->company_id)
->paginate(5);
if (empty($authors->items())) {
return response()->json([
'data' => null,
'error' => 'Authors Have Not Been Found'
], 404);
}
return response()->json([
'data' => [
'authors' => $authors
],
'error' => null
], 200);
}
Sorry for my English.
There are nothing condition like ILIKE in laravel or Mysql. There should be LIKE. There are two lines of codes have ILIKE.
$query->orWhere('name', 'ILIKE', '%'.$searchKey.'%');
$query->orWhere($column, 'ILIKE', $searchKey);
Remove I from ILIKE of above two lines. After removing I from ILIKE it should look like
$query->orWhere('name', 'LIKE', '%'.$searchKey.'%');
$query->orWhere($column, 'LIKE', $searchKey);
Did it. Just created new array for mark of matches. Another question: who know how to append array to the object in pagination?
$matches = [];
foreach ($authors->items() as $author) {
$matches[$author->id]['name'] = 0;
foreach ($columns as $column) {
$matches[$author->id][$column] = 0;
}
foreach ($search as $searchKey) {
if (!empty($searchKey)) {
foreach ($author->toArray() as $key => $attribute) {
if (!strcasecmp($searchKey, $attribute)) {
$matches[$author->id][$key] = 1;
}
}
}
}
}
return response()->json([
'data' => [
'authors' => $authors,
'matches' => $matches
],
'error' => null
], 200);

Eloquent calculate if I have more results left

I'm building a Products API. I need to return a collection of products and a variable telling me if I have more results starting from the last the answer has just returned me to show or hide a load more button. This is all I have until now:
$query = Product::query();
$query->where('category_id', $request->get('category_id'));
$query->orderBy('order', 'asc')
->orderBy('name', 'asc')
->skip($skip)
->take($take);
And this is how I return it:
return [
'products' => $query->get(['id', 'name', 'front_image', 'back_image', 'slug']),
'has_more' => ????
];
How can I calculate the has_more?
The easiest approach would be to query the database twice:
$query = Product::query()
->where('category_id', $request->get('category_id'))
->orderBy('order', 'asc')
->orderBy('name', 'asc');
$count = $query->count();
$hasMore = $skip + $take < $count;
$models = $query->skip($skip)
->take($take)
->get(['id', 'name', 'front_image', 'back_image', 'slug']);
return [
'products' => $models,
'has_more' => $hasMore
];
You can just get the count of the entire records and then simply do the check for has more like so:
<?php
$query = Product::query()
->where('category_id', $request->get('category_id'));
->orderBy('order', 'asc')
->orderBy('name', 'asc');
$count = $query->count();
return [
'products' => $query->skip($skip)
->take($take)
->get(['id', 'name', 'front_image', 'back_image', 'slug']),
'has_more' => ($hm = ($count - ($take + $skip))) > 0 ? $hm : false
];

Laravel 5.2 - Update previous query

I have this query:
Sendqueue::select()
->where('userID', Session::get('uid'))
->where('campaign', $id)
->where('status', 'pending')
->update(array(
'status' => 'stopped',
));
The problem is that the amount of records it has to go through to do the update causes it to take around 15 minutes or so to finish.
I would like to split it up so the select and update queries are separate entities. Something sort of like this:
$pending = Sendqueue::select()
->where('userID', Session::get('uid'))
->where('campaign', $id)
->where('status', 'pending')
->get();
$pending->update(array(
'status' => 'stopped',
));
How would I go about doing this? Or is there an easier way?
Thanks!
I wasn't thinking, I figured out the answer. I had to run the second part in a foreach like so:
$records = Sendqueue::select()
->where('userID', Session::get('uid'))
->where('campaign', $id)
->where('status', 'pending')
->get();
foreach ($records as $record) {
DB::table('sendqueue')
->where('ID', $record->ID)
->update(['status' => 'stopped']);
}
protected $table="user";
public function updateUser($id,$username)
{
$resultData = array();
$updateArray = array('user_name'=>$username);
$update=DB::table('user')
->where('user_id', $id)
->update($updateArray);
return $resultData['status'] = true;
}
$my_id = preg_replace ('#[^0-9]#', '', $request->id);
if (! empty ($my_id)) {
$this->c->where ('id', $my_id )->update ( [
'first_name' => $request->get ( 'first_name' ),
'last_name' => $request->get ( 'last_name' ) ,
'phone' => $request->get ( 'phone' )
] );`enter code here`
\Session::flash ('message', 'Update Successful');
return redirect ('customer');
}
$this->edit ();
http://developer.e-power.com.kh/update-query-in-laravel-5-2/

Categories