How to Fetch Latest youtube Video's in Laravel - laravel

I am using alaouy/Youtube package on my laravel 5.4 its fetching my all video's from my channel with that code
$videoList = Youtube::listChannelVideos('UC9PWIZ20pnEXgT1fT69bX8A', 50);
but its showing me old first i want to to fetch latest first what do i do
thank you

In git repository of that package we can se this:
public function listChannelVideos($channelId, $maxResults = 10, $order = null, $part = ['id', 'snippet'], $pageInfo = false)
{
$params = array(
'type' => 'video',
'channelId' => $channelId,
'part' => implode(', ', $part),
'maxResults' => $maxResults,
);
if (!empty($order)) {
$params['order'] = $order;
}
return $this->searchAdvanced($params, $pageInfo);
}
That function seems to accept a third parameter "order"
So maybe this work:
$videoList = Youtube::listChannelVideos('UC9PWIZ20pnEXgT1fT69bX8A', 50, "date");

I ran the snippet you pasted and the videos do not appear to be in an order at all - the top few are 2016, then 2017, then 2016 again.
You can fetch the latest first by sorting the list:
$videoList = Youtube::listChannelVideos('UC9PWIZ20pnEXgT1fT69bX8A', 50);
usort($videoList, function ($a, $b) {
return strtotime($a->snippet->publishedAt) < strtotime($b->snippet->publishedAt);
});
Once the list is sorted, $videoList[0] will contain your most recent video

I am just trying this package too and found that by using the search method you can loop through all of your videos and store the results in your database whilst capturing the publish date and other properties. From there you can use these records to easily sort by date or title etc and paginate through your videos. This also saves on multiple requests to the you tube api.
Anyone else taken that approach?

Related

Update Laravel model from external API

I have a Coin model with id,name,price.
In a function, I extract all the coins and create a comma separated string with all the ids:
$coins = Coin::all();
$coinsIds = $coins->pluck('id')->toArray();
$coinsIdsString = implode(',', $coinsIds);
After that I make a call to an external API:
$url = 'https://myapi.com?ids' . $coinsIdsString;
$response = Http::get($url)->json();
$response value is an array of coins, something like:
[
{
"id":"1",
"name":"A",
"price":"1.2",
},
...
]
What would be the best way to update and save my Coin model with the price value from API?
Unfortunately, you're not going to be able to do anything other than update a single record at a time. That is, loop through the results of the array and perform a database update on each record. My recommendation is
$results = ... // Result of API call;
foreach ($results as $result) {
DB::table('coins')
->where('id', $result['id'])
->update(['price' => $result['price']]);
}
I would then create a scheduled command to periodically perform the update since it is likely to be resource intensive depending on the volume of calls.
https://laravel.com/docs/8.x/scheduling#scheduling-artisan-commands

How to load relations with { json:api } Client?

I am using the {json:api} Client to parse json into Eloquent like models.
I have two models, Congress and Speaker. A Congress has many Speaker.
This is what I was able to do:
$repository = app(App\Repositories\CongressRepository::class);
$document = $repository->all();
$document is a CollectionDocument with the following attributes:
I would like to get the speakers of the first Congress. This is what I tried
$congresses = $document->getData();
$congress = $congresses->first();
$congress->speakers // <- this is null!
Why is $congress->speakers null? I also tried to us $repository->all(['includes' => 'speakers']);
but this makes no differences.
It seems that $congress->speakers was null because the relation was null:
I use this package to create the json output. Inside the Schema.php I had to add self::DATA to make the data visible, as explained in the docs.
public function getRelationships($resource, $isPrimary, array $includeRelationships)
{
return [
'speakers' => [
self::SHOW_SELF => true,
self::SHOW_RELATED => true,
self::DATA => function () use ($resource) {
return $resource->speakers;
},
],
];
}
I still wonder if its possible to load the relation, if only the link is given in the API.

Contentful/Laravel Delivery API setInclude does not work as expected

