示例#1
0
 /**
  * Выполняет обработку запроса
  * 
  * @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;
 }
示例#2
0
 /**
  * Выполняет обработку запроса
  *
  * @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;
 }
示例#3
0
 /**
  * Выполняет обработку запроса
  *
  * @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;
 }
示例#4
0
 /**
  * Собирает города
  * 
  * @param string $typeCode
  * @param string $format CSV или JSON формат
  * @param \Kladr\Core\Plugins\Base\PluginResult $result
  */
 private function processCities($typeCode, $format, PluginResult $result)
 {
     set_time_limit(600);
     ini_set('max_execution_time', 600);
     ini_set('memory_limit', '600M');
     $format = $format == self::FORMAT_JSON ? self::FORMAT_JSON : self::FORMAT_CSV;
     $cacheKey = 'all_cities';
     $typeCodes = FindPlugin::ConvertCodeTypeToArray($typeCode);
     if ($typeCodes != null) {
         foreach ($typeCodes as $code) {
             $cacheKey .= '_' . $code;
         }
     }
     $cacheKey .= $format == self::FORMAT_JSON ? '_json' : '';
     if (!$this->checkCache($cacheKey)) {
         $cities = new Cities();
         $mongo = $cities->getConnection();
         $tmp = $this->getCachePath($cacheKey) . '_' . rand(10000, 10000000);
         $cities = $typeCodes == null ? $mongo->cities->find(array('Bad' => false)) : $mongo->cities->find(array('Bad' => false, 'TypeCode' => array('$in' => $typeCodes)));
         $fp = fopen($tmp, 'w');
         if ($format == self::FORMAT_CSV) {
             fputcsv($fp, $this->cityToArray());
             foreach ($cities as $city) {
                 $districtCode = $city['CodeDistrict'];
                 $regionCode = $city['CodeRegion'];
                 $district = null;
                 $region = null;
                 if ($districtCode != null) {
                     $district = $mongo->district->findOne(array('CodeDistrict' => (int) $districtCode, 'CodeRegion' => (int) $regionCode, 'Bad' => false));
                 }
                 $region = $mongo->regions->findOne(array('CodeRegion' => (int) $regionCode, 'Bad' => false));
                 fputcsv($fp, $this->cityToArray($city, $district, $region));
             }
         } else {
             fwrite($fp, '{ "result" : [');
             $first = true;
             foreach ($cities as $city) {
                 if ($first) {
                     $first = false;
                 } else {
                     fwrite($fp, ',' . PHP_EOL);
                 }
                 $districtCode = $city['CodeDistrict'];
                 $regionCode = $city['CodeRegion'];
                 $district = null;
                 $region = null;
                 if ($districtCode != null) {
                     $district = $mongo->district->findOne(array('CodeDistrict' => (int) $districtCode, 'CodeRegion' => (int) $regionCode, 'Bad' => false));
                 }
                 $region = $mongo->regions->findOne(array('CodeRegion' => (int) $regionCode, 'Bad' => false));
                 fwrite($fp, $this->cityToJson($city, $district, $region));
             }
             fwrite($fp, ']}');
         }
         fclose($fp);
         copy($tmp, $this->getCachePath($cacheKey));
         unlink($tmp);
     }
     $result->fileToSend = $this->getCachePath($cacheKey);
 }
示例#5
0
 /**
  * Выполняет обработку запроса
  * 
  * @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;
 }
示例#6
0
 /**
  * Выполняет обработку запроса
  * 
  * @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;
 }