Yii2 mongodb relational searching - php

I have two collections - Users and Order
I have a list of orders(OrderSearch model) with some users details(email, name..). Now I want to search user details relationally.
OrderSearch Model---
public function search($params)
{
// Email getting from query params
if(!empty($params['email'])){
$this->email = $params['email'];
}
$query = Order::find();
$query->with(['user']); // for related document
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pagesize' => 10,
],
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => isset($this->id)?(int)$this->id:$this->id,
'status' => $this->status,
'user_id' => $this->user_id,
]);
$query->andFilterWhere(['like', 'sku', $this->sku])
->andFilterWhere(['like', 'message', $this->message])
// Tried below code but it is not working.
->andFilterWhere(['like', 'user.email', $this->email]); // $this->email is email which I want to search
return $dataProvider;
}
Relation in Order Model -
public function getUser(){
return $this->hasOne(User::className(), ['_id' => 'user_id']);
}

Related

How do I add a filter on yii2 models

I have a query used to read data from a view. I am then applying a non related sql filter to this, to take out the models I don't need and then returning an arrayDataProvider instance. The filter I am applying is the promotion period. However, when I pass query params to this search model, it doesn't work. How do I solve this?
Here's the code to select data from the view:
public function search($params, $promotion_period)
{
$query = StaffEmploymentListView::find()->alias('LIST')
->joinWith(['employment EMPLOYMENT'])
->where(['LIST.EMPLOYMENT_TYPE' => 'PROMOTION']);
$query->andFilterWhere(['like', 'DEPT_NAME', $this->DEPT_NAME])
->andFilterWhere(['like', 'COL_NAME', $this->COL_NAME])
->andFilterWhere(['like', 'GRADE_DESCR', $this->GRADE_DESCR])
->andFilterWhere(['like', 'DESG_NAME', $this->DESG_NAME])
->andFilterWhere(['like', 'TRIBE_NAME', $this->TRIBE_NAME])
->andFilterWhere(['like', 'GENDER', $this->GENDER])
->andFilterWhere(['like', 'HOME_DISTRICT', $this->HOME_DISTRICT]);
$allModels = [];
if($promotion_period !== null){
$to_date = strtotime($promotion_period['to_date']);
$from_date = strtotime($promotion_period['from_date']);
foreach ($query->all() as $model)
{
$effective_date = strtotime($model->employment->APPOINT_DATE);
if ($effective_date >= $from_date && $effective_date <= $to_date){
$allModels[] = $model;
}
}
}
else{
foreach ($query->all() as $model)
{
$allModels[] = $model;
}
}
$dataProvider = new ArrayDataProvider([
'allModels' => $allModels,
'pagination' => [
'pageSize' => 20,
],
'sort' => false
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
return $dataProvider;
}
Here's the dump of the params from the URL:
[
'from_date' => ''
'to_date' => ''
'PromotedStaffSearch' => [
'COL_NAME' => 'CENTRAL ADMINISTRATION'
'DEPT_NAME' => ''
'GRADE_DESCR' => ''
'DESG_NAME' => ''
'GENDER' => ''
'TRIBE_NAME' => ''
'HOME_DISTRICT' => ''
]
]
Like i understand, you trying to find all models between specified period if it is set.
Try this:
public function search($params, $promotion_period)
{
$query = StaffEmploymentListView::find()->alias('LIST')
->joinWith(['employment']) //Here should be your relation name from StaffEmploymentListView model
->where(['LIST.EMPLOYMENT_TYPE' => 'PROMOTION']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 20,
],
'sort' => false
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere(['like', 'DEPT_NAME', $this->DEPT_NAME])
->andFilterWhere(['like', 'COL_NAME', $this->COL_NAME])
->andFilterWhere(['like', 'GRADE_DESCR', $this->GRADE_DESCR])
->andFilterWhere(['like', 'DESG_NAME', $this->DESG_NAME])
->andFilterWhere(['like', 'TRIBE_NAME', $this->TRIBE_NAME])
->andFilterWhere(['like', 'GENDER', $this->GENDER])
->andFilterWhere(['like', 'HOME_DISTRICT', $this->HOME_DISTRICT]);
//$allModels = [];
if(is_array($promotion_period) && isset($promotion_period['to_date']) && isset($promotion_period['from_date'])){
//also check if you $promotion_period params are not empty
$to_date = strtotime($promotion_period['to_date']);
$from_date = strtotime($promotion_period['from_date']);
$query->andFilterWhere(['BETWEEN', 'EMPLOYMENT_TABLE_NAME.APPOINT_DATE', $from_date, $to_date]);
}
//Now you can get all your filtered models as array like this:
return $dataProvider->getModels();
}
Documentation for Data Providers

how to limit content in yii model

Is there any way to limit n number of contents in yii model any my code is
public function rules()
{
return [
[['id', 'editedby', 'cat_id', 'prod_id', 'parent', 'order', 'status'], 'integer'],
[['name', 'content', 'excerpt', 'date', 'url', 'posttype'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = Posts::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params,'');
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'date' => $this->date,
'editedby' => $this->editedby,
'cat_id' => $this->cat_id,
'prod_id' => $this->prod_id,
'parent' => $this->parent,
'order' => $this->order,
'status' => $this->status,
]);
$query->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'content', $this->content])
->andFilterWhere(['like', 'excerpt', $this->excerpt])
->andFilterWhere(['like', 'url', $this->url])
->andFilterWhere(['like', 'posttype', $this->posttype]);
return $dataProvider;
}
it was a model to list products if the user was in free plan have to show only one product or else have to display products based on plan count will change i have no idea that how to add the condition i need something like
if($user_type==1){
$query->andFilterWhere([['id' => SORT_DESC])->one();]);
}
As Raul Sauco already mentioned you could use something like that
$query->andFilterWhere([['id' => SORT_DESC])->limit($user_type == 1 ? 1 : 20);

Yii2 Gridview filtering a column that has Int data type based on varchar as inputed value

I've an gridView for showing data. GridView table has a column that called as Created By, this column contain the ID of User that I get from user table. Basicly, this column will show data as Integer(ID) like this:
But I've set code like this to show the username of the ID:
[
'attribute' => 'created_by',
'format' => 'raw',
'value' => function ($data) {
$modelUser = Users::find()->where(['id' => $data->created_by])->one();
$nama = $modelUser->username;
return $nama;
},
'vAlign' => 'middle',
'hAlign' => 'center',
],
Result:
The gridView has filter column, I'm trying to filter data based on inserted value. I'm trying input username as the value for filtering but it give an error message "created By must be an Integer", like this:
How do I can filtering that column using the a username(varchar)?
Thanks
Update
This is my searchModel.php
<?php
namespace app\search;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use app\models\Product;
/**
* ProductSearch represents the model behind the search form of `app\models\Product`.
*/
class ProductSearch extends Product {
/**
* #inheritdoc
*/
public function rules() {
return [
[['productId', 'userId', 'parentId', 'created_by'], 'integer'],
[['date', 'created_at', 'name', 'address'], 'safe'],
[['price'], 'number'],
];
}
/**
* #inheritdoc
*/
public function scenarios() {
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params) {
$query = Product::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'productId' => $this->productId,
'price' => $this->price,
'created_at' => $this->created_at,
'created_by' => $this->created_by,
]);
$query->andFilterWhere(['MONTH(date)' => $this->date])
->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'address', $this->address]);
return $dataProvider;
}
}
public function rules()
{
return [
[['productId', 'userId', 'parentId'], 'integer'],
[['date', 'created_at', 'name', 'address'], 'safe'],
[['price'], 'number'],
[['created_by'], 'string'],
];
}
public function search($params)
{
$query = Product::find()->joinWith('createdBy'); // Whatever relation name
.
.
.
.
.
// grid filtering conditions
$query->andFilterWhere([
'productId' => $this->productId,
'price' => $this->price,
'created_at' => $this->created_at,
]);
$query->andFilterWhere(['MONTH(date)' => $this->date])
->andFilterWhere(['like', 'name', $this->name])
->andFilterWhere(['like', 'address', $this->address])
->andFilterWhere(['like', 'userTableName.username', $this->created_by]); // Whatever table name and field name.
return $dataProvider;
}
You should add a proper filter to your column
[
'attribute'=>'your_attribute',
......
'filter'=>ArrayHelper::map(YourModel::find()->asArray()->all(),
'your_id_column', 'your_name_column'),
],

