okapi r608
This commit is contained in:
@ -778,7 +778,7 @@ class Okapi
|
||||
{
|
||||
public static $data_store;
|
||||
public static $server;
|
||||
public static $revision = 594; # This gets replaced in automatically deployed packages
|
||||
public static $revision = 608; # This gets replaced in automatically deployed packages
|
||||
private static $okapi_vars = null;
|
||||
|
||||
/** Get a variable stored in okapi_vars. If variable not found, return $default. */
|
||||
|
@ -13,6 +13,7 @@ use okapi\OkapiAccessToken;
|
||||
use okapi\InvalidParam;
|
||||
use okapi\services\caches\search\SearchAssistant;
|
||||
use okapi\OkapiInternalConsumer;
|
||||
use okapi\Db;
|
||||
|
||||
class WebService
|
||||
{
|
||||
@ -137,12 +138,41 @@ class WebService
|
||||
|
||||
$vars['caches'] = OkapiServiceRunner::call('services/caches/geocaches', new OkapiInternalRequest(
|
||||
$request->consumer, $request->token, array('cache_codes' => $cache_codes,
|
||||
'langpref' => $langpref, 'fields' => $fields, 'lpc' => $lpc, 'user_uuid' => $user_uuid)));
|
||||
'langpref' => $langpref, 'fields' => $fields, 'lpc' => $lpc, 'user_uuid' => $user_uuid,
|
||||
'log_fields' => 'uuid|date|user|type|comment|internal_id|was_recommended')));
|
||||
$vars['installation'] = OkapiServiceRunner::call('services/apisrv/installation', new OkapiInternalRequest(
|
||||
new OkapiInternalConsumer(), null, array()));
|
||||
$vars['cache_GPX_types'] = self::$cache_GPX_types;
|
||||
$vars['cache_GPX_sizes'] = self::$cache_GPX_sizes;
|
||||
|
||||
/* OC sites always used internal user_ids in their generated GPX files.
|
||||
* This might be considered an error in itself (groundspeak's XML namespace
|
||||
* doesn't allow that), but it very common (Garmin's OpenCaching.COM
|
||||
* also does that). Therefore, for backward-compatibility reasons, OKAPI
|
||||
* will do it the same way. See issue 174.
|
||||
*
|
||||
* Currently, the caches method does not expose "owner.internal_id" and
|
||||
* "latest_logs.user.internal_id" fields, we will read them manually
|
||||
* from the database here. */
|
||||
|
||||
$dict = array();
|
||||
foreach ($vars['caches'] as &$cache_ref)
|
||||
{
|
||||
$dict[$cache_ref['owner']['uuid']] = true;
|
||||
if (isset($cache_ref['latest_logs']))
|
||||
foreach ($cache_ref['latest_logs'] as &$log_ref)
|
||||
$dict[$log_ref['user']['uuid']] = true;
|
||||
}
|
||||
$rs = Db::query("
|
||||
select uuid, user_id
|
||||
from user
|
||||
where uuid in ('".implode("','", array_map('mysql_real_escape_string', array_keys($dict)))."')
|
||||
");
|
||||
while ($row = mysql_fetch_assoc($rs))
|
||||
$dict[$row['uuid']] = $row['user_id'];
|
||||
$vars['user_uuid_to_internal_id'] = &$dict;
|
||||
unset($dict);
|
||||
|
||||
$response = new OkapiHttpResponse();
|
||||
$response->content_type = "text/xml; charset=utf-8";
|
||||
$response->content_disposition = 'attachment; filename="results.gpx"';
|
||||
|
@ -37,7 +37,7 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
<groundspeak:cache archived="<?= ($c['status'] == 'Archived') ? "True" : "False" ?>" available="<?= ($c['status'] == 'Available') ? "True" : "False" ?>" id="<?= $c['internal_id'] ?>" xmlns:groundspeak="http://www.groundspeak.com/cache/1/0/1">
|
||||
<groundspeak:name><?= Okapi::xmlescape($c['name']) ?></groundspeak:name>
|
||||
<groundspeak:placed_by><?= Okapi::xmlescape($c['owner']['username']) ?></groundspeak:placed_by>
|
||||
<groundspeak:owner id="<?= $c['owner']['uuid'] ?>"><?= Okapi::xmlescape($c['owner']['username']) ?></groundspeak:owner>
|
||||
<groundspeak:owner id="<?= $vars['user_uuid_to_internal_id'][$c['owner']['uuid']] ?>"><?= Okapi::xmlescape($c['owner']['username']) ?></groundspeak:owner>
|
||||
<groundspeak:type><?= $vars['cache_GPX_types'][$c['type']] ?></groundspeak:type>
|
||||
<groundspeak:container><?= $vars['cache_GPX_sizes'][$c['size2']] ?></groundspeak:container>
|
||||
<groundspeak:difficulty><?= $c['difficulty'] ?></groundspeak:difficulty>
|
||||
@ -108,11 +108,11 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
<? if ($vars['latest_logs']) { /* Does user want us to include latest log entries? */ ?>
|
||||
<groundspeak:logs>
|
||||
<? foreach ($c['latest_logs'] as $log) { ?>
|
||||
<groundspeak:log id="<?= $log['uuid'] ?>">
|
||||
<groundspeak:log id="<?= $log['internal_id'] ?>">
|
||||
<groundspeak:date><?= $log['date'] ?></groundspeak:date>
|
||||
<groundspeak:type><?= $log['type'] ?></groundspeak:type>
|
||||
<groundspeak:finder id="<?= $log['user']['uuid'] ?>"><?= Okapi::xmlescape($log['user']['username']) ?></groundspeak:finder>
|
||||
<groundspeak:text encoded="False"><?= Okapi::xmlescape($log['comment']) ?></groundspeak:text>
|
||||
<groundspeak:finder id="<?= $vars['user_uuid_to_internal_id'][$log['user']['uuid']] ?>"><?= Okapi::xmlescape($log['user']['username']) ?></groundspeak:finder>
|
||||
<groundspeak:text encoded="False"><?= $log['was_recommended'] ? "(*) ": "" ?><?= Okapi::xmlescape($log['comment']) ?></groundspeak:text>
|
||||
</groundspeak:log>
|
||||
<? } ?>
|
||||
</groundspeak:logs>
|
||||
|
@ -63,6 +63,11 @@ class WebService
|
||||
if (!in_array($field, self::$valid_field_names))
|
||||
throw new InvalidParam('fields', "'$field' is not a valid field code.");
|
||||
|
||||
# Currently, the "owner" field needs to be included whenever the "description" field is.
|
||||
# That's a little ugly. Grep for "issue 178" below for more insight on this.
|
||||
if ((in_array('description', $fields) || in_array('descriptions', $fields)) && !in_array('owner', $fields))
|
||||
$fields[] = "owner";
|
||||
|
||||
$log_fields = $request->get_parameter('log_fields');
|
||||
if (!$log_fields) $log_fields = "uuid|date|user|type|comment"; // validation is done on call
|
||||
|
||||
@ -424,8 +429,19 @@ class WebService
|
||||
$cache_code = $cacheid2wptcode[$row['cache_id']];
|
||||
// strtolower - ISO 639-1 codes are lowercase
|
||||
if ($row['desc'])
|
||||
$results[$cache_code]['descriptions'][strtolower($row['language'])] = $row['desc'].
|
||||
"\n".self::get_cache_attribution_note($row['cache_id'], strtolower($row['language']), $langpref);
|
||||
{
|
||||
/* Regarding the attribution note - please note, that the "owner" field
|
||||
* is automatically included, whenever the cache description is included.
|
||||
* This is because we may need it for the attribution note - see issue 178. */
|
||||
|
||||
$results[$cache_code]['descriptions'][strtolower($row['language'])] = (
|
||||
$row['desc']."\n".
|
||||
self::get_cache_attribution_note(
|
||||
$row['cache_id'], strtolower($row['language']), $langpref,
|
||||
$results[$cache_code]['owner']
|
||||
)
|
||||
);
|
||||
}
|
||||
if ($row['hint'])
|
||||
$results[$cache_code]['hints'][strtolower($row['language'])] = $row['hint'];
|
||||
}
|
||||
@ -738,7 +754,7 @@ class WebService
|
||||
{
|
||||
# OCDE uses 'coordinates' table (with type=1) to store additional waypoints.
|
||||
# All waypoints are are public.
|
||||
|
||||
|
||||
$waypoints = Db::select_all("
|
||||
select
|
||||
cache_id,
|
||||
@ -871,14 +887,24 @@ class WebService
|
||||
|
||||
/**
|
||||
* Return attribution note to be included in the cache description.
|
||||
*
|
||||
* The $lang parameter identifies the language of the cache description
|
||||
* (one cache may have descriptions in multiple languages!). Whereas
|
||||
* the $langpref parameter is *an array* of language preferences
|
||||
* extracted from the langpref parameter passed to the method. Both
|
||||
* values ($lang and $langpref) will be taken into account ($lang
|
||||
* has the higher priority).
|
||||
* to which the attribution note will be appended to (one cache may
|
||||
* have descriptions in multiple languages!).
|
||||
*
|
||||
* The $langpref parameter is *an array* of language preferences
|
||||
* extracted from the langpref parameter passed to the method by the
|
||||
* OKAPI Consumer.
|
||||
*
|
||||
* Both values ($lang and $langpref) will be taken into account when
|
||||
* generating the attribution note, but $lang will have a higher
|
||||
* priority than $langpref (we don't want to mix the languages in the
|
||||
* descriptions if we don't have to).
|
||||
*
|
||||
* $owner is in object describing the user, it has the same format as
|
||||
* defined in "geocache" method specs (see the "owner" field).
|
||||
*/
|
||||
public static function get_cache_attribution_note($cache_id, $lang, array $langpref)
|
||||
public static function get_cache_attribution_note($cache_id, $lang, array $langpref, $owner)
|
||||
{
|
||||
$site_url = Settings::get('SITE_URL');
|
||||
$site_name = Okapi::get_normalized_site_name();
|
||||
@ -886,10 +912,24 @@ class WebService
|
||||
|
||||
Okapi::gettext_domain_init(array_merge(array($lang), $langpref));
|
||||
$note = "<p>";
|
||||
$note .= sprintf(
|
||||
_("This <a href='%s'>geocache</a> description comes from the <a href='%s'>%s</a> site."),
|
||||
$cache_url, $site_url, $site_name
|
||||
);
|
||||
if (Settings::get('OC_BRANCH') == 'oc.de')
|
||||
{
|
||||
$note .= sprintf(
|
||||
_(
|
||||
"<em>© <a href='%s'>%s</a>, <a href='%s'>%s</a>, ".
|
||||
"<a href='http://creativecommons.org/licenses/by-nc-nd/3.0/en/'>CC-BY-NC-ND</a>, ".
|
||||
"as of Jan 15, 2013; all log entries © their authors</em>"
|
||||
),
|
||||
$owner['profile_url'], $owner['username'], $site_url, $site_name
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$note .= sprintf(
|
||||
_("This <a href='%s'>geocache</a> description comes from the <a href='%s'>%s</a> site."),
|
||||
$cache_url, $site_url, $site_name
|
||||
);
|
||||
}
|
||||
$note .= "</p>";
|
||||
Okapi::gettext_domain_restore();
|
||||
|
||||
|
@ -184,35 +184,38 @@ class ReplicateListener
|
||||
and y = '".mysql_real_escape_string($y)."'
|
||||
)";
|
||||
}
|
||||
Db::execute("
|
||||
replace into okapi_tile_caches (
|
||||
z, x, y, cache_id, z21x, z21y, status, type, rating, flags
|
||||
)
|
||||
select
|
||||
z, x, y,
|
||||
'".mysql_real_escape_string($row[0])."',
|
||||
'".mysql_real_escape_string($row[1])."',
|
||||
'".mysql_real_escape_string($row[2])."',
|
||||
'".mysql_real_escape_string($row[3])."',
|
||||
'".mysql_real_escape_string($row[4])."',
|
||||
".(($row[5] === null) ? "null" : $row[5]).",
|
||||
'".mysql_real_escape_string($row[6])."'
|
||||
from okapi_tile_status
|
||||
where
|
||||
(".implode(" or ", $alternatives).")
|
||||
and status in (1,2)
|
||||
");
|
||||
if (count($alternatives) > 0)
|
||||
{
|
||||
Db::execute("
|
||||
replace into okapi_tile_caches (
|
||||
z, x, y, cache_id, z21x, z21y, status, type, rating, flags
|
||||
)
|
||||
select
|
||||
z, x, y,
|
||||
'".mysql_real_escape_string($row[0])."',
|
||||
'".mysql_real_escape_string($row[1])."',
|
||||
'".mysql_real_escape_string($row[2])."',
|
||||
'".mysql_real_escape_string($row[3])."',
|
||||
'".mysql_real_escape_string($row[4])."',
|
||||
".(($row[5] === null) ? "null" : $row[5]).",
|
||||
'".mysql_real_escape_string($row[6])."'
|
||||
from okapi_tile_status
|
||||
where
|
||||
(".implode(" or ", $alternatives).")
|
||||
and status in (1,2)
|
||||
");
|
||||
|
||||
# We might have just filled some empty tiles (status 1) with data.
|
||||
# We need to update their status to 2.
|
||||
# We might have just filled some empty tiles (status 1) with data.
|
||||
# We need to update their status to 2.
|
||||
|
||||
Db::execute("
|
||||
update okapi_tile_status
|
||||
set status=2
|
||||
where
|
||||
(".implode(" or ", $alternatives).")
|
||||
and status=1
|
||||
");
|
||||
Db::execute("
|
||||
update okapi_tile_status
|
||||
set status=2
|
||||
where
|
||||
(".implode(" or ", $alternatives).")
|
||||
and status=1
|
||||
");
|
||||
}
|
||||
|
||||
# And that's all. That should do the trick.
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use okapi\OkapiServiceRunner;
|
||||
use okapi\OkapiRequest;
|
||||
use okapi\ParamMissing;
|
||||
use okapi\InvalidParam;
|
||||
use okapi\BadRequest;
|
||||
|
||||
class WebService
|
||||
{
|
||||
@ -49,6 +50,9 @@ class WebService
|
||||
if (!is_array($retr_params))
|
||||
throw new InvalidParam('retr_params', "Should be a JSON-encoded dictionary");
|
||||
|
||||
self::map_values_to_strings($search_params);
|
||||
self::map_values_to_strings($retr_params);
|
||||
|
||||
# Wrapped?
|
||||
$wrap = $request->get_parameter('wrap');
|
||||
if ($wrap == null) throw new ParamMissing('wrap');
|
||||
@ -102,4 +106,16 @@ class WebService
|
||||
return Okapi::formatted_response($request, $retr_result);
|
||||
}
|
||||
}
|
||||
|
||||
private static function map_values_to_strings(&$dict)
|
||||
{
|
||||
foreach (array_keys($dict) as $key)
|
||||
{
|
||||
$val = $dict[$key];
|
||||
if (is_numeric($val) || is_string($val))
|
||||
$dict[$key] = (string)$val;
|
||||
else
|
||||
throw new BadRequest("Invalid value format for key: ".$key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,12 +46,22 @@ class WebService
|
||||
|
||||
$cache_code = $request->get_parameter('cache_code');
|
||||
if (!$cache_code) throw new ParamMissing('cache_code');
|
||||
|
||||
$logtype = $request->get_parameter('logtype');
|
||||
if (!$logtype) throw new ParamMissing('logtype');
|
||||
if (!in_array($logtype, array('Found it', "Didn't find it", 'Comment')))
|
||||
throw new InvalidParam('logtype', "'$logtype' in not a valid logtype code.");
|
||||
|
||||
$comment = $request->get_parameter('comment');
|
||||
if (!$comment) $comment = "";
|
||||
|
||||
$comment_format = $request->get_parameter('comment_format');
|
||||
if ($comment_format)
|
||||
{
|
||||
if (!in_array($comment_format, array('html', 'plaintext')))
|
||||
throw new InvalidParam('comment_format', $comment_format);
|
||||
}
|
||||
|
||||
$tmp = $request->get_parameter('when');
|
||||
if ($tmp)
|
||||
{
|
||||
@ -64,10 +74,12 @@ class WebService
|
||||
}
|
||||
else
|
||||
$when = time();
|
||||
|
||||
$on_duplicate = $request->get_parameter('on_duplicate');
|
||||
if (!$on_duplicate) $on_duplicate = "silent_success";
|
||||
if (!in_array($on_duplicate, array('silent_success', 'user_error', 'continue')))
|
||||
throw new InvalidParam('on_duplicate', "Unknown option: '$on_duplicate'.");
|
||||
|
||||
$rating = $request->get_parameter('rating');
|
||||
if ($rating !== null && (!in_array($rating, array(1,2,3,4,5))))
|
||||
throw new InvalidParam('rating', "If present, it must be an integer in the 1..5 scale.");
|
||||
@ -83,6 +95,7 @@ class WebService
|
||||
Okapi::get_normalized_site_name());
|
||||
$rating = null;
|
||||
}
|
||||
|
||||
$recommend = $request->get_parameter('recommend');
|
||||
if (!$recommend) $recommend = 'false';
|
||||
if (!in_array($recommend, array('true', 'false')))
|
||||
@ -90,6 +103,7 @@ class WebService
|
||||
$recommend = ($recommend == 'true');
|
||||
if ($recommend && $logtype != 'Found it')
|
||||
throw new BadRequest(_("Recommending is allowed only for 'Found it' logtypes."));
|
||||
|
||||
$needs_maintenance = $request->get_parameter('needs_maintenance');
|
||||
if (!$needs_maintenance) $needs_maintenance = 'false';
|
||||
if (!in_array($needs_maintenance, array('true', 'false')))
|
||||
|
@ -14,10 +14,13 @@
|
||||
log types which are used for Event Caches (we are planning to add this).</p>
|
||||
</req>
|
||||
<opt name='comment'>
|
||||
<p>Text to be submitted with the log entry. Plain-text (no HTML).</p>
|
||||
<p><b>Note:</b> Due to <a href='http://code.google.com/p/opencaching-api/issues/detail?id=124'>some issues</a>
|
||||
(which we cannot currently fix), you MAY be allowed to use some basic HTML tags (on some OC installations).
|
||||
However, you should not (this may stop working at any time).</p>
|
||||
<p>Text to be submitted with the log entry.</p>
|
||||
</opt>
|
||||
<opt name='comment_format' default='(unspecified!)'>
|
||||
<p>Indicates the format of your <b>comment</b>. Two values allowed: <b>html</b> or <b>plaintext</b>.</p>
|
||||
<p><b>Important note:</b> Due to <a href='http://code.google.com/p/opencaching-api/issues/detail?id=124'>some issues</a>,
|
||||
this switch is currently completelly ignored (!). However, we still advise you to use it,
|
||||
for future-compatibility.</p>
|
||||
</opt>
|
||||
<opt name='when'>
|
||||
<p>A date and time string. This should be in ISO 8601 format (currently any
|
||||
|
@ -121,7 +121,7 @@ class View
|
||||
if ($_POST['authorization_result'] == 'granted')
|
||||
{
|
||||
Db::execute("
|
||||
insert into okapi_authorizations (consumer_key, user_id)
|
||||
insert ignore into okapi_authorizations (consumer_key, user_id)
|
||||
values (
|
||||
'".mysql_real_escape_string($token['consumer_key'])."',
|
||||
'".mysql_real_escape_string($OC_user_id)."'
|
||||
|
@ -60,6 +60,29 @@ class View
|
||||
}
|
||||
|
||||
public static function call()
|
||||
{
|
||||
# First, let's acquire a lock to make sure the update isn't already running.
|
||||
# We will use one of the existing lock handles, because we don't want to use
|
||||
# to many of them. See issue 141.
|
||||
|
||||
$lock = OkapiLock::get('cronjobs-cron-5');
|
||||
$lock->acquire();
|
||||
|
||||
try
|
||||
{
|
||||
self::_call();
|
||||
$lock->release();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
# Error occured. Make sure the lock is released and rethrow.
|
||||
|
||||
$lock->release();
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private static function _call()
|
||||
{
|
||||
ignore_user_abort(true);
|
||||
set_time_limit(0);
|
||||
|
Reference in New Issue
Block a user