Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions okapi/core/OkapiServiceRunner.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,18 @@ class OkapiServiceRunner
'services/caches/geocaches',
'services/caches/mark',
'services/caches/save_personal_notes',
'services/caches/save_user_coords',
'services/caches/formatters/gpx',
'services/caches/formatters/garmin',
'services/caches/formatters/ggz',
'services/caches/map/tile',
'services/lists/add_caches',
'services/lists/create',
'services/lists/delete',
'services/lists/get_caches',
'services/lists/remove_caches',
'services/lists/query',
'services/lists/update',
'services/logs/capabilities',
'services/logs/delete',
'services/logs/edit',
Expand Down
108 changes: 108 additions & 0 deletions okapi/services/caches/save_user_coords/WebService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace okapi\services\caches\save_user_coords;

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

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

public static function call(OkapiRequest $request)
{

$user_coords = $request->get_parameter('user_coords');
if ($user_coords == null)
throw new ParamMissing('user_coords');
$parts = explode('|', $user_coords);
if (count($parts) != 2)
throw new InvalidParam('user_coords', "Expecting 2 pipe-separated parts, got ".count($parts).".");
foreach ($parts as &$part_ref)
{
if (!preg_match("/^-?[0-9]+(\.?[0-9]*)$/", $part_ref))
throw new InvalidParam('user_coords', "'$part_ref' is not a valid float number.");
$part_ref = floatval($part_ref);
}
list($latitude, $longitude) = $parts;

# Verify cache_code

$cache_code = $request->get_parameter('cache_code');
if ($cache_code == null)
throw new ParamMissing('cache_code');
$geocache = OkapiServiceRunner::call(
'services/caches/geocache',
new OkapiInternalRequest($request->consumer, $request->token, array(
'cache_code' => $cache_code,
'fields' => 'internal_id'
))
);
$cache_id = $geocache['internal_id'];

self::update_notes($cache_id, $request->token->user_id, $latitude, $longitude);

$ret_value = 'ok';

$result = array(
'status' => $ret_value
);
return Okapi::formatted_response($request, $result);
}

