Is there a way to get /tracks/{id}/comments for a track ordered by timestamp asc/desc? The default order is by created_at property descending.
I do not know if soundcloud offers the possibility to sort the requests, but you can sort the response of the request whit usort() and strnatcmp() for natural order string.
Like this:
function orderBy($data, $field) {
$code = "return strnatcmp(\$a['$field'], \$b['$field']);";
usort($data, create_function('$a,$b', $code));
return $data;
}
// Get comments
$comments = json_decode($soundcloud->get('tracks/{id_track}/comments'), true);
// Order comments by 'timestamp'
$data = orderBy($comments, 'timestamp');
Related
I have the following query.
$projects = Project::orderBy('created_at', 'desc');
$data['sorted'] = $projects->groupBy(function ($project) {
return Carbon::parse($project->created_at)->format('Y-m-d');
})->simplePaginate(5);
When I try to paginate with the simplePaginate() method I get this error.
stripos() expects parameter 1 to be string, object given
How can I paginate grouped data in this case?
The created_at attribute is already casted as a Carbon Object (by default in laravel models). that's why you are getting that error. Try this:
$projects = Project::orderBy('created_at', 'desc')->get();
$data['sorted'] = $projects->groupBy(function ($project) {
return $project->created_at->format('Y-m-d');
})->simplePaginate(5);
this answer is just for the error you're getting. now if you want help with the QueryBuilder, can you provide an example of the results you're expecting to have and an example of the database structure ?
The pagination methods should be called on queries instead of collection.
You could try:
$projects = Project::orderBy('created_at', 'desc');
$data['sorted'] = $projects->groupBy('created_at');
The problem was solved. I was create custom paginator via this example:
https://stackoverflow.com/a/30014621/6405083
$page = $request->has('page') ? $request->input('page') : 1; // Use ?page=x if given, otherwise start at 1
$numPerPage = 15; // Number of results per page
$count = Project::count(); // Get the total number of entries you'll be paging through
// Get the actual items
$projects = Project::orderBy('created_at', 'desc')
->take($numPerPage)->offset(($page-1)*$numPerPage)->get()->groupBy(function($project) {
return $project->created_at->format('Y-m-d');
});
$data['sorted'] = new Paginator($projects, $count, $numPerPage, $page, ['path' => $request->url(), 'query' => $request->query()]);
simplePaginate Method is exist in the path below:
Illuminate\Database\Eloquent\Builder.php::simplePaginate()
I want to sort a collection by name column. Using sortBy() method is not working.
$collection = \App\Http\Resources\MyResource::collection($test);
return $collection->sortBy('name');
For me only worked example exactly as in the docs
$statisticCollection = collect($statistics);
$sorted = $statisticCollection->sortByDesc('date');
return $sorted->values()->all();
So the problem was that I did not save the sorted result to a variable before returning it.
I found that I had to use values() after sorting, as suggested in the documentation.
The thing you want to do is:
$collection = \App\Http\Resources\MyResource::collection($test);
return $collection->sortBy('name')->all();
Check how it is done in the docs.
The default sortBy for Laravel is defined as ascending:
public function sortBy($callback, $options = SORT_REGULAR, $descending = false)
If you were looking to sort descending use sortByDesc:
public function sortByDesc($callback, $options = SORT_REGULAR)
{
return $this->sortBy($callback, $options, true);
}
Where the first parameter $callback can be a string or a callable, so your code could look something like this with items sorted descending:
$collection = \App\Http\Resources\MyResource::collection($test);
return $collection->sortByDesc('name')->all();
If the Laravel default sorting doesn't work for your purpose, try to do this:
$collection = \App\Http\Resources\MyResource::collection->sortBy(function ($element, $key) {
return yourFunctionForSorting($element['name']);
});
Replace obviously "yourFunctionForSorting", with your sorting criteria.
I am working on a back-end that needs to re-calculate the price based on user-specific currency.
I fetch all required records from the database as following:
$tasks = Task::with([
'images' => function($query){},
'price' => function($query){},
'user' => function($query){ $query->with('images');},
])->whereDoesntHave('tasksState', function($query) use ($user){
$query->where('user_id', $user->id);
$query->where('state', '<>', 0);
})->where('id', '>', $offset)->where('user_id', '<>', $user->id)->take($limit)->get();
Task's price model consists of currency and value attributes.
Then I iterate through $tasks and re-calculate the price based on the user-specific currency:
foreach ($tasks as $k => $task){
$price = $task->price->value;
$price = $price * $rate->getValue();
$tasks[$k]->price = $price;
//$task->price = $price;
}
After inspecting the tasks, all price are re-calculated correctly.
However when I subsequently serialize $tasks and send it as a response, it contains the data as they were fetched from the database - no re-calculated prices.
Does anybody where is the problem? Any ideas will be greatly appreciated!
Since you're serializing the data anyway, you can first convert collection into an array and work it as with an array:
$tasks->toArray();
In this case you'll be able to override original data as you've tried to accomplish with foreach loop.
As alternative, you could create a mutator which will add calculated_price property to the collection.
You can use Eloquent Mutator for this.
Create following function in Task Model
public function getNewPriceAttribute($value)
{
...// do your processing here
}
And then you can use it as:
$task->new_price;
After creating the accessor, add the attribute name to the appends property on the Task model.
protected $appends = ['new_price'];
Once the attribute has been added to the appends list, it will be included in both the model's array and JSON representations.
I have a collection with records that include the created_at row. Now i want to get specific rows by date without time. I mean :
$users->whereLoose('created_at', '2016-11-23')
of course this returns empty but the format I need to use is "Y-m-d" without the "H:i:s" part. How can use this format to get records from the collection?
You could also use the filter method and the isSameDay() method.
$date = \Carbon\Carbon::parse('2016-11-23');
$usersForDate = $users->filter(function ($user) use ($date) {
return $user->created_at->isSameDay($date);
});
Hope this helps!
You can do this:
$date = Carbon::parse('2016-11-23');
$users->where('created_at', '>', $date->startOdDay())
->where('created_at', '<', $date->endOfDay());
Or you could try this:
$users->whereDate('created_at', '=', '2016-11-23');
You can try using the map() function on the collection per the docs https://laravel.com/docs/5.2/collections:
https://laravel.com/docs/5.2/collections#method-map
$collection = collect(['taylor', 'abigail', null])->map(function ($name) {
return strtoupper($name);
})
->reject(function ($name) {
return empty($name);
});
I am trying to learn whether or not there is a simple way to pass a variable number of parameters to a query in Eloquent, hopefully using an array.
From what I can find, there doesn't seem to be a way to do this without looping through the Input to see what was set in the request.
Examples here: Laravel Eloquent search two optional fields
This would work, but feels non-Laravel to me in its complexity/inelegance.
Here is where I am, and this may not be possible, just hoping someone else has solved a similar issue:
$where = array("user_id" => 123, "status" => 0, "something else" => "some value");
$orders = Order::where($where)->get()->toArray();
return Response::json(array(
'orders' => $orders
),
200
);
That returns an error of course strtolower() expects parameter 1 to be string, array given.
Is this possible?
Order::where actually returns an instance of query builder, so this is probably easier than you thought. If you just want to grab that instance of query builder and "build" your query one where() at a time you can get it like this:
$qb = (new Order)->newQuery();
foreach ($searchParams as $k => $v) {
$qb->where($k, $v);
}
return $qb->get(); // <-- fetch your results
If you ever want to see what query builder is doing you can also execute that get() and shortly after:
dd(\DB::getQueryLog());
That will show you what the resulting query looks like; this can be very useful when playing with Eloquent.
You can try this:
Method 1:
If you have one optional search parameter received in input
$orders = Order::select('order_id','order_value',...other columns);
if($request->has(user_id)) {
$orders->where('orders.user_id','=',$request->user_id);
}
//considering something_else as a substring that needs to be searched in orders table
if($request->has('something_else')) {
$orders->where('orders.column_name', 'LIKE', '%'.$request->something_else.'%');
}
$orders->paginate(10);
Method 2:
If you have multiple optional parameters in input
$orders = Order::select('columns');
foreach($input_parameters as $key => $value) {
//this will return results for column_name=value
$orders->where($key, $value);//key should be same as the column_name
//if you need to make some comparison
$orders->where($key, '>=', $value);//key should be same as the column_name
}
return $orders->paginate(15);