OKAPI Project update (r938)

This commit is contained in:
Wojciech Rygielski 2014-01-12 19:01:01 +01:00 committed by Nils Bohrs
parent 979121c470
commit e657c3c409
19 changed files with 279 additions and 50 deletions

View File

@ -480,14 +480,16 @@ class OkapiConsumer extends OAuthConsumer
public $name;
public $url;
public $email;
public $admin;
public function __construct($key, $secret, $name, $url, $email)
public function __construct($key, $secret, $name, $url, $email, $admin=false)
{
$this->key = $key;
$this->secret = $secret;
$this->name = $name;
$this->url = $url;
$this->email = $email;
$this->admin = $admin;
}
public function __toString()
@ -814,7 +816,7 @@ class Okapi
{
public static $data_store;
public static $server;
public static $revision = 896; # This gets replaced in automatically deployed packages
public static $revision = 938; # 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. */
@ -855,7 +857,13 @@ class Okapi
/** Send an email message to local OKAPI administrators. */
public static function mail_admins($subject, $message)
{
# First, make sure we're not spamming.
# Make sure we're not sending HUGE emails.
if (strlen($message) > 10000) {
$message = substr($message, 0, 10000)."\n\n...(message clipped at 10k chars)\n";
}
# Make sure we're not spamming.
$cache_key = 'mail_admins_counter/'.(floor(time() / 3600) * 3600).'/'.md5($subject);
try {
@ -1146,17 +1154,19 @@ class Okapi
# Message for the Consumer.
ob_start();
print "This is the key-pair we've generated for your application:\n\n";
print "This is the key-pair we have created for your application:\n\n";
print "Consumer Key: $consumer->key\n";
print "Consumer Secret: $consumer->secret\n\n";
print "Note: Consumer Secret is needed only when you intend to use OAuth.\n";
print "You don't need Consumer Secret for Level 1 Authentication.\n\n";
print "Now you may easily access Level 1 methods of OKAPI! For example:\n";
print "Now you can easily access Level 1 OKAPI methods. E.g.:\n";
print Settings::get('SITE_URL')."okapi/services/caches/geocache?cache_code=$sample_cache_code&consumer_key=$consumer->key\n\n";
print "If you plan on using OKAPI for a longer time, then you should subscribe\n";
print "to the OKAPI News blog to stay up-to-date. Check it out here:\n";
print "If you plan on using OKAPI for a longer time, then you may want to\n";
print "subscribe to the OKAPI News blog to stay up-to-date:\n";
print "http://opencaching-api.blogspot.com/\n\n";
print "Have fun!";
print "Have fun!\n\n";
print "-- \n";
print "OKAPI Team\n";
Okapi::mail_from_okapi($email, "Your OKAPI Consumer Key", ob_get_clean());
# Message for the Admins.
@ -1616,6 +1626,7 @@ class Okapi
# Other.
if ($id == 4) return "Moved";
if ($id == 5) return "Needs maintenance";
if ($id == 6) return "Maintenance performed";
if ($id == 9) return "Archived";
if ($id == 10) return "Ready to search";
if ($id == 11) return "Temporarily unavailable";
@ -1628,6 +1639,33 @@ class Okapi
return "Comment";
}
/**
* "Fix" user-supplied HTML fetched from the OC database.
*/
public static function fix_oc_html($html)
{
/* There are thousands of relative URLs in cache descriptions. We will
* attempt to find them and fix them. In theory, the "proper" way to do this
* would be to parse the description into a DOM tree, but that would simply
* be very hard (and inefficient) to do, since most of the descriptions are
* not even valid HTML.
*/
$html = preg_replace(
"~\b(src|href)=([\"'])(?![a-z0-9_-]+:)~",
"$1=$2".Settings::get("SITE_URL"),
$html
);
/* Other things to do in the future:
*
* 1. Check for XSS vulerabilities?
* 2. Transform to a valid (X)HTML?
*/
return $html;
}
}
/** A data caching layer. For slow SQL queries etc. */
@ -2001,6 +2039,16 @@ class OkapiHttpRequest extends OkapiRequest
}
}
if (is_object($this->consumer) && $this->consumer->admin)
{
/* Some chosen Consumers gain special permissions within OKAPI.
* Currently, there's only a single "admin" flag in the okapi_consumers
* table, and there's just a single extra permission to gain, but
* the this set of permissions may grow in time. */
$this->skip_limits = true;
}
#
# Prevent developers from accessing request parameters with PHP globals.
# Remember, that OKAPI requests can be nested within other OKAPI requests!