Yii2 Grid view sort and filteration using custom label

In my user table I have fields like firstname and lastname.
then I generated a views using Gii.In my index page now I have Firstname,Lastname,Username etc....
I concatenated my fistname and lastname as Name.
[
'attribute'=>'firstname',
'label' => 'Name',
'format' => 'raw',
'value' => function ($data) {
return Html::a($data->Name);
},
],
In Model
public function getName()
{
return $this->firstname.' '.$this->lastname;
}
unfortunately I am unable to search the name field with last name...
I need to filter the field with both firstname and lastname.
Can anyone please help me....
Thanks in advance.
This is how you setup search model (I did not include your other columns, so dont forget on those)
You can find more here: http://www.yiiframework.com/wiki/621/filter-sort-by-calculated-related-fields-in-gridview-yii-2-0/
class UserSearch extends User
{
public $name;
public function rules()
{
return [
[['name'], 'safe'],
// some other rules ...
];
}
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
public function search($params)
{
$query = User::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$dataProvider->sort->attributes['name'] = [
'asc' => ['lastname' => SORT_ASC, 'firstname' => SORT_ASC],
'desc' => ['lastname' => SORT_DESC, 'firstname' => SORT_DESC],
'label' => 'Name',
'default' => SORT_ASC
];
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
// some other filters ...
$query->andFilterWhere([
'or',
['like', 'lastname', $this->name],
['like', 'firstname', $this->name],
]);
return $dataProvider;
}
}
And in your gridview instead of
[
'attribute'=>'firstname',
// ...
],
just use
[
'attribute'=>'name',
],

Yii2 only display data where posted on date is less than or equal to current datetime

I have a field within my database called publish_on_date where I store the date the post should become active.
Now I am unsure on how to add the query to my dataprovider/search model.
So I need to add a query that will query the display date and check if it is less than or equal to now (now being the current date/server date).
Here is my current search functon
public function search($params, $pageSize = 3, $published = false)
{
$query = Article::find();
// this means that editor is trying to see articles
// we will allow him to see published ones and drafts made by him
if ($published === true)
{
$query->where(['status' => Article::STATUS_PUBLISHED]);
$query->orWhere(['user_id' => Yii::$app->user->id]);
}
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort'=> ['defaultOrder' => ['id' => SORT_DESC]],
'pagination' => [
'pageSize' => $pageSize,
]
]);
if (!($this->load($params) && $this->validate())) {
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'user_id' => $this->user_id,
'status' => $this->status,
'category' => $this->category,
]);
$query->andFilterWhere(['like', 'title', $this->title])
->andFilterWhere(['like', 'summary', $this->summary])
->andFilterWhere(['like', 'content', $this->content]);
return $dataProvider;
}
Just add someplace another condition with
$query->andWhere('publish_on_date <= NOW()');
You can add this when you first create the query
$query = Article::find()->andWhere('publish_on_date <= NOW()');
or later down the page

Categories