private static function update_notes($cache_id, $user_id, $latitude, $longitude)
{
/* See:
*
* - https://github.com/OpencachingDeutschland/oc-server3/tree/development/htdocs/src/Oc/Libse/CacheNote
* - https://www.opencaching.de/okapi/devel/dbstruct
*/

$rs = Db::query("
select max(id) as id
from coordinates
where
type = 2 -- personal note
and cache_id = '".Db::escape_string($cache_id)."'
and user_id = '".Db::escape_string($user_id)."'
");
$id = null;
if($row = Db::fetch_assoc($rs)) {
$id = $row['id'];
}
if ($id == null) {
Db::query("
insert into coordinates (
type, latitude, longitude, cache_id, user_id
) values (
2,
'".Db::escape_string($latitude)."',
'".Db::escape_string($longitude)."',
'".Db::escape_string($cache_id)."',
'".Db::escape_string($user_id)."'
)
");
} else {
Db::query("
update coordinates
set latitude = '".Db::escape_string($latitude)."',
longitude = '".Db::escape_string($longitude)."',
where
id = '".Db::escape_string($id)."'
and type = 2
");
}
}

}
29 changes: 29 additions & 0 deletions okapi/services/caches/save_user_coords/docs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<xml>
<brief>Update personal coordinates of a geocache</brief>
<issue-id>629</issue-id>
<desc>
<p>This method allows your users to update the coordinates of their
personal geocache coordinates.</p>

<p>Current personal coordinates for the geocache can be retrieved
using the <b>alt_wpts</b> field in the
<a href="%OKAPI:methodargref:services/caches/geocache#fields%">services/caches/geocache</a>
method.</p>
</desc>
<req name='cache_code'>
<p>Code of the geocache</p>
</req>
<req name='user_coords'>
<p>The coordinates are defined by a string in the format "lat|lon"</p>
<p>Use positive numbers for latitudes in the northern hemisphere and longitudes
in the eastern hemisphere (and negative for southern and western hemispheres
accordingly). These are full degrees with a dot as a decimal point (ex. "48.7|15.89").</p>
</req>
<common-format-params/>
<returns>
<p>A dictionary of the following structure:</p>
<ul>
<li>status - ok</li>
</ul>
</returns>
</xml>
77 changes: 77 additions & 0 deletions okapi/services/lists/add_caches/WebService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace okapi\services\lists\add_caches;

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

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

public static function call(OkapiRequest $request)
{
if (Settings::get('OC_BRANCH') != 'oc.de')
throw new BadRequest('This method is not supported in this OKAPI installation.');

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kojoty this is the guard for functions that are platform specific

$user_id = $request->token->user_id;

$list_id = $request->get_parameter('list_id');
$cache_codes = $request->get_parameter('cache_codes');

if (empty($list_id)) {
throw new InvalidParam('list_id', 'list_id is mandatory and must not be empty.');
}

if (empty($cache_codes)) {
throw new InvalidParam('cache_codes', 'cache_codes is mandatory and must not be empty.');
}

// Verify list ownership
$count = Db::select_value("
SELECT COUNT(*)
FROM cache_lists
WHERE id = '".Db::escape_string($list_id)."'
AND user_id = '".Db::escape_string($user_id)."'
");
if ($count == 0) {
throw new InvalidParam('list_id', 'The specified list does not exist or does not belong to you.');
}

$cache_codes_array = array_unique(explode('|', $cache_codes));

// Check the length
if (count($cache_codes_array) > 500) {
throw new InvalidParam('cache_codes', 'The number of cache codes exceeds the limit of 500.');
}

// Escape cache codes and build the SQL query
$escaped_cache_codes = implode("','", array_map('\okapi\core\Db::escape_string', $cache_codes_array));

// Fetch cache_ids from the caches table using INSERT IGNORE
$rs = Db::query("
INSERT IGNORE INTO cache_list_items (cache_list_id, cache_id)
SELECT '".Db::escape_string($list_id)."', cache_id
FROM caches
WHERE wp_oc IN ('$escaped_cache_codes')
");

$inserted_count = $rs->rowCount();

$result = array(
'success' => true,
'added_count' => $inserted_count
);

return Okapi::formatted_response($request, $result);
}
}
23 changes: 23 additions & 0 deletions okapi/services/lists/add_caches/docs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<xml>
<brief>Add Caches To List</brief>
<issue-id>627</issue-id>
<desc>
<p>This method is used to add geocaches to an existing list.</p>
</desc>
<req name="list_id">
<p>The id of a list. List IDs can be obtained by ::services/lists/query</p>
</req>
<req name="cache_codes">
<p>A pipe separated list of cache_codes to be added to the list.</p>
<p>Up to 500 geoaches can be added to the list by one request to
this method</p>
</req>
<common-format-params/>
<returns>
<p>A dictionary of the following structure:</p>
<ul>
<li>success - true</li>
<li>added_count - number of geocaches added to the list</li>
</ul>
</returns>
</xml>
94 changes: 94 additions & 0 deletions okapi/services/lists/create/WebService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace okapi\services\lists\create;

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

class WebService
{

public static function options()
{
return array(
'min_auth_level' => 3
);
}

public static function call(OkapiRequest $request)
{
$result = array(
'success' => false
);

if (Settings::get('OC_BRANCH') == 'oc.de')
{
$user_id = $request->token->user_id;

$list_name = $request->get_parameter('list_name');
$list_description = $request->get_parameter('list_description');
$list_status = $request->get_parameter('list_status');
$is_watched = $request->get_parameter('is_watched');
$list_password = $request->get_parameter('list_password');

if (empty($list_name)) {
throw new InvalidParam('list_name', 'list_name is mandatory and must not be empty.');
}

$insert_fields = array(
'name' => Db::escape_string($list_name),
'user_id' => Db::escape_string($user_id)
);

if (!empty($list_description)) {
$insert_fields['description'] = Db::escape_string($list_description);
}

if ($list_status !== null && $list_status !== '') {
$list_status = (int)$list_status;
if (!in_array($list_status, [0, 2, 3])) {
throw new InvalidParam('list_status', 'list_status must be a valid value (0, 2, 3).');
}
$insert_fields['is_public'] = $list_status;

// Handle list_password only if list_status is 0 (private)
if ($list_status == 0) {
if (isset($list_password) && $list_password !== '') {
$insert_fields['password'] = Db::escape_string(substr($list_password, 0, 16));
}
}
}

$columns = implode(', ', array_keys($insert_fields));
$values = "'" . implode("', '", $insert_fields) . "'";

$insert_query = "INSERT INTO cache_lists ($columns) VALUES ($values)";
Db::query($insert_query);

$list_id = Db::last_insert_id();

// Handle is_watched
if ($is_watched !== null && $is_watched !== '') {
$is_watched = (int)$is_watched;
if (!in_array($is_watched, [0, 1])) {
throw new InvalidParam('is_watched', 'is_watched must be a valid value (0, 1).');
}

Db::query("
INSERT INTO cache_list_watches (cache_list_id, user_id, is_watched)
VALUES ('".Db::escape_string($list_id)."', '".Db::escape_string($user_id)."', '".Db::escape_string($is_watched)."')
");
}

$result = array(
'success' => true,
'message' => 'Cache list created successfully.',
'list_id' => $list_id
);
}
return Okapi::formatted_response($request, $result);
}
}
Loading