How to delete an item from array in Laravel Session? - php

I'm creating a cart system, this is my code to input some itens into the user Session:
public function jsonResponse($data){
return response()->json([
'success' => true,
'users' => $data
]);
}
public function post(Request $request ,User $user)
{
$request->session()->push('users', $user);
return $this->jsonResponse($request->session()->get('users'));
}
How can I delete an unique item from the users array?
Alternative 01
It's able to remove the item from the users array with the following code:
public function delete(Request $request, User $user)
{
$users = $request->session()->get('users');
foreach ($users as $key => $val) {
if($user->id == $users[$key]->id){
$array = $request->session()->pull('users', []);
unset($array[$key]);
$request->session()->put('users', $array);
return $this->jsonResponse($request->session()->get('users'));
}
}
return $this->jsonResponse($request->session()->get('users'));
}
But I was searching for a clean way... Without remove the array and put it back to the Session...
Solution 01
The following alternative has been found for a cleaner code:
public function delete(Request $request, User $user)
{
$users = $request->session()->get('users');
foreach ($users as $key => $val) {
if($user->id == $users[$key]->id){
$request->session()->forget('users.'.$key);
return $this->jsonResponse($request->session()->get('users'));
}
}
return $this->jsonResponse($request->session()->get('users'));
}
Thanks to Kyslik for remind the dot notation...

You can use forget() or pull() methods for that.
$request->session()->forget('key');
The forget method will remove a piece of data from the session
$request->session()->pull('key', 'default');
The pull method will retrieve and delete an item from the session in a single statement

Related

Addition of a new value to API response

Currently learning Laravel and any help is much appreciated!
My API controller has the following index function
public function index()
{
abort_if(Gate::denies('course_access'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$response=Course::all()->toArray();
$allData = [];
foreach (Course::all() as $ids=>$CMF) {
UNSET($response[$ids]['media']);
$data_sequence = DB::table('media_sequence')->where('data_id', $CMF["id"])->where('type','CMF')->first();
$data_id=$data_sequence->id;
$data_sequence = json_decode($data_sequence->data_sequence);
$data = [];
$data["id"] = $CMF["id"];
$data["title"] = $CMF["title"];
foreach ($data_sequence as $id => $dataSeq) {
if ($dataSeq->type == "Text") {
$response[$ids]['media'][]=["id"=>$data_id,"text"=> $dataSeq->name,"mime_type"=>"text"];
} elseif ($dataSeq->type == "file") {
foreach ($CMF["media"] as $file) {
if (str::slug($dataSeq->name) == str::slug($file["file_name"])) {
$file["thumb"] = $file->getUrl('video_thumb');
$response[$ids]['media'][]=$file;
}
}
}
}
$allData[] = $data;
}
return new CourseResource($response);
//Commented: return new CourseResource(Course::with(['category', 'assigned_teams', 'team'])->get());
}
Getting no result when trying to return 'assigned_teams' with $response
The API response still doesn't include 'assigned_teams'
I tried: return new CourseResource($response, 'assigned_teams');
It is not returning the assigned_items since it is not included in the $response array.
Change
$response=Course::all()->toArray();
To
$response=Course::with(['category', 'assigned_teams', 'team'])->get();
Read more: eager-loading-multiple-relationships
Btw, as #apokryfos mentioned, you should refactor your code using Eloquent Relationships and Eager Loading.
I assume that the assigned_teams are not handled in your CourseResource.
You need to extend your resource to respect this additional relation.
class CourseResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
// return teams if they have been loaded
'teams' => TeamsResource::collection($this->whenLoaded('assigned_teams')),
];
}
}
This is just exemplary, since you did not provided your code for CourceResource yet, you need to update it according to your needs.
Here is the link to the appropriate laravel documentation: https://laravel.com/docs/8.x/eloquent-resources#conditional-relationships

Laravel: Custom Auth with 2 tables

I am using Laravel 8, and I need to validate a user using data from 2 tables: users and customers. When user logs in, they will input 3 values: email, password and account. "Account" field comes from customer table.
So I need to do a join to access "account" field from "customers" table.
One option I see is:
public function validateCredentials(UserContract $user, array $credentials) {
$plain = $credentials['password'];
//Custom Query
return $this->hasher->check($plain, $user->getAuthPassword());
}
In section "Custom Query", I can do a query to get customer data using $user->customer_id and check if matches $credentials['account'], but not sure if it is the best way.
Thanks in advance for your help.
I end up building a Custom Provider, and override "retrieveByCredentials" method, that made the trick.
public function retrieveByCredentials(array $credentials)
{
if (empty($credentials) ||
(count($credentials) === 1 &&
Str::contains($this->firstCredentialKey($credentials), 'password'))) {
return;
}
$query = User::select(['customer.identifier', 'users.*'])->join('customer', 'customer_id', '=', 'customer.id');
foreach ($credentials as $key => $value) {
if (Str::contains($key, 'password')) {
continue;
}
if($key == 'account') {
$query->where('customer.identifier', '=', $credentials['account']);
} else {
$query->where($key, $value);
}
}
return $query->first();
}

Where like not working inside foreach loop in laravel

