/** * Выполняет обработку запроса * * @param \Phalcon\Http\Request $request * @param \Kladr\Core\Plugins\Base\PluginResult $prevResult * @return \Kladr\Core\Plugins\Base\PluginResult */ public function process(Request $request, PluginResult $prevResult) { if ($prevResult->error) { return $prevResult; } // Проверяем, что ищем город // с принадлежностью региону if ($request->getQuery('contentType') != 'city') { return $prevResult; } if (!$request->getQuery('regionId')) { return $prevResult; } // добавляем к результату поиск в другом регионе $arRegionCodeSpecialCases = array(50 => 77, 47 => 78); $objects = $this->cache->get('SpecialCasesPlugin', $request); if ($objects === null) { $objects = array(); $arCodes = array(); // regionId $regionId = $request->getQuery('regionId'); if ($regionId) { $arCodes = Regions::getCodes($regionId); } // districtId $districtId = $request->getQuery('districtId'); if ($districtId) { $arCodes = Districts::getCodes($districtId); } // cityId $cityId = $request->getQuery('cityId'); if ($cityId) { $arCodes = Cities::getCodes($cityId); } // streetId $streetId = $request->getQuery('streetId'); if ($streetId) { $arCodes = Streets::getCodes($streetId); } // buildingId $buildingId = $request->getQuery('buildingId'); if ($buildingId) { $arCodes = Buildings::getCodes($buildingId); } if (!isset($arCodes[KladrFields::CodeRegion]) && !isset($arRegionCodeSpecialCases[$arCodes[KladrFields::CodeRegion]])) { return $prevResult; } $arCodes[KladrFields::CodeRegion] = $arRegionCodeSpecialCases[$arCodes[KladrFields::CodeRegion]]; // query $query = $request->getQuery('query'); $query = Tools::Key($query); $query = Tools::Normalize($query); // limit $limit = $request->getQuery('limit'); $limit = intval($limit); $limit = $limit ? $limit : 5000; if ($limit > 400) { $limit = 400; } switch ($request->getQuery('contentType')) { case Regions::ContentType: $objects = Regions::findByQuery($query, $arCodes, $limit); break; case Districts::ContentType: $objects = Districts::findByQuery($query, $arCodes, $limit); break; case Cities::ContentType: $objects = Cities::findByQuery($query, $arCodes, $limit); break; case Streets::ContentType: $objects = Streets::findByQuery($query, $arCodes, $limit); break; case Buildings::ContentType: $objects = Buildings::findByQuery($query, $arCodes, $limit); break; } $this->cache->set('SpecialCasesPlugin', $request, $objects); } $result = $prevResult; $result->result = array_merge($prevResult->result, $objects); return $result; }
/** * Выполняет обработку запроса * * @param \Phalcon\Http\Request $request * @param \Kladr\Core\Plugins\Base\PluginResult $prevResult * @return \Kladr\Core\Plugins\Base\PluginResult */ public function process(Request $request, PluginResult $prevResult) { if ($prevResult->error) { return $prevResult; } if (!$request->getQuery('withParent')) { return $prevResult; } $objects = $this->cache->get('FindParentsPlugin', $request); $result = $prevResult; if ($objects === null) { $objects = $result->result; switch ($request->getQuery('contentType')) { case Regions::ContentType: foreach ($objects as $key => $object) { $objects[$key]['parents'] = self::findParents(Regions::getCodes($object['id'])); } break; case Districts::ContentType: foreach ($objects as $key => $object) { $objects[$key]['parents'] = self::findParents(Districts::getCodes($object['id'])); } break; case Cities::ContentType: foreach ($objects as $key => $object) { $objects[$key]['parents'] = self::findParents(Cities::getCodes($object['id'])); } break; case Streets::ContentType: foreach ($objects as $key => $object) { $objects[$key]['parents'] = self::findParents(Streets::getCodes($object['id'])); } break; case Buildings::ContentType: foreach ($objects as $key => $object) { $objects[$key]['parents'] = self::findParents(Buildings::getCodes($object['id'])); } break; } $this->cache->set('FindParentsPlugin', $request, $objects); } $result->result = $objects; return $result; }
/** * Выполняет обработку запроса * * @param \Phalcon\Http\Request $request * @param \Kladr\Core\Plugins\Base\PluginResult $prevResult * @return \Kladr\Core\Plugins\Base\PluginResult */ public function process(Request $request, PluginResult $prevResult) { if ($prevResult->error || $prevResult->isPluginDisabled('FindPlugin')) { return $prevResult; } $objects = null; $objects = $this->cache->get('FindPlugin', $request); if ($objects === null) { $objects = array(); // query $query = $request->getQuery('query'); $query = Tools::Key($query); $query = Tools::Normalize($query); $arCodes = null; // regionId $regionId = $request->getQuery('regionId'); if ($regionId) { $arCodes = $request->getQuery('contentType') == 'region' ? $regionId : Regions::getCodes($regionId); } // districtId $districtId = $request->getQuery('districtId'); if ($districtId) { $arCodes = $request->getQuery('contentType') == 'district' ? $districtId : Districts::getCodes($districtId); } // cityId $cityId = $request->getQuery('cityId'); if ($cityId) { $arCodes = $request->getQuery('contentType') == 'city' ? $cityId : Cities::getCodes($cityId); } // streetId $streetId = $request->getQuery('streetId'); if ($streetId) { $arCodes = $request->getQuery('contentType') == 'street' ? $streetId : Streets::getCodes($streetId); } // buildingId $buildingId = $request->getQuery('buildingId'); if ($buildingId) { $arCodes = Buildings::getCodes($buildingId); } // zip $zip = (int) $request->getQuery('zip'); if ($zip <= 0 || $zip > 999999) { $zip = null; } // limit $limit = $request->getQuery('limit'); $limit = intval($limit); $limit = $limit ? $limit : 400; if ($limit > 400) { $limit = 400; } //offset $offset = $request->getQuery('offset'); $offset = intval($offset); $typeCodes = self::ConvertCodeTypeToArray($request->getQuery('typeCode')); switch ($request->getQuery('contentType')) { case Regions::ContentType: $objects = Regions::findByQuery($query, $arCodes, $limit, $offset); break; case Districts::ContentType: $objects = Districts::findByQuery($query, $arCodes, $limit, $offset); break; case Cities::ContentType: $objects = Cities::findByQuery($query, $arCodes, $limit, $offset, $typeCodes); break; case Streets::ContentType: $objects = Streets::findByQuery($query, $arCodes, $limit, $offset); break; case Buildings::ContentType: $objects = Buildings::findByQuery($query, $arCodes, $limit, $zip); break; } $this->cache->set('FindPlugin', $request, $objects); } $result = $prevResult; $result->result = $objects; return $result; }
/** * Выполняет обработку запроса * * @param \Phalcon\Http\Request $request * @param \Kladr\Core\Plugins\Base\PluginResult $prevResult * @return \Kladr\Core\Plugins\Base\PluginResult */ public function process(Request $request, PluginResult $prevResult) { if ($prevResult->error) { return $prevResult; } if (!$request->getQuery('oneString')) { return $prevResult; } $arReturn = $this->cache->get('OneStringPlugin', $request); if ($arReturn === null) { $objects = array(); $query = $request->getQuery('query'); //разбиваем строку запроса на слова $arWords = preg_split('/(\\ |\\.|\\;|\\,)+/', $query, -1, PREG_SPLIT_NO_EMPTY); //нормализуем foreach ($arWords as $key => $word) { $arWords[$key] = preg_replace('/"/u', '', $arWords[$key]); //Tools::Normalize($word); if (mb_strlen($arWords[$key], mb_detect_encoding($arWords[$key])) < 4) { $arWords[$key] = preg_replace('/-/u', '', $arWords[$key]); } } //$arExceptionWords = array('рн', 'бр'); $arExceptionWords = array(); for ($i = 0; $i < count($arWords); $i++) { if ($i === count($arWords) - 1 || mb_strlen($arWords[$i], mb_detect_encoding($arWords[$i])) <= 3 && !in_array($arWords[$i], $arExceptionWords)) { $arWords[$i] = $arWords[$i] . '*'; } } $houseForMongo = null; //строка для поиска номера дома в монго $possibleBuildingName = end($arWords); $houseForMongo = Tools::Normalize($possibleBuildingName); //array_pop($arWords); //$houseForMongo = str_replace('*', '', $houseForMongo); $searchString = implode(" ", $arWords); $sphinxClient = $this->sphinxClient; $limit = $request->getQuery('limit') ? (int) $request->getQuery('limit') >= 50 ? 50 : (int) $request->getQuery('limit') : 50; $sphinxClient->SetLimits(0, $limit); $sphinxClient->SetMatchMode(SPH_MATCH_EXTENDED2); $sphinxClient->SetSortMode(SPH_SORT_ATTR_ASC, 'sort'); $regionForSphinx = (string) $request->getQuery('regionId'); $districtForSphinx = (string) $request->getQuery('districtId'); $cityForSphinx = (string) $request->getQuery('cityId'); $sphinxRes = null; //echo "@fullname \"$searchString\""; if ($cityForSphinx) { $sphinxRes = $sphinxClient->Query("@fullname \"{$searchString}\" @cityid {$cityForSphinx}"); } elseif ($districtForSphinx) { $sphinxRes = $sphinxClient->Query("@fullname \"{$searchString}\" @districtid {$districtForSphinx}"); } elseif ($regionForSphinx) { $sphinxRes = $sphinxClient->Query("@fullname \"{$searchString}\" @regionid {$regionForSphinx}"); } else { $sphinxRes = $sphinxClient->Query("@fullname \"{$searchString}\""); } if ($sphinxRes === false) { $result = $prevResult; $result->terminate = true; $result->error = true; $result->errorMessage = $sphinxClient->GetLastError(); return $result; } if (empty($sphinxRes['matches'])) { array_pop($arWords); $searchString = implode(" ", $arWords); $sphinxRes = $sphinxClient->Query($searchString); //подумать о повторном запросе при разных заданных областях } //ID в сфинксе числовые, поэтому мы теряем нули в начале //0100000000000 — 13 //01000001000000300 — 17 //0100000100000030001 — 19 if (!empty($sphinxRes['matches'])) { $sphinxIds = array(); $sphinxIds = array_keys($sphinxRes['matches']); foreach ($sphinxIds as &$id) { $id = "{$id}"; $len = strlen($id); if ($len == 13 || $len == 17 || $len == 19) { continue; } if ($len > 19) { continue; } while ($len != 13 && $len != 17 && $len != 19) { $id = '0' . $id; $len = strlen($id); } } $objects = Complex::find(array(array('Id' => array('$in' => $sphinxIds)))); } if ($houseForMongo) { $streets = array(); foreach ($objects as $object) { if ($object->readAttribute(KladrFields::ContentType) == 'street') { $streets[] = $object; } } if (count($streets) > 0) { $retBuildings = array(); $mainBuilding = null; foreach ($streets as $street) { $buildingsOfStr = Complex::find(array(array(KladrFields::StreetId => $street->readAttribute(KladrFields::StreetId), KladrFields::ContentType => 'building'))); foreach ($buildingsOfStr as $buildingOfStr) { foreach ($buildingOfStr->readAttribute(KladrFields::NormalizedBuildingName) as $buildName) { if ($buildName === $houseForMongo) { $mainBuilding = $buildingOfStr; //находим точное совпадение $mainBuilding->NormalizedBuildingName = $buildName; } $reg = '#^' . $houseForMongo . '#'; $match = preg_match($reg, $buildName) ? $buildName : null; //убираем длинные строки из домов $match = preg_match('/\\,/', $match) ? null : $match; if ($match) { $building = clone $buildingOfStr; $building->NormalizedBuildingName = $match; $retBuildings[] = $building; } } } //убираем повторное точное вхождение, ставим его на первое место if ($mainBuilding) { foreach ($retBuildings as $key => $retBuilding) { if ($mainBuilding->NormalizedBuildingName == $retBuilding->NormalizedBuildingName) { unset($retBuildings[$key]); } } $retBuildings = array_merge(array($mainBuilding), $retBuildings); } if (count($objects) > floor($limit / 2)) { if (count($retBuildings) >= ceil($limit / 2)) { break; } } elseif (count($retBuildings) >= $limit - count($objects)) { break; } } //заполянем лимит по максимуму if (count($objects) > floor($limit / 2)) { if ($retBuildings > ceil($limit / 2)) { $retBuildings = array_slice($retBuildings, 0, ceil($limit / 2)); } } else { $retBuildings = array_slice($retBuildings, 0, $limit - count($objects)); } //сливаем массивы домов и остальных совпадений $objects = array_merge($retBuildings, $objects); //финальная обрезка массива if ($objects > $limit) { $objects = array_slice($objects, 0, $limit, true); } } } $withParent = $request->getQuery('withParent') != ''; $ids = array(); foreach ($objects as $object) { $key = $object->readAttribute(KladrFields::Id) . '_' . $object->readAttribute(KladrFields::NormalizedBuildingName); if (in_array($key, $ids)) { continue; } $ids[] = $key; if ($object) { $retObj = array('id' => $object->readAttribute(KladrFields::Id), 'name' => $object->readAttribute(KladrFields::Name), 'zip' => $object->readAttribute(KladrFields::ZipCode), 'type' => $object->readAttribute(KladrFields::Type), 'typeShort' => $object->readAttribute(KladrFields::TypeShort), 'okato' => $object->readAttribute(KladrFields::Okato), 'contentType' => $object->readAttribute(KladrFields::ContentType), 'fullName' => $object->readAttribute(KladrFields::FullName)); $ownerId = \Kladr\Core\Models\Cities::getCityOwnerId($retObj['id']); switch ($retObj['contentType']) { case 'district': if ($withParent) { $retObj['parents'] = FindParentsPlugin::findParents(\Kladr\Core\Models\Districts::getCodes($retObj['id'])); } //$retObj['districtId'] = $object->readAttribute(KladrFields::DistrictId); break; case 'city': if ($withParent) { $retObj['parents'] = FindParentsPlugin::findParents(\Kladr\Core\Models\Cities::getCodes($retObj['id']), $ownerId); } //$retObj['districtId'] = $object->readAttribute(KladrFields::DistrictId); //$retObj['cityId'] = $object->readAttribute(KladrFields::CityId); break; case 'street': if ($withParent) { $retObj['parents'] = FindParentsPlugin::findParents(\Kladr\Core\Models\Streets::getCodes($retObj['id']), $ownerId); } //$retObj['districtId'] = $object->readAttribute(KladrFields::DistrictId); //$retObj['cityId'] = $object->readAttribute(KladrFields::CityId); //$retObj['streetId'] = $object->readAttribute(KladrFields::StreetId); break; case 'building': if ($withParent) { $retObj['parents'] = FindParentsPlugin::findParents(\Kladr\Core\Models\Buildings::getCodes($retObj['id']), $ownerId); } //$retObj['districtId'] = $object->readAttribute(KladrFields::DistrictId); //$retObj['cityId'] = $object->readAttribute(KladrFields::CityId); //$retObj['streetId'] = $object->readAttribute(KladrFields::StreetId); //$retObj['buildingId'] = $object->readAttribute(KladrFields::BuildingId); break; default: break; } } if ($retObj['contentType'] == 'building') { $name = $object->readAttribute(KladrFields::NormalizedBuildingName); $retObj['fullName'] .= ', ' . $name; $retObj['name'] = $name; $arReturn[] = $retObj; } else { $arReturn[] = $retObj; } } $this->cache->set('OneStringPlugin', $request, $arReturn); } $result = $prevResult; $result->result = $arReturn; $result->terminate = true; return $result; }
/** * Выполняет обработку запроса * * @param \Phalcon\Http\Request $request * @param \Kladr\Core\Plugins\Base\PluginResult $prevResult * @return \Kladr\Core\Plugins\Base\PluginResult */ public function process(Request $request, PluginResult $prevResult) { if ($prevResult->error) { return $prevResult; } $objects = $this->cache->get('DuplicatePlugin', $request); if ($objects === null) { $objects = array(); $arCodes = array(); $existDuplicate = false; // regionId $regionId = $request->getQuery('regionId'); if ($regionId && $this->arDuplicates[$regionId]) { $arCodes = Regions::getCodes($this->arDuplicates[$regionId]); $existDuplicate = true; } // districtId $districtId = $request->getQuery('districtId'); if ($districtId && $this->arDuplicates[$districtId]) { $arCodes = Districts::getCodes($this->arDuplicates[$districtId]); $existDuplicate = true; } // cityId $cityId = $request->getQuery('cityId'); if ($cityId && $this->arDuplicates[$cityId]) { $arCodes = Cities::getCodes($this->arDuplicates[$cityId]); $existDuplicate = true; } // streetId $streetId = $request->getQuery('streetId'); if ($streetId && $this->arDuplicates[$streetId]) { $arCodes = Streets::getCodes($streetId); $existDuplicate = true; } // buildingId $buildingId = $request->getQuery('buildingId'); if ($buildingId && $this->arDuplicates[$buildingId]) { $arCodes = Buildings::getCodes($this->arDuplicates[$buildingId]); $existDuplicate = true; } if ($existDuplicate) { // query $query = $request->getQuery('query'); $query = Tools::Key($query); $query = Tools::Normalize($query); // limit $limit = $request->getQuery('limit'); $limit = intval($limit); $limit = $limit ? $limit : 5000; if ($limit > 400) { $limit = 400; } switch ($request->getQuery('contentType')) { case Regions::ContentType: $objects = Regions::findByQuery($query, $arCodes, $limit); break; case Districts::ContentType: $objects = Districts::findByQuery($query, $arCodes, $limit); break; case Cities::ContentType: $objects = Cities::findByQuery($query, $arCodes, $limit); break; case Streets::ContentType: $objects = Streets::findByQuery($query, $arCodes, $limit); break; case Buildings::ContentType: $objects = Buildings::findByQuery($query, $arCodes, $limit); break; } } $this->cache->set('DuplicatePlugin', $request, $objects); } $result = $prevResult; $objects = array_merge($prevResult->result, $objects); $arResult = array(); $arIgnore = array(); foreach ($objects as $object) { $ignoreId = isset($this->arDuplicates[$object['id']]) ? $this->arDuplicates[$object['id']] : false; if ($ignoreId) { $arIgnore[] = $ignoreId; } if (!in_array($object['id'], $arIgnore)) { $arResult[] = $object; } } $result->result = $objects; return $result; }