private static function updateAllCitiesByCountryId($country_id) { if (empty($country_id)) { return; } $xml_resp = simplexml_load_file('http://xml.weather.ua/1.2/city/?country=' . $country_id); if (!$xml_resp) { throw new ErrorException("Couldn't load city xml for country " . $country_id); } $delay = 100000; foreach ($xml_resp->city as $city) { $geocode_pending = true; while ($geocode_pending) { $item = array(); $item['id'] = intval($city->attributes()->id); $db_city = Mysql::getInstance()->from('cities')->where(array('id' => $item['id']))->get()->first(); foreach ($city as $field => $val) { $item[$field] = strval($val); } $item['country'] = Mysql::getInstance()->from('countries')->where(array('id' => $item['country_id']))->get()->first('name_en'); $geocode_pending = false; if (empty($db_city['timezone'])) { try { $item['timezone'] = self::getTimezoneForCity($item['country'], $item['name_en']); } catch (GeoCodeException $ge) { echo "Bad status for country: " . $item['country'] . ", city: " . $item['name_en'] . "; Status: " . $ge->getMessage() . ";\n"; if ($ge->getMessage() == 'OVER_QUERY_LIMIT') { $delay += 100000; echo "Increasing the delay to " . $delay . " microseconds\n"; $geocode_pending = true; } } catch (GeoNamesException $gn) { echo "Bad status for country: " . $item['country'] . ", city: " . $item['name_en'] . "; Status: " . $gn->getMessage() . ";\n"; if ($gn->getCode() >= 18 && $gn->getCode() <= 20) { if (self::$geonames_username != 'demo') { self::$geonames_username = '******'; $geocode_pending = true; } else { throw new ErrorException("GeoNames credits exceeded"); } } } catch (Exception $e) { echo $e; } } if (!$geocode_pending) { if (empty($db_city['id'])) { Mysql::getInstance()->insert('cities', $item); } else { Mysql::getInstance()->update('cities', $item, array('id' => $db_city['id'])); } } usleep($delay); } } }