private static function updateCache(callback $callback = null) { $cache = base::expand('app:/cache/geonames/'); if (!file_exists($cache)) { mkdir($cache, 0777, true); } $db = new DatabaseConnection(); // Pull the list of countries to update $rs = $db->getRows("SELECT * FROM geonames_datasets WHERE active=1"); foreach ($rs as $ci) { $download = false; if (!file_exists($cache . $ci['setkey'] . '.gz')) { $download = true; } else { $file = new HttpRequest($ci['url'], $cache . $ci['setkey'] . '.zip', array('method' => 'head')); $hdr = $file->headers(); $etaglocal = file_get_contents($cache . $ci['setkey'] . '.etag'); $etagremote = $hdr['ETag']; if ($etaglocal != $etagremote) { $download = true; } } if ($download) { cb($callback, 'Downloading ' . $ci['url'], 0, 1); $file = new HttpDownload($ci['url'], $cache . $ci['setkey'] . '.zip'); $hdr = $file->headers(); file_put_contents($cache . $ci['setkey'] . '.etag', $hdr['ETag']); cb($callback, 'Recompressing ' . $ci['setkey'] . '.gz', 0, 1); // Open input stream $fin = fopen('zip://' . $cache . $ci['setkey'] . '.zip#' . $ci['setkey'] . '.txt', 'r'); $fout = fopen('compress.zlib://' . $cache . $ci['setkey'] . '.gz', 'w'); stream_copy_to_stream($fin, $fout); fclose($fin); fclose($fout); cb($callback, 'Saved ' . $ci['setkey'] . '.gz'); } } // Update hierarchy $url = self::getUrl('hierarchy.zip'); if (file_exists($cache . 'hierarchy.etag')) { $hetag = file_get_contents($cache . 'hierarchy.etag'); } else { $hetag = null; } cb($callback, 'Updating hierarchy...', 0, 1); $head = new HttpRequest($url, array('method' => 'head')); $headers = $head->headers(); if ($hetag != $headers['ETag']) { file_put_contents($cache . 'hierarchy.etag', $headers['ETag']); $file = new HttpDownload($url, $cache . 'hierarchy.zip'); } // Open input stream $fin = fopen('zip://' . $cache . 'hierarchy.zip#hierarchy.txt', 'r'); $fout = fopen('compress.zlib://' . $cache . 'hierarchy.gz', 'w'); stream_copy_to_stream($fin, $fout); fclose($fin); fclose($fout); cb($callback, 'Saved hierarchy...'); }