Navigation Menu

Skip to content

Commit

Permalink
Merged cache-capabilities; closes #398
Browse files Browse the repository at this point in the history
  • Loading branch information
following5 committed Nov 18, 2018
2 parents 49cb964 + 9201cea commit 3b2ebae
Show file tree
Hide file tree
Showing 12 changed files with 252 additions and 74 deletions.
4 changes: 3 additions & 1 deletion okapi/core/Db.php
Expand Up @@ -299,6 +299,8 @@ public static function field_length($table, $field)
table_schema='".self::escape_string(Settings::get('DB_NAME'))."'
and table_name='".self::escape_string($table)."'
and column_name='".self::escape_string($field)."'
");
") + 0;
/* OC.DE installation returned a string here, OC.PL an integer.
* Added type cast. */
}
}
121 changes: 88 additions & 33 deletions okapi/core/Okapi.php
Expand Up @@ -917,47 +917,59 @@ public static function xmlmap2_dumps(&$obj)
private static $cache_types = array(
#
# OKAPI does not expose type IDs. Instead, it uses the following
# "code words". Only the "primary" cache types are documented.
# This means that all other types may (in theory) be altered.
# Cache type may become "primary" ONLY when *all* OC servers recognize
# that type.
# "code words".
#
# IMPORTANT: For backward compatibility, cache types must never be
# removed from this table! If a type is discarded, assign it to [].
#
# Changing this may introduce nasty bugs (e.g. in the replicate module).
# CONTACT ME BEFORE YOU MODIFY THIS!
#
'oc.pl' => array(
# Primary types (documented, cannot change)
'Traditional' => 2, 'Multi' => 3, 'Quiz' => 7, 'Virtual' => 4,
'Event' => 6,
# Additional types (may get changed)
'Other' => 1, 'Webcam' => 5,
'Moving' => 8, 'Podcast' => 9, 'Own' => 10,
),
'oc.de' => array(
# Primary types (documented, cannot change)
'Traditional' => 2, 'Multi' => 3, 'Quiz' => 7, 'Virtual' => 4,
'Event' => 6,
# Additional types (might get changed)
'Other' => 1, 'Webcam' => 5,
'Math/Physics' => 8, 'Moving' => 9, 'Drive-In' => 10,
)

# common types of all OC sites
'Traditional' => ['oc.de' => 2, 'oc.pl' => 2],
'Multi' => ['oc.de' => 3, 'oc.pl' => 3],
'Quiz' => ['oc.de' => 7, 'oc.pl' => 7],
'Virtual' => ['oc.de' => 4, 'oc.pl' => 4],
'Event' => ['oc.de' => 6, 'oc.pl' => 6],
'Webcam' => ['oc.de' => 5, 'oc.pl' => 5],
'Moving' => ['oc.de' => 9, 'oc.pl' => 8],
'Other' => ['oc.de' => 1, 'oc.pl' => 1],

# local types
'Podcast' => ['oc.pl' => 9],
'Own' => ['oc.pl' => 10],
'Math/Physics' => ['oc.de' => 8, 'mapto' => ['name' => 'Quiz', 'acodes' => ['A16']]],
'Drive-In' => ['oc.de' => 10, 'mapto' => ['name' => 'Traditional', 'acodes' => ['A19']]],
);

/** E.g. 'Traditional' => 2. For unknown names throw an Exception. */
public static function cache_type_name2id($name)
/** Return all types of this OC site which are exposed by OKAPI. **/
public static function get_local_okapi_cache_types()
{
$ref = &self::$cache_types[Settings::get('OC_BRANCH')];
if (isset($ref[$name]))
return $ref[$name];
throw new \Exception("Method cache_type_name2id called with unsupported cache ".
"type name '$name'. You should not allow users to submit caches ".
"of non-primary type.");
static $local_types = [];
if (!$local_types)
{
$branch = Settings::get('OC_BRANCH');
foreach (self::$cache_types as $cache_type => $properties)
if (isset($properties[$branch]) && !isset($properties['mapto']))
$local_types[] = $cache_type;
}
return $local_types;
}

/** Cache types that can be searched for. **/
public static function is_searchable_cache_type($name)
{
return isset(self::$cache_types[$name]);
}

public static function is_known_cache_type($name)
/** E.g. 'Traditional' => 2. For unknown names throw an Exception. */
public static function cache_type_name2id($name)
{
return array_key_exists($name, self::$cache_types['oc.pl']) ||
array_key_exists($name, self::$cache_types['oc.de']);
if (isset(self::$cache_types[$name][Settings::get('OC_BRANCH')]))
return self::$cache_types[$name][Settings::get('OC_BRANCH')];
throw new \Exception("Method cache_type_name2id called with unsupported cache ".
"type name '$name'.");
}

