Skip to content

Commit d5f8eaa

Browse files
committed
issue#627 listservices
1 parent 2333616 commit d5f8eaa

File tree

15 files changed

+769
-0
lines changed

15 files changed

+769
-0
lines changed

okapi/core/OkapiServiceRunner.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ class OkapiServiceRunner
4343
'services/caches/formatters/garmin',
4444
'services/caches/formatters/ggz',
4545
'services/caches/map/tile',
46+
'services/lists/add_caches',
47+
'services/lists/create',
48+
'services/lists/delete',
49+
'services/lists/get_caches',
50+
'services/lists/remove_caches',
51+
'services/lists/query',
52+
'services/lists/update',
4653
'services/logs/capabilities',
4754
'services/logs/delete',
4855
'services/logs/edit',
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace okapi\services\lists\add_caches;
4+
5+
use okapi\core\Db;
6+
use okapi\core\Okapi;
7+
use okapi\core\Request\OkapiRequest;
8+
use okapi\Settings;
9+
use okapi\core\Exception\InvalidParam;
10+
11+
class WebService
12+
{
13+
public static function options()
14+
{
15+
return array(
16+
'min_auth_level' => 3
17+
);
18+
}
19+
20+
public static function call(OkapiRequest $request)
21+
{
22+
$result = array(
23+
'success' => false
24+
);
25+
26+
$user_id = $request->token->user_id;
27+
28+
$listId = $request->get_parameter('list_id');
29+
$cacheCodes = $request->get_parameter('cache_codes');
30+
31+
if (empty($listId)) {
32+
throw new InvalidParam('list_id', 'list_id is mandatory and must not be empty.');
33+
}
34+
35+
if (empty($cacheCodes)) {
36+
throw new InvalidParam('cache_codes', 'cache_codes is mandatory and must not be empty.');
37+
}
38+
39+
$cacheCodesArray = array_unique(explode('|', $cacheCodes));
40+
41+
// Check the length
42+
if (count($cacheCodesArray) > 500) {
43+
throw new InvalidParam('cache_codes', 'The number of cache codes exceeds the limit of 500.');
44+
}
45+
46+
// Escape cache codes and build the SQL query
47+
$escapedCacheCodes = implode("','", array_map('\okapi\core\Db::escape_string', $cacheCodesArray));
48+
49+
// Fetch cache_ids from the caches table using INSERT IGNORE
50+
$rs = Db::query("
51+
INSERT IGNORE INTO cache_list_items (cache_list_id, cache_id)
52+
SELECT '$listId', cache_id
53+
FROM caches
54+
WHERE wp_oc IN ('$escapedCacheCodes')
55+
");
56+
57+
$insertedCount = $rs->rowCount(); // Get the number of affected rows
58+
59+
$result = array(
60+
'success' => true,
61+
'added_count' => $insertedCount
62+
);
63+
64+
return Okapi::formatted_response($request, $result);
65+
}
66+
}
67+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<xml>
2+
<brief>Add Caches To List</brief>
3+
<issue-id>627</issue-id>
4+
<desc>
5+
<p>This method is used to add geocaches to an existing list.</p>
6+
</desc>
7+
<req name="list_id">
8+
<p>The id of a list. List IDs can be obtained by ::service/lists/query</p>
9+
</req>
10+
<req name="cache_codes">
11+
<p>A pipe separated list of cache_codes to be added to the list.</p>
12+
<p>Up to 500 geoaches can be added to the list by one request to
13+
this method</p>
14+
</req>
15+
<common-format-params/>
16+
<returns>
17+
<p>A dictionary of the following structure:</p>
18+
<ul>
19+
<li>success - true</li>
20+
<li>added_count - number of geocaches added to the list</li>
21+
</ul>
22+
</returns>
23+
</xml>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace okapi\services\lists\create;
4+
5+
use okapi\core\Db;
6+
use okapi\core\Okapi;
7+
use okapi\core\Request\OkapiRequest;
8+
use okapi\Settings;
9+
use okapi\core\Exception\InvalidParam;
10+
11+
class WebService
12+
{
13+
14+
public static function options()
15+
{
16+
return array(
17+
'min_auth_level' => 3
18+
);
19+
}
20+
21+
public static function call(OkapiRequest $request)
22+
{
23+
$result = array(
24+
'success' => false
25+
);
26+
27+
if (Settings::get('OC_BRANCH') == 'oc.de')
28+
{
29+
$user_id = $request->token->user_id;
30+
31+
$listName = $request->get_parameter('list_name');
32+
$listDescription = $request->get_parameter('list_description');
33+
$listStatus = $request->get_parameter('list_status');
34+
$isWatched = $request->get_parameter('is_watched');
35+
$listPassword = $request->get_parameter('list_password');
36+
37+
if (empty($listName)) {
38+
throw new InvalidParam('list_name', 'list_name is mandatory and must not be empty.');
39+
}
40+
41+
$insertFields = array(
42+
'name' => Db::escape_string($listName),
43+
'user_id' => Db::escape_string($user_id)
44+
);
45+
46+
if (!empty($listDescription)) {
47+
$insertFields['description'] = Db::escape_string($listDescription);
48+
}
49+
50+
if ($listStatus !== null && $listStatus !== '') {
51+
$listStatus = (int)$listStatus;
52+
if (!in_array($listStatus, [0, 2, 3])) {
53+
throw new InvalidParam('list_status', 'list_status must be a valid value (0, 2, 3).');
54+
}
55+
$insertFields['is_public'] = $listStatus;
56+
57+
// Handle list_password only if list_status is 0 (private)
58+
if ($listStatus == 0) {
59+
if (isset($listPassword) && $listPassword !== '') {
60+
$insertFields['password'] = substr(Db::escape_string($listPassword), 0, 16);
61+
}
62+
}
63+
}
64+
65+
$columns = implode(', ', array_keys($insertFields));
66+
$values = "'" . implode("', '", $insertFields) . "'";
67+
68+
$insertQuery = "INSERT INTO cache_lists ($columns) VALUES ($values)";
69+
Db::query($insertQuery);
70+
71+
$listId = Db::last_insert_id();
72+
73+
// Handle is_watched
74+
if ($isWatched !== null && $isWatched !== '') {
75+
$isWatched = (int)$isWatched;
76+
if (!in_array($isWatched, [0, 1])) {
77+
throw new InvalidParam('is_watched', 'is_watched must be a valid value (0, 1).');
78+
}
79+
80+
// Insert a new record
81+
Db::query("INSERT INTO cache_list_watches (cache_list_id, user_id, is_watched) VALUES (LAST_INSERT_ID(), '$user_id', $isWatched)");
82+
}
83+
84+
$result = array(
85+
'success' => true,
86+
'message' => 'Cache list created successfully.',
87+
'list_id' => $listId
88+
);
89+
}
90+
return Okapi::formatted_response($request, $result);
91+
}
92+
}
93+

okapi/services/lists/create/docs.xml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<xml>
2+
<brief>Create Cache List</brief>
3+
<issue-id>627</issue-id>
4+
<desc>
5+
<p>This method creates a list for adding geocaches to. Only the list is created,
6+
no geocaches are added to it during the create. For adding and removing geocaches
7+
to/from the list use specific methods within the ::services/lists namespace
8+
</p>
9+
</desc>
10+
<req name="list_name">
11+
<p>A string, defining the human readable name of the list</p>
12+
</req>
13+
<opt name="list_description">
14+
<p>A string via which a description of the list's purpose and
15+
potentially content can be defined.</p>
16+
</opt>
17+
<opt name="list_status">
18+
<p>This parameter can take the following values:
19+
<ul>
20+
<li><b>0</b> - The list is private</li>
21+
<li><b>2</b> - The list is public</li>
22+
<li><b>3</b> - The list is public and is visible in cache listings</li>
23+
</ul>
24+
</p>
25+
</opt>
26+
<opt name="list_password">
27+
<p>This parameter allows to add a password to a private list. The password
28+
has no meaning if the list is public. The first 16 alphanumeric characters
29+
are used as a password. No encryption is performed in the password, instead
30+
it is stored in the database in plain text.</p>
31+
</opt>
32+
<opt name="list_watch">
33+
<p>A boolean, either 0, 1, false, true. If set to 1 or true
34+
a user wants to get a notification if the content of the list
35+
changes.</p>
36+
</opt>
37+
<common-format-params/>
38+
<returns>
39+
<p>A dictionary of the following structure:</p>
40+
<ul>
41+
<li>success - true</li>
42+
<li>message - Cache list created successfully</li>
43+
<li>list_id - The id of the list by which it can be referenced</li>
44+
</ul>
45+
</returns>
46+
</xml>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace okapi\services\lists\delete;
4+
5+
use okapi\core\Db;
6+
use okapi\core\Okapi;
7+
use okapi\core\Request\OkapiRequest;
8+
use okapi\Settings;
9+
use okapi\core\Exception\InvalidParam;
10+
11+
class WebService
12+
{
13+
14+
public static function options()
15+
{
16+
return array(
17+
'min_auth_level' => 3
18+
);
19+
}
20+
21+
public static function call(OkapiRequest $request)
22+
{
23+
$result = array(
24+
'success' => false
25+
);
26+
27+
if (Settings::get('OC_BRANCH') == 'oc.de')
28+
{
29+
$user_id = $request->token->user_id;
30+
31+
$listId = $request->get_parameter('list_id');
32+
33+
if (empty($listId) || !is_numeric($listId)) {
34+
throw new InvalidParam('list_id', 'list_id is mandatory and must be numeric.');
35+
}
36+
37+
// Check if the list exists
38+
$countQuery = Db::query("SELECT COUNT(*) AS count FROM cache_lists WHERE id = '$listId' AND user_id = '$user_id'");
39+
$listExists = Db::fetch_assoc($countQuery)['count'];
40+
if ($listExists == 0) {
41+
throw new InvalidParam('list_id', 'The specified list does not exist.');
42+
}
43+
44+
// Proceed with the deletion process
45+
Db::query("DELETE FROM cache_lists WHERE id = '$listId'");
46+
Db::query("DELETE FROM cache_list_watches WHERE cache_list_id = '$listId'");
47+
Db::query("DELETE FROM cache_list_items WHERE cache_list_id = '$listId'");
48+
49+
$result = array(
50+
'success' => true,
51+
'message' => 'Cache list deleted successfully.'
52+
);
53+
}
54+
return Okapi::formatted_response($request, $result);
55+
}
56+
}
57+

okapi/services/lists/delete/docs.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<xml>
2+
<brief>Delete Cache List</brief>
3+
<issue-id>627</issue-id>
4+
<desc>
5+
<p>This method is used to delete a geocache list. The geocache objects
6+
that were on the list will not be touched in any way.</p>
7+
</desc>
8+
<req name="list_id">
9+
<p>The id of the list to be removed. IDs can be obtained by
10+
the service ::services/lists/query</p>
11+
</req>
12+
<common-format-params/>
13+
<returns>
14+
<p>A dictionary of the following structure:</p>
15+
<ul>
16+
<li>success - true</li>
17+
<li>message - cache list deleted successfully</li>
18+
</ul>
19+
</returns>
20+
</xml>
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace okapi\services\lists\get_caches;
4+
5+
use okapi\core\Db;
6+
use okapi\core\Okapi;
7+
use okapi\core\Request\OkapiRequest;
8+
use okapi\Settings;
9+
use okapi\core\Exception\InvalidParam;
10+
11+
class WebService
12+
{
13+
public static function options()
14+
{
15+
return array(
16+
'min_auth_level' => 3
17+
);
18+
}
19+
20+
public static function call(OkapiRequest $request)
21+
{
22+
$result = array(
23+
'success' => false
24+
);
25+
26+
$user_id = $request->token->user_id;
27+
$listId = $request->get_parameter('list_id');
28+
29+
if (empty($listId)) {
30+
throw new InvalidParam('list_id', 'list_id is mandatory and must not be empty.');
31+
}
32+
33+
// Fetch cache_ids associated with the specified list
34+
$cacheIdsArray = Db::select_column("
35+
SELECT cache_id
36+
FROM cache_list_items
37+
WHERE cache_list_id = '$listId'
38+
");
39+
40+
$cacheCount = count($cacheIdsArray);
41+
42+
// Fetch cache_codes based on cache_ids
43+
$cacheCodesArray = array();
44+
45+
if (!empty($cacheIdsArray)) {
46+
$cacheIds = implode(',', $cacheIdsArray);
47+
$cacheCodesArray = Db::select_column("
48+
SELECT wp_oc
49+
FROM caches
50+
WHERE cache_id IN ($cacheIds)
51+
", $cacheIdsArray);
52+
}
53+
54+
$result = array(
55+
'success' => true,
56+
'cache_codes' => implode('|', $cacheCodesArray),
57+
'cache_count' => $cacheCount
58+
);
59+
60+
return Okapi::formatted_response($request, $result);
61+
}
62+
}
63+

0 commit comments

Comments
 (0)