While using the contentful laravel sdk the set include is not fetching any of the assets that belong to the entries I fetch. The code below (mine):
public function index()
{
$query = $this->query
->setContentType('gallery')
->setInclude(10);
$entry = $this->client->getEntries($query);
if (!$entry) {
abort(404);
}
$data = ['galleries' => $entry];
return view('welcome', ['data' => $data]);
}
The contenful example:
// contentful.php 3.0
$client = new Contentful\Delivery\Client(
'<content_delivery_api_key>',
'<space_id>',
'<environment_id>' // Defaults to "master" if ommitted
);
$query = (new Contentful\Delivery\Query())
->setInclude(2);
$entries = $client->getEntries($query);
my results:
[]
I expect for the previewImage and Images array to include the 'fields' that contain the location of the file. I only get 'sys'. I can't see why the include is not fetching this data. If i set setInclude to 20, over the limit i get an error. Below
What should i do differently? I achieved the desired results in a javascript frontend project, but with laravel i get nothing.
The include is actually working fine. Internally, linked entries/assets are represented using a Link object, which is resolved to an actual entry/asset as soon as you access the field (in your case, that's done with $entry->getPreviewImage(), which will return the Asset object that was loaded in your previous query).
This means that if you dump the entry you won't see the actual object you're expecting in the previewImage field, but everything will work fine if in regular use.

Storing a new post tag if it doesn't exist in the table?

I have a single input field (using select2 plugin) in a blog post form which allow user to insert post tags from existing tags in the table or create new ones and store them in the Tag table and also attach them to the post when they hit submit post button. I've managed to get this work by filtering the input with array_filter(), if the input is !is_numeric the input will first get stored in Tag table and then attach the id to the post.
The problem with this is that it's not working when the new tag from the input is in full numeric type, like 2017 tag. Is there a solution to get this working so the new tag is not limited to string only but also numeric type ? and if possible, I don't want to use any package for this.
The post store method :
public function store(PostsReq $request) {
$input = $request->all();
$post = Post::create($input);
//Handle the tags
$getTags = $request->input('tagspivot');
$oldTags = array_filter($getTags, 'is_numeric');
$newTags = array_filter($getTags, function($item) {
return !is_numeric($item);
});
foreach ($newTags as $newTag) {
if ($tag = Tag::create(['title' => strtolower(trim($newTag))])) {
$oldTags[] = $tag->id;
}
}
$post->tags()->attach($oldTags);
// Upload Image
if ($request->hasFile('image')) {
$input['image'] = $this->uploadImage($request, $post);
}
return redirect()->route('postindex')->with($this->postStoreSuccess);
}
Here is three lines of code would be more than enough:
$tag = Tag::firstOrCreate([
'title' => $request->input('tagspivot'),
]);
You don't need to check for !is_numeric. However, in your form don't use tag id as value. use the title.

How to increment a column using Eloquent Model in Laravel 4

I am not sure how to increment the value in a column using Eloquent Model in Laravel 4?
This is what I currently have and I am not sure how correct is this.
$visitor = Visitor::where('token','=','sometoken')->first();
if(isset($visitor)){
$visitor->increment('totalvisits');
}else{
Visitor::create(array(
'token'=>'sometoken',
'totalvisits'=>0
));
}
With Query Builder we could do it using
DB::table('visitors')->increment('totalvisits');
Looks like the code that I posted worked after all
$visitor = Visitor::where('token','=','sometoken')->first();
if(isset($visitor)){
$visitor->increment('totalvisits');
}else{
Visitor::create(array(
'token'=>'sometoken',
'totalvisits'=>0
));
}
Prior to a fix a few weeks ago the increment method actually fell through to the query builder and would be called on the entire table, which was undesirable.
Now calling increment or decrement on a model instance will perform the operation only on that model instance.
Laravel 5 now has atomic increment:
public function increment($column, $amount = 1, array $extra = [])
{
if (! is_numeric($amount)) {
throw new InvalidArgumentException('Non-numeric value passed to increment method.');
}
$wrapped = $this->grammar->wrap($column);
$columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra);
return $this->update($columns);
}
which essentially works like:
Customer::query()
->where('id', $customer_id)
->update([
'loyalty_points' => DB::raw('loyalty_points + 1')
]);
Below is old answer for Laravel 4 where the built-in increment was a seperate select and then update which of course leads to bugs with multiple users:
If you'd like to accurately count your visitors by ensuring the update is atomic then try putting this in your Visitor model:
public function incrementTotalVisits(){
// increment regardless of the current value in this model.
$this->where('id', $this->id)->update(['totalVisits' => DB::raw('last_insert_id(totalVisits + 1)')]);
//update this model incase we would like to use it.
$this->totalVisits = DB::getPdo()->lastInsertId();
//remove from dirty list to prevent any saves overwriting the newer database value.
$this->syncOriginalAttribute('totalVisits');
//return it because why not
return $this->totalVisits;
}
I'm using it for a change tag system but might work for your needs too.
Does anyone know what to replace the "$this->where('id',$this->id)" with because since dealing with $this Visitor it should be redundant.

Resources