/** E.g. 2 => 'Traditional'. For unknown ids returns "Other". */
Expand All @@ -967,14 +979,41 @@ public static function cache_type_id2name($id)
if ($reversed == null)
{
$reversed = array();
foreach (self::$cache_types[Settings::get('OC_BRANCH')] as $key => $value)
$reversed[$value] = $key;
$branch = Settings::get('OC_BRANCH');
foreach (self::$cache_types as $name => $properties)
if (isset($properties[$branch]))
$reversed[$properties[$branch]] = $name;
}
if (isset($reversed[$id]))
return $reversed[$id];
return "Other";
}

/** Map cache types which is not exposed by OKAPI to a common types. **/
public static function map_cache_type($mapfrom_type)
{
if (isset(self::$cache_types[$mapfrom_type]['mapto']))
return self::$cache_types[$mapfrom_type]['mapto'];
else
return ['name' => $mapfrom_type, 'acodes' => []];
}

/** Returns an array of cache types which are mapped to the given type. **/
public static function reverse_map_cache_type($mapto_type)
{
static $reversed = null;
if (!$reversed)
{
$reversed = array();
foreach (self::$cache_types as $name => $properties)
if (isset($properties['mapto']))
$reversed[$properties['mapto']['name']][] = $name;
}
if (isset($reversed[$mapto_type]))
return $reversed[$mapto_type];
return [];
}

private static $cache_statuses = array(
'Available' => 1, 'Temporarily unavailable' => 2, 'Archived' => 3
);
Expand Down Expand Up @@ -1013,6 +1052,22 @@ public static function cache_status_id2name($id)
'other' => 1,
);

public static function get_local_cache_sizes()
{
# OCPL only knows a subset of sizes, which is defined in the
# GeoCacheCommons class. OCDE supports all sizes; they are listed
# in the 'cache_size' table.

if (Settings::get('OC_BRANCH') == 'oc.pl')
{
return ['none', 'micro', 'small', 'regular', 'large', 'xlarge'];
}
else
{
return array_keys(self::$cache_sizes);
}
}

/** E.g. 'micro' => 2. For unknown names throw an Exception. */
public static function cache_size2_to_sizeid($size2)
{
Expand Down
1 change: 1 addition & 0 deletions okapi/core/OkapiServiceRunner.php
Expand Up @@ -33,6 +33,7 @@ class OkapiServiceRunner
'services/caches/search/by_urls',
'services/caches/search/save',
'services/caches/shortcuts/search_and_retrieve',
'services/caches/capabilities',
'services/caches/edit',
'services/caches/geocache',
'services/caches/geocaches',
Expand Down
7 changes: 6 additions & 1 deletion okapi/services/apisrv/installation/WebService.php
Expand Up @@ -30,7 +30,12 @@ public static function call(OkapiRequest $request)
$result['mobile_registration_url'] = Settings::get('MOBILE_REGISTRATION_URL');
$result['image_max_upload_size'] = Settings::get('IMAGE_MAX_UPLOAD_SIZE');
$result['image_rcmd_max_pixels'] = Settings::get('IMAGE_MAX_PIXEL_COUNT');
$result['geocache_passwd_max_length'] = Db::field_length('caches', 'logpw');

# Version 1623 added the 'geocache_passwd_max_length' field. It turned out
# to have wrong data type (string) only at OCDE. services/caches/edit had
# not be used until then at least at OCPL sites, and the OCDE field was
# buggy. So we removed it and added a new 'password_max_length' field with
# services/caches/capabilities.

return Okapi::formatted_response($request, $result);
}
Expand Down
5 changes: 0 additions & 5 deletions okapi/services/apisrv/installation/docs.xml
Expand Up @@ -93,11 +93,6 @@
site to fit this restriction. Larger images may have been
uploaded in the past, or by other means than OKAPI.</p>
</li>
<li>
<p><b>geocache_passwd_max_length</b> - the maximum length of
a password that will be accepted by
<a href='%OKAPI:methodargref:services/caches/edit%'>services/caches/edit</a>.</p>
</li>
</ul>
</returns>
</xml>
31 changes: 31 additions & 0 deletions okapi/services/caches/capabilities/WebService.php
@@ -0,0 +1,31 @@
<?php

namespace okapi\services\caches\capabilities;

use okapi\core\Db;
use okapi\core\Exception\InvalidParam;
use okapi\core\Okapi;
use okapi\core\Request\OkapiRequest;
use okapi\Settings;

class WebService
{
public static function options()
{
return array(
'min_auth_level' => 1
);
}

public static function call(OkapiRequest $request)
{
$result = array();

$result['types'] = Okapi::get_local_okapi_cache_types();
$result['sizes'] = Okapi::get_local_cache_sizes();
$result['has_ratings'] = (Settings::get('OC_BRANCH') == 'oc.pl');
$result['password_max_length'] = Db::field_length('caches', 'logpw') + 0;

return Okapi::formatted_response($request, $result);
}
}
40 changes: 40 additions & 0 deletions okapi/services/caches/capabilities/docs.xml
@@ -0,0 +1,40 @@
<xml>
<brief>Get information on available geocache properties</brief>
<issue-id>TODO</issue-id>
<desc>
<p>This method tells which geocache properties are available at this
OKAPI installation.</p>

