How to sort a collection from a pagination result - laravel

I have this collection I have obtained with a pagination query:
$apps = $query->paginate(10);
The result is something like this:
I would like to sort this collection before to send it, especially the "data" array. I tried a lot of things with "sortBy" and "sortByDesc". Without success. Each time I use these methods, the pagination is "broken".
How to sort this kind of json obtained by pagination?

You can use orderBy, orderByDesc or orderByRaw to order the query before paginating the results:
docs:
$apps = $query->orderBy('created_at')->paginate(10);

use Illuminate\Pagination\LengthAwarePaginator;
$sortedApps = $query->get()->sortBy('name');
$result = $this->paginateCollection($sortedApps,50);
public function paginateCollection(
$collection,
$perPage,
$pageName = 'page',
$fragment = null
) : LengthAwarePaginator
{
$currentPage = LengthAwarePaginator::resolveCurrentPage($pageName);
$currentPageItems = $collection->slice(($currentPage - 1) * $perPage, $perPage);
parse_str(request()->getQueryString(), $query);
unset($query[$pageName]);
$paginator = new LengthAwarePaginator(
$currentPageItems,
$collection->count(),
$perPage,
$currentPage,
[
'pageName' => $pageName,
'path' => LengthAwarePaginator::resolveCurrentPath(),
'query' => $query,
'fragment' => $fragment
]
);
return $paginator;
}

Related

Laravel 7 : Why I am Getting Only First Array? I want to Fetch All Category ID data

I am getting a issue while fetching array data in Laravel 7 here is my code
https://i.stack.imgur.com/IZbg6.png
and the result is : https://i.stack.imgur.com/ByKaV.png
It is fetching only one array data. I don't know where i am missing.
If anybody know the error, please help me to solve this issue.
Below is my code ======================================
$cat_id = $category->id;
$location = null;
$sites = \DB::select( 'SELECT id FROM sites WHERE category_id = ?', [ $category->id ]);
$all = [ ];
foreach( $sites as $s ) {
$all[ ] = $s->id;
}
$sites = $all;
$all_cat_id = implode(',', array_map('intval', $sites));
// echo "<pre>";
// print($all_cat_id);
// die();
$sites = Sites::withCount('reviews')->orderBy('reviews_count', 'desc')->where('id', [$all_cat_id])->paginate(10);
return view('browse-category', [ 'activeNav' => 'home',
'reviews' => $reviews,
'sites' => $sites,
'category' => $category,
'all_categories' => $all_categories,
'location' => $location
]);
$sites = Sites::withCount('reviews')->orderBy('reviews_count', 'desc')->whereIn('id', [$all_cat_id])->paginate(10);
You need to use whereIn() instead of where()
whereIn() checks column against array.

Get Raw SQL of Insert Statement

I am looking for a way to get the correct SQL queries for an INSERT statement. I'm having to export this data for use in another (non-laravel) system. The post at How to get the raw SQL for a Laravel delete/update/insert statement? got me part of the way there but my queries are still parameterized:
Post::all()->each(function($post)
{
$builder = DB::table('posts');
$insertStatement = $builder->getGrammar()->compileInsert($builder->select(['created_at', 'title']), [
'created_at' => $post->created_at,
'title' => $post->title
]);
Storage::disk('sql')->append('posts-latest.sql', $insertStatement);
dump($insertStatement);
}
this results in...
insert into `posts` (`created_at`, `title`) values (?, ?)
So I've managed to set the fields to be updated but how to swap out the parameters for real values?
You can do this:
Post::all()->each(function($post){
$builder = DB::table('posts');
$grammar = $builder->getGrammar();
$values = [
'created_at' => $post->created_at,
'title' => $post->title
];
$table = $grammar->wrapTable($builder->from);
if (!is_array(reset($values))) {
$values = [$values];
}
$columns = $grammar->columnize(array_keys(reset($values)));
$parameters = collect($values)->map(function ($record) use ($grammar) {
$record = array_map(function($rec){
$rec = str_replace("'", "''", $rec);
return "'$rec'";
},array_values($record));
return '('.implode(', ', $record).')';
})->implode(', ');
$insertStatement = "insert into $table ($columns) values $parameters";
// $insertStatement should contains everything you need for this post
});
I ended up discovering DB::pretend which will generate the query without running it. Then it's a case of substitution. It seems that there is no way to get the raw SQL without substitution due to the use of parameters.
Post::all()->each(function($post)
{
$builder = DB::table('posts');
$query = DB::pretend(function() use ($builder, $post)
{
return $builder->insert([
'created_at' => $post->created_at,
'title' => $post->title,
'content' => $post->content,
'featured_image_link' => $post->featured_image_link,
'slug' => $post->slug
]);
});
$bindings = [];
collect($query[0]['bindings'])->each(function($binding) use (&$bindings)
{
$binding = str_replace("'", "\\'", $binding);
$bindings[] = "'$binding'";
});
$insertStatement = Str::replaceArray('?', $bindings, $query[0]['query']);
Storage::disk('sql')->append('posts-latest.sql', $insertStatement.';');
});

how can convert list of info to paginate laravel when info dosnt read an database

how can convert list of info to paginate Laravel when info dos not read an database
$list=[1,2,3,4,5,6,7,9];
/* how this line work*/
$list=$list->paginate(3);
You could use the forPage collection helper
$list = collect([1,2,3,4,5,6,7,9]);
$list->forPage(1, 3)->values() // collect([1,2,3])
$list->forPage(2, 3)->values() // collect([4,5,6])
$list->forPage(3, 3)->values() // collect([7,8,9])
$list->forPage(4, 3)->values() // collect([10])
$list->forPage(5, 3)->values() // collect()
If you want the full paginator (with links()), you're going to need a bit more logic.
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
$list = collect([1,2,3,4,5,6,7,8,9]);
$pageName = 'page';
$perPage = 3;
$page = Paginator::resolveCurrentPage($pageName);
$total = $list->count();
$results = $total ? $this->forPage($page, $perPage)->values() : collect();
$options = ['path' => Paginator::resolveCurrentPath(), 'pageName' => $pageName];
$paginated_list = new LengthAwarePaginator($results, $total, $perPage, $page, $options);
This code is based on the paginate() method on the Query Builder.
public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null)
{
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$total = $this->getCountForPagination();
$results = $total ? $this->forPage($page, $perPage)->get($columns) : collect();
return $this->paginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
}