Where like not working inside foreach loop in Laravel. The following always return null. Here i want to use multi sorting, but the response in always blank.
public function searchBy(Request $request)
{
if($request->name!=''){
$data['name']=$request->name;
}
if($request->s_name!=''){
$data['short_name']=$request->s_name;
}
if($request->pin!=''){
$data['pin_code']=$request->pin;
}
if($request->city!=''){
$data['city']=$request->city;
}
$customers = Customer::get();
foreach ($data as $key => $value) {
// return $key;
$customers = $customers->where($key,'LIKE','%'.$value.'%');
}
return response()->json([
'data' =>$customers,
]);
}
The variable $customers should be a QueryBuilder and you should call get() on it in the end to retrieve your items.
$customers = Customer::query();
foreach ($data as $key => $value) {
$customers->where($key,'LIKE','%'.$value.'%');
}
return response()->json([
'data' => $customers->get(),
]);
The QueryBuilder is an object, which is by design pass by reference, therefor you do not need to reassign it.

Laravel Increase SQL speed

I am trying to increase the speed of my queries in Laravel 5.7 and I have the call down to ~2.5 seconds. I am trying to figure out more ways to make it faster and if I could get some help I'd greatly appreciate it.
Thanks
How my data is structured:
Function(Controller):
public function getUserDataTmp(Request $request) {
$input = file_get_contents("php://input");
$request = json_decode($input);
if ($this->authTokenAccess($request) == true) {
$bottomWords = bottom_exterior_word::select('word','sentence','sequence','id','group_id')->where('user_id','=', $request->id)->get();
$emergencyWords = left_exterior_word::select('word','sentence','sequence','id')->where('user_id','=', $request->id)->get();
foreach($bottomWords as $tmp => $key) {
$group_id = $key->group_id;
$bottomWords->user_id = $request->id;
$bottomWords[$tmp]->words = $key->getMainWords($group_id, $request->id);
}
foreach($emergencyWords as $key => $word) {
$emergencyWords[$key]->image = imageModel::select('base64','id')->where('emergency_id','=', $word->id)->first();
}
$data = [
'data' => [
'return' => 'success',
'code' => 'VEDC001',
'response' => 'Successfully Gathered Words',
'main_categories' => $bottomWords,
'emergency_words' => $emergencyWords
]
];
return(json_encode($data));
}
}
getMainWords Function(bottom_exterior_word model):
public function getMainWords($group_id, $id)
{
// return("TEST");
$words = \App\main_word::select('id','group_id','sentence','sequence','word')->where('group_id','=', $group_id)->where('user_id','=', $id)->get();
foreach ($words as $key => $word) {
$words[$key]->image = Image::select('base64','id')->where('word_id','=', $word->id)->first();
}
return $words;
}
Start by refactoring so that you dont query inside a foreach loop
foreach($bottomWords as $tmp => $key) {
$group_id = $key->group_id;
$bottomWords->user_id = $request->id;
$bottomWords[$tmp]->words = $key->getMainWords($group_id, $request->id);
}
I would change the getMainWords function to accepts an array of group id's and use the whereIn clause:
The whereIn method verifies that a given column's value is contained
within the given array:
$users = DB::table('users')
->whereIn('id', [1, 2, 3])
->get();
Same treatment for this loop.
foreach($emergencyWords as $key => $word) {
$emergencyWords[$key]->image = imageModel::select('base64','id')->where('emergency_id','=', $word->id)->first();
}
In general minimizing the NUMBER of queries will improve response time.
Old post, would just like to update it though. Since I have first posted this, I have learned a lot more about Laravel and am a lot more experienced with it.
Here is my new function and solution:
Controller:
public function data(Request $request)
{
return response()->success(
[
'emergencywords' => EmergencyWord::with('image')->whereUserId($request->user()->id)->get(),
'categorywords' => CategoryWord::with(['image','words.image'])->whereUserId($request->user()->id)->get(),
]
);
}
Category Word Relationships:
public function image()
{
return $this->hasOne('App\Image','id','image_id');
}
public function words()
{
return $this->hasMany('App\MainWord','category_words_id','sequence');
}
Emergency Word Relationships:
public function image()
{
return $this->hasOne('App\Image','id','image_id');
}
Main Word Relationships:
public function image()
{
return $this->hasOne('App\Image','id','image_id');
}

Laravel Eloquent 'with' has empty result

I am working on a small API based on Laravel 5.3 passport (https://laravel.com/docs/5.3/passport).
After Googling a lot I didn't find an answer yet to my problem.
I got the following function that has to retrieve the people I follow from the database. This is working great. After that I need to grab all friends statuses from the DB with the user info, drink info, file info and toast info. This also works great. It isn't working when file or toast or drink is empty. I get an empty array back.
The function:
public function index(Request $request)
{
$user = $request->user();
$friends = Follow::with(['user'])->where('follows_user_id', '=', $user->id)->get();
foreach ($friends as $friend) {
$status = Status::with(['user', 'drink', 'file', 'toast'])->where(
'user_id', '=', $friend->id
)->CreatedAtDescending()->get();
}
if (!isset($status) || empty($status)) {
return response(['message' => 'Nothing found.'], 404);
}
return $status;
}
How can I get the result back, even when the drink or file or toast is empty?
I got it working! The solution is:
public function index(Request $request)
{
$user = $request->user();
$friends = Follow::with(['user'])->where('follows_user_id', '=', $user->id)->get();
foreach ($friends as $friend) {
$status = Status::with(['user' => function ($query) use ($friend) {
$query->where('id', '=', $friend->following_user_id);
}, 'drink', 'file', 'toast'])->get();
}
if (!isset($status) || empty($status)) {
return response(['message' => 'Nothing found.'], 404);
}
return $status;
}
It where just some small issues in the query.

Categories