<p>Using this method is mostly optional. You never need to know about
differences between OKAPI installations when searching for or
retrieving geocaches. But this method may help to improve user
interfaces, e.g. by hiding unnecessary search options.</p>
</desc>
<common-format-params/>
<returns>
<p>A dictionary of the following structure:</p>
<ul>
<li>
<p><b>types</b> - list of the cache types which are currently
available at this installation. See the
<a href='%OKAPI:methodargref:services/caches/geocache%'>services/caches/geocache</a>
method for more information on cache types.</p>
</li>
<li>
<p><b>sizes</b> - list of the cache sizes which are currently
available at this installation.</p>
</li>
<li>
<p><b>has_ratings</b> - boolean, <b>true</b> if this installation
can store geocache quality ratings. OKAPI provides methods to
submit and retrieve ratings, and to search for geocaches by
rating.</p>
</li>
<li>
<p><b>password_max_length</b> - the maximum length of
a password that will be accepted by
<a href='%OKAPI:methodargref:services/caches/edit%'>services/caches/edit</a>.</p>
</li>
</ul>
</returns>
</xml>
2 changes: 1 addition & 1 deletion okapi/services/caches/edit/docs.xml
Expand Up @@ -14,7 +14,7 @@
If you supply an empty string, the password will be cleared, i.e.
the geocache will not require a log password.</p>
<p>You may query the maximum accepted password length for the OC site by
<a href='%OKAPI:methodargref:services/apisrv/installation%'>services/apsrv/installation</a>.
<a href='%OKAPI:methodargref:services/caches/capabilities%'>services/caches/capabilities</a>.
There may also be installation-dependent restrictions on which
geocaches may have passwords. <b>success</b> will be <b>false</b> and
an explanation message will be returned if a password is rejected.</p>
Expand Down
42 changes: 28 additions & 14 deletions okapi/services/caches/geocache/docs.xml
Expand Up @@ -127,24 +127,38 @@
(<i>lat</i> and <i>lon</i> are in full degrees with a dot as a decimal point),
</li>
<li>
<p><b>type</b> - cache type. This might be <b>pretty much everything</b>,
but there are some predefined types that you might want to treat
in a special way (separate icons etc.). Well-known types include:</p>
<p><b>type</b> - cache type, one of the type codes that are included
in the <b>types</b> field of
<a href='%OKAPI:methodargref:services/caches/capabilities%'>services/caches/capabilities</a>.
Currently there are eight types which are in use at all OKAPI
installations:</p>
<ul>
<li><b>Traditional</b>,</li>
<li><b>Multi</b>,</li>
<li><b>Quiz</b>,</li>
<li><b>Moving</b>,</li>
<li><b>Quiz</b>, also known as "Mystery",</li>
<li><b>Moving</b>, a geocache with changing coordinates,</li>
<li><b>Virtual</b>,</li>
<li><b>Webcam</b>,</li>
<li><b>Event</b>,</li>
<li><i>(any other value is valid too)</i></li>
<li><b>Other</b>, also dubbed "unknown type"; allows OC users to
create special caches which don't fit into the scheme of
well-known types,</li>
<li><b>Event</b>, a peculiar type of geocache which is NOT a geocache
at all, but it <b>is</b> stored as a geocache in OC database. Just
keep in mind, that in case of Event Caches, some fields may have
a little different meaning than you would tell by their name.</li>
<li>(Types may be added or removed. Your application MUST be
prepared for any new types and may handle them as "Other".)</li>
</ul>
<p><b>Event</b> is a peculiar type of geocache which is NOT a geocache
at all, but it <b>is</b> stored as a geocache in OC database (this design
decision is as old as the OC network itself!). Just keep in mind, that
in case of Event Caches, some fields may have a little different meaning
than you would tell by their name.</p>
<p>More types are in use at some installations:</p>
<ul>
<li><b>Own</b>, a moving geocache which is carried by the owner,</li>
<li><b>Podcast</b>, a geocache with attached MP3 file(s). The MP3
data is not accessible via OKAPI.</li>
<li>(Types may be added or removed. Your application MUST be
prepared for any new types and may handle them as "Other".)</li>
</ul>
<p>There are even more types, but OKAPI maps them to common types
(and eventually some attributes), so you won't see them in OKAPI data.</p>
</li>
<li>
<p><b>status</b> - cache status. Valid cache status codes currently include:</p>
Expand Down Expand Up @@ -508,8 +522,8 @@
<p><b>Note:</b> This data is user-supplied and is not validated in
any way. Consider using external geocoding services instead. Also,
currently you have no way of knowing in which language it will appear
in (but it *may* start to vary on the value of your <b>langpref</b>
parameter in the future).</p>
in. Only some OKAPI installations will localize it by the
<b>langpref</b> parameter.</p>
</li>
<li>
<p><b>state</b> - name of the major subnational entity the cache
Expand Down

0 comments on commit 3b2ebae

Please sign in to comment.