View File

@ -9,14 +9,14 @@ class OkapiDataStore extends OAuthDataStore
public function lookup_consumer($consumer_key)
{
$row = Db::select_row("
select `key`, secret, name, url, email
select `key`, secret, name, url, email, admin
from okapi_consumers
where `key` = '".mysql_real_escape_string($consumer_key)."'
");
if (!$row)
return null;
return new OkapiConsumer($row['key'], $row['secret'], $row['name'],
$row['url'], $row['email']);
$row['url'], $row['email'], $row['admin'] ? true : false);
}
public function lookup_token($consumer, $token_type, $token)

View File

@ -38,10 +38,33 @@ class WebService
private static function get_inner_xml($node)
{
/* Fetch as <some-node>content</some-node>, extract content. */
$s = $node->asXML();
$start = strpos($s, ">") + 1;
$length = strlen($s) - $start - (3 + strlen($node->getName()));
return substr($s, $start, $length);
$s = substr($s, $start, $length);
/* Find and replace %okapi:plugins%. */
$s = preg_replace_callback("~%OKAPI:([a-z:]+)%~", array("self", "plugin_callback"), $s);
return $s;
}
public static function plugin_callback($matches)
{
$input = $matches[1];
$arr = explode(":", $input);
$plugin_name = $arr[0];
switch ($plugin_name) {
case 'docurl':
$fragment = $arr[1];
return Settings::get('SITE_URL')."okapi/introduction.html#".$fragment;
default:
throw new Exception("Unknown plugin: ".$input);
}
}
public static function call(OkapiRequest $request)

View File

