input->getpost('act', TYPE_STR)) { /** * Autocomplete для городов/областей */ case 'region-suggest': return $this->regionSuggest(); case 'filter-suggest': $response['html'] = $this->filterData('filter-suggest'); break; case 'filter-regions': $id = $this->input->post('id', TYPE_UINT); $response['html'] = $this->filterData('regions-list', ['id' => $id]); break; /** * Подтверждаем текущий регион пользователя * @param int $nRegionID ID региона */ case 'filter-confirm-region': $regionID = $this->input->post('region_id', TYPE_UINT); $regionData = $this->regionData($regionID); if (! empty($regionData)) { $response['success'] = $this->filterUser($regionID, 'ip-location-confirm-finish'); $response['redirect'] = $this->url($this->regionParents($regionData)['keys'] ?? []); } break; /** * Список станций метро города для формы ОБ * @param int $cityID ID города */ case 'form-metro': $cityID = $this->input->postget('city', TYPE_UINT); $data = $this->cityMetro($cityID); $response['data'] = $data['data']; $response['branches'] = $this->template('form.metro.step1', $data); $response['stations'] = []; foreach ($data['data'] as $key => $branch) { $branch['city_id'] = $cityID; $response['stations'][$key] = $this->template('form.metro.step2', $branch); } break; /** * Список районов города * @param int $cityID ID города * @param bool $asOptions true - в формате select::options, false - array */ case 'districts-list': $cityID = $this->input->postget('city', TYPE_UINT); $asOptions = $this->input->postget('opts', TYPE_BOOL); if (! $cityID) { $this->errors->impossible(); break; } if ($asOptions) { $response['districts'] = $this->districtOptions($cityID, 0, _t('filter', 'Not specified')); } else { $response['districts'] = $this->districtList($cityID); } break; /** * todo comment */ case 'country-presuggest': $countryID = $this->input->postget('country', TYPE_UINT); $lang = $this->locale->current(); $response = false; if ($countryID) { $response = $this->regionPreSuggest($countryID, ['json' => false, 'lang' => $lang]); } return $this->ajaxResponse($response); default: $this->errors->impossible(); } return $this->ajaxResponseForm($response); } /** * todo comment * @param $dataType * @param array $opts * @return array|\bff\http\Response|mixed|string */ public function filterData($dataType, $opts = []) { $opts = $this->defaults($opts, [ 'id' => 0, 'first' => false, 'asArray' => false, ]); switch ($dataType) { case 'filter-suggest': $data = $this->regionSuggest(['asArray' => true]); return $opts['asArray'] ? $data : $this->template('filter/suggest', $data); case 'countries-list': $data = []; $data['list'] = $this->countriesList(); foreach ($data['list'] as &$v) { $v['link'] = $this->url(['region1' => $v['keyword']]); } unset($v); return $opts['asArray'] ? $data : $this->template('filter/countries', $data); case 'regions-list': $data = $opts; $region = $this->regionData($opts['id']); if (empty($region)) { return $opts['asArray'] ? [] : ''; } $region['link'] = $this->url($this->regionParents($region)['keys'] ?? []); $data['region'] = $region; $filter = [ 'numlevel' => $region['numlevel'] + 1, 'enabled' => 1, ['numleft', '>', $region['numleft']], ['numright', '<', $region['numright']], ]; $data['list'] = $this->model->regionsListing($filter, ['fields' => ['parents']]); foreach ($data['list'] as & $v) { $v['link'] = $this->url($this->regionParents($v)['keys'] ?? []); } unset($v); return $opts['asArray'] ? $data : $this->template('filter/regions', $data); case 'cities-list': $data = []; $filter = [ 'id' => $this->coveringRegion(), 'enabled' => 1, 'city' => 1, ]; $data['list'] = $this->model->regionsListing($filter, ['fields' => ['parents']]); foreach ($data['list'] as & $v) { $v['link'] = $this->url($this->regionParents($v)['keys'] ?? []); } unset($v); return $opts['asArray'] ? $data : $this->template('filter/cities', $data); } return ''; } /** * todo comment * @param string|null $ipAddress * @return array|int[]|mixed */ public function regionFilterByIp(?string $ipAddress = null) { $data = $this->regionDataByIp($ipAddress); if (empty($data)) { $data = ['id' => 0]; } else { if (! $this->coveringRegionCorrect($data)) { $data = ['id' => 0]; } } return $data; } /** * Получаем шаблон карты по ID региона * @param int $regionID ID региона * @return string HTML */ public function regionMap(int $regionID, $opts = []) { $opts = $this->defaults($opts, [ 'lang' => $this->locale->current(), 'counters' => true, ]); if (! file_exists($this->view->resolveViewPath('map.' . $regionID, $this->module_dir_tpl))) { return ''; } $data = [ 'regions' => [], 'counters' => $opts['counters'], ]; $data['map'] = $this->template('map.' . $regionID); $cacheKey = 'geo.region.map.' . $regionID . '.' . $opts['lang']; $regions = Cache::remember($cacheKey, 3600, static function () use (&$data, &$opts) { preg_match_all('/data-id=\"(\d+)\"/', $data['map'], $m); if (! empty($m[1])) { $filter = [ 'enabled' => 1, 'id' => $m[1], ]; return Geo::model()->regionsListing($filter, [ 'orderBy' => 'fav', 'keyBy' => 'id', 'fields' => ['parents'], 'lang' => $opts['lang'], ]); } return []; }); if (!empty($regions)) { if ($opts['counters']) { $items = Listings::model()->itemsCountByFilter([ 'cat_id' => 0, 'region_id' => array_keys($regions), 'delivery' => 0, ], ['region_id', 'items'], false, 60); $items = func::array_transparent($items, 'region_id', true); } foreach ($regions as &$v) { $v['items'] = ($opts['counters'] ? ($items[ $v['id'] ]['items'] ?? 0) : 0); $v['l'] = Listings::url('items.search', $this->regionParents($v)['keys'] ?? []); } unset($v); } $fields = ['id', 'title', 'items', 'l', 'numlevel']; foreach ($regions as $v) { foreach ($fields as $f) { $data['regions'][$v['id']][$f] = $v[$f]; } } $data['regions'] = array_values($data['regions']); return $this->template('map.layout', $data); } }