Skip to content

Instantly share code, notes, and snippets.

@tony-brewerio
Created September 28, 2012 13:06
Show Gist options
  • Save tony-brewerio/3799724 to your computer and use it in GitHub Desktop.
Save tony-brewerio/3799724 to your computer and use it in GitHub Desktop.
Random drupal code | Alternating views query
<?php
/**
* Принимает айди места, находит айди страны ( если есть ) и айди регионов,
* куда входит это место
* @return string
*/
function my_module_expand_location($location_tid = null) {
// кэш
$cache = &drupal_static(__FUNCTION__, array());
// по умолчанию - текущее местоположение
if ($location_tid === null) {
// берем из сессии
$location_tid = my_module_get_user_location();
}
if (isset($cache[$location_tid])) {
return $cache[$location_tid];
}
//
$locations_tids = array($location_tid);
// чекаем страну ( если текущее размещение = город, что должно быть всегда )
$parent_location_tid = taxonomy_get_parents($location_tid);
if ($parent_location_tid) {
$parent_location_tid = array_shift($parent_location_tid);
$parent_location_tid = $parent_location_tid->tid;
$locations_tids[] = $parent_location_tid;
} else {
$parent_location_tid = null;
}
// для текущего размещения, подтягиваем список релевантных регионов
$regions_select = db_select('field_data_field_locations', 'fl');
$regions_select->condition('fl.bundle', 'regions');
$regions_select->condition('fl.field_locations_tid', $locations_tids);
$regions_select->fields('fl', array('entity_id'))->distinct();
$regions_tids = $regions_select->execute()->fetchCol();
//
return $cache[$location_tid] = array(
'places' => $locations_tids, 'regions' => $regions_tids
);
}
function my_module_join_prices_by_location($select, $locations = null) {
if ($locations === null) {
$locations = my_module_expand_location();
}
// джойним цены по конкретным местам
$select->leftJoin(
'field_data_field_price_by_location', 'pbl',
implode(' and ', array(
"pbl.entity_type = 'commerce_product'",
'pbl.deleted = 0',
'pbl.entity_id = p.product_id',
))
);
$select->leftJoin(
'field_data_field_locations', 'pbl_fl',
implode(' and ', array(
"pbl_fl.bundle = 'field_price_by_location'",
'pbl_fl.deleted = 0',
'pbl_fl.entity_id = pbl.field_price_by_location_value',
'pbl_fl.delta = pbl.delta',
'pbl_fl.field_locations_tid in ('.implode(',', $locations['places']).')',
))
);
$select->leftJoin(
'field_data_field_price', 'pbl_fp',
implode(' and ', array(
"pbl_fp.bundle = 'field_price_by_location'",
'pbl_fp.deleted = 0',
'pbl_fp.entity_id = pbl.field_price_by_location_value',
'pbl_fp.delta = pbl.delta',
))
);
// джойним цены по регионам
$select->leftJoin(
'field_data_field_price_by_region', 'pbr',
implode(' and ', array(
"pbr.entity_type = 'commerce_product'",
'pbr.deleted = 0',
'pbr.entity_id = p.product_id',
))
);
$select->leftJoin(
'field_data_field_regions', 'pbr_fr',
implode(' and ', array(
"pbr_fr.bundle = 'field_price_by_region'",
'pbr_fr.deleted = 0',
'pbr_fr.entity_id = pbr.field_price_by_region_value',
'pbr_fr.delta = pbr.delta',
'pbr_fr.field_regions_tid in ('.implode(',', $locations['regions']).')',
))
);
$select->leftJoin(
'field_data_field_price', 'pbr_fp',
implode(' and ', array(
"pbr_fp.bundle = 'field_price_by_region'",
'pbr_fp.deleted = 0',
'pbr_fp.entity_id = pbr.field_price_by_region_value',
'pbr_fp.delta = pbr.delta',
))
);
}
function my_module_views_pre_execute_catalogue(&$view) {
// окей, то ли views - тупое гумно, то ли я, а может и оба
// суть в том, что оно не хочет ни нормально джойнить ни делать группировку
// мне показалось проще втупую переписать всю гребаную кверю так как надо
$select = $view->build_info['query'];
// а теперь - уличная магия
// наша задача - вытянуть все товары, у которых цена проставлена в текущем городе
// или в текущей стране ( берется из города )
// или в городах/странах региона
// но если цена = 0, то продукт не продается
my_module_join_prices_by_location($select);
// нам нужны только товары, где проставлена хоть какая-то цена
$select->where('('.implode(' or ', array(
'pbl_fp.field_price_amount is not null',
'pbr_fp.field_price_amount is not null',
)).')');
// также те товары, где цена по месту <= 0 идут лесом
// это спец фича, чтобы исключать товары из групп
$select->where('not ('.implode(' and ', array(
'pbl_fp.field_price_amount is not null',
'pbl_fp.field_price_amount <= 0',
)).')');
$select->groupBy('n.nid');
$view->build_info['query'] = $select;
$view->build_info['count_query'] = $select->countQuery();
}
function my_module_views_pre_execute(&$view) {
if ($view->name == 'catalogue' && $view->current_display == 'page') {
my_module_views_pre_execute_catalogue($view);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment