Ну, один из способов — расширить класс Query
и переопределить черты where()
from()
и select()
и изменить пространство имен с yii\db\Query
на common\components\Query
в целом в моделях, где вы хотите добавить условие. Но помните, что вы несете ответственность за то, чтобы во всех этих таблицах были эти 2 поля (application_id
и branch_id
) внутри таблиц, где бы вы ни заменяли yii\db\Query
на common\components\Query
.
Зачем переопределять where()
from()
и select()
? у вас есть возможность писать запросы в следующих форматах.
Допустим, у нас есть таблица product
с полями id
и name
, теперь рассмотрим следующие запросы.
$q->from ( '{{product}}' )
->all ();
$q->select ( '*' )
->from ( '{{product}}' )
->all ();
$q->from ( '{{product}}' )
->where ( [ 'name' => '' ] )
->all ();
$q->from ( '{{product}}' )
->andWhere ( [ 'name' => '' ] )
->all ();
$q->select ( '*' )
->from ( '{{product}}' )
->where ( [ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] )
->andwhere ( [ 'name' => '' ] )
->all ();
$q->select ( '*' )
->from ( '{{product}}' )
->where ( [ 'and' ,
[ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] ,
[ 'name' => '' ]
] )
->all();
Вышеприведенное сгенерирует следующие SQL-запросы
SELECT * FROM `product`
SELECT * FROM `product`
SELECT * FROM `product` WHERE (`name`='')
SELECT * FROM `product` WHERE (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`name`='')
Поэтому вам нужно добавить все вышеперечисленные запросы с двумя условиями where по умолчанию
создайте имя файла Query
внутри common/components
и добавьте следующее,
Примечание. Я добавил условия с жестко закодированными значениями для столбцов, подобных этому [ 'application_id' => 1 ] , [ 'branch_id' => 1 ]
, замените их соответствующими переменными из сеанса, прежде чем фактически использовать его для целей тестирования, которые вы можете оставить как есть. Я предполагаю, что вы хотите, чтобы два вышеуказанных поля были добавлены с помощью условие and
в запросе.
<?php
namespace common\components;
use yii\db\Query as BaseQuery;
class Query extends BaseQuery {
/**
*
* @param type $condition
* @param type $params
* @return $this
*/
public function where( $condition , $params = array() ) {
parent::where ( $condition , $params );
$defaultConditionEmpty = !isset ( $this->where[$this->from[0] . '.company_id'] );
if ( $defaultConditionEmpty ) {
if ( is_array ( $this->where ) && isset ( $this->where[0] ) && strcasecmp ( $this->where[0] , 'and' ) === 0 ) {
$this->where = array_merge ( $this->where , [ [ $this->from[0] . '.company_id' => 1 ] , [ $this->from[0] . '.branch_id' => 1 ] ] );
} else {
$this->where = [ 'and' , $this->where , [ $this->from[0] . '.company_id' => 1 ] , [ $this->from[0] . '.branch_id' => 1 ] ];
}
}
return $this;
}
/**
*
* @param type $tables
* @return $this
*/
public function from( $tables ) {
parent::from ( $tables );
$this->addDefaultWhereCondition ();
return $this;
}
/**
* Private method to add the default where clause
*/
private function addDefaultWhereCondition() {
if ( $this->from !== null ) {
$this->where = [ 'and' ,
[ $this->from[0] . '.company_id' => 1 ] , [ $this->from[0] . '.branch_id' => 1 ]
];
}
}
}
Теперь, чтобы протестировать его, создайте тестовое действие внутри вашего SiteController
, как показано ниже, и получите к нему доступ.
public function actionTest() {
$q = new \common\components\Query();
echo $q->from ( '{{product}}' )->createCommand ()->rawSql;
echo "<br>";
echo $q->select ( '*' )->from ( '{{product}}' )->createCommand ()->rawSql;
echo "<br/>";
echo $q->from ( '{{product}}' )->where ( [ 'name' => '' ] )->createCommand ()->rawSql;
echo "<br>";
echo $q->from ( '{{product}}' )->andWhere ( [ 'name' => '' ] )->createCommand ()->rawSql;
echo "<br>";
echo $q->select ( '*' )->from ( '{{product}}' )->where ( [ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] )->andwhere ( [ 'name' => '' ] )->createCommand ()->rawSql;
echo "<br />";
echo $q->select ( '*' )->from ( '{{product}}' )
->where ( [ 'and' ,
[ 'IN' , 'id' , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 89 , 0 ] ] ,
[ 'name' => '' ]
] )
->createCommand ()->rawSql;
return;
}
Не беспокойтесь о таблице product
, нам нужно проверить сгенерированный запрос, поэтому мы не выполняем запрос, а используем ->createCommand()->rawSql
для печати построенного запроса. поэтому получите доступ к вышеуказанному действию, теперь он должен напечатать вам запросы с добавлением обоих столбцов, как показано ниже.
SELECT * FROM `product` WHERE (`application_id`=1) AND (`branch_id`=1)
SELECT * FROM `product` WHERE (`application_id`=1) AND (`branch_id`=1)
SELECT * FROM `product` WHERE (`name`='') AND (`application_id`=1) AND (`branch_id`=1)
SELECT * FROM `product` WHERE (`application_id`=1) AND (`branch_id`=1) AND (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`application_id`=1) AND (`branch_id`=1) AND (`name`='')
SELECT * FROM `product` WHERE (`id` IN (1, 2, 3, 4, 5, 6, 7, 89, 0)) AND (`name`='') AND (`application_id`=1) AND (`branch_id`=1)
Надеюсь, это поможет вам или кому-то еще, кто ищет такое же решение.
ИЗМЕНИТЬ
Я обновил класс выше и добавил исправление для запросов с использованием соединений, которые выдают ошибку.
Столбец 'company_id' в предложении where неоднозначен
Я добавил первое имя table
, доступное в массиве from
, поскольку все ваши таблицы имеют имя поля, и добавление условия для первой выбранной таблицы будет работать, поскольку оно будет объединено со следующей таблицей с условием ON
. И я удалил переопределение признака select()
из класса, так как он нам не понадобится.
person
Muhammad Omer Aslam
schedule
09.03.2018
Order::find()->select('SUM(product_order.order_price * product_order.quantity) as return_price') ->innerJoin('product_order', 'product_order.order_id = order.id') ->where(['=', 'order.user_id', $user_id]) ->andWhere(['=', 'order.status', '4']) ->one();
- person Golub   schedule 07.03.2018Query
классомDependencyInjection
. - person Yupik   schedule 07.03.2018