Здравствуйте.
Помогите построить запрос. Специфика такая, требуется сделать выборку, в форме фильтрации условия такие:
- часть параметров это доп свойства shop_items
- часть параметров это доп свойства shop_groups
в зависимости должны присутствовать все товары из групп товаров, которые соответствуют всем условиям фильтров
Только вот у меня что-то не получается построить SQL.
на данный момент это выглядит так:
if (Core_Array::getGet('filter') || Core_Array::getGet('sorting')) {
$backLinkFilter = Core::$url['path'] . '?' . Core::$url['query'];
if ($newRealEstate) {
$_SESSION['backLinkFilterNew'] = $backLinkFilter;
}
if ($eliteRealEstate) {
$_SESSION['backLinkFilterElite'] = $backLinkFilter;
}
if ($liveRealEstate) {
$_SESSION['backLinkFilterLive'] = $backLinkFilter;
}
$Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('filter')->value(1)
);
$sorting = (int)Core_Array::getGet('sorting');
$sorting && $Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('sorting')->value($sorting)
);
// Prices
$price_from = (int)Core_Array::getGet('price_from') * $price_multiplier;
$price_to = (int)Core_Array::getGet('price_to') * $price_multiplier;
if ($price_from || $price_to || $sorting == 1 || $sorting == 2) {
// Получаем список валют магазина
$aShop_Currencies = Core_Entity::factory('Shop_Currency')->findAll();
$query_currency_switch = 'price';
$Shop_Controller_Show->shopItems()
->queryBuilder()
->select(array(Core_QueryBuilder::expression($query_currency_switch), 'absolute_price'));
if ($price_from) {
$Shop_Controller_Show
->addEntity(
Core::factory('Core_Xml_Entity')
->name('price_from')->value($price_from / $price_multiplier))
->shopItems()
->queryBuilder()
->having('absolute_price', '>=', $price_from);
}
if ($price_to) {
$Shop_Controller_Show
->addEntity(
Core::factory('Core_Xml_Entity')
->name('price_to')->value($price_to / $price_multiplier))
->shopItems()
->queryBuilder()
->having('absolute_price', '<=', $price_to);
}
$Shop_Controller_Show
->shopItems()
->queryBuilder()
->clearOrderBy()
->orderBy('absolute_price', $sorting == 1 ? 'ASC' : 'DESC');
}
$sorting == 3 && $Shop_Controller_Show->shopItems()->queryBuilder()
->clearOrderBy()
->orderBy('shop_items.name', 'ASC');
$aProperties = $Shop_Controller_Show->group !== FALSE ? $oShop_Item_Property_List->getPropertiesForGroup($Shop_Controller_Show->group) : $oShop_Item_Property_List->Properties->findAll();
if ($newRealEstate) {
$aShopGroupProperty = $oCurrentShopGroup->getPropertyValues();
foreach ($aShopGroupProperty as $oPropertyValue) {
$aProperties[] = Core_Entity::factory('Property', (int)$oPropertyValue->property_id);
}
}
$aTmpProperties = array();
$aTmpGroupProperties = array();
$havingCount = 0;
foreach ($aProperties as $oProperty) {
// Св-во может иметь несколько значений
if ($newRealEstate) {
$aPropertiesValue = Core_Array::getGet('property_group_' . $oProperty->id);
if ($aPropertiesValue) {
foreach ((array)$aPropertiesValue as $sPropertyValue) {
$aTmpGroupProperties[] = array($oProperty, strval($sPropertyValue));
}
//++$havingCount;
}
}
$aPropertiesValue = Core_Array::getGet('property_' . $oProperty->id);
if ($aPropertiesValue) {
foreach ((array)$aPropertiesValue as $sPropertyValue) {
$aTmpProperties[] = array($oProperty, strval($sPropertyValue));
}
++$havingCount;
}
if (!is_null(Core_Array::getGet('property_' . $oProperty->id . '_from'))) {
// From ... to ...
$aTmpProperties[] = array($oProperty, array(
'from' => Core_Array::getGet('property_' . $oProperty->id . '_from'),
'to' => Core_Array::getGet('property_' . $oProperty->id . '_to')
));
++$havingCount;
}
if ($oProperty->tag_name == 'floor') {
// "Не первый этаж"
$aPropertiesValue = (int)Core_Array::getGet('not_first');
if ($aPropertiesValue) {
$aTmpProperties[] = array($oProperty, $aPropertiesValue);
$Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('not_first')
->value($aPropertiesValue)
);
++$havingCount;
}
}
if (!Core_Array::getGet('not_first') && $oProperty->tag_name == 'floor_max') {
// "Не последний этаж"
$aPropertiesValue = (int)Core_Array::getGet('not_last');
if ($aPropertiesValue) {
$aTmpProperties[] = array($oProperty, $aPropertiesValue);
++$havingCount;
}
}
}
if (!empty($aTmpGroupProperties)) {
$aTableNames = array();
$Shop_Controller_Show->shopItems()->queryBuilder()
->leftJoin('shop_group_properties', 'shop_items.shop_id', '=', 'shop_group_properties.shop_id');
reset($aTmpGroupProperties);
while (list(, list($oProperty, $propertyValue)) = each($aTmpGroupProperties)) {
$Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('property_group')
->addAttribute('id', $oProperty->id)
->value($propertyValue)
);
}
}
if (!empty($aTmpProperties)) {
$aTableNames = array();
$Shop_Controller_Show->shopItems()->queryBuilder()
->leftJoin('shop_item_properties', 'shop_items.shop_id', '=', 'shop_item_properties.shop_id')
->setAnd()
->open();
reset($aTmpProperties);
while (list(, list($oProperty, $propertyValue)) = each($aTmpProperties)) {
$tableName = $oProperty->createNewValue(0)->getTableName();
!in_array($tableName, $aTableNames) && $aTableNames[] = $tableName;
$Shop_Controller_Show->shopItems()->queryBuilder()
->open()
->where('shop_item_properties.property_id', '=', $oProperty->id);
if (!is_array($propertyValue)) {
if ($oProperty->tag_name == 'floor') {
if (Core_Array::getGet('not_last')) {
$Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('not_last')
->value(1)
);
$Shop_Controller_Show->shopItems()->queryBuilder()
->open()
->where($tableName . '.value', '!=', 1)
->setAnd()
->where($tableName . '.value', '<', Core_QueryBuilder::select('value')
->from($tableName)
->where('property_id', '=', 78)
->where('entity_id', '=', Core_QueryBuilder::expression('`shop_items`.`id`'))
)
->close()
->setAnd();
} else {
$Shop_Controller_Show->shopItems()->queryBuilder()
->where($tableName . '.value', '!=', 1)
->setAnd();
}
} else if ($oProperty->tag_name == 'floor_max') {
$Shop_Controller_Show->shopItems()->queryBuilder()
->where($tableName . '.value', '>', 1)
->setAnd();
} else {
$Shop_Controller_Show->shopItems()->queryBuilder()
->where($tableName . '.value', '=', $propertyValue)
->setOr();
}
$Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('property')
->addAttribute('id', $oProperty->id)
->value($propertyValue)
);
} else {
$from = trim(strval(Core_Array::get($propertyValue, 'from')));
$from && $Shop_Controller_Show->shopItems()->queryBuilder()
->where($tableName . '.value', '>=', $from)
->setAnd();
$to = trim(strval(Core_Array::get($propertyValue, 'to')));
$to && $Shop_Controller_Show->shopItems()->queryBuilder()
->where($tableName . '.value', '<=', $to);
$Shop_Controller_Show->shopItems()->queryBuilder()
->setOr();
$Shop_Controller_Show->addEntity(
Core::factory('Core_Xml_Entity')
->name('property')
->addAttribute('id', $oProperty->id)
->addEntity(
Core::factory('Core_Xml_Entity')
->name('from')->value($from)
)->addEntity(
Core::factory('Core_Xml_Entity')
->name('to')->value($to)
)
);
}
$Shop_Controller_Show->shopItems()->queryBuilder()
->close()
->setOr();
}
$Shop_Controller_Show->shopItems()->queryBuilder()
->close()
->groupBy('shop_items.id')
->having('COUNT(shop_item_properties.id)', '=', $havingCount);
foreach ($aTableNames as $tableName) {
$Shop_Controller_Show->shopItems()->queryBuilder()
->leftJoin($tableName, 'shop_items.id', '=', $tableName . '.entity_id', array(
array(
'AND' => array(
'shop_item_properties.property_id', '=', Core_QueryBuilder::expression($tableName . '.property_id')
)
)
)
);
}
}
}
(мои добавления выделены жирным)
Вот на моменте добавления
leftJoin('shop_group_properties', 'shop_items.shop_id', '=', 'shop_group_properties.shop_id'
я и застрял, т.к. непонятно как именно собрать товары из групп, которые содержат значения переданных доп свойств.