Laravel. How to insert nested data into database - laravel

It's very easy to insert a register when I have a JSON to insert an Article like this:
--JSON to insert--
{
"title" : "a title",
"content" : "some content",
"user_id" : 3
}
To put it short, I create the route aiming to the store method of the controller and go for something simple like:
--ArticleController--
public function store(Request $request)
{
$article = Article::create($request->all());
return response()->json($article, 201);
}
But, what is the correct way to insert the data to store if I have something JSON:API complying like this?:
{
"data":
{
"type": "articles",
"attributes": {
"title": "a title",
"content" : "some content",
"user_id" : 3
}
}
}
What is the correct approach?

I can't believe it was so easy,
I just changed this:
$article = Article::create($request->all());
return response()->json($article, 201);
for this:
$article = Article::create($request->data['attributes']);
return response()->json($article, 201);
And that's it

Related

spatie/laravel-medialibrary, filters on getMedia() function not working

I am trying to get media for certain modal as follows:
public function show(Gallery $gallery)
{
$images = $gallery->getMedia('default'); //returns images
// $images = $gallery->getMedia('default', ['name', 'original_url']); //returns empty
return response()->json(['data' => $images]);
}
when not adding filters I get the correct data as follows:
{
"data": {
"686cc1b1-cfdc-425d-9b93-c99290f0d35e": {
"name": "Screenshot from 2022-06-27 23-29-29",
"file_name": "Screenshot-from-2022-06-27-23-29-29.png",
"uuid": "686cc1b1-cfdc-425d-9b93-c99290f0d35e",
"preview_url": "",
"original_url": "http://app.test/storage/media/25/Screenshot-from-2022-06-27-23-29-29.png",
"order": 1,
"custom_properties": [],
"extension": "png",
"size": 10546
}
}
}
but when I use filters I get empty array.
You have to retrieve single media, then you can chain property name
$gallery->getMedia('default')[0]->name;
or
$gallery->getFirstMedia('default')->name;
If you want to return json with name and original_url field for every media, that can be achieved by using API resource, something like this:
$images = $gallery->getMedia('default');
return MediaResource::collection($images);
and in MediaResource class you have:
public function toArray($request)
{
return [
'name' => $this->name,
'original_url' => $this->original_url
];
}

SMS Alert API Validation in laravel

public function verifyotp(Request $request)
{
$mobile=$request->mobilenumber;
$otp=$request->otp;
$client = new \GuzzleHttp\Client();
$tem='https://www.smsalert.co.in/api/mverify.json?apikey=#&mobileno=';
$cod='&code=';
$msg=($tem.$mobile.$cod.$otp);
$res=$client->request('POST', $msg);
(string) $res->getBody();
if($res->getBody(['description']=== "['desc']:Code does not match.")
{
echo 'Code Not Matched';
}
elseif(($res->getBody(['description'] === "['desc']:Code Matched successfully."))
{
echo 'Code Matched;
}
}
I have get response from api.I got Two response
one is like this
{
"status": "success",
"description": {
"desc": "Code does not match."
}
}
Second like this
{
"status": "success",
"description": {
"desc": "Code matched successfully." }
}
In This response i want to read "desc" on my controller
How to check desc using if condition ?
You can use json_decode function like this :
$result = json_decode($response);
echo $result->description->desc;
see this for detail
Done...

Laravel: Cannot reindex collection's array in eager loading after using unset()

I have following code:
// User.php
public function groups() {
return $this->belongsToMany(
Group::class,
'group_user',
'user_id',
'group_id',
'id'
);
}
// Group.php
public function users() {
return $this->belongsToMany(
User::class,
'group_class',
'group_id',
'user_id',
'id'
);
}
And in routes/web.php
Route::get('/test', function () {
$me = App\User::first();
$group = App\Group::with('users')->first();
foreach ($group->users as $user_index => $user) {
// Show all users (a.k.a members) of this group, except myself
if ($user->id == $me->id) {
unset($group->users[$user_index]);
}
}
return $group;
}):
Result:
{
"id": 1,
"name": "ABC Group",
"users": { // This should be array right?
"1": { // This should be start with 0
"id": 2,
"name": "...",
"email": "...",
},
"2": { // This should be 1
"id": 3,
"name": "...",
"email": "...",
}
}
}
What I have tried:
#1 Put values() in the end of foreach loop, like:
foreach ($group->users as $user_index => $user) {
// Show all users (a.k.a members) of this group, except myself
if ($user->id == $me->id) {
unset($group->users[$user_index]);
}
$group->users->values(); // Not working
}
#2 Put values() after the foreach loop, like:
Route::get('/test', function () {
$me = App\User::first();
$group = App\Group::with('users')->first();
foreach ($group->users as $user_index => $user) {
// Show all users (a.k.a members) of this group, except myself
if ($user->id == $me->id) {
unset($group->users[$user_index]);
}
}
$group->users->values(); // Still not working
return $group;
}):
Expected result:
{
"id": 1,
"name": "ABC Group",
"users": [ // Array
{ // index 0
"id": 2,
"name": "...",
"email": "...",
},
{ // index 1
"id": 3,
"name": "...",
"email": "...",
}
]
}
Q: How to reindex collection array in eager loading after using unset()?
Thanks in advance
You've got a few things to unpack here that might help you.
First, your query returns a Laravel collection of users attached to the single model Group. Laravel has a bit of magic in the background that allows for array notation as well, but probably easiest to think about this as a collection for your purposes. In some cases, you can translate this to an array using Laravel's toArray() method, something like:
$userArray = $group->users->toArray();
For dropping an index, or in this case a user from the Group's users, take a look at the forget() method, which works on the collection object.
However, I think you may wish to come at this from the reverse... Pull the unwanted index(es) in a single query, rather than having to loop through the collection after the fact. Something like this may be of value to you:
$me = App\User::first();
$group = App\Group::with(['users' => function($query) use($me){
$query->where('users.id', '!=', $me->id);
}])->first();
This query will remove the unwanted user from the collection right out of the database, eliminating the need for additional code, which is what I think you were after.
HTH.

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 API : how to get only some fields and sort the response

I would like to know if I do the things correctly.
Let's say I have a table "countries". To get only some fields of this table, in a certain order, I have this url :
/countries?fields=id,country_name&desc=country_name
And the result is clear:
[
{
"id": "SP",
"country_name": "Spain"
},
{
"id": "IT",
"country_name": "Italy"
},
{
"id": "FR",
"country_name": "France"
},
{
"id": "CN",
"country_name": "China"
} ]
To do that I have this route :
Route::get('/countries', 'CountryController#index');
And the method index is :
public function index(Request $request)
{
$query = Country::query();
if ($request->has('fields')){
$fields = explode(',', $request->input('fields') );
foreach ($fields as $field) {
$query->addSelect($field);
}
}
if ($request->has('sort')){
$query->orderBy($request->input('sort'));
}
if ($request->has('desc')){
$query->orderBy($request->input('desc'), 'desc');
}
$countries = $query->get();
return response()->json($countries, 200);
}
It works fine.
My question is am I doing the things correctly ? Is there any other methods ?
To prevent unknown column exception try this:
import Schema class use Illuminate\Support\Facades\Schema;
add this:
$table = "countries";
if ($request->has('fields')){
$fields = explode(',', $request->input('fields') );
foreach ($fields as $field) {
if(!Schema::hasColumn($table,$field)){
return response("Unknown field", 422);
}
$query->addSelect($field);
}
}
What you are doing to me has no vulnerability in it and is very optimized too.
You can try using this:
$countries = $query->pluck('id', 'country_name');
Please check and let me know.

Resources