Retrieving data from a countries API - laravel

I'm using an API to get a list of countries in Laravel. I have been able to isolate the countries list only but the countries now have an inner array with details of the country. I only need the name. I've tried using foreach but it didn't work.
This below is the result from the api
#items: array:2 [▼
"countries" => array:198 [▼
0 => array:4 [▼
"code" => "BT"
"name" => "Bhutan"
"geonameid" => 1252634
"depends_on" => null
]
1 => array:4 [▶]
This below is the code fetching it
$response = Http::withHeaders([
'x-rapidapi-host' => 'world-geo-data.p.rapidapi.com',
'x-rapidapi-key' => '1fa601995fmshcc1d2fcc97ee24cp1ac29djsn9b9b11cc10ec',
//'x-rapidapi-key' => config('app.rapid_api_key'),
])->get('https://world-geo-data.p.rapidapi.com/countries');
//dd($response->collect());
return $response->collect()->pluck('name')
->all();
I'm trying to get only the name value. the return is returning null

I think this is what you want:
return collect($response->collect()["countries"])->pluck('name');
The result will be like:

Related

Laravel : Countries with Laravel Analytics

I'm using Laravel Analytics to get data of the visitors of my application.
In my Google Analytics dashboard, every page have it own visits numbers, unique visitors, countries of visitors etc .. like in this image :
In my web.php, I'm creating a route to test the package :
Route::get('/data', function () {
$analyticsData = Analytics::fetchMostVisitedPages(Period::days(7));
dd($analyticsData);
});
This route returns :
Illuminate\Support\Collection {#1564 ▼
#items: array:3 [▼
0 => array:3 [▼
"url" => "/new"
"pageTitle" => "test"
"pageViews" => 1534
]
1 => array:3 [▼
"url" => "/"
"pageTitle" => "test"
"pageViews" => 450
]
2 => array:3 [▼
"url" => "/customize/8"
"pageTitle" => "test"
"pageViews" => 196
]
As you can see the returned array have only url, pageTitle and pageViews. How can I add additional informations in the returned array such as countries or geographic localisation as shown in the first image ?
I've never used the package, but reading the docs, something like this will do.
The package docs state you can use any query you want, and the Google Analytics docs give an example of getting session by location.
public function myCustomMethod($maxResults = 20)
{
$response = $this->performQuery(
$period,
'ga:sessions', // metrics
[
'dimensions' => 'ga:country',
'sort' => '-ga:sessions',
'max-results' => $maxResults,
],
);
return collect($response['rows'] ?? [])->map(fn (array $pageRow) => [
// Do something with the rows that are returned.
// I'm not sure how they're returned from the main response.
]);
}
Note, this is completely untested, you might want to fiddle with some of the data here.
Assuming I understand the documentation, this will get all countries (dimensions), it will use sessions (ga:sessions from second parameter) to measure the countries data.
It'll then just sort and get a maximum number of results.
You could change the metrics to ga:pageviews, but it's ultimately down to you what queries you want to use.
I've linked the documentation so you can find them out yourself.
You're using spatie/laravel-analytics package.
As you can see here: spatie laravel analytics - Analytics.php the fetchMostVisitedPages method that you are calling only returns that data.
Please take a look in github to see more information about this package.
fetchMostVisitedPages method:
public function fetchMostVisitedPages(Period $period, int $maxResults = 20): Collection
{
$response = $this->performQuery(
$period,
'ga:pageviews',
[
'dimensions' => 'ga:pagePath,ga:pageTitle',
'sort' => '-ga:pageviews',
'max-results' => $maxResults,
],
);
return collect($response['rows'] ?? [])->map(fn (array $pageRow) => [
'url' => $pageRow[0],
'pageTitle' => $pageRow[1],
'pageViews' => (int) $pageRow[2],
]);
}

Laravel Microsoft Graph request how to solve Cannot use object of type?

I try to do a graph request in my laravel project to connect Microsoft API. All works fine, but I don't find a way to get single data from my request.
$info = $graph->createRequest("GET", "/groups/{id}/calendar/events?\$filter=start/dateTime ge '" . $todayDate . "T00:00' and end/dateTime lt '" . $todayDate . "T23:00'")
->addHeaders(array("Content-Type" => "application/json"))
->setReturnType(\Microsoft\Graph\Model\User::class)
->setTimeout("1000")
->execute();
Output is a large json with all information. If I just want to get $info[0]['attendees'];
I get error: Cannot use object of type Microsoft\Graph\Model\User as array in file
Why? And how to access? If I try load object like $info->attendees I got error: Trying to get property 'attendees' of non-object.
This is my output (not all) of dd($info) it includes attendees as array like "id"
array:10 [▼
0 => Microsoft\Graph\Model\Event {#1532 ▼
#_propDict: array:43 [▼
"#odata.etag" => "{tag}""
"id" => "{id}"
"createdDateTime" => "2021-03-19T10:36:08.0812445Z"
"lastModifiedDateTime" => "2021-03-19T10:36:11.9402917Z"
"attendees" => array:1 [▼
0 => array:3 [▼
"type" => "required"
"status" => array:2 [▶]
"emailAddress" => array:2 [▼
"name" => "name"
"address" => "mail"
]
]
]
It seems your array is returning an array of attendees, you have an extra level in your array. So to fetch the first attendees status, you need to use the following code:
Try this
foreach($info as $item){
foreach($item as $inf ){
$a = $inf->status
dd($a)
}
}

Laravel resource ignoring given fields

I'm trying to convert a given API response in something easy to work with.
This is what I have so far:
Controller:
public function drive()
{
$optParams = [
'corpora' => 'drive',
'driveId' => env('GOOGLE_DRIVE_ID'),
'includeItemsFromAllDrives' => true,
'supportsAllDrives' => true,
'fields' => 'files(*)'
];
$results = $this->googleDrive->files->listFiles($optParams);
$data = collect($results);
$collection = new FileCollection($data);
dd($collection);
return 'Hi!';
}
FileCollection resource:
public function toArray($request)
{
return [
'data' => $this->collection,
'meta' => ['files_count' => $this->collection->count()],
];
}
File resource:
public function toArray($request)
{
return [
'name' => $this->resource['name'],
'mime' => $this->resource['mimeType'],
'parents' => $this->resource['parents'],
'version' => $this->resource['version'],
'webDownloadLink' => $this->resource['webContentLink'],
'webLink' => $this->resource['webViewLink'],
'modified_at' => $this->resource['modifiedTime'],
'size' => $this->resource['size']
];
}
This is the result I'm getting:
FileCollection {#223 ▼
+collects: null
+collection: Collection {#243 ▶}
+resource: Collection {#243 ▼
#items: array:2 [▼
0 => File {#224 ▼
+resource: Google_Service_Drive_DriveFile {#279 ▶}
+with: []
+additional: []
}
1 => File {#263 ▼
+resource: Google_Service_Drive_DriveFile {#269 ▶}
+with: []
+additional: []
}
]
}
+with: []
+additional: []
}
So as you can see the types of resources are correct, but for some reason the 'meta' in the FileCollection isn't there, nor are the fields in the File resource. All fields are still shown, like 30+ (instead of the 8 requested in the FileResource).
Am I missing something here?
EDIT:
When accessing the collection with the toArray() method ($collection->toArray(null)), I do indeed get the appropriate result:
array:2 [▼
"data" => Collection {#243 ▼
#items: array:2 [▼
0 => File {#224 ▶}
1 => File {#263 ▶}
]
}
"meta" => array:1 [▼
"files_count" => 2
]
]
So how do I make sure now that this collection uses the toArray() of the FileResources? (I'm still getting over 30 fields, instead of 8).
PS: I don't really get why I need to call the toArray(), nowhere in their documentation is it written : https://laravel.com/docs/5.8/eloquent-resources .

Facebook marketing API insights (Destination url)

I'm trying to get data using Facebook Marketing API.
$api = FacebookAds::init('TOKEN');
$start = Carbon::create(2018,11,16);
$end = Carbon::create(2018,11,16);
$period = Period::create($start,$end);
$in = $api->insights($period,'act_ID', 'ad',[
'fields' => ['impressions', 'objective', 'actions'....]
]);
I'm getting each ad actions like this:
"actions" => array:10 [▼
0 => array:2 [▼
"action_type" => "comment"
"value" => "1"
]
1 => array:2 [▼
"action_type" => "offsite_conversion.fb_pixel_purchase"
"value" => "1"
]
2 => array:2 [▼
"action_type" => "photo_view"
"value" => "114"
]....
]
My question is how to get each ad destination URL?
Thanks
You actually have to use AdCreative information to get the destination URL: https://developers.facebook.com/docs/marketing-api/reference/ad-creative/
I use the object_story_spec and match the AdCreative with the Ad by id ( they share the same ID ).
https://graph.facebook.com/v14.0/'adcreativeid'/?fields=object_story_spec
You can use this code. Destination URL will mentioned in link data -> link

Get relation of relation

I'm trying to get the comments of the links with laravel relationship, the comments of links return normally, but I don't know how to get it in view or dd(), how can I do it?
Controller:
$page = Page::where('friendly_url', $id)
->select('id', 'photo', 'friendly_url', 'name', 'description', 'followers', 'links', 'tag_id', 'links_clicks')
->with('ptag', 'links', 'links.comments', 'links.tag')
->with(['links.comments.user' => function($query) {
$query->select('id', 'name', 'lastname');
}])->with(['links.comments.userProfile' => function($query) {
$query->select('id', 'photo');
}])->first();
dd($page->getRelation('links')
Collection {#301 ▼
#items: array:2 [▼
0 => Link {#307 ▼
#relations: array:2 [▼
"comments" => Collection {#316 ▼
#items: array:1 [▶]
"tag" => Tag {#322 ▶}
]
dd($page->getRelation('links')->getRelation('comments'))
BadMethodCallException
Method getRelation does not exist.
dd($page->getRelation('links')->comments)
Exception
Property [comments] does not exist on this collection instance.
EDIT:
I want to show the attributes of comment and comment.user, how I can do it?
foreach($page->getRelation('links')->pluck('comments') as $comment) {
dd($comment);
}
Collection {#327 ▼
#items: array:1 [▼
0 => Comment {#325 ▼
#attributes: array:5 [▼
"id" => 3
"content" => "teste"
"link_id" => 1
"user_id" => 1
"created_at" => "2018-01-11 00:47:32"
]
#relations: array:2 [▼
"user" => User {#330 ▼
#attributes: array:3 [▼
"id" => 1
"name" => "Halysson"
"lastname" => "Teves dos Santos"
]
}
"userProfile" => UserProfile {#326 ▶}
]
Try this-
foreach($page->links as $link){
$comments = $link->comments;
}
You should define relations first on relevent models and then using 'with' function can load models with relations OR a relation can be called directly by single model see documentation for further details
eg: you have defined a relation for user to phone, as user has a phone, one to one relation. in user model define a relation like
public function phone()
{
return $this->hasOne('App\Phone');
}
now to call this relation on user model instance.
$user = User::find(1);
dd($user->phone);
Because you're using the select() method, you also need to include all the foreign keys in it to allow Eloquent to be able to load these relationships.
But since you just start using Laravel, I'd recommend you to just remove select() method from this complex query.
If you want the links of a page :
$page->links
if you want all the comments of a page :
$page->links->pluck('comments')
that's it :)

Resources