private static function handle_geocache_replace($c)
 {
     # Check if any relevant geocache attributes have changed.
     # We will pick up "our" copy of the cache from zero-zoom level.
     try {
         $cache = OkapiServiceRunner::call("services/caches/geocache", new OkapiInternalRequest(new OkapiInternalConsumer(), null, array('cache_code' => $c['object_key']['code'], 'fields' => 'internal_id|code|name|location|type|status|rating|recommendations|founds|trackables_count')));
     } catch (InvalidParam $e) {
         # Unprobable, but possible. Ignore changelog entry.
         return;
     }
     # Fetch our copy of the cache.
     $ours = mysql_fetch_row(Db::query("\n            select cache_id, z21x, z21y, status, type, rating, flags, name_crc\n            from okapi_tile_caches\n            where\n                z=0\n                and cache_id = '" . mysql_real_escape_string($cache['internal_id']) . "'\n        "));
     # Caches near the poles caused our computations to break here. We will
     # ignore such caches!
     list($lat, $lon) = explode("|", $cache['location']);
     if (floatval($lat) >= 89.98999999999999 || floatval($lat) <= -89.98999999999999) {
         if ($ours) {
             self::remove_geocache_from_cached_tiles($ours[0]);
         }
         return;
     }
     # Compute the new row for okapi_tile_caches. Compare with the old one.
     $theirs = TileTree::generate_short_row($cache);
     if (!$ours) {
         # Aaah, a new geocache! How nice... ;)
         self::add_geocache_to_cached_tiles($theirs);
     } elseif ($ours[1] != $theirs[1] || $ours[2] != $theirs[2]) {
         # Location changed.
         self::remove_geocache_from_cached_tiles($ours[0]);
         self::add_geocache_to_cached_tiles($theirs);
     } elseif ($ours != $theirs) {
         self::update_geocache_attributes_in_cached_tiles($theirs);
     } else {
         # No need to update anything. This is very common (i.e. when the
         # cache was simply found, not actually changed). Replicate module generates
         # many updates which do not influence our cache.
     }
 }
