Yii2 - Query with Pagination - php

I have a Category model that has a relation with the Products model.
I am doing the following query:
$model = Category::find()->where(['slug' => $slug])->with('products')->one();
And in the view I can retrieve all the products that belong to that Category with:
foreach ($model->products as $value)...
Now I want to do the pagination in the products but I can not find how to do it in the "with" part of the query.

Try this
In Controller:
...
$pages = new Pagination(['totalCount' => $model->products->count()]);
return $this->render('index', [
'model' => $model,
'pages' => $pages,
]);
In View:
foreach ($model->products as $value) {
// display $model here
}
// display pagination
echo LinkPager::widget([
'pagination' => $pages,
]);

Related

Yii2 pagination

is it possible to use post id in pagination instead of page number
example instead of :
&page=2
it will be
&id=63
Pagination code is :
function actionIndex()
{
$query = Article::find()->where(['status' => 1]);
$countQuery = clone $query;
$pages = new Pagination(['totalCount' => $countQuery->count()]);
$models = $query->offset($pages->offset)
->limit($pages->limit)
->all();
return $this->render('index', [
'models' => $models,
'pages' => $pages,
]);
}
view :
foreach ($models as $model) {
// display $model here
}
// display pagination
echo LinkPager::widget([
'pagination' => $pages,
]);

Yii2: checkboxList doesn't show ArrayDataProvider

I want to use a checkboxList to show data from a data provider.
My view file:
$offices = Offices::findMyOffices();
echo Html::checkboxList('name', [], $offices);
My model file:
public static function findMyOffices()
{
$dataProvider = new ArrayDataProvider([
'allModels' => 'SELECT id_office ...'
]);
return $dataProvider;
}
But the view shows me the checkbox list with the sql query instead of the sql query's results:
I solve it using sqlDataProvider:
View:
$offices = Offices::findMyOffices();
echo Html::checkboxList('name', [], ArrayHelper::map($offices, 'id_office', 'name_office'));
Model:
public static function findMyOffices()
{
$dataProvider = new sqlDataProvider([
'sql' => 'SELECT id_office ...'
]);
return $dataProvider->getModels();
}
ArrayDataProvider needs an array of items. you can add ->asArray() to your activequery.
$dataProvider = new ArrayDataProvider([
'allModels' => [['id' => 1, 'title' => 'xxx, ...], ...],
]);
my favorite for fetching data for a dropdown is:
MyModel::find()->select('name', 'id')->indexBy('id')->column()

Two paginations on one page YII2

I can’t do two paginations on one page. I have a page in the form of tabs, and each tab has a list of different products, I want to paginate each list
Here is the error code and screenshot
$posts = Wishlist::find()->where(['user_id'=>$id]);
$pagination =new Pagination([
'defaultPageSize' =>10,
'totalCount' => $posts->count()
]);
$posts = $posts->offset($pagination->offset )->limit($pagination->limit)->all();
$favs = FavLists::find()->where(['user_id'=>$id]);
$pag_favs =new Pagination([
'defaultPageSize' =>10,
'totalCount' => $favs->count()
]);
$favs = $favs->offset($pag_favs->offset )->limit($pag_favs->limit)->all();
return $this->render('view', [
'model' => $this->findModel($id),
'posts' =>$posts,
'pagination' => $pagination,
'favs' =>$favs,
'pag_favs' => $pag_favs
]);
In view 1st pagination
echo LinkPager::widget([
'pagination' => $pagination,
]);
?>
In view 2nd pagination
<?php
echo LinkPager::widget([
'pag_favs' => $pag_favs,
]);
?>
Replace pag_fvs with pagination in LinkPager. LinkPager don't have property page_fvs.
<?= LinkPager::widget([
'pagination' => $pag_favs,
]) ?>

Many-to-many relation in yii2 activedataprovider

I have many-to-many relation with three tables: Category, Product, ProductCategory.
Relation in Category:
public function getProductCategories()
{
return $this->hasMany(ProductCategory::className(), ['category_id' => 'id']);
}
Relation in Product:
public function getProductCategories()
{
return $this->hasMany(ProductCategory::ClassName(), ['product_id' => 'id']);
}
And in ProductCategory
public function getProduct()
{
return $this->hasOne(Product::className(), ['id' => 'product_id']);
}
public function getCategory()
{
return $this->hasOne(Category::className(), ['id' => 'category_id']);
}
In my Category Controller I used this code to show the products I need according to their category (one-to-many):
$cats = Category::findOne(['slug1'=>$slug1]);
$dataProvider = new ActiveDataProvider([
'query' => $query = Product::find()->where(['category_id' => $cats->id]),
'sort'=>array(
'defaultOrder'=>['id' => SORT_ASC],
),
'pagination' => [
'pageSize' => 9,
],
]);
So the question is how to make my ActiveDataProvider to get in query the many-to-many relation?
You can create two more relations like this
In category:
public function getProducts()
{
return $this->hasMany(Product::className(), ['id' => 'product_id'])->via("productCategories");
}
And in product:
public function getCategories()
{
return $this->hasMany(Category::ClassName(), ['id' => 'category_id'])->via("productCategories");
}
Then you can use it like this
$cats = Category::findOne(['slug1'=>$slug1]);
$dataProvider = new ActiveDataProvider([
'query' => $query = $cats->getProducts(),
'sort'=>array(
'defaultOrder'=>['id' => SORT_ASC],
),
'pagination' => [
'pageSize' => 9,
],
]);

Yii2 Many to Many with Self - filter through grid view (no attribute?)

I've used the Gii AJAX Crud generator, and I'm being driven up a wall by my own stupidity. I am using Yii 2 and want to search with many to many, on a table that has that relation with ITSELF in a junction table, with the Grid View.
table tag (id, name).
table tag_child (parent_id, child_id)
Class Tag
...
public function getParents()
{
return $this->hasMany(self::className(), ['id' => 'child_id'])
->viaTable('tag_child', ['parent_id' => 'id']);
}
public function getChildren()
{
return $this->hasMany(self::className(), ['id' => 'parent_id'])
->viaTable('tag_child', ['child_id' => 'id']);
}
And in my grid-view /columns:
[
'class' => '\kartik\grid\DataColumn',
'attribute'=>'name',
],
[
'class' => '\kartik\grid\DataColumn',
'label' => 'Tag Type',
'value' => function($tag) {
return $tag->displayTagTypes();
},
'attribute' => 'tagTypes'
],
TagQuery.php
...
public $tagTypes;
public function search($params)
{
$query = Tag::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// $query->where('0=1');
return $dataProvider;
}
$query->joinWith('parents p');
$query->andFilterWhere(['id' => $this->id]);
$query->andFilterWhere(['like', 'tag.name', $this->name]);
return $dataProvider;
}
I'm able to display the results in my index table with that value function, but my Tag filter isn't able to search by tagTypes. How do I populate that?
As an example, when it's not many to many, I can use set my attribute to 'joinedTableName.value' and it works as soon as I add a $query->orFilterWhere('like', 'parent.name', $this->id) or whatever. But I'm at a loss now...
Declare $searchModel = new TagQuery() in your controller, then pass the $searchModel to the view and include it in the GridView options as 'filterModel' => $searchModel.
Either that, or you can do really custom filters using specific filterTypes and filter logic for each column.
You declare public tagType in the query model, but you don't do anything with it. $query->andFilterWhere(['like', 'tag.name', $this->tagType]);

Categories