Laravel - How to resolve special Date issue from External API - laravel

In my Laravel-5.8 project, I am having this model: Employee
Employee
class Employee extends Model
{
protected $table = 'employees';
protected $primaryKey = 'id';
protected $fillable = [
'staff_code',
'first_name',
'last_name',
'date_of_birth',
];
}
That is,:
App\Employee
CREATE TABLE `employees` (
`id` int NOT NULL auto_increment,
`staff_code` varchar(255) UNIQUE NOT NULL,
`first_name` varchar(255) UNIQUE NOT NULL,
`last_name` varchar(255) NOT NULL,
`date_of_birth` date NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Also I have an external api that comes in form of JSON get request.
https://api.employees.net/allemployees
I have viewed it with postman get request and I have something like this:
{
"ID": "1",
"StaffCode": "STC001",
"FirstName": "Japheth",
"LastName": "Shalom",
"DateOfBirth": "1992-07-11T00:00:00",
},
{
"ID": "2",
"StaffCode": "STC002",
"FirstName": "Ahitophel",
"last_name": "Nedum",
"DateOfBirth": "1991-10-23T00:00:00",
},
{
"ID": "3",
"StaffCode": "STC003",
"FirstName": "Joash",
"FirstName": "Nathan",
"DateOfBirth": "1979-09-22T00:00:00",
},
and so on... this continues
Already I have created this function:
use App\Employee;
public function index()
{
$client = new GuzzleHttp\Client();
$res = $client->request('GET','https://api.employees.net/allemployees');
$clientdatas = json_decode($res->getBody()->getContents(), true);
foreach($clientdatas as $clientdata)
{
$employee = Employee::firstOrNew(['id' => $clientdata['ID']]);
$employee->staff_code = $clientdata['StaffCode'];
$employee->first_name = $clientdata['FirstName'];
$employee->last_name = $clientdata['LastName'];
$employee->date_of_birth = $clientdata['DateOfBirth'];
$employee->save();
}
}
The DateOfBirth that is coming from the external API is carrying a special character (T) along with it. And the data type for date_of_birth in the database is date.
I want to save the data from the external API into the local database.
How do I format DateOfBirth from the API into date data type and remove T00:00:00 from it?
Thank you

Just take what you need from that string:
$employee->date_of_birth = substr($clientdata['DateOfBirth'], 0,10);

Related

Laravel Eloquent Advance Querying

I have 5 different tables as projects, systems, attachments, tasks, users on Laravel I haven't assign a relationship for each table what I am trying to do is linking each table using ID.
$objFetch = Task::addSelect(
[
'project_id' => Project::select('title')->whereColumn('project_id', 'projects.id'),
'tester_id' => User::select('name')->whereColumn('tester_id', 'users.id'),
'system_id' => System::select('name')->whereColumn('system_id', 'systems.id'),
'assigned_id' => User::select('name')->whereColumn('assigned_id', 'users.id'),
],
)->paginate(20);
This return the expected output as
{
"id": 1,
"document_auto_id": 101,
"document_type": null,
"document_name": "Tasks",
"file_name": "Task_394_1622175671_195.png",
"file_extention": "png",
"file_size": "105383",
"note": null,
"created_at": "2021-05-28T04:21:11.000000Z",
"updated_at": "2021-05-28T04:21:11.000000Z"
},
Question is there any solutions to get the attachments for each tasks?
Laravel Eloquent answer is highly appreciated instead of Query building
DB tables are often related to one another. therefore we can use table ID to get the output. the error occurs because I have not defined it on the Model. THE PROBLEM WAS SOLVED AS I DO FOLLOWING STEPS
MODEL
class Task extends Model
{
use HasFactory;
protected $fillable = [
'title',
'priority',
'project_id',
'system_id',
'tester_id',
'assigned_id',
'description',
'status',
];
protected $casts = [
'attachments' => 'array',
];
public function Attachment()
{
return $this->hasMany(Attachment::class, 'document_auto_id');
}
public function Project()
{
return $this->hasOne(Project::class, 'id', 'project_id');
}
public function System()
{
return $this->hasOne(System::class, 'id', 'system_id');
}
public function assignedTo()
{
return $this->hasOne(User::class, 'id','assigned_id');
}
public function testerTo()
{
return $this->hasOne(User::class, 'id','tester_id');
}
}
FETCHING DATA WITH RELEVANT TABLES
$objFetch1 = Task::with(
'testerTo',
'assignedTo',
'System',
'Project',
'Attachment'
)->get();

Laravel store JSON data API to database

I got the data json from API and I want to store them to my database.
data json sample :
{
"success": true,
"data": [
{
"status_employee_id": "1",
"name": "Manager"
},
{
"status_employee_id": "2",
"name": "Staff"
},
{
"status_employee_id": "3",
"name": "OB"
},
{
"status_employee_id": "4",
"name": "Fired"
},
{
"status_employee_id": "5",
"name": "Retired"
}
]
}
My model
class StatusEmployee extends Model
{
use HasFactory;
protected $table = 'status_employee';
protected $fillable = [
'status_employee_id','name'
];
public $timestamps = false;
}
I have tried use this in my controller
public function store()
{
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', 'http://xx.xx.xx.xx/tools/public/get_status_employee');
$datas = json_decode($res->getBody(), true);
foreach($datas as $data){
StatusEmployee::create([
'status_employee_id' => $data->status_employee_id,
'name' => $data->name,
]);
}
}
And I want to store the data json sample to my table status_employee. How to make it?
It's easy, Laravel Eloquent will do everything for you.
// If json is in string decode first
$data = json_decode($res->getBody(), true); // to array
// Eloquent approach
StatusEmployee::insert(#$data['data']);
I assume you use Laravel since you have mentioned Laravel in your tags.
DB::table('status_employee')->insert(json_decode($res->getBody(),true)['data']);

Laravel - How to consume and refresh external api into db using Guzzle

I am having this model in my Laravel-5.8 project:
Employee
class Employee extends Model
{
protected $table = 'employees';
protected $primaryKey = 'id';
protected $fillable = [
'staff_code',
'first_name',
'last_name',
'department_id',
];
public function department()
{
return $this->belongsTo('App\Department','department_id');
}
}
That is,:
App\Employee
Also I have an external api that comes in form of JSON get request.
https://api.employees.net/allemployees
I have viewed it with postman get request and I have something like this:
{
"ID": "1",
"StaffCode": "STC001",
"FirstName": "Japheth",
"LastName": "Shalom",
"DepartmentCode": "dep2",
},
{
"ID": "2",
"StaffCode": "STC002",
"FirstName": "Ahitophel",
"last_name": "Nedum",
"DepartmentCode": "dep1",
},
{
"ID": "3",
"StaffCode": "STC003",
"FirstName": "Joash",
"FirstName": "Nathan",
"DepartmentCode": "dep2",
},
and so on... this continues
Already I have created this function:
use App\Employee;
use App\Department;
public function index()
{
$client = new GuzzleHttp\Client();
$res = $client->request('GET','https://api.employees.net/allemployees');
$clientdatas = json_decode($res, true);
...
}
Apart from the id and staff_code that are UNIQUE, any of the others fields too can change from the source.
Since any of the fields can change at any time. How do I refresh the entire db, save new data and update changes?
Thank you
I could do something like this:
use App\Employee;
use App\Department;
public function index()
{
$client = new GuzzleHttp\Client();
$res = $client->request('GET','https://api.employees.net/allemployees');
$clientdatas = json_decode($res->getBody()->getContents(), true);
foreach($clientdatas as $clientdata)
{
$employee = Employee::firstOrNew(['id' => $clientdata['ID']]);
$employee->staff_code = $clientdata['StaffCode'];
$employee->first_name = $clientdata['FirstName'];
$employee->last_name = $clientdata['LastName'];
$employee->save();
}
}
Every time you will make an API call, create an instance of the employee model, or get the associated model if the ID exists. Then assign the new values and save your model. This way, you will be able to either create or update the models in a single loop without any complexities.
Don't know will it work or not but the logic you can keep.. In the other answer he is querying under a loop which is bad!
Hope It will Help you a little bit
public function index() {
$client = new GuzzleHttp\Client();
$res = $client->request('GET','https://api.employees.net/allemployees');
$clientdatas = json_decode($res->getBody()->getContents(), true);
// create a blank array for insert
$insert_arr = [];
foreach($clientdatas as $clientdata) {
$make_array = [
'id' => $clientdata['ID'],
'staff_code' => $clientdata['StaffCode'],
'first_name' => $clientdata['FirstName'],
.
.
];
array_push($insert_arr, $make_array);
// Now the the $insert_arr will ready for insert
}
// Here you have to check its duplicate or not
$exist_in_db = Employee::all('id')->toArray(); // get the id array from db
// do the stuff for unset the duplicate
$final_id = array_map(function($value) {
return $value['id'];
}, $team_id);
unset($exist_in_db);
if(count($final_id) > 0){
foreach ($insert_arr as $key => $value) {
if (in_array($value['id'], $final_id)) {
unset($insert_arr[$key]);
} else {
array_push($final_id, $value['id']);
}
}
}
// finally insert it here
if (count($insert_arr) > 0) {
Employee::insert($insert_arr);
}
}
Let me know its helpful or not!

Laravel, remove null Eloquent object attributes from JSON

Is there an elegant way to remove NULL values from an Eloquent Object? My object is nested with relationships. This particular call can be 1000s of lines long, so my main reason for trying this is to save bandwidth for the user, but server performance is also a consideration.
My code:
$data['locations'] = Location::with('address')->where('user_id', '1')->get();
return Response::json($data);
I experimented with Mutators, but unless I'm mistaken Mutators don't have power over the object key, just the value.
I also tried and failed to use array_filter like these:
Any PHP function that will strip properties of an object that are null?
How to remove empty associative array entries
EDIT As requested,
{
"status": "ok",
"locations": [
{
"id": "1",
"latitude": "12.239107980271",
"longitude": "109.19479025725",
"user_time": "",
"transport": "Bus",
"title1": "",
"title2": "",
"address": {
"town": "Nha Trang",
"country": "Vietnam",
"address": "36-44 Hùng Vương, Lộc Thọ, Nha Trang, Khanh Hoa Province, Vietnam"
},
"altitude": {
"altitude": "10.006237983704"
},
"timezone": {
"offset": "25200"
},
"forecast": {
"icon": "",
"high_temp": "",
"low_temp": ""
}
},
{
"id": "2",
Desired response:
{
"status": "ok",
"locations": [
{
"id": "1",
"latitude": "12.239107980271",
"longitude": "109.19479025725",
"transport": "Bus",
"address": {
"town": "Nha Trang",
"country": "Vietnam",
"address": "36-44 Hùng Vương, Lộc Thọ, Nha Trang, Khanh Hoa Province, Vietnam"
},
"altitude": {
"altitude": "10.006237983704"
},
"timezone": {
"offset": "25200"
}
},
{
"id": "2",
As you can see, I could simply loop through the whole lot and remove any keys - or keys of keys - without values. I was hoping Laravel might provide a neat/fast way of doing the same.
I should add that technically only the latitude and longitude are required fields!
3 possibilities:
Write a response macro which cleans up your json data:
http://laravel.com/docs/responses#response-macros
Extend the Response class and implement your cleanup routine there. See this great tutorial for details how to do this: http://fideloper.com/extend-request-response-laravel
Implement the jsonSerialize method in your model which will be automatically called when your model is converted to json and place your cleanup routines there. You can even go a step further and write your own Collection for your Location model. Depending on your data structure this can make things a little bit easier. A nice tutorial for this purpose can be found here: http://heera.it/extend-laravel-eloquent-collection-object
I personally would prefer option 3.) because the data modifications happens where it should happen - in your model.
But bottom line it really depends which solutions fits best to your project.
First make a trait and add your custom validation then use in your each resource where you need
trait ResourceHelpers
{
/**
* Remove null values from Eloquent api resource
* #param array $data
* #return array
*/
public function removeNullValues(array $data)
{
$filtered_data = [];
foreach ($data as $key => $value) {
// if resource is empty
if ($value instanceof JsonResource and $value->resource === null) {
continue;
}
$filtered_data[$key] = $this->when($value !== null, $value);
}
return $filtered_data;
}
}
Then use it in your resource
class UserResource extends JsonResource
{
use ResourceHelpers;
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return $this->removeNullValues([
"id" => $this->id,
"first_name" => $this->first_name,
"last_name" => $this->last_name,
"phone" => $this->phone,
"email" => $this->email,
"balance" => $this->balance,
'address' => $this->address,
'city' => $this->city,
'state' => $this->state,
'zip_code' => $this->zip_code,
'country' => CountryResource::make($this->whenLoaded('country')),
"joined_at" => $this->created_at,
"updated_at" => $this->updated_at,
]);
}
}
I enhanced the removeNullValues to also ignore empty arrays and be recursive to handle nested arrays. Please check this one.
function removeNullValues(array $data)
{
$filtered_data = [];
foreach ($data as $key => $value) {
if (is_array($value))
{
if (sizeof($value) > 0)
$filtered_data[$key] = $this->removeNullValues($value);
}
else if ($value != null){
$filtered_data[$key] = $value;
}
}
return $filtered_data;
}

Laravel 4.1 remove pivot attributes from response

I am using laravel 4.1 to build an api. I have pivot a table which is working fine. But the response comes with pivot attributes which i don't want. as you will see in my example i have to two tables name: trips and users. I don't want to see pivot table attributes in my response. Here is the example:
[
{
"id": 140,
"name_first": "hasan",
"name_last": "hasibul",
"profile_image": "/assets/images/default-profile-img.png",
"created_at": "2013-09-18 08:19:50",
"last_login": "2013-12-26 11:28:44",
"status": "active",
"last_update": "2013-10-15 13:40:47",
"google_refresh_token": null,
"is_admin": 1,
"updated_at": null,
"pivot": {
"trip_id": 200,
"user_id": 140
}
}
This is my User Model:
public function trips(){
return $this->belongsToMany('Trip');
}
This is my trip model:
public function users(){
return $this->belongsToMany('User');
}
This is my controller:
public function index($tripId)
{
$userCollection = Trip::find($tripId)->users;
return $userCollection;
}
This is my route:
//get all the users belongs to the trip
Route::get('trips/{tripId}/users', array(
'as' => 'trips/users/index',
'uses' => 'TripUserController#index'
));
is there any way i can remove pivot attributes using laravel or i have to use php ?
Use the $hidden property of the model, you can add attributes or relations to it and the pivot is basicly acts as a relation.
class Foo extends Eloquent
{
protected $hidden = array('pivot');
public function bars()
{
return $this->belongsToMany('Bar');
}
}
If you want to remove just any one column from the response, then you can try something like this:
In you Model:
public function toArray()
{
$attributes = $this->attributesToArray();
$attributes = array_merge($attributes, $this->relationsToArray());
unset($attributes['pivot']['user_id']);
return $attributes;
}
This way you will get only attribute required.
You can add it to your "hidden" array. At Model page
protected $hidden = [
'pivot'
];
As mentioned above you can remove the pivot attribute from the response, by adding the following to the related model.
protected $hidden = [
'pivot'
];
Moreover, in case you want to select specific fields from the pivot to be displayed in the related user object you can add this to your controller using Laravel 5.8. This works also when you hide the pivot information with the above code snippet.
public function index(Trip $trip)
{
return $trip->users()->select(['trip_id'])->paginate();
}
and you will receive something objects where the trip_id is added to the user object.
{
"data": [
{
"id": 140,
"trip_id": 200,
"name_first": "hasan",
"name_last": "hasibul",
"profile_image": "/assets/images/default-profile-img.png",
"created_at": "2013-09-18 08:19:50",
"last_login": "2013-12-26 11:28:44",
"status": "active",
"last_update": "2013-10-15 13:40:47",
"google_refresh_token": null,
"is_admin": 1,
"updated_at": null,
"pivot": {
"trip_id": 200,
"user_id": 140
}
}
]
}

Resources