yii2 get sum and related model data together

Below is my query. I want the sum of the hours. But when I write select, it does not return the data of the related model.
$query = JobPositions::find()
->select(['sum(assign_applicant.hours) as hours'])
->joinWith(['assign','position','shift'])
->groupBy(['position_id','shift_id']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
The below line return the data when I remove the select line from the above query.
$model->position->name
what should be the solution to this when I want both ?
Try add explictally the columns you need eg:
$query = JobPositions::find()
->select(['sum(assign_applicant.hours) as hours', 'name'])
->joinWith(['assign','position','shift'])
->groupBy(['position_id','shift_id']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
or
$query = JobPositions::find()
->select('*, sum(assign_applicant.hours) as hours')
->joinWith(['assign','position','shift'])
->groupBy(['position_id','shift_id']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);

How to add limit option in Magento API call

I am creating web service for my store. I am using magento API to collect product list from store. But it display all the 500 records. And i want it 25 records per page. What to add in API call? Or What filter will be apply for this?
//create soap object
$proxy = new SoapClient('http://localhsot/magento/api/soap/?wsdl');
// create authorized session id using api user name and api key
// $sessionId = $proxy->login('apiUser', 'apiKey');
$sessionId = $proxy->login('test_admin', '12345678');
$filters = array(
);
// Get list of product
$productlist = $proxy->call($sessionId, 'product.list', array($filters));
print_r($productlist );
that didn't work, can you limit it by id like:
$filters = array('id'=>array("gteq"=>1), 'id'=>array("lteq"=>1000));
that way you could add some paging?
I know this is an old question but I struggled with this. I've created my own SOAP API endpoint which does exactly the same as the default catalogProductList function but has an extra param. See the code below:
$collection = Mage::getModel('catalog/product')->getCollection()
->addStoreFilter($this->_getStoreId($store))
->addAttributeToSelect('name');
if($limit) {
$collection->setOrder('updated_at', 'ASC');
$collection->setPageSize($limit);
}
/** #var $apiHelper Mage_Api_Helper_Data */
$apiHelper = Mage::helper('api');
$filters = $apiHelper->parseFilters($filters, $this->_filtersMap);
try {
foreach ($filters as $field => $value) {
$collection->addFieldToFilter($field, $value);
}
} catch (Mage_Core_Exception $e) {
$this->_fault('filters_invalid', $e->getMessage());
}
$result = array();
foreach ($collection as $product) {
$result[] = array(
'product_id' => $product->getId(),
'sku' => $product->getSku(),
'name' => $product->getName(),
'set' => $product->getAttributeSetId(),
'type' => $product->getTypeId(),
'category_ids' => $product->getCategoryIds(),
'website_ids' => $product->getWebsiteIds(),
'updated_at' => $product->getUpdatedAt(),
'created_at' => $product->getCreatedAt()
);
}
return $result;
And from there we keep track of the last updated_at value and use that as a filter to get the next [LIMIT] items. By default updated_at and created_at are not in the response and the list is not orderred by updated_at so I've added this.
I am not sure of this but you could try this, as the API is working with collections and this is the way to limit a collection size
$filters = array(
'setPageSize' => 10
);

Resources