@ -61,6 +61,12 @@ It also defines attribute names and descriptions in several languages.
es sich lohnt näher anzusehen.
</desc>
</lang>
<lang id="nl">
<name>Alleen te loggen op Opencaching</name>
<desc>
Deze cache is alleen beschikbaar en te loggen op opencaching.
</desc>
</lang>
<lang id="es">
<name>Solo loggeable en Opencaching</name>
<desc>
@ -77,9 +83,7 @@ It also defines attribute names and descriptions in several languages.
interessanti cache OC di qualità.
</desc>
</lang>
<lang id="nl">
<name>Alleen te loggen op Opencaching</name>
</lang>
</attr>
<attr acode="A2" categories="de-cache-types">
@ -105,6 +109,12 @@ It also defines attribute names and descriptions in several languages.
Der Cache ist in der Nähe eines festen Vermessungspunktes versteckt.
</desc>
</lang>
<lang id="nl">
<name>Meetpunt</name>
<desc>
Deze cache heeft te maken met een meetpunt of geodetisch punt.
</desc>
</lang>
</attr>
<attr acode="A3" categories="de-cache-types">
@ -168,6 +178,14 @@ It also defines attribute names and descriptions in several languages.
<a href="http://wiki.opencaching.de/index.php/Letterboxing">Weitere Informationen</a>.
</desc>
</lang>
<lang id="nl">
<name>Letterbox (een stempel nodig)</name>
<desc>
Er bevind sich een stempel in de cache waarmee je een in een eigen logboek
kan stempelen. Met een eigen stempel kun je het logboek in de cache stempelen.
Let op om niet per ongeluk de stempels te verwisselen!
</desc>
</lang>
<lang id="es">
<name>Letterbox (necesita un estampador)</name>
<desc>
@ -214,6 +232,10 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>GeoHotel</name>
<desc>
Deze cache is speciaal voor reizende items zoals: GeoKrets,
TravelBugs enz.
</desc>
</lang>
</attr>
@ -240,6 +262,9 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Bevestigd met magneet</name>
<desc>
Deze cache is met een magneet bevestigt.
</desc>
</lang>
</attr>
@ -268,6 +293,13 @@ It also defines attribute names and descriptions in several languages.
die der Cachbeschreibung beigefügt ist.
</desc>
</lang>
<lang id="nl">
<name>Beschrijving bevat een audio bestand</name>
<desc>
Om deze cache te vinden moeten instructies via een audio bestand
(bijv. MP3) beluisterd worden welke in de cachebeschrijving te vinden is.
</desc>
</lang>
</attr>
<attr acode="A8" categories="de-cache-types">
@ -324,6 +356,12 @@ It also defines attribute names and descriptions in several languages.
werden. Dazu wird ein passender Empfänger benötigt.
</desc>
</lang>
<lang id="nl">
<name>Beacon - Garmin chirp</name>
<desc>
Deze cache is gemaakt met 1 of meer Garmins chirp draadloze zenders.
</desc>
</lang>
</attr>
<attr acode="A10" categories="de-cache-types">
@ -355,6 +393,15 @@ It also defines attribute names and descriptions in several languages.
logbook.txt zum Loggen.
</desc>
</lang>
<lang id="nl">
<name>Dead Drop USB cache</name>
<desc>
Deze cache bestaat uit een vast gemonteerde USB stick, zoals in een
muur of paal enz. Deze bevat een readme.txt bestand met de cache
beschrijving en een logboek.txt bestand om je bezoek te kunnen loggen.
<a href="http://wiki.opencaching.nl/index.php/Dead_Drop_Caches">Voor informatie</a>.
</desc>
</lang>
</attr>
<attr acode="A11" categories="de-cache-types">
@ -620,6 +667,10 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Rolstoel toegankelijk</name>
<desc>
Deze cache is zo gemaakt dat de cache ook met de rolstoel te vinden
en te loggen is.
</desc>
</lang>
</attr>
@ -915,6 +966,12 @@ It also defines attribute names and descriptions in several languages.
Der Cache ist mit dem Fahrrad erreichbar.
</desc>
</lang>
<lang id="nl">
<name>Fietsen toegestaan</name>
<desc>
Deze cache is ook met de fiets te doen.
</desc>
</lang>
</attr>
<attr acode="A28" categories="de-location">
@ -943,6 +1000,9 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Cache met veel natuur</name>
<desc>
Deze cache loopt door de natuur. Zoals bossen, heide, moerasgebieden enz.
</desc>
</lang>
</attr>
@ -1108,6 +1168,9 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Parkeerplaats vlakbij</name>
<desc>
Er is een parkeerplaats vlak bij om deze cache te beginnen.
</desc>
</lang>
</attr>
@ -2174,7 +2237,7 @@ It also defines attribute names and descriptions in several languages.
</desc>
</lang>
<lang id="nl">
<name>jachtgebied</name>
<name>Let op: jachtgebied</name>
</lang>
</attr>
@ -2209,6 +2272,9 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Let op: doornen</name>
<desc>
Er kunnen doornen bij de cache zijn. Draag beschermende kleding.
</desc>
</lang>
</attr>
@ -2254,6 +2320,11 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Let op: teken</name>
<desc>
In dit gebied zouden teken voorkomen. Neem voorzorgen om geen teken
op te lopen door beschermende kleding te dragen. Vor meer informatie
kijk op <a href="http://nl.wikipedia.org/wiki/Teken_%28dieren%29">www.meningitis.de</a>
</desc>
</lang>
</attr>
@ -2439,7 +2510,7 @@ It also defines attribute names and descriptions in several languages.
<attr acode="A70" categories="de-rating">
<groundspeak id="6" inc="true" name="Recommended for kids" />
<opencaching schema="http://opencaching.pl/" id="41" />
<opencaching schema="http://www.opencaching.nl/" id="59" />
<opencaching schema="http://www.opencaching.nl/" id="41" />
<lang id="en">
<name>Take your children</name>
<desc>
@ -2463,6 +2534,10 @@ It also defines attribute names and descriptions in several languages.
</lang>
<lang id="nl">
<name>Kindvriendelijke cache</name>
<desc>
Dit is een makkelijke en veilige cache. De kleine kinderen
kunnen ook aan deze cache deelnemen.
</desc>
</lang>
</attr>

View File

@ -80,12 +80,29 @@ class WebService
throw new BadRequest("In order for 'latest_logs' to work you have to also include 'ns_ground' extensions.");
$tmp = $request->get_parameter('my_notes');
if (!$tmp) $tmp = "none";
if (!in_array($tmp, array("none", "desc:text")))
throw new InvalidParam("my_notes");
if (($tmp != 'none') && ($request->token == null))
throw new BadRequest("Level 3 Authentication is required to access my_notes data.");
$vars['my_notes'] = $tmp;
$vars['my_notes'] = array();
if ($tmp && $tmp != 'none') {
$tmp = explode('|', $tmp);
foreach ($tmp as $elem) {
if ($elem == 'none') {
/* pass */
} elseif (in_array($elem, array('desc:text', 'gc:personal_note'))) {
if (in_array('none', $tmp)) {
throw new InvalidParam(
'my_notes', "You cannot mix 'none' and '$elem'"
);
}
if ($request->token == null) {
throw new BadRequest(
"Level 3 Authentication is required to access my_notes data."
);
}
$vars['my_notes'][] = $elem;
} else {
throw new InvalidParam('my_notes', "Invalid list entry: '$elem'");
}
}
}
$images = $request->get_parameter('images');
if (!$images) $images = 'descrefs:nonspoilers';
@ -155,7 +172,7 @@ class WebService
$fields .= "|alt_wpts";
if ($vars['recommendations'] != 'none')
$fields .= "|recommendations|founds";
if ($vars['my_notes'] != 'none')
if (count($vars['my_notes']) > 0)
$fields .= "|my_notes";
if ($vars['latest_logs'])
$fields .= "|latest_logs";
@ -232,7 +249,7 @@ class WebService
# The assignment via GC-ID as array key will prohibit duplicate
# GC attributes, which can result from
# - assigning the same GC ID to multiple A-Codes,
# - contradicting attributes in one OC listing, e.g. 24/4 + not 24/7.
# - contradicting attributes in one OC listing, e.g. 24/4 + not 24/7.
$cache['gc_attrs'][$gc['id']] = $gc;
$has_gc_equivs = true;

View File

@ -11,6 +11,8 @@
This method can produce many various types of GPX files. The simplest list of
waypoints takes ~50 times less space than the same list with cache descriptions
and log entries included.</p>
<p>Note, that GPX files may contain <a href='%OKAPI:docurl:html%'>unvalidated
HTML</a>.</p>
</desc>
<req name='cache_codes'>
<p>Pipe-separated list of cache codes which you are interested in.
@ -138,10 +140,24 @@
<p>Note: When using "desc:" mode, remember to set <b>ns_ground</b> to <b>true</b>.</p>
</opt>
<opt name='my_notes' default='none'>
<p>Allows you to include personal user's notes on each cache. One of the following values:</p>
<p>Allows you to include personal user's notes on each cache. This parameter
takes either <b>none</b> (default value), or pipe separeted list of the
following values:</p>
<ul>
<li><b>none</b> - don't include personal notes,</li>
<li><b>desc:text</b> - include personal notes as part of the cache description.</li>
<li><b>desc:text</b> - include personal notes as part of the cache
description.</li>
<li>
<p><b>gc:personal_note</b> - include personal notes as
&lt;groundspeak:personal_note&gt; element (under
&lt;groundspeak:cache&gt; element).</p>
<p><b>Warning:</b> This element is not a part of
<i>http://www.groundspeak.com/cache/1/0/1</i> groundspeak schema, but it
is a <i>http://www.groundspeak.com/cache/1/0/2</i> schema element. Using
this option will generate formally invalid XML file.</p>
</li>
</ul>
<p>Note: You need to use Level 3 Authentication in order to set it to anything else than "none".</p>
</opt>

View File

