OKAPI update, revision 1075
This commit is contained in:
@@ -784,31 +784,35 @@ class OkapiRedirectResponse extends OkapiHttpResponse
|
||||
}
|
||||
}
|
||||
|
||||
require_once ($GLOBALS['rootpath'].'okapi/lib/tbszip.php');
|
||||
use \clsTbsZip;
|
||||
|
||||
class OkapiZIPHttpResponse extends OkapiHttpResponse
|
||||
{
|
||||
public $zip;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
require_once ($GLOBALS['rootpath'].'okapi/lib/tbszip.php');
|
||||
|
||||
$this->zip = new \clsTbsZip();
|
||||
$this->zip = new clsTbsZip();
|
||||
$this->zip->CreateNew();
|
||||
}
|
||||
|
||||
public function print_body()
|
||||
{
|
||||
$this->zip->Flush(TBSZIP_DOWNLOAD|TBSZIP_NOHEADER);
|
||||
$this->zip->Flush(clsTbsZip::TBSZIP_DOWNLOAD|clsTbsZip::TBSZIP_NOHEADER);
|
||||
}
|
||||
|
||||
public function get_body()
|
||||
{
|
||||
$this->zip->Flush(TBSZIP_STRING);
|
||||
return $this->zip->OutputSrc;
|
||||
$this->zip->Flush(clsTbsZip::TBSZIP_STRING);
|
||||
return $this->zip->OutputSrc;
|
||||
}
|
||||
|
||||
public function get_length()
|
||||
{
|
||||
# The _EstimateNewArchSize() method returns *false* if archive
|
||||
# size can not be calculated *exactly*, which causes display()
|
||||
# method to skip Content-Length header, and triggers chunking
|
||||
return $this->zip->_EstimateNewArchSize();
|
||||
}
|
||||
|
||||
@@ -890,7 +894,7 @@ class Okapi
|
||||
{
|
||||
public static $data_store;
|
||||
public static $server;
|
||||
public static $revision = 1055; # This gets replaced in automatically deployed packages
|
||||
public static $revision = 1075; # 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. */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi\cronjobs;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
@@ -103,7 +103,7 @@ class Facade
|
||||
'caches.status in (1,2,3)',
|
||||
);
|
||||
return \okapi\services\caches\search\save\WebService::get_set(
|
||||
$tables, $where_conds, $min_store, $max_ref_age
|
||||
$tables, array() /* joins */, $where_conds, $min_store, $max_ref_age
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
|
||||
@@ -10,12 +10,12 @@ for TinyButStrong Template Engine (TBS). OpenTbs makes TBS able to merge OpenOff
|
||||
Visit http://www.tinybutstrong.com
|
||||
*/
|
||||
|
||||
define('TBSZIP_DOWNLOAD',1); // download (default)
|
||||
define('TBSZIP_NOHEADER',4); // option to use with DOWNLOAD: no header is sent
|
||||
define('TBSZIP_FILE',8); // output to file , or add from file
|
||||
define('TBSZIP_STRING',32); // output to string, or add from string
|
||||
|
||||
class clsTbsZip {
|
||||
const TBSZIP_DOWNLOAD = 1; // download (default)
|
||||
const TBSZIP_NOHEADER = 4; // option to use with DOWNLOAD: no header is sent
|
||||
const TBSZIP_FILE = 8; // output to file , or add from file
|
||||
const TBSZIP_STRING = 32; // output to string, or add from string
|
||||
|
||||
function __construct() {
|
||||
$this->Meth8Ok = extension_loaded('zlib'); // check if Zlib extension is available. This is need for compress and uncompress with method 8.
|
||||
@@ -77,7 +77,7 @@ class clsTbsZip {
|
||||
$this->AddInfo = array();
|
||||
}
|
||||
|
||||
function FileAdd($Name, $Data, $DataType=TBSZIP_STRING, $Compress=true) {
|
||||
function FileAdd($Name, $Data, $DataType=self::TBSZIP_STRING, $Compress=true) {
|
||||
|
||||
if ($Data===false) return $this->FileCancelModif($Name, false); // Cancel a previously added file
|
||||
|
||||
@@ -389,7 +389,7 @@ class clsTbsZip {
|
||||
|
||||
}
|
||||
|
||||
function FileReplace($NameOrIdx, $Data, $DataType=TBSZIP_STRING, $Compress=true) {
|
||||
function FileReplace($NameOrIdx, $Data, $DataType=self::TBSZIP_STRING, $Compress=true) {
|
||||
// Store replacement information.
|
||||
|
||||
$idx = $this->FileGetIdx($NameOrIdx);
|
||||
@@ -472,9 +472,9 @@ class clsTbsZip {
|
||||
|
||||
}
|
||||
|
||||
function Flush($Render=TBSZIP_DOWNLOAD, $File='', $ContentType='') {
|
||||
function Flush($Render=self::TBSZIP_DOWNLOAD, $File='', $ContentType='') {
|
||||
|
||||
if ( ($File!=='') && ($this->ArchFile===$File) && ($Render==TBSZIP_FILE) ) {
|
||||
if ( ($File!=='') && ($this->ArchFile===$File) && ($Render==self::TBSZIP_FILE) ) {
|
||||
$this->RaiseError('Method Flush() cannot overwrite the current opened archive: \''.$File.'\''); // this makes corrupted zip archives without PHP error.
|
||||
return false;
|
||||
}
|
||||
@@ -627,21 +627,21 @@ class clsTbsZip {
|
||||
|
||||
function OutputOpen($Render, $File, $ContentType) {
|
||||
|
||||
if (($Render & TBSZIP_FILE)==TBSZIP_FILE) {
|
||||
$this->OutputMode = TBSZIP_FILE;
|
||||
if (($Render & self::TBSZIP_FILE)==self::TBSZIP_FILE) {
|
||||
$this->OutputMode = self::TBSZIP_FILE;
|
||||
if (''.$File=='') $File = basename($this->ArchFile).'.zip';
|
||||
$this->OutputHandle = @fopen($File, 'w');
|
||||
if ($this->OutputHandle===false) {
|
||||
return $this->RaiseError('Method Flush() cannot overwrite the target file \''.$File.'\'. This may not be a valid file path or the file may be locked by another process or because of a denied permission.');
|
||||
}
|
||||
} elseif (($Render & TBSZIP_STRING)==TBSZIP_STRING) {
|
||||
$this->OutputMode = TBSZIP_STRING;
|
||||
} elseif (($Render & self::TBSZIP_STRING)==self::TBSZIP_STRING) {
|
||||
$this->OutputMode = self::TBSZIP_STRING;
|
||||
$this->OutputSrc = '';
|
||||
} elseif (($Render & TBSZIP_DOWNLOAD)==TBSZIP_DOWNLOAD) {
|
||||
$this->OutputMode = TBSZIP_DOWNLOAD;
|
||||
} elseif (($Render & self::TBSZIP_DOWNLOAD)==self::TBSZIP_DOWNLOAD) {
|
||||
$this->OutputMode = self::TBSZIP_DOWNLOAD;
|
||||
// Output the file
|
||||
if (''.$File=='') $File = basename($this->ArchFile);
|
||||
if (($Render & TBSZIP_NOHEADER)==TBSZIP_NOHEADER) {
|
||||
if (($Render & self::TBSZIP_NOHEADER)==self::TBSZIP_NOHEADER) {
|
||||
} else {
|
||||
header ('Pragma: no-cache');
|
||||
if ($ContentType!='') header ('Content-Type: '.$ContentType);
|
||||
@@ -677,17 +677,17 @@ class clsTbsZip {
|
||||
}
|
||||
|
||||
function OutputFromString($data) {
|
||||
if ($this->OutputMode===TBSZIP_DOWNLOAD) {
|
||||
if ($this->OutputMode===self::TBSZIP_DOWNLOAD) {
|
||||
echo $data; // donwload
|
||||
} elseif ($this->OutputMode===TBSZIP_STRING) {
|
||||
} elseif ($this->OutputMode===self::TBSZIP_STRING) {
|
||||
$this->OutputSrc .= $data; // to string
|
||||
} elseif (TBSZIP_FILE) {
|
||||
} elseif (self::TBSZIP_FILE) {
|
||||
fwrite($this->OutputHandle, $data); // to file
|
||||
}
|
||||
}
|
||||
|
||||
function OutputClose() {
|
||||
if ( ($this->OutputMode===TBSZIP_FILE) && ($this->OutputHandle!==false) ) {
|
||||
if ( ($this->OutputMode===self::TBSZIP_FILE) && ($this->OutputHandle!==false) ) {
|
||||
fclose($this->OutputHandle);
|
||||
$this->OutputHandle = false;
|
||||
}
|
||||
@@ -908,7 +908,7 @@ class clsTbsZip {
|
||||
}
|
||||
|
||||
// TODO support for data taken from okapi cache
|
||||
if ($DataType==TBSZIP_STRING) {
|
||||
if ($DataType==self::TBSZIP_STRING) {
|
||||
$path = false;
|
||||
if ($Compress) {
|
||||
// we compress now in order to save PHP memory
|
||||
@@ -956,9 +956,10 @@ class clsTbsZip {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the size of the new archive, or false if it cannot be calculated (because of external file that must be compressed before to be insered)
|
||||
*/
|
||||
function _EstimateNewArchSize($Optim=true) {
|
||||
// Return the size of the new archive, or false if it cannot be calculated (because of external file that must be compressed before to be insered)
|
||||
|
||||
if ($this->ArchIsNew) {
|
||||
$Len = strlen($this->CdInfo['bin']);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: OKAPI\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2014-01-23 16:05+0100\n"
|
||||
"PO-Revision-Date: 2014-11-01 00:36+0100\n"
|
||||
"PO-Revision-Date: 2015-03-22 14:48+0100\n"
|
||||
"Last-Translator: Harrie Klomp <harrie@harrieklomp.be>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: nl_NL\n"
|
||||
@@ -359,9 +359,8 @@ msgstr ""
|
||||
"\n"
|
||||
"<p>Dit is een lijst met toegestane toepassingen op jouw <b>%s</b> account.\n"
|
||||
"Op deze pagina kun je alle toestemmingen intrekken die gegeven zijn.\n"
|
||||
"Met een klik op \"verwijderen\" zal de toepassing verwijderen en is dan ook "
|
||||
"niet meer beschikbaar\n"
|
||||
"oor anderen.</p>"
|
||||
"Met een klik op \"verwijderen\" zal de toestemming ingetrokken worden en\n"
|
||||
"niet meer namens jou gebruikt kunnen worden.</p>"
|
||||
|
||||
#: okapi/views/apps/index.tpl.php:45
|
||||
msgid "remove"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ class WebService
|
||||
$context = stream_context_create($opts);
|
||||
$xml = file_get_contents("http://opencaching-api.googlecode.com/svn/trunk/etc/installations.xml",
|
||||
false, $context);
|
||||
$doc = simplexml_load_string($xml);
|
||||
if (!$doc) {
|
||||
throw new ErrorException(); # just to get to the catch block
|
||||
}
|
||||
}
|
||||
catch (ErrorException $e)
|
||||
{
|
||||
@@ -71,7 +75,6 @@ class WebService
|
||||
return Okapi::formatted_response($request, $results);
|
||||
}
|
||||
|
||||
$doc = simplexml_load_string($xml);
|
||||
$results = array();
|
||||
$i_was_included = false;
|
||||
foreach ($doc->installation as $inst)
|
||||
|
||||
@@ -88,7 +88,7 @@ It also defines attribute names and descriptions in several languages.
|
||||
|
||||
<attr acode="A2" categories="de-cache-types">
|
||||
<opencaching schema="http://opencaching.pl/" id="54" />
|
||||
<opencaching schema="http://www.opencaching.nl/" id="61" />
|
||||
<opencaching schema="http://www.opencaching.nl/" id="54" />
|
||||
<lang id="en">
|
||||
<name>Near a Survey Marker</name>
|
||||
<desc>
|
||||
@@ -1008,6 +1008,7 @@ It also defines attribute names and descriptions in several languages.
|
||||
|
||||
<attr acode="A29" categories="de-location">
|
||||
<opencaching schema="http://opencaching.pl/" id="61" />
|
||||
<opencaching schema="http://www.opencaching.nl/" id="61" />
|
||||
<lang id="en">
|
||||
<name>Historic site</name>
|
||||
<desc>
|
||||
@@ -1029,11 +1030,17 @@ It also defines attribute names and descriptions in several languages.
|
||||
einer Burg, einem Friedhof, einer ehemaligem Militäranlage etc.
|
||||
</desc>
|
||||
</lang>
|
||||
<lang id="nl">
|
||||
<name>Lost Place</name>
|
||||
<desc>
|
||||
Deze cache bevind zich op of rond een verlaten plek. Zoals een,
|
||||
verlaten kasteel, oude bunker, industrie, etc.
|
||||
</desc>
|
||||
</lang>
|
||||
</attr>
|
||||
|
||||
<attr acode="A30" categories="de-location">
|
||||
<opencaching schema="http://www.opencaching.de/" id="30" />
|
||||
<opencaching schema="http://www.opencaching.nl/" id="30" />
|
||||
<lang id="en">
|
||||
<name>Point of interest</name>
|
||||
<desc>
|
||||
@@ -2652,4 +2659,23 @@ It also defines attribute names and descriptions in several languages.
|
||||
</desc>
|
||||
</lang>
|
||||
</attr>
|
||||
|
||||
<attr acode="A74" categories="de-dangers">
|
||||
<groundspeak id="40" inc="true" name="Stealth required" />
|
||||
<opencaching schema="http://www.opencaching.nl/" id="45" />
|
||||
<lang id="en">
|
||||
<name>Stealth required</name>
|
||||
<desc>
|
||||
The cache is hidden in an area where other non-geocaching people might
|
||||
see it. You should be extra careful to avoid this unwanted attention.
|
||||
</desc>
|
||||
</lang>
|
||||
<lang id="nl">
|
||||
<name>Stealth vereist</name>
|
||||
<desc>
|
||||
Deze cache dient ongezien gelogd te worden.
|
||||
</desc>
|
||||
</lang>
|
||||
</attr>
|
||||
|
||||
</xml>
|
||||
|
||||
@@ -46,7 +46,7 @@ class WebService
|
||||
$format = $request->get_parameter('caches_format');
|
||||
if (!$format) $format = "gpx";
|
||||
if (!in_array($format, array("gpx", "ggz")))
|
||||
throw new InvalidParam('format');
|
||||
throw new InvalidParam('caches_format');
|
||||
|
||||
$location_source = $request->get_parameter('location_source');
|
||||
$location_change_prefix = $request->get_parameter('location_change_prefix');
|
||||
@@ -89,7 +89,7 @@ class WebService
|
||||
'my_notes' => ($request->token != null) ? "desc:text" : "none",
|
||||
'location_source' => $location_source,
|
||||
'location_change_prefix' => $location_change_prefix
|
||||
)))->get_body(), TBSZIP_STRING, $data_use_compression);
|
||||
)))->get_body(), clsTbsZip::TBSZIP_STRING, $data_use_compression);
|
||||
|
||||
# Then, include all the images.
|
||||
|
||||
@@ -143,7 +143,7 @@ class WebService
|
||||
$syspath = Settings::get('IMAGES_DIR')."/".$img['uuid'].".jpg";
|
||||
if (file_exists($syspath))
|
||||
{
|
||||
$response->zip->FileAdd($zippath, $syspath, TBSZIP_FILE, false);
|
||||
$response->zip->FileAdd($zippath, $syspath, clsTbsZip::TBSZIP_FILE, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -181,7 +181,7 @@ class WebService
|
||||
}
|
||||
}
|
||||
if ($jpeg_contents) # This can be "null" *or* "false"!
|
||||
$response->zip->FileAdd($zippath, $jpeg_contents, TBSZIP_STRING, false);
|
||||
$response->zip->FileAdd($zippath, $jpeg_contents, clsTbsZip::TBSZIP_STRING, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi\services\caches\formatters\ggz;
|
||||
|
||||
@@ -9,12 +9,12 @@ echo '<?xml version="1.0" encoding="utf-8"?>'."\n";
|
||||
?>
|
||||
<ggz xmlns="http://www.opencaching.com/xmlschemas/ggz/1/0">
|
||||
<time><?= date('c') ?></time>
|
||||
<? foreach ($vars['files'] as $f) { ?>
|
||||
<?php foreach ($vars['files'] as $f) { ?>
|
||||
<file>
|
||||
<name><?= $f['name'] ?></name>
|
||||
<crc><?= $f['crc32'] ?></crc>
|
||||
<time><?= date('c') ?></time>
|
||||
<?
|
||||
<?php
|
||||
foreach ($f['caches'] as $c) {
|
||||
?><gch>
|
||||
<code><?= $c['code'] ?></code>
|
||||
@@ -24,20 +24,20 @@ echo '<?xml version="1.0" encoding="utf-8"?>'."\n";
|
||||
<lon><?= $c['lon'] ?></lon>
|
||||
<file_pos><?= $c['file_pos'] ?></file_pos>
|
||||
<file_len><?= $c['file_len'] ?></file_len>
|
||||
<? if (isset($c['ratings'])) {
|
||||
<?php if (isset($c['ratings'])) {
|
||||
?><ratings>
|
||||
<?
|
||||
<?php
|
||||
foreach ($c['ratings'] as $rating_key => $rating_val){
|
||||
echo "<$rating_key>$rating_val</$rating_key>\n";
|
||||
}
|
||||
?>
|
||||
</ratings><?
|
||||
</ratings><?php
|
||||
}
|
||||
if (isset($c['found']) && $c['found']) { ?>
|
||||
<found>true</found>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</gch>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</file>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ggz>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi\services\caches\formatters\gpx;
|
||||
|
||||
@@ -22,8 +22,8 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
<url><?= $vars['installation']['site_url'] ?></url>
|
||||
<urlname><?= $vars['installation']['site_name'] ?></urlname>
|
||||
<time><?= date('c') ?></time>
|
||||
<? foreach ($vars['caches'] as &$cache_ref) { ?>
|
||||
<?
|
||||
<?php foreach ($vars['caches'] as &$cache_ref) { ?>
|
||||
<?php
|
||||
if (isset($cache_ref['ggz_entry'])) {
|
||||
/* The base parts of the GGZ index are the offset and length of the entry
|
||||
* in the GPX file. This needs to be calculated here. */
|
||||
@@ -35,21 +35,21 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
<wpt lat="<?= $lat ?>" lon="<?= $lon ?>">
|
||||
<time><?= $c['date_created'] ?></time>
|
||||
<name><?= $c['code'] ?></name>
|
||||
<desc><?= Okapi::xmlescape(isset($c['name_2']) ? $c['name_2'] : $c['name']) ?> <?= _("hidden by") ?> <?= Okapi::xmlescape($c['owner']['username']) ?> :: <?= ucfirst($c['type']) ?> Cache (<?= $c['difficulty'] ?>/<?= $c['terrain'] ?><? if ($c['size'] !== null) { echo "/".$c['size']; } else { echo "/X"; } ?>/<?= $c['rating'] ?>)</desc>
|
||||
<desc><?= Okapi::xmlescape(isset($c['name_2']) ? $c['name_2'] : $c['name']) ?> <?= _("hidden by") ?> <?= Okapi::xmlescape($c['owner']['username']) ?> :: <?= ucfirst($c['type']) ?> Cache (<?= $c['difficulty'] ?>/<?= $c['terrain'] ?><?php if ($c['size'] !== null) { echo "/".$c['size']; } else { echo "/X"; } ?>/<?= $c['rating'] ?>)</desc>
|
||||
<url><?= $c['url'] ?></url>
|
||||
<urlname><?= Okapi::xmlescape($c['name']) ?></urlname>
|
||||
<sym><?= ($vars['mark_found'] && $c['is_found']) ? "Geocache Found" : "Geocache" ?></sym>
|
||||
<type>Geocache|<?= $vars['cache_GPX_types'][$c['type']] ?></type>
|
||||
<? if ($vars['ns_ground']) { /* Does user want us to include Groundspeak's <cache> element? */ ?>
|
||||
<?php if ($vars['ns_ground']) { /* Does user want us to include Groundspeak's <cache> element? */ ?>
|
||||
<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(isset($c['name_2']) ? $c['name_2'] : $c['name']) ?></groundspeak:name>
|
||||
<groundspeak:placed_by><?= Okapi::xmlescape($c['owner']['username']) ?></groundspeak:placed_by>
|
||||
<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>
|
||||
<? if ($vars['gc_attrs'] || $vars['gc_ocde_attrs']) { /* Does user want us to include groundspeak:attributes? */ ?>
|
||||
<?php if ($vars['gc_attrs'] || $vars['gc_ocde_attrs']) { /* Does user want us to include groundspeak:attributes? */ ?>
|
||||
<groundspeak:attributes>
|
||||
<?
|
||||
<?php
|
||||
foreach ($c['gc_attrs'] as $gc_id => $gc_attr) {
|
||||
print "<groundspeak:attribute id=\"".$gc_id."\" ";
|
||||
print "inc=\"".$gc_attr['inc']."\">";
|
||||
@@ -58,54 +58,54 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
}
|
||||
?>
|
||||
</groundspeak:attributes>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<groundspeak:difficulty><?= $c['difficulty'] ?></groundspeak:difficulty>
|
||||
<groundspeak:terrain><?= $c['terrain'] ?></groundspeak:terrain>
|
||||
<? if ($c['short_description']) { ?>
|
||||
<?php if ($c['short_description']) { ?>
|
||||
<groundspeak:short_description html="False"><?= Okapi::xmlescape($c['short_description']) ?></groundspeak:short_description>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<groundspeak:long_description html="True">
|
||||
<? if (isset($c['warning_prefix'])) { ?>
|
||||
<?php if (isset($c['warning_prefix'])) { ?>
|
||||
<p style='font-size: 120%'><?= Okapi::xmlescape($c['warning_prefix']) ?></p>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<p>
|
||||
<a href="<?= $c['url'] ?>"><?= Okapi::xmlescape($c['name']) ?></a>
|
||||
<?= _("hidden by") ?> <a href='<?= $c['owner']['profile_url'] ?>'><?= Okapi::xmlescape($c['owner']['username']) ?></a><br/>
|
||||
<? if ($vars['recommendations'] == 'desc:count') { /* Does user want us to include recommendations count? */ ?>
|
||||
<?php if ($vars['recommendations'] == 'desc:count') { /* Does user want us to include recommendations count? */ ?>
|
||||
<?= sprintf(ngettext("%d recommendation", "%d recommendations", $c['recommendations']), $c['recommendations']) ?>
|
||||
(<?= sprintf(ngettext("found %d time", "found %d times", $c['founds']), $c['founds']) ?>).
|
||||
<? } ?>
|
||||
<? if ($vars['trackables'] == 'desc:count') { /* Does user want us to include trackables count? */ ?>
|
||||
<?php } ?>
|
||||
<?php if ($vars['trackables'] == 'desc:count') { /* Does user want us to include trackables count? */ ?>
|
||||
<?= sprintf(ngettext("%d trackable", "%d trackables", $c['trackables_count']), $c['trackables_count']) ?>.
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</p>
|
||||
<? if ((in_array('desc:text', $vars['my_notes'])) && ($c['my_notes'] != null)) { /* Does user want us to include personal notes? */ ?>
|
||||
<?php if ((in_array('desc:text', $vars['my_notes'])) && ($c['my_notes'] != null)) { /* Does user want us to include personal notes? */ ?>
|
||||
<p><b><?= _("Personal notes") ?>:</b><br><?= Okapi::xmlescape(nl2br($c['my_notes'])) ?></p>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
|
||||
<? if (in_array('desc:text', $vars['attrs']) && count($c['attrnames']) > 0) { /* Does user want us to include attributes? */ ?>
|
||||
<?php if (in_array('desc:text', $vars['attrs']) && count($c['attrnames']) > 0) { /* Does user want us to include attributes? */ ?>
|
||||
<p><?= _("Attributes") ?>:</p>
|
||||
<ul><li><?= implode("</li><li>", $c['attrnames']) ?></li></ul>
|
||||
<? } ?>
|
||||
<? if ($vars['trackables'] == 'desc:list' && count($c['trackables']) > 0) { /* Does user want us to include trackables list? */ ?>
|
||||
<?php } ?>
|
||||
<?php if ($vars['trackables'] == 'desc:list' && count($c['trackables']) > 0) { /* Does user want us to include trackables list? */ ?>
|
||||
<p><?= _("Trackables") ?>:</p>
|
||||
<ul>
|
||||
<? foreach ($c['trackables'] as $t) { ?>
|
||||
<?php foreach ($c['trackables'] as $t) { ?>
|
||||
<li><a href='<?= Okapi::xmlescape($t['url']) ?>'><?= Okapi::xmlescape($t['name']) ?></a> (<?= $t['code'] ?>)</li>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<?= Okapi::xmlescape($c['description']) ?>
|
||||
<? if ((strpos($vars['images'], "descrefs:") === 0) && count($c['images']) > 0) { /* Does user want us to include <img> references in cache descriptions? */
|
||||
<?php if ((strpos($vars['images'], "descrefs:") === 0) && count($c['images']) > 0) { /* Does user want us to include <img> references in cache descriptions? */
|
||||
if ($vars['images'] == "descrefs:thumblinks") { ?>
|
||||
<h2><?= _("Images") ?> (<?= count($c['images']) ?>)</h2>
|
||||
<div>
|
||||
<? foreach ($c['images'] as $img) { ?>
|
||||
<?php foreach ($c['images'] as $img) { ?>
|
||||
<div style='float:left; padding:6px'><a href='<?= Okapi::xmlescape($img['url']) ?>'><img src='<?= Okapi::xmlescape($img['thumb_url']) ?>'></a><br>
|
||||
<?= Okapi::xmlescape($img['caption']) ?></div>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<? } else {
|
||||
<?php } else {
|
||||
# We will split images into two subcategories: spoilers and nonspoilers.
|
||||
$spoilers = array();
|
||||
$nonspoilers = array();
|
||||
@@ -113,91 +113,91 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
if ($img['is_spoiler']) $spoilers[] = $img;
|
||||
else $nonspoilers[] = $img;
|
||||
?>
|
||||
<? if (count($nonspoilers) > 0) { ?>
|
||||
<?php if (count($nonspoilers) > 0) { ?>
|
||||
<h2><?= _("Images") ?> (<?= count($nonspoilers) ?>)</h2>
|
||||
<? foreach ($nonspoilers as $img) { ?>
|
||||
<?php foreach ($nonspoilers as $img) { ?>
|
||||
<p><img src='<?= Okapi::xmlescape($img['url']) ?>'><br>
|
||||
<?= Okapi::xmlescape($img['caption']) ?></p>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<? if (count($spoilers) > 0 && $vars['images'] == 'descrefs:all') { ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if (count($spoilers) > 0 && $vars['images'] == 'descrefs:all') { ?>
|
||||
<h2><?= _("Spoilers") ?> (<?= count($spoilers) ?>)</h2>
|
||||
<? foreach ($spoilers as $img) { ?>
|
||||
<?php foreach ($spoilers as $img) { ?>
|
||||
<p><img src='<?= Okapi::xmlescape($img['url']) ?>'><br>
|
||||
<?= Okapi::xmlescape($img['caption']) ?></p>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<? if ((strpos($vars['images'], "ox:") === 0) && count($c['images']) > 0) { /* Include image descriptions (for ox:image numbers)? */ ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if ((strpos($vars['images'], "ox:") === 0) && count($c['images']) > 0) { /* Include image descriptions (for ox:image numbers)? */ ?>
|
||||
<p><?= _("Image descriptions") ?>:</p>
|
||||
<ul>
|
||||
<? foreach ($c['images'] as $no => $img) { ?>
|
||||
<?php foreach ($c['images'] as $no => $img) { ?>
|
||||
<li><?= $img['unique_caption'] ?>. <?= Okapi::xmlescape($img['caption']) ?></li>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<? } ?>
|
||||
<? if ($vars['protection_areas'] == 'desc:text' && count($c['protection_areas'])) { ?>
|
||||
<?php } ?>
|
||||
<?php if ($vars['protection_areas'] == 'desc:text' && count($c['protection_areas'])) { ?>
|
||||
<p><?= _("The cache probably is located in the following protection areas:") ?></p>
|
||||
<ul>
|
||||
<? foreach($c['protection_areas'] as $protection_area) { ?>
|
||||
<?php foreach($c['protection_areas'] as $protection_area) { ?>
|
||||
<li><?= Okapi::xmlescape($protection_area['type'])." - ".Okapi::xmlescape($protection_area['name']) ?></li>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ul;>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</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 */ ?>
|
||||
<?php 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? */ ?>
|
||||
<?php } ?>
|
||||
<?php if ($vars['latest_logs']) { /* Does user want us to include latest log entries? */ ?>
|
||||
<groundspeak:logs>
|
||||
<? foreach ($c['latest_logs'] as $log) { ?>
|
||||
<?php foreach ($c['latest_logs'] as $log) { ?>
|
||||
<groundspeak:log id="<?= $log['internal_id'] ?>">
|
||||
<groundspeak:date><?= $log['date'] ?></groundspeak:date>
|
||||
<groundspeak:type><?= $log['type'] ?></groundspeak:type>
|
||||
<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>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</groundspeak:logs>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</groundspeak:cache>
|
||||
<? } ?>
|
||||
<? if ($vars['ns_ox']) { /* Does user want us to include Garmin's <opencaching> element? */ ?>
|
||||
<?php } ?>
|
||||
<?php if ($vars['ns_ox']) { /* Does user want us to include Garmin's <opencaching> element? */ ?>
|
||||
<ox:opencaching xmlns:ox="http://www.opencaching.com/xmlschemas/opencaching/1/0">
|
||||
<ox:ratings>
|
||||
<? if ($c['rating'] !== null) { ?><ox:awesomeness><?= $c['rating'] ?></ox:awesomeness><? } ?>
|
||||
<?php if ($c['rating'] !== null) { ?><ox:awesomeness><?= $c['rating'] ?></ox:awesomeness><?php } ?>
|
||||
<ox:difficulty><?= $c['difficulty'] ?></ox:difficulty>
|
||||
<? if ($c['oxsize'] !== null) { ?><ox:size><?= $c['oxsize'] ?></ox:size><? } ?>
|
||||
<?php if ($c['oxsize'] !== null) { ?><ox:size><?= $c['oxsize'] ?></ox:size><?php } ?>
|
||||
<ox:terrain><?= $c['terrain'] ?></ox:terrain>
|
||||
</ox:ratings>
|
||||
<? if (in_array('ox:tags', $vars['attrs']) && count($c['attrnames']) > 0) { /* Does user want us to include ox:tags? */ ?>
|
||||
<?php if (in_array('ox:tags', $vars['attrs']) && count($c['attrnames']) > 0) { /* Does user want us to include ox:tags? */ ?>
|
||||
<ox:tags><ox:tag><?= implode("</ox:tag><ox:tag>", $c['attrnames']) ?></ox:tag></ox:tags>
|
||||
<? } ?>
|
||||
<? if ((strpos($vars['images'], "ox:") === 0) && count($c['images']) > 0) { /* Does user want us to include ox:image references? */ ?>
|
||||
<?php } ?>
|
||||
<?php if ((strpos($vars['images'], "ox:") === 0) && count($c['images']) > 0) { /* Does user want us to include ox:image references? */ ?>
|
||||
<ox:images>
|
||||
<? foreach ($c['images'] as $no => $img) { ?>
|
||||
<?php foreach ($c['images'] as $no => $img) { ?>
|
||||
<ox:image>
|
||||
<ox:name><?= $img['unique_caption'] ?>.jpg</ox:name>
|
||||
<ox:size>0</ox:size>
|
||||
<ox:required>false</ox:required>
|
||||
<ox:spoiler><?= ($img['is_spoiler'] ? "true" : "false") ?></ox:spoiler>
|
||||
</ox:image>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ox:images>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ox:opencaching>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</wpt>
|
||||
<?
|
||||
<?php
|
||||
if (isset($cache_ref['ggz_entry'])) {
|
||||
$cache_ref['ggz_entry']['file_len'] = ob_get_length() - $cache_ref['ggz_entry']['file_pos'];
|
||||
}
|
||||
?>
|
||||
<? if ($vars['alt_wpts']) { ?>
|
||||
<? foreach ($cache_ref['alt_wpts'] as &$wpt_ref) { ?>
|
||||
<?
|
||||
<?php if ($vars['alt_wpts']) { ?>
|
||||
<?php foreach ($cache_ref['alt_wpts'] as &$wpt_ref) { ?>
|
||||
<?php
|
||||
if (isset($wpt_ref['ggz_entry'])) {
|
||||
$wpt_ref['ggz_entry']['file_pos'] = ob_get_length();
|
||||
}
|
||||
@@ -213,18 +213,18 @@ http://www.gsak.net/xmlv1/5 http://www.gsak.net/xmlv1/5/gsak.xsd
|
||||
<urlname><?= Okapi::xmlescape($c['name']) ?></urlname>
|
||||
<sym><?= $wpt['sym'] ?></sym>
|
||||
<type>Waypoint|<?= $wpt['sym'] ?></type>
|
||||
<? if ($vars['ns_gsak']) { ?>
|
||||
<?php if ($vars['ns_gsak']) { ?>
|
||||
<gsak:wptExtension xmlns:gsak="http://www.gsak.net/xmlv1/5">
|
||||
<gsak:Parent><?= $c['code'] ?></gsak:Parent>
|
||||
</gsak:wptExtension>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</wpt>
|
||||
<?
|
||||
<?php
|
||||
if (isset($wpt_ref['ggz_entry'])){
|
||||
$wpt_ref['ggz_entry']['file_len'] = ob_get_length() - $wpt_ref['ggz_entry']['file_pos'];
|
||||
}
|
||||
?>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</gpx>
|
||||
|
||||
@@ -187,6 +187,7 @@ class WebService
|
||||
$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.
|
||||
|
||||
|
||||
@@ -160,6 +160,15 @@
|
||||
Boolean. If set to <b>true</b>, only caches which have not yet been
|
||||
found <b>by anyone</b> will be included.
|
||||
</opt>
|
||||
<opt name='powertrail_only' default='false'>
|
||||
<p>BETA. Boolean. If set to <b>true</b>, only caches which belong to at
|
||||
least one <b>active</b> Power Trail will be included.</p>
|
||||
|
||||
<p>Power Trails are sets of geocaches. Only some Opencaching nodes
|
||||
implement this feature. If this node does not implement it, and you
|
||||
will set this parameter to <b>true</b>, then you will <b>always</b>
|
||||
receive an empty result.</p>
|
||||
</opt>
|
||||
<opt name='set_and'>
|
||||
<p>ID of a set previously created with the <b>search/save</b> method.
|
||||
If given, the results are <a href='http://en.wikipedia.org/wiki/Logical_conjunction'>AND</a>ed
|
||||
|
||||
@@ -57,18 +57,28 @@ class WebService
|
||||
$search_assistant->prepare_location_search_params();
|
||||
|
||||
$where_conds = array();
|
||||
$where_conds[] = $search_assistant->get_latitude_expr()." between '".mysql_real_escape_string($bbsouth)."' and '".mysql_real_escape_string($bbnorth)."'";
|
||||
$lat = $search_assistant->get_latitude_expr();
|
||||
$lon = $search_assistant->get_longitude_expr();
|
||||
$where_conds[] = "(
|
||||
$lat >= '".mysql_real_escape_string($bbsouth)."'
|
||||
and $lat < '".mysql_real_escape_string($bbnorth)."'
|
||||
)";
|
||||
if ($bbeast > $bbwest)
|
||||
{
|
||||
# Easy one.
|
||||
$where_conds[] = $search_assistant->get_longitude_expr()." between '".mysql_real_escape_string($bbwest)."' and '".mysql_real_escape_string($bbeast)."'";
|
||||
$where_conds[] = "(
|
||||
$lon >= '".mysql_real_escape_string($bbwest)."'
|
||||
and $lon < '".mysql_real_escape_string($bbeast)."'
|
||||
)";
|
||||
}
|
||||
else
|
||||
{
|
||||
# We'll have to assume that this box goes through the 180-degree meridian.
|
||||
# We'll have to assume that this bbox goes through the 180-degree meridian.
|
||||
# For example, $bbwest = 179 and $bbeast = -179.
|
||||
$where_conds[] = "(".$search_assistant->get_longitude_expr()." > '".mysql_real_escape_string($bbwest)
|
||||
."' or ".$search_assistant->get_longitude_expr()." < '".mysql_real_escape_string($bbeast)."')";
|
||||
$where_conds[] = "(
|
||||
$lon >= '".mysql_real_escape_string($bbwest)."'
|
||||
or $lon < '".mysql_real_escape_string($bbeast)."'
|
||||
)";
|
||||
}
|
||||
|
||||
#
|
||||
|
||||
@@ -74,12 +74,18 @@ class WebService
|
||||
array('caches.wp_oc is not null'),
|
||||
$search_params['where_conds']
|
||||
);
|
||||
|
||||
if (isset($search_params['extra_joins']) && is_array($search_params['extra_joins']))
|
||||
$joins = $search_params['extra_joins'];
|
||||
else
|
||||
$joins = array();
|
||||
|
||||
unset($search_params);
|
||||
|
||||
# Generate, or retrieve an existing set, and return the result.
|
||||
# All user-supplied data in $tables and $where_conds MUST be escaped!
|
||||
|
||||
$result = self::get_set($tables, $where_conds, $min_store, $ref_max_age);
|
||||
$result = self::get_set($tables, $joins, $where_conds, $min_store, $ref_max_age);
|
||||
return Okapi::formatted_response($request, $result);
|
||||
}
|
||||
|
||||
@@ -87,11 +93,11 @@ class WebService
|
||||
* Important: YOU HAVE TO make sure $tables and $where_conds don't contain
|
||||
* unescaped user-supplied data!
|
||||
*/
|
||||
public static function get_set($tables, $where_conds, $min_store, $ref_max_age)
|
||||
public static function get_set($tables, $joins, $where_conds, $min_store, $ref_max_age)
|
||||
{
|
||||
# Compute the "params hash".
|
||||
|
||||
$params_hash = md5(serialize(array($tables, $where_conds)));
|
||||
$params_hash = md5(serialize(array($tables, $joins, $where_conds)));
|
||||
|
||||
# Check if there exists an entry for this hash, which also meets the
|
||||
# given freshness criteria.
|
||||
@@ -133,7 +139,9 @@ class WebService
|
||||
select distinct
|
||||
'".mysql_real_escape_string($set_id)."',
|
||||
caches.cache_id
|
||||
from ".implode(", ", $tables)."
|
||||
from
|
||||
".implode(", ", $tables)."
|
||||
".implode(" ", $joins)."
|
||||
where (".implode(") and (", $where_conds).")
|
||||
");
|
||||
|
||||
|
||||
@@ -514,13 +514,35 @@ class SearchAssistant
|
||||
if ($tmp = $this->request->get_parameter('ftf_hunter'))
|
||||
{
|
||||
if (!in_array($tmp, array('true', 'false'), 1))
|
||||
throw new InvalidParam('not_yet_found_only', "'$tmp'");
|
||||
throw new InvalidParam('ftf_hunter', "'$tmp'");
|
||||
if ($tmp == 'true')
|
||||
{
|
||||
$where_conds[] = "$X_FOUNDS = 0";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# powertrail_only
|
||||
#
|
||||
if (!is_null($tmp = $this->request->get_parameter('powertrail_only')))
|
||||
{
|
||||
if (!in_array($tmp, array('true', 'false'), 1))
|
||||
throw new InvalidParam('powertrail_only', "'$tmp'");
|
||||
if ($tmp == 'true')
|
||||
{
|
||||
if (Settings::get('OC_BRANCH') == 'oc.pl') {
|
||||
$extra_joins[] = 'inner join powerTrail_caches on powerTrail_caches.cacheId = caches.cache_id';
|
||||
#
|
||||
# Filter out caches from inactive powerTrails as well
|
||||
#
|
||||
$extra_joins[] = 'inner join PowerTrail on PowerTrail.id = powerTrail_caches.powerTrailId';
|
||||
$where_conds[] = 'PowerTrail.status = 1';
|
||||
} else {
|
||||
$where_conds[] = "0=1";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# set_and
|
||||
#
|
||||
|
||||
@@ -30,6 +30,13 @@
|
||||
and may depend on the installation
|
||||
(<a href='https://code.google.com/p/opencaching-api/issues/detail?id=124'>more info</a>).</p>
|
||||
|
||||
<p><b>Important note:</b> Unfortunatelly, some OC nodes don't support this
|
||||
parameter properly - regardless of what you choose, you may end up with
|
||||
<a href='https://code.google.com/p/opencaching-api/issues/detail?id=324'>unexpected
|
||||
results</a>. Currently, there is nothing OKAPI developers can do
|
||||
to fix this, but you should use this parameter either way (to indicate how
|
||||
you <b>expect</b> it to behave) - we hope this will be fixed, eventually.</p>
|
||||
|
||||
<p><b>Important note:</b> The subset of allowed HTML elements is left undefined
|
||||
and may change in the future. For future-compatibility, you should use only
|
||||
basic formatting tags.</p>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi\services\oauth\request_token;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi;
|
||||
|
||||
|
||||
@@ -137,7 +137,10 @@ class View
|
||||
# back to the Consumer application with an error.
|
||||
|
||||
if ($token['callback']) {
|
||||
return new OkapiRedirectResponse($token['callback'].$callback_concat_char."error=access_denied");
|
||||
return new OkapiRedirectResponse(
|
||||
$token['callback'].$callback_concat_char."error=access_denied".
|
||||
"&oauth_token=".$token['key']
|
||||
);
|
||||
} else {
|
||||
# Consumer did not provide a callback URL (oauth_callback=oob).
|
||||
# We'll have to redirect to the Opencaching main page then...
|
||||
|
||||
@@ -36,16 +36,16 @@
|
||||
<div style='float: right; clear: right; margin: 10px 0 10px 30px'>
|
||||
Choose your language:
|
||||
<select id='langpref' style='border: 1px solid #ccc'>
|
||||
<? foreach ($vars['locales'] as $locale => $attrs) { ?>
|
||||
<?php foreach ($vars['locales'] as $locale => $attrs) { ?>
|
||||
<option value='<?= $attrs['lang'] ?>' <?= ($attrs['locale'] == $vars['locale_displayed']) ? "selected" : "" ?>><?= $attrs['name'] ?></option>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<? if (isset($vars['token_expired']) && $vars['token_expired']) { ?>
|
||||
<?php if (isset($vars['token_expired']) && $vars['token_expired']) { ?>
|
||||
<h1 style='clear: both'><?= _("Expired request") ?></h1>
|
||||
<p><?= _("Unfortunately, the request has expired. Please try again.") ?></p>
|
||||
<? } elseif ($vars['token']) { ?>
|
||||
<?php } elseif ($vars['token']) { ?>
|
||||
<h1 style='clear: both'><?= _("External application is requesting access...") ?></h1>
|
||||
<p><?= sprintf(_("<b>%s</b> wants to access your <b>%s</b> account. Do you agree to grant access to this application?"), htmlentities($vars['token']['consumer_name']), $vars['site_name']) ?></p>
|
||||
<form id='authform' method='POST' class='form'>
|
||||
@@ -61,7 +61,7 @@
|
||||
by the OKAPI Framework, i.e. post log entries on geocaches in your name.
|
||||
You can revoke this permission at any moment.</p>
|
||||
"), $vars['okapi_base_url']."apps/", $vars['okapi_base_url']) ?>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
<a href='<?= $vars['site_url'] ?>' class='opencaching'><?= $vars['site_name'] ?></a>
|
||||
|
||||
<h1 style='clear: both'><?= _("Your external applications") ?></h1>
|
||||
<? if (count($vars['apps']) > 0) { ?>
|
||||
<?php if (count($vars['apps']) > 0) { ?>
|
||||
<?= sprintf(_("
|
||||
<p>This is the list of applications which you granted access to your <b>%s</b> account.
|
||||
This page gives you the abbility to revoke all previously granted privileges.
|
||||
@@ -35,24 +35,24 @@
|
||||
actions on your behalf.</p>
|
||||
"), $vars['site_name']) ?>
|
||||
<ul>
|
||||
<? foreach ($vars['apps'] as $app) { ?>
|
||||
<?php foreach ($vars['apps'] as $app) { ?>
|
||||
<li>
|
||||
<? if ($app['url']) { ?>
|
||||
<?php if ($app['url']) { ?>
|
||||
<a href='<?= htmlspecialchars($app['url'], ENT_QUOTES, 'utf-8') ?>'><?= htmlspecialchars($app['name'], ENT_QUOTES, 'utf-8') ?></a>
|
||||
<? } else { ?>
|
||||
<?php } else { ?>
|
||||
<?= htmlspecialchars($app['name'], ENT_QUOTES, 'utf-8') ?>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
- <a href='<?= $vars['okapi_base_url'] ?>apps/revoke_access?consumer_key=<?= $app['key'] ?>'><?= _("remove") ?></a>
|
||||
</li>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<? } else { ?>
|
||||
<?php } else { ?>
|
||||
<?= sprintf(_("
|
||||
<p>Thanks to the <a href='%s'>OKAPI Framework</a> you can grant external applications
|
||||
access to your <b>%s</b> account. Currently no applications are authorized to act
|
||||
on your behalf. Once you start using external Opencaching applications, they will appear here.</p>
|
||||
"), $vars['okapi_base_url'], $vars['site_name']) ?>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
/**
|
||||
TODO: make it work even without ';' delimiters or at least warn about that
|
||||
TODO: better parse error reporting
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<body class='api'>
|
||||
<div class='okd_mid'>
|
||||
<div class='okd_top'>
|
||||
<? include 'installations_box.tpl.php'; ?>
|
||||
<?php include 'installations_box.tpl.php'; ?>
|
||||
<table cellspacing='0' cellpadding='0'><tr>
|
||||
<td class='apimenu'>
|
||||
<?= $vars['menu'] ?>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<body class='api'>
|
||||
<div class='okd_mid'>
|
||||
<div class='okd_top'>
|
||||
<? include 'installations_box.tpl.php'; ?>
|
||||
<?php include 'installations_box.tpl.php'; ?>
|
||||
<table cellspacing='0' cellpadding='0'><tr>
|
||||
<td class='apimenu'>
|
||||
<?= $vars['menu'] ?>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<div class='okd_top_pad'>
|
||||
<div class='okd_switcher'>
|
||||
<select id='switcher'>
|
||||
<? foreach ($vars['installations'] as $inst) { ?>
|
||||
<?php foreach ($vars['installations'] as $inst) { ?>
|
||||
<option value='<?= $inst['okapi_base_url'] ?>'<?= $inst['selected'] ? " selected current='true'" : "" ?>><?= $inst['site_name'] ?></option>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,7 +14,7 @@
|
||||
<body class='api'>
|
||||
<div class='okd_mid'>
|
||||
<div class='okd_top'>
|
||||
<? include 'installations_box.tpl.php'; ?>
|
||||
<?php include 'installations_box.tpl.php'; ?>
|
||||
<table cellspacing='0' cellpadding='0'><tr>
|
||||
<td class='apimenu'>
|
||||
<?= $vars['menu'] ?>
|
||||
@@ -26,53 +26,66 @@
|
||||
<div class='subh1'>:: <b>Opencaching API</b> Reference</div>
|
||||
</h1>
|
||||
|
||||
<p><b>OKAPI</b> is a <b>public API</b> project for National Opencaching sites (also known as
|
||||
Opencaching Nodes).</p>
|
||||
<p><b>OKAPI</b> is a publically available
|
||||
<a href='http://en.wikipedia.org/wiki/Application_programming_interface'>API</a>
|
||||
for "National Opencaching" sites (also known as Opencaching National Nodes).</p>
|
||||
|
||||
<ul>
|
||||
<li>It provides OC site with a set of useful well-documented API methods,</li>
|
||||
<li>Allows external developers to easily <b>read public</b> Opencaching data,</li>
|
||||
<li>Allows <b>read and write private</b> (user-related) data with OAuth 3-legged authentication.</li>
|
||||
<li>Allows <b>read and write private</b> (user-related) data with OAuth Authentication.</li>
|
||||
</ul>
|
||||
<p>The project is aiming to become a standard API for all National Opencaching.<i>xx</i> sites.
|
||||
This OKAPI installation provides API for the
|
||||
|
||||
<p>The project has grown to become a standard and common API for all National
|
||||
Opencaching.<i>xx</i> sites. This OKAPI installation provides services for the
|
||||
<a href='<?= $vars['site_url']; ?>'><?= $vars['site_url']; ?></a> site.
|
||||
Check out other OKAPI installations:</p>
|
||||
Here is the list of other OKAPI installations:</p>
|
||||
|
||||
<ul>
|
||||
<? foreach ($vars['installations'] as $inst) { ?>
|
||||
<li><?= $inst['site_name'] ?> - <a href='<?= $inst['okapi_base_url'] ?>'><?= $inst['okapi_base_url'] ?></a></li>
|
||||
<? } ?>
|
||||
<?php foreach ($vars['installations'] as $inst) { ?>
|
||||
<li>
|
||||
<?= $inst['site_name'] ?><? if ($inst['site_name'] == "Opencaching.DE") { print "*"; } ?>
|
||||
- <a href='<?= $inst['okapi_base_url'] ?>'><?= $inst['okapi_base_url'] ?></a>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
<p>Opencaching.DE includes the sites Opencaching.IT and OpencachingSpain.ES,
|
||||
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>Other links you might want to check out:</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>
|
||||
<li>OKAPI News blog - <a href='http://opencaching-api.blogspot.com/'>http://opencaching-api.blogspot.com/</a></li>
|
||||
</ul>
|
||||
|
||||
<p>* - Opencaching.DE includes other sites - Opencaching.IT and
|
||||
OpencachingSpain.ES - which are in fact the one site visible on multiple
|
||||
domains. All three share one database, so you can access all their data through
|
||||
Opencaching.DE OKAPI installation.</p>
|
||||
|
||||
<div class='issue-comments' issue_id='28'></div>
|
||||
|
||||
<h2 id='howto'>How can I use OKAPI?</h2>
|
||||
|
||||
<p>We assume that you're a software developer and you know the basics.</p>
|
||||
<p><b>OKAPI is a set of simple (REST) web services.</b> Basicly, you make a proper HTTP request,
|
||||
and you receive a JSON-formatted data, that you may parse and use within your own application.</p>
|
||||
<p><b>Example.</b> Click the following link to run a method that prints out the list of
|
||||
all available methods:</p>
|
||||
|
||||
<p>OKAPI is a set of simple web services. Basicly, you make a proper HTTP
|
||||
request, and you receive a JSON-formatted response, that you may parse and use
|
||||
within your application.</p>
|
||||
|
||||
<p><b>Example.</b> Click the following link to run a method that prints out the
|
||||
list of all available methods:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><a href='<?= $vars['site_url'] ?>okapi/services/apiref/method_index'><?= $vars['site_url'] ?>okapi/services/apiref/method_index</a></p>
|
||||
<p>Note: You need to install a proper <a href='https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc'>Chrome</a>
|
||||
or <a href='https://addons.mozilla.org/en-US/firefox/addon/jsonview/'>Firefox</a> extension
|
||||
in order to view JSON directly in your browser.</p>
|
||||
<p>Note: You might need to install a proper browser addon (like
|
||||
<a href='https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc'>this one</a>
|
||||
or <a href='https://addons.mozilla.org/en-US/firefox/addon/jsonview/'>this one</a>)
|
||||
in order to view formatted JSON data directly in your browser.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>You've made your first OKAPI request! This method was a simple one.
|
||||
|
||||
<p>You've made your first OKAPI request! This method was a simple one though.
|
||||
It didn't require any arguments and it didn't require you to use a Consumer Key.
|
||||
Other methods are more complex and require you to use
|
||||
<a href='<?= $vars['site_url'] ?>okapi/signup.html'>your own API key</a>.</p>
|
||||
@@ -80,26 +93,33 @@ Other methods are more complex and require you to use
|
||||
<h2 id='auth_levels'>Authentication Levels</h2>
|
||||
|
||||
<p>Each OKAPI method has a <b>minimum authentication level</b>.</p>
|
||||
|
||||
<p>This means, that if you want to call a method which requires "Level 1"
|
||||
authentication, you have to use "Level 1" authentication <b>or higher</b>
|
||||
("Level 2" or "Level 3" will also work).</p>
|
||||
<p><b>Important:</b> Most developers will only need to use "Level 1" authentication
|
||||
and don't have to care about OAuth.</p>
|
||||
|
||||
<p><b>Important:</b> Most developers will only need to use "Level 1"
|
||||
authentication and don't have learn OAuth.</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>Level 0.</b> Anonymous. You may call this method with no extra
|
||||
arguments.</p>
|
||||
<p><b>Level 0.</b> Anonymous. You may call such methods with no extra
|
||||
authentication-related arguments.</p>
|
||||
|
||||
<p><code>some_method?arg=44</code></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>Level 1.</b> Simple Consumer Authentication. You must call this
|
||||
method with <b>consumer_key</b> argument and provide the key which has
|
||||
been generated for your application on the <a href='<?= $vars['site_url'] ?>okapi/signup.html'>Sign up</a> page.</p>
|
||||
been generated for your application on the
|
||||
<a href='<?= $vars['site_url'] ?>okapi/signup.html'>Sign up</a> page.</p>
|
||||
|
||||
<p><code>some_method?arg=44&consumer_key=a7Lkeqf8CjNQTL522dH8</code></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>Level 2.</b> OAuth Consumer Signature. You must call this method
|
||||
with proper OAuth Consumer signature (based on your Consumer Secret).</p>
|
||||
|
||||
<p><code>some_method<br>
|
||||
?arg=44<br>
|
||||
&oauth_consumer_key=a7Lkeqf8CjNQTL522dH8<br>
|
||||
@@ -110,9 +130,10 @@ and don't have to care about OAuth.</p>
|
||||
&oauth_signature=mWEpK2e%2fm8QYZk1BMm%2fRR74B3Co%3d</code></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>Level 3.</b> OAuth Consumer+Token Signature. You must call this method
|
||||
with proper OAuth Consumer+Token signature (based on both Consumer Secret and
|
||||
Token Secret).</p>
|
||||
<p><b>Level 3.</b> OAuth Consumer+Token Signature. You must call this
|
||||
method with proper OAuth Consumer+Token signature (based on both
|
||||
Consumer Secret and Token Secret).</p>
|
||||
|
||||
<p><code>some_method<br>
|
||||
?arg=44<br>
|
||||
&oauth_consumer_key=a7Lkeqf8CjNQTL522dH8<br>
|
||||
@@ -129,72 +150,86 @@ and don't have to care about OAuth.</p>
|
||||
|
||||
<h2 id='http_methods'>GET or POST?</h2>
|
||||
|
||||
<p>Whichever you want. OKAPI will treat GET and POST requests as equal.
|
||||
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>
|
||||
<p>Whichever you want. OKAPI will treat GET and POST requests as equal. You may
|
||||
also use the HTTP <code>Authorization</code> header for passing OAuth
|
||||
arguments. OKAPI does not support other HTTP request types (such as PUT or
|
||||
DELETE).</p>
|
||||
|
||||
<h2 id='html'>About HTML fields</h2>
|
||||
<h2 id='html'>A warning 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.
|
||||
<p>Many of the fields returned in OKAPI responses are formatted in HTML.
|
||||
However, most of these fields come directly from the underlying Opencaching
|
||||
database. Currently, these fields are <b>not validated by OKAPI</b>. They
|
||||
<b>should</b> be validated by the Opencaching site itself (prior to inserting
|
||||
it to the database), but we cannot guarantee that they will be. And you
|
||||
shouldn't count on it too.</p>
|
||||
|
||||
<p>You must assume that our HTML content may contain anything, including
|
||||
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
|
||||
of strings and integers. Such objects can be formatted in several ways using
|
||||
<i>common formatting parameters</i> (supplied by you along all the other
|
||||
parameters required for the method to run):</p>
|
||||
<p>Most of the methods return simple objects, such as lists and dictionaries of
|
||||
strings and integers. We may format such objects for you in several ways. If
|
||||
you want to change the default (JSON) then you should include <i>common
|
||||
formatting parameters</i> in your request:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>format</b> - name of the format in which you'd like your result
|
||||
to be returned in. Currently supported output formats include:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>json</b> - <a href='http://en.wikipedia.org/wiki/JSON'>JSON</a> format (default),</p>
|
||||
<p>Use <a href='https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc'>Chrome</a>
|
||||
or <a href='https://addons.mozilla.org/en-US/firefox/addon/jsonview/'>Firefox</a> extensions
|
||||
to view JSON results directly in your browser. This simplifies debugging a lot!</p>
|
||||
<p><b>json</b> - <a href='http://en.wikipedia.org/wiki/JSON'>JSON</a>
|
||||
format (default),</p>
|
||||
</li>
|
||||
<li>
|
||||
<b>jsonp</b> - <a href='http://en.wikipedia.org/wiki/JSONP'>JSONP</a>
|
||||
format (if you choose this one then you have to specify the
|
||||
<b>callback</b> parameter too),
|
||||
</li>
|
||||
<li class='deprecated'>
|
||||
<b>xmlmap</b> - deprecated (<a href='http://code.google.com/p/opencaching-api/issues/detail?id=128'>why?</a>),
|
||||
</li>
|
||||
<li>
|
||||
<b>xmlmap2</b> - XML format. This is produced by mapping JSON
|
||||
data types to XML elements.
|
||||
</li>
|
||||
<li><b>jsonp</b> - <a href='http://en.wikipedia.org/wiki/JSONP'>JSONP</a> format, if
|
||||
you choose this one, you have to specify the <b>callback</b> parameter,</li>
|
||||
<li class='deprecated'><b>xmlmap</b> - deprecated (<a href='http://code.google.com/p/opencaching-api/issues/detail?id=128'>why?</a>),</li>
|
||||
<li><b>xmlmap2</b> - XML format. This is produced by mapping JSON data types to XML elements.
|
||||
Keep in mind, that XML format is larger than JSON and it takes more time to generate
|
||||
and parse. Try to use JSON when it's possible.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<b>callback</b> - (when using JSONP output format) name of the JavaScript function
|
||||
to be executed with the result as its parameter.
|
||||
<b>callback</b> - (when using JSONP output format) name of the
|
||||
JavaScript function to be executed with the result as its parameter.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p><b><u>Important:</u></b> Almost all of the returned data types are <b>extendible</b>. This means,
|
||||
that (in future) they <b>may contain data that currently they don't</b>.
|
||||
Such data will be included in backward-compatible manner, but still you should remember about
|
||||
it in some cases (i.e. when iterating over attributes of an object). This additional data may
|
||||
appear as extra elements in GPX files or extra keys in JSON responses.
|
||||
Your software <b>must ignore</b> such occurrences if it doesn't understand them!</p>
|
||||
<p>Some methods expose formatting of their own, for example, they may return a
|
||||
JPEG or GPX file. Such methods do not accept <i>common formatting
|
||||
parameters</i>.</p>
|
||||
|
||||
<p>Some methods expose some <b>special formatting</b> of their own, for example, they may return
|
||||
a JPEG or a GPX file. Such methods do not accept <i>common formatting parameters</i>.</p>
|
||||
<p><b><u>Important:</u></b> Almost all of the returned data types are
|
||||
<b>extendible</b>. This means, that (in future) they <b>may contain data that
|
||||
currently they don't</b>. Such data will be included in backward-compatible
|
||||
manner, but still you should remember about it in some cases (i.e. when
|
||||
iterating over attributes of an object). This additional data may appear as
|
||||
extra elements in GPX files or extra keys in JSON responses. Your software
|
||||
<b>must ignore</b> such occurrences if it doesn't understand them!</p>
|
||||
|
||||
<div class='issue-comments' issue_id='30'></div>
|
||||
|
||||
|
||||
<h2 id='oauth'>OAuth Dance URLs</h2>
|
||||
|
||||
<p>If you want to use <b>Level 3</b> methods, you will have to make "the OAuth dance" (series of
|
||||
method calls and redirects which provide you with an Access Token).</p>
|
||||
<p>The three OAuth request URLs defined in the <a href='http://oauth.net/core/1.0a/'>OAuth specification</a> are:</p>
|
||||
<p>If you want to use <b>Level 3</b> methods, you will first have to perform
|
||||
"the OAuth dance" (series of method calls and redirects which provide you with
|
||||
an Access Token).</p>
|
||||
|
||||
<p>The three OAuth request URLs defined in the
|
||||
<a href='http://oauth.net/core/1.0a/'>OAuth specification</a> are:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href='<?= $vars['site_url'] ?>okapi/services/oauth/request_token'><?= $vars['site_url'] ?>okapi/services/oauth/request_token</a>
|
||||
@@ -211,26 +246,35 @@ method calls and redirects which provide you with an Access Token).</p>
|
||||
</ul>
|
||||
|
||||
<p>Things you should pay attention to:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>The <b>oauth_callback</b> argument of the <b>request_token</b> method is <b>required</b>.</p>
|
||||
<p>As the OAuth 1.0a specification states, it should be set to "<i>oob</i>" or a callback URL
|
||||
(this usually starts with http:// or https://, but you can use any other myapp:// scheme).</p>
|
||||
<p>The <b>oauth_callback</b> argument of the <b>request_token</b>
|
||||
method is <b>required</b>.</p>
|
||||
|
||||
<p>As the OAuth 1.0a specification states, it should be set to
|
||||
"<i>oob</i>" or a callback URL (this usually starts with http:// or
|
||||
https://, but you can use any other myapp:// scheme).</p>
|
||||
|
||||
<p>For most OAuth client libraries, you just should provide
|
||||
"<i><?= $vars['site_url'] ?>okapi/services/oauth/request_token?oauth_callback=oob</i>"
|
||||
as the request_token URL, to get it started. Later, probably you'd want to switch "oob"
|
||||
to something more useful.</p>
|
||||
as the request_token URL, to get it started. Later, probably you'd want
|
||||
to switch "oob" to something more useful.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <b>oauth_verifier</b> argument of the <b>access_token</b> method is also <b>required</b>.</p>
|
||||
<p>When user authorizes your application, he will receive a PIN code (OAuth verifier). You
|
||||
have to use this code to receive your Access Token.</p>
|
||||
<p>The <b>oauth_verifier</b> argument of the <b>access_token</b> method
|
||||
is also <b>required</b>.</p>
|
||||
|
||||
<p>When user authorizes your application, he will receive a PIN code
|
||||
(OAuth verifier). You have to use this code to receive your Access
|
||||
Token.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>Access Tokens do not expire</b> (but can be revoked). This means, that once the user
|
||||
authorizes your application, you receive a "lifetime access" to his/her account.
|
||||
User may still <b>revoke access</b> to his account from your
|
||||
application - when this happens, you will have to redo the authorization dance.</p>
|
||||
<p><b>Access Tokens do not expire</b> (but can be revoked). This means,
|
||||
that once the user authorizes your application, you receive a "lifetime
|
||||
access" to his/her account. User may still <b>revoke access</b> to his
|
||||
account from your application - when this happens, you will have to
|
||||
redo the authorization dance.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -239,145 +283,192 @@ method calls and redirects which provide you with an Access Token).</p>
|
||||
<h2 id='errors'>Advanced error handling</h2>
|
||||
|
||||
<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 there is something wrong with your request, you will get a <b>HTTP
|
||||
4xx</b> response. The body will contain a JSON object describing the error
|
||||
(see 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>If something goes wrong <b>on our part</b>, you will get a <b>HTTP
|
||||
5xx</b> response. Usually you should treat such errors as other I/O errors
|
||||
(e.g. display a "No connection, try later" notice). 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
|
||||
<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>
|
||||
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
|
||||
response</b>. You may retrieve the body of such response and use it inside your application
|
||||
(for example, to construct various exception subclasses). In most of the cases, only OAuth applications
|
||||
need to do this. All other applications are fine with threating all HTTP 4xx errors the same.</p>
|
||||
<p>Every <b>HTTP 4xx</b> error will contain an additional description in the
|
||||
response body. This description will be <b>always</b> formatted in JSON
|
||||
(regardless of the <b>format</b> parameter you might have used in your
|
||||
request). You can use this information to pinpoint the source of the error.</p>
|
||||
|
||||
<p>The error response is a dictionary with a single <b>error</b> key. Its value
|
||||
contains <b>at least</b> the following keys:</p>
|
||||
|
||||
<p>The error response is a dictionary with a single <b>error</b> key. Its value contains
|
||||
<b>at least</b> the following keys:</p>
|
||||
<ul>
|
||||
<li><b>developer_message</b> - description of the error,</li>
|
||||
<li><b>reason_stack</b> - list of keywords (see below for valid values) which may be
|
||||
use to subclass exceptions,</li>
|
||||
<li><b>status</b> - HTTP status code (the same which you'll get in response headers),
|
||||
<li><b>more_info</b> - url pointing to a more detailed description of the error
|
||||
(or, more probably, to the page you're now reading).</li>
|
||||
<li>
|
||||
<b>reason_stack</b> - a list of keywords which depicts the exception's
|
||||
position in our exception class hierarchy (see below for valid values),
|
||||
</li>
|
||||
<li>
|
||||
<b>status</b> - HTTP status code (the same which you'll get in response
|
||||
HTTP header),
|
||||
</li>
|
||||
<li>
|
||||
<b>more_info</b> - url pointing to a more detailed description of the
|
||||
error (or, more probably, to the page you're now reading).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Depending on the values on the <b>reason_stack</b>, the <b>error</b> dictionary may
|
||||
contain additional keys. Possible values of the <b>reason_stack</b> include:</p>
|
||||
<p>Depending on the values on the <b>reason_stack</b>, the <b>error</b>
|
||||
dictionary may contain additional keys. Currently possible values of the
|
||||
<b>reason_stack</b> include:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>["bad_request"]</b> - you've made a bad request.
|
||||
|
||||
<p>Subclasses:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>[ ... , "missing_parameter"]</b> - you didn't supply a required
|
||||
parameter. Extra keys:</p>
|
||||
<p><b>[ "bad_request", "missing_parameter"]</b> - you didn't
|
||||
supply a required parameter. Extra keys:</p>
|
||||
|
||||
<ul>
|
||||
<li><b>parameter</b> - the name of the missing parameter.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "invalid_parameter"]</b> - one of your parameters
|
||||
has invalid value. Extra keys:</p>
|
||||
<p><b>[ "bad_request", "invalid_parameter"]</b> - one of your
|
||||
parameters has an invalid value. Extra keys:</p>
|
||||
|
||||
<ul>
|
||||
<li><b>parameter</b> - the name of the parameter,</li>
|
||||
<li><b>whats_wrong_about_it</b> - description of what was wrong about it.</li>
|
||||
<li>
|
||||
<b>whats_wrong_about_it</b> - a string, pretty
|
||||
self-explanatory,
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>["invalid_oauth_request"]</b> - you've tried to use OAuth, but your request
|
||||
was invalid.</p>
|
||||
<p><b>["invalid_oauth_request"]</b> - you've tried to use OAuth, but
|
||||
your request was invalid.</p>
|
||||
|
||||
<p>Subclasses:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p><b>[ ... , "unsupported_oauth_version"]</b> - you tried
|
||||
to use unsupported OAuth version (OKAPI requires OAuth 1.0a).</p>
|
||||
<p><b>[ "invalid_oauth_request", "unsupported_oauth_version"]</b>
|
||||
- you have tried to use unsupported OAuth version (OKAPI
|
||||
requires OAuth 1.0a).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "missing_parameter"]</b> - you didn't supply
|
||||
a required parameter. Extra keys:</p>
|
||||
<p><b>[ "invalid_oauth_request", "missing_parameter"]</b> - you
|
||||
didn't supply a required parameter. Extra keys:</p>
|
||||
|
||||
<ul>
|
||||
<li><b>parameter</b> - the name of the missing parameter.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "unsupported_signature_method"]</b> - you
|
||||
tried to use an unsupported OAuth signature method (OKAPI requires
|
||||
HMAC-SHA1).</p>
|
||||
<p><b>[ "invalid_oauth_request", "unsupported_signature_method"]</b>
|
||||
- you tried to use an unsupported OAuth signature method (OKAPI
|
||||
requires HMAC-SHA1).</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "invalid_consumer"]</b> - your consumer
|
||||
does not exist.</p>
|
||||
<p><b>[ "invalid_oauth_request", "invalid_consumer"]</b> - your
|
||||
consumer does not exist.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "invalid_token"]</b> - your token
|
||||
does not exist. This is pretty common, it may have expired (in case
|
||||
of request tokens) or may have been revoked (in case of access tokens).
|
||||
You should ask your user to redo the authorization dance.</p>
|
||||
<p><b>[ "invalid_oauth_request", "invalid_token"]</b> - your
|
||||
token does not exist. This error is pretty common! Your token
|
||||
may have expired (in case of request tokens) or may have been
|
||||
revoked (in case of access tokens). You should ask your user to
|
||||
redo the authorization dance.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "invalid_signature"]</b> - your request
|
||||
signature was invalid.</p>
|
||||
<p><b>[ "invalid_oauth_request", "invalid_signature"]</b> -
|
||||
your request signature was invalid.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "invalid_timestamp"]</b> - you used a timestamp
|
||||
which was too far off, compared to the current server time. This is
|
||||
pretty common, especially when your app is for mobile phones. You should
|
||||
ask your user to fix the clock or use the provided extra keys to adjust
|
||||
it yourself. Extra keys:</p>
|
||||
<p><b>[ "invalid_oauth_request", "invalid_timestamp"]</b> - you
|
||||
used a timestamp which was too far off, compared to the current
|
||||
server time. This error is pretty common, especially if your
|
||||
app is for mobile phones! You may ask your user to fix his
|
||||
clock, <b><u>or</u></b> you could use the provided extra keys
|
||||
to adjust your <b>oauth_timestamp</b> parameter yourself. Extra
|
||||
keys:</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<b>yours</b> - timestamp you have supplied (this used to be a
|
||||
string, but now it is being casted to an integer, see
|
||||
<b>yours</b> - UNIX timestamp you have supplied (this
|
||||
used to be a string, but now it is being casted to an
|
||||
integer, see
|
||||
<a href='https://code.google.com/p/opencaching-api/issues/detail?id=314'>here</a>),
|
||||
</li>
|
||||
<li><b>ours</b> - timestamp on our server,</li>
|
||||
<li><b>difference</b> - the difference (to be added to your clock),</li>
|
||||
<li><b>ours</b> - UNIX timestamp on our server,</li>
|
||||
<li>
|
||||
<b>difference</b> - the difference, in seconds (to be
|
||||
added to your clock),
|
||||
</li>
|
||||
<li><b>threshold</b> - the maximum allowed difference.</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<p><b>[ ... , "nonce_already_used"]</b> - most probably,
|
||||
you have supplied the same request twice (user double-clicked something?).
|
||||
Or, you have some error in the nonce generator in your OAuth client.</p>
|
||||
<p><b>[ "invalid_oauth_request", "nonce_already_used"]</b> -
|
||||
most probably, you have supplied the same request twice (user
|
||||
double-clicked something?). Or, you have some error in the
|
||||
nonce generator in your OAuth client.</p>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>Almost always, you should be fine with catching just three of those:</p>
|
||||
<p>In most cases, you should be fine with catching just the following (order
|
||||
significant):</p>
|
||||
|
||||
<ul>
|
||||
<li><b>["invalid_oauth_request", "invalid_token"]</b> (reauthorize),</li>
|
||||
<li><b>["invalid_oauth_request", "invalid_timestamp"]</b> (adjust the timestamp),</li>
|
||||
<li>and <i>"any other 4xx status exception"</i> (send yourself a bug report).</li>
|
||||
<li><i>any other 4xx status exception</i> (send yourself a bug report).</li>
|
||||
<li>
|
||||
All other errors - including HTTP 5xx responses, JSON parsing errors,
|
||||
timeouts etc. - should be treated as connection errors (ask the user to
|
||||
try later).
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p><b>Important backward compatibility note:</b> If Z is a subclass of X, then
|
||||
it will forever stay a subclass of X. However, class X won't necessarilly stay
|
||||
Z's <i>direct</i> parent. This means that <b>["x", "z"]</b> may become <b>["x",
|
||||
"y", "z"]</b> or even <b>["w", "x", "y", "z"]</b> one day. In other words,
|
||||
instead writing <code>if (reason_stack == ["x", "z"]) { ... }</code> you should
|
||||
rather use <code>if ("z" in reason_stack) { ... }</code>.</p>
|
||||
|
||||
|
||||
<div class='issue-comments' issue_id='117'></div>
|
||||
|
||||
|
||||
<h2 id='participate'>How can I participate in OKAPI development?</h2>
|
||||
|
||||
<p>OKAPI is Open Source and everyone is welcome to participate in the development.
|
||||
In fact, if you'd like a particular method to exist, we encourage you to
|
||||
submit your patches.</p>
|
||||
<p>OKAPI is Open Source and everyone is welcome to participate in the development.</p>
|
||||
|
||||
<p>We have our <a href='http://code.google.com/p/opencaching-api/issues/list'>Issue tracker</a>.
|
||||
You can use it to contact us!<br>You may also contact some of
|
||||
<a href='http://code.google.com/p/opencaching-api/people/list'>the developers</a> directly,
|
||||
if you want.</p>
|
||||
<a href='http://code.google.com/p/opencaching-api/people/list'>the developers</a>
|
||||
directly, if you want.</p>
|
||||
|
||||
<p>Visit <b>project homepage</b> for details:
|
||||
<a href='http://code.google.com/p/opencaching-api/'>http://code.google.com/p/opencaching-api/</a></p>
|
||||
@@ -388,9 +479,9 @@ if you want.</p>
|
||||
<p>OKAPI web services (methods) currently available on this server:</p>
|
||||
|
||||
<ul>
|
||||
<? foreach ($vars['method_index'] as $method_info) { ?>
|
||||
<?php foreach ($vars['method_index'] as $method_info) { ?>
|
||||
<li><a href='<?= $vars['site_url']."okapi/".$method_info['name'].".html" ?>'><?= $method_info['name'] ?></a> - <?= $method_info['brief_description'] ?></li>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
namespace okapi\views\menu;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?
|
||||
<?php
|
||||
|
||||
# Shortcuts
|
||||
$m = $vars['method'];
|
||||
@@ -20,7 +20,7 @@ $m = $vars['method'];
|
||||
<body class='api'>
|
||||
<div class='okd_mid'>
|
||||
<div class='okd_top'>
|
||||
<? include 'installations_box.tpl.php'; ?>
|
||||
<?php include 'installations_box.tpl.php'; ?>
|
||||
<table cellspacing='0' cellpadding='0'><tr>
|
||||
<td class='apimenu'>
|
||||
<?= $vars['menu'] ?>
|
||||
@@ -50,30 +50,30 @@ $m = $vars['method'];
|
||||
<?= $m['description'] ?>
|
||||
</td>
|
||||
</tr>
|
||||
<? foreach ($m['arguments'] as $arg) { ?>
|
||||
<?php foreach ($m['arguments'] as $arg) { ?>
|
||||
<tr class='<?= $arg['class'] ?>' id='<?= 'arg_'.$arg['name'] ?>'>
|
||||
<td class='argname'><?= $arg['name'] ?></td>
|
||||
<td class='<? echo $arg['is_required'] ? 'required' : 'optional'; ?>'><? echo $arg['is_required'] ? 'required' : 'optional'; ?></td>
|
||||
<td class='<?php echo $arg['is_required'] ? 'required' : 'optional'; ?>'><?php echo $arg['is_required'] ? 'required' : 'optional'; ?></td>
|
||||
<td class='argdesc'>
|
||||
<?= $arg['description'] ?>
|
||||
</td>
|
||||
</tr>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<td colspan='3' class='oauth_args'>
|
||||
<? if ($m['auth_options']['min_auth_level'] == 0) { ?>
|
||||
<?php if ($m['auth_options']['min_auth_level'] == 0) { ?>
|
||||
No additional authentication parameters are required.
|
||||
<? } elseif ($m['auth_options']['min_auth_level'] == 1) { ?>
|
||||
<?php } elseif ($m['auth_options']['min_auth_level'] == 1) { ?>
|
||||
<b>Plus required</b> <i>consumer_key</i> argument, assigned for your application.
|
||||
<? } else { ?>
|
||||
<?php } else { ?>
|
||||
<b>Plus required</b>
|
||||
standard OAuth Consumer signing arguments:
|
||||
<i>oauth_consumer_key, oauth_nonce, oauth_timestamp, oauth_signature,
|
||||
oauth_signature_method, oauth_version</i>.
|
||||
<? if ($m['auth_options']['min_auth_level'] == 3) { ?>
|
||||
<?php if ($m['auth_options']['min_auth_level'] == 3) { ?>
|
||||
<b>Plus required</b> <i>oauth_token</i> for Token authorization.
|
||||
<? } ?>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td colspan='3' class='returns'>
|
||||
@@ -81,9 +81,9 @@ $m = $vars['method'];
|
||||
<?= $m['returns'] ?>
|
||||
</td></tr>
|
||||
</table>
|
||||
<? if ($m['issue_id']) { ?>
|
||||
<?php if ($m['issue_id']) { ?>
|
||||
<div class='issue-comments' issue_id='<?= $m['issue_id'] ?>'></div>
|
||||
<? } ?>
|
||||
<?php } ?>
|
||||
</td>
|
||||
</tr></table>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
<body class='api'>
|
||||
<div class='okd_mid'>
|
||||
<div class='okd_top'>
|
||||
<? include 'installations_box.tpl.php'; ?>
|
||||
<?php include 'installations_box.tpl.php'; ?>
|
||||
<table cellspacing='0' cellpadding='0'><tr>
|
||||
<td class='apimenu'>
|
||||
<?= $vars['menu'] ?>
|
||||
|
||||
Reference in New Issue
Block a user