Ejemplo n.º 2
0
 public static function call(OkapiRequest $request)
 {
     $checkpointA_started = microtime(true);
     # Make sure the request is internal.
     if (in_array($request->consumer->key, array('internal', 'facade'))) {
         /* Okay, these two consumers can always access it. */
     } elseif ($request->consumer->hasFlag(OkapiConsumer::FLAG_MAPTILE_ACCESS)) {
         /* If the Consumer is aware that it is not backward-compatible, then
          * he may be granted permission to access it. */
     } else {
         throw new BadRequest("Your Consumer Key has not been allowed to access this method.");
     }
     # zoom, x, y - required tile-specific parameters.
     $zoom = self::require_uint($request, 'z');
     if ($zoom > 21) {
         throw new InvalidParam('z', "Maximum value for this parameter is 21.");
     }
     $x = self::require_uint($request, 'x');
     $y = self::require_uint($request, 'y');
     if ($x >= 1 << $zoom) {
         throw new InvalidParam('x', "Should be in 0.." . ((1 << $zoom) - 1) . ".");
     }
     if ($y >= 1 << $zoom) {
         throw new InvalidParam('y', "Should be in 0.." . ((1 << $zoom) - 1) . ".");
     }
     # Now, we will create a search set (or use one previously created).
     # Instead of creating a new OkapiInternalRequest object, we will pass
     # the current request directly. We can do that, because we inherit all
     # of the "save" method's parameters.
     $search_set = OkapiServiceRunner::call('services/caches/search/save', new OkapiInternalRequest($request->consumer, $request->token, $request->get_all_parameters_including_unknown()));
     $set_id = $search_set['set_id'];
     # Get caches which are present in the result set AND within the tile
     # (+ those around the borders).
     $rs = TileTree::query_fast($zoom, $x, $y, $set_id);
     $rows = array();
     if ($rs !== null) {
         while ($row = Db::fetch_row($rs)) {
             $rows[] = $row;
         }
         unset($row);
     }
     OkapiServiceRunner::save_stats_extra("caches/map/tile/checkpointA", null, microtime(true) - $checkpointA_started);
     $checkpointB_started = microtime(true);
     # Add dynamic, user-related flags.
     if (count($rows) > 0) {
         # Load user-related cache ids.
         $cache_key = "tileuser/" . $request->token->user_id;
         $user = self::$USE_OTHER_CACHE ? Cache::get($cache_key) : null;
         if ($user === null) {
             $user = array();
             # Ignored caches.
             $rs = Db::query("\n                    select cache_id\n                    from cache_ignore\n                    where user_id = '" . Db::escape_string($request->token->user_id) . "'\n                ");
             $user['ignored'] = array();
             while (list($cache_id) = Db::fetch_row($rs)) {
                 $user['ignored'][$cache_id] = true;
             }
             # Found caches.
             $rs = Db::query("\n                    select distinct cache_id\n                    from cache_logs\n                    where\n                        user_id = '" . Db::escape_string($request->token->user_id) . "'\n                        and type = 1\n                        and " . (Settings::get('OC_BRANCH') == 'oc.pl' ? "deleted = 0" : "true") . "\n                ");
             $user['found'] = array();
             while (list($cache_id) = Db::fetch_row($rs)) {
                 $user['found'][$cache_id] = true;
             }
             # Own caches.
             $rs = Db::query("\n                    select distinct cache_id\n                    from caches\n                    where user_id = '" . Db::escape_string($request->token->user_id) . "'\n                ");
             $user['own'] = array();
             while (list($cache_id) = Db::fetch_row($rs)) {
                 $user['own'][$cache_id] = true;
             }
             Cache::set($cache_key, $user, 30);
         }
         # Add extra flags to geocaches.
         foreach ($rows as &$row_ref) {
             # Add the "found" flag (to indicate that this cache needs
             # to be drawn as found) and the "own" flag (to indicate that
             # the current user is the owner).
             if (isset($user['found'][$row_ref[0]])) {
                 $row_ref[6] |= TileTree::$FLAG_FOUND;
             }
             # $row[6] is "flags"
             if (isset($user['own'][$row_ref[0]])) {
                 $row_ref[6] |= TileTree::$FLAG_OWN;
             }
             # $row[6] is "flags"
         }
     }
     # Compute the image hash/fingerprint. This will be used both for ETags
     # and internal cache ($cache_key).
     $tile = new TileRenderer($zoom, $rows);
     $image_fingerprint = $tile->get_unique_hash();
     # Start creating response.
     $response = new OkapiHttpResponse();
     $response->content_type = $tile->get_content_type();
     $response->cache_control = "Cache-Control: private, max-age=600";
     $response->etag = 'W/"' . $image_fingerprint . '"';
     $response->allow_gzip = false;
     // images are usually compressed, prevent compression at Apache level
     # Check if the request didn't include the same ETag.
     OkapiServiceRunner::save_stats_extra("caches/map/tile/checkpointB", null, microtime(true) - $checkpointB_started);
     $checkpointC_started = microtime(true);
     if (self::$USE_ETAGS_CACHE && $request->etag == $response->etag) {
         # Hit. Report the content was unmodified.
         $response->etag = null;
         $response->status = "304 Not Modified";
         return $response;
     }
     # Check if the image was recently rendered and is kept in image cache.
     $cache_key = "tile/" . $image_fingerprint;
     $response->body = self::$USE_IMAGE_CACHE ? Cache::get($cache_key) : null;
     OkapiServiceRunner::save_stats_extra("caches/map/tile/checkpointC", null, microtime(true) - $checkpointC_started);
     $checkpointD_started = microtime(true);
     if ($response->body !== null) {
         # Hit. We will use the cached version of the image.
         return $response;
     }
     # Miss. Render the image. Cache the result.
     $response->body = $tile->render();
     Cache::set_scored($cache_key, $response->body);
     OkapiServiceRunner::save_stats_extra("caches/map/tile/checkpointD", null, microtime(true) - $checkpointD_started);
     return $response;
 }