@ -66,8 +66,8 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
<?= sprintf(ngettext("%d trackable", "%d trackables", $c['trackables_count']), $c['trackables_count']) ?>.
<? } ?>
&lt;/p&gt;
<? if (($vars['my_notes'] == 'desc:text') && ($c['my_notes'] != null)) { /* Does user want us to include personal notes? */ ?>
&lt;p&gt;&lt;b&gt;<?= _("Personal notes") ?>:&lt;/b&gt; <?= Okapi::xmlescape($c['my_notes']) ?>&lt;/p&gt;
<? if ((in_array('desc:text', $vars['my_notes'])) && ($c['my_notes'] != null)) { /* Does user want us to include personal notes? */ ?>
&lt;p&gt;&lt;b&gt;<?= _("Personal notes") ?>:&lt;/b&gt;&lt;br&gt;<?= Okapi::xmlescape(nl2br($c['my_notes'])) ?>&lt;/p&gt;
<? } ?>
<? if (in_array('desc:text', $vars['attrs']) && count($c['attrnames']) > 0) { /* Does user want us to include attributes? */ ?>
@ -134,6 +134,9 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
<? } ?>
</groundspeak:long_description>
<groundspeak:encoded_hints><?= Okapi::xmlescape($c['hint2']) ?></groundspeak:encoded_hints>
<? if ((in_array('gc:personal_note', $vars['my_notes'])) && ($c['my_notes'] != null)) { /* Does user want us to include personal notes? -> Issue 294 */ ?>
<groundspeak:personal_note><?= Okapi::xmlescape($c['my_notes']) ?></groundspeak:personal_note>
<? } ?>
<? if ($vars['latest_logs']) { /* Does user want us to include latest log entries? */ ?>
<groundspeak:logs>
<? foreach ($c['latest_logs'] as $log) { ?>

View File

@ -241,14 +241,17 @@
<li><b>recommendations</b> - number of recommendations for this cache,</li>
<li><b>req_passwd</b> - boolean; states if this cache requires a password
in order to submit a "Found it" log entry,</li>
<li><b>description</b> - HTML string, description of the cache,</li>
<li><b>descriptions</b> - a dictionary (language code =&gt; HTML string) of cache
descriptions,</li>
<li class="deprecated"><b>hint</b> - HTML-encoded string, cache hints/spoilers;
deprecated (<a href="http://code.google.com/p/opencaching-api/issues/detail?id=261">why?</a>),
<li><b>description</b> - <a href='%OKAPI:docurl:html%'>HTML string</a>,
description of the cache,</li>
<li><b>descriptions</b> - a dictionary (language code =&gt;
<a href='%OKAPI:docurl:html%'>HTML string</a>) of cache descriptions,</li>
<li class="deprecated"><b>hint</b> - <a href='%OKAPI:docurl:html%'>HTML-encoded</a>
string, cache hints/spoilers; deprecated
(<a href="http://code.google.com/p/opencaching-api/issues/detail?id=261">why?</a>),
use <b>hint2</b> instead,</li>
<li class="deprecated"><b>hints</b> - a dictionary (language code =&gt;
HTML-encoded string) of cache hints/spoilers; deprecated, use hints2 instead,</li>
<a href='%OKAPI:docurl:html%'>HTML-encoded</a> string) of cache hints/spoilers;
deprecated, use hints2 instead,</li>
<li><b>hint2</b> - plain-text string, cache hints/spoilers; in general, hints
should not be displayed to the user unless user specifically asks for them,</li>
<li><b>hints2</b> - a dictionary (language code =&gt;

View File

@ -105,7 +105,7 @@ class WebService
$user_id = Db::select_value("select user_id from user where uuid='".mysql_real_escape_string($user_uuid)."'");
if ($user_id == null)
throw new InvalidParam('user_uuid', "User not found.");
if (($request->token != null) && ($this->token->user_id != $user_id))
if (($request->token != null) && ($request->token->user_id != $user_id))
throw new InvalidParam('user_uuid', "User does not match the Access Token used.");
}
elseif (($user_uuid == null) && ($request->token != null))
@ -497,7 +497,8 @@ class WebService
/* Note, that the "owner" and "internal_id" fields are automatically included,
* whenever the cache description is included. */
$tmp = $row['desc'];
$tmp = Okapi::fix_oc_html($row['desc']);
if ($attribution_append != 'none')
{
$tmp .= "\n<p><em>".

View File

@ -185,12 +185,16 @@
<p><b>Examples:</b></p>
<ul>
<li>to order by cache name use "order_by=name" or "order_by=+name",</li>
<li>to have the largest caches in front, use "order_by=-size",</li>
<li>multicolumn sorting is also allowed, ex. "order_by=-founds|-size|distance"</li>
<li>to have the most recommended caches caches in front, use "order_by=-rcmds%",</li>
<li>multicolumn sorting is also allowed, ex. "order_by=-founds|name"</li>
</ul>
<p><b>Note:</b> Try to avoid executing separate OKAPI request every time you
want to sort the data which you <b>already have</b>. Consider caching and
sorting on client side. This will speed up things for both sides.</p>
<p><b>Note:</b> For most other methods (like <b>bbox</b> and <b>nearest</b>),
the default order is <i>by the distance from the center</i>. If you supply
custom <b>order_by</b> parameter, then we will try to order by your preference
first, and then by the distance later.</p>
</opt>
<common-format-params/>
<returns>

View File

@ -498,7 +498,12 @@ class SearchAssistant
if (!is_numeric($limit))
throw new InvalidParam('limit', "'$limit'");
if ($limit < 1 || (($limit > 500) && (!$request->skip_limits)))
throw new InvalidParam('limit', "Has to be between 1 and 500.");
throw new InvalidParam(
'limit',
$request->skip_limits
? "Cannot be lower than 1."
: "Has to be between 1 and 500."
);
#
# offset
@ -510,8 +515,13 @@ class SearchAssistant
throw new InvalidParam('offset', "'$offset'");
if (($offset + $limit > 500) && (!$request->skip_limits))
throw new BadRequest("The sum of offset and limit may not exceed 500.");
if ($offset < 0 || $offset > 499)
throw new InvalidParam('offset', "Has to be between 0 and 499.");
if ($offset < 0 || (($offset > 499) && (!$request->skip_limits)))
throw new InvalidParam(
'offset',
$request->skip_limits
? "Cannot be lower than 0."
: "Has to be between 0 and 499."
);
#
# order_by

View File

@ -101,7 +101,7 @@ class WebService
),
'type' => Okapi::logtypeid2name($row['type']),
'was_recommended' => $row['was_recommended'] ? true : false,
'comment' => $row['text'],
'comment' => Okapi::fix_oc_html($row['text']),
'images' => array(),
'internal_id' => $row['id'],
);

View File

@ -63,6 +63,8 @@
<ul>
<li>"Needs maintenance" - a user states that the cache is
in need of maintenance.</li>
<li>"Maintenance performed" - the cache owner states that he
had performed the maintenance.</li>
<li>"Moved" - the cache has been moved to a different location.</li>
<li>"OC Team comment" - a comment made by the official OC Team
member.</li>
@ -82,7 +84,8 @@
<p><b>was_recommended</b> - <b>true</b>, if the author included his recommendation
in this log entry,</p>
</li>
<li><b>comment</b> - HTML string, text entered with the log entry,</li>
<li><b>comment</b> - <a href='%OKAPI:docurl:html%'>HTML string</a>, text entered
with the log entry,</li>
<li>
<p><b>images</b> - list of dictionaries, each dictionary represents one
image saved along with the log; each dictionary has the following

View File

@ -34,7 +34,8 @@
everything</b>, but there are some primary types (see logs/entry
method for more info).</p>
</li>
<li><b>comment</b> - HTML string, text entered with the log entry.</li>
<li><b>comment</b> - <a href='%OKAPI:docurl:html%'>HTML string</a>, text entered
with the log entry.</li>
</ul>
</returns>
</xml>

View File

@ -18,7 +18,7 @@ use okapi\Settings;
class ReplicateCommon
{
private static $chunk_size = 200;
private static $chunk_size = 50;
private static $logged_cache_fields = 'code|names|location|type|status|url|owner|founds|notfounds|size|size2|oxsize|difficulty|terrain|rating|rating_votes|recommendations|req_passwd|descriptions|hints|images|trackables_count|trackables|alt_wpts|last_found|last_modified|date_created|date_hidden';
private static $logged_log_entry_fields = 'uuid|cache_code|date|user|type|was_recommended|comment';
@ -471,7 +471,7 @@ class ReplicateCommon
# Geocaches
$cache_codes = Db::select_column("select wp_oc from caches");
$cache_code_groups = Okapi::make_groups($cache_codes, 200);
$cache_code_groups = Okapi::make_groups($cache_codes, self::$chunk_size);
unset($cache_codes);
foreach ($cache_code_groups as $cache_codes)
{

View File

@ -19,6 +19,9 @@ class View
{
public static function call()
{
if (!isset($_GET['id'])) {
throw new ParamMissing("id");
}
$tmp = Db::select_value("
select data
from okapi_clog

View File

@ -48,7 +48,7 @@ Check out other OKAPI installations:</p>
which are "national views" of Opencaching.DE. All three share one
database, so you can access all their data through the Opencaching.DE
OKAPI installation and select Italian or Spanish language.</p>
<p>And also:</p>
<ul>
<li>OKAPI Project Homepage - <a href='http://code.google.com/p/opencaching-api/'>http://code.google.com/p/opencaching-api/</a></li>
@ -133,6 +133,18 @@ and don't have to care about OAuth.</p>
You may also use the HTTP <code>Authorization</code> header for passing OAuth arguments.
OKAPI does not allow usage of PUT and DELETE requests.</p>
<h2 id='html'>About HTML fields</h2>
<p>There are many HTML-formatted fields in OKAPI. However, most of them come directly
from the underlying Opencaching database. These fields are <b>not validated by OKAPI</b>.
They <b>may</b> be validated by some other Opencaching code
(prior to inserting it to the database), but we cannot guarantee it. And you shouldn't
count on it too. You must assume that HTML content may contain anything, e.g.
invalid HTML markup, tracking images (pixels), or even
<a href='http://en.wikipedia.org/wiki/Cross-site_scripting'>XSS vectors</a>.
This also applies to the descriptions included in the GPX files.</p>
<h2 id='common-formatting'>Common formatting parameters</h2>
<p>Most of the methods return simple objects, such as lists and dictionaries
@ -229,11 +241,20 @@ method calls and redirects which provide you with an Access Token).</p>
<p>Basic rules apply:</p>
<ul>
<li>If all goes well, OKAPI will respond with a <b>HTTP 200</b> status.</li>
<li>If there is something wrong with your request, you will get a <b>HTTP 4xx</b>
response (with a JSON object described below). These kind of responses should
trigger some kind of an exception inside your application.</li>
<li>If something goes wrong <b>on our part</b>, you will get a <b>HTTP 5xx</b> response.
We will try to fix such errors as soon as possible.</li>
<li>Sometimes, due to invalid server configuration, you may receive <b>HTTP 200</b>
instead of <b>HTTP 500</b>. We know that's "unprofessional", but we cannot guarantee
that all OC servers are configured properly
(<a href='https://code.google.com/p/opencaching-api/issues/detail?id=293'>example</a>).
If you get <b>HTTP 200</b> <u>and</u> you cannot parse the server response, you should
treat it as <b>HTTP 500</b>.</li>
</ul>
<p>Each <b>HTTP 4xx</b> error will be properly described in the response, using a <b>JSON error

View File

@ -32,8 +32,8 @@ class View
$notice = "Application name should be less than 100 characters long.";
elseif (mb_strlen($appurl) > 250)
$notice = "Application URL should be less than 250 characters long.";
elseif ($appurl && (substr($appurl, 0, 7) != "http://"))
$notice = "Application homepage URL should start with http://. (Note: this URL is OPTIONAL and it is NOT for OAuth callback.)";
elseif ($appurl && (substr($appurl, 0, 7) != "http://") && (substr($appurl, 0, 8) != "https://"))
$notice = "Application homepage URL should start with http(s)://. (Note: this URL is OPTIONAL and it is NOT for OAuth callback.)";
elseif (!$email)
$notice = "Please provide a valid email address.";
elseif (mb_strlen($email) > 70)

View File

@ -676,4 +676,5 @@ class View
private static function ver85() { Db::execute("alter table okapi_nonces drop primary key;"); }
private static function ver86() { Db::execute("alter table okapi_nonces change column `key` nonce_hash varchar(32) character set utf8 collate utf8_bin not null;"); }
private static function ver87() { Db::execute("alter table okapi_nonces add primary key (consumer_key, nonce_hash);"); }
private static function ver88() { Db::execute("alter table okapi_consumers add column admin tinyint not null default 0;"); }
}