Skip to content

Geocache lists: services/lists/* (OCDE) - #656

Draft
hxdimpf wants to merge 4 commits into
opencaching:masterfrom
OpencachingDeutschland:up/lists
Draft

hxdimpf wants to merge 4 commits into
opencaching:masterfrom
OpencachingDeutschland:up/lists

Conversation

@hxdimpf

@hxdimpf hxdimpf commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

The fifth of the changes from OpencachingDeutschland/okapi, cut into separate PRs (see #632). Supersedes #631.

Stacked on #655: the commits before the last two are #655 (draft logs), since both add to apisrv/installation, OkapiServiceRunner and the tests. Please review only the last two commits, f48a9b6 (the lists methods) and 46e2412 (fixes from building a client against them, see the comment below). Once #655 is merged, I'll rebase this PR so that only these commits remain.

Geocache lists, OCDE only:

  • Seven new methods (level 3) that manage the user's cache lists, as on the OCDE website:
    • services/lists/create, update, delete and query for the lists themselves;
    • services/lists/add_caches, remove_caches and get_caches for the caches on a list.
  • New flag has_lists in apisrv/installation, so clients can check before calling any of them.
  • On OCPL: has_lists is false, and all seven methods return HTTP 400 pointing to the flag. Their docs are marked ocde-specific. Nothing else changes for OCPL.
  • Tests: with --write, a list is created, the test cache added, the list read back, the cache removed and the list deleted.

Review history: this is the change from #631 (opened 2023-11-28), carried forward. It got one review round there, from @kojoty on 2026-05-12. His three points, all in this version:

  1. Is it tested with the current code and database? Yes, at the time on OCDE. This version is tested on OCDE and on OCPL, see below.
  2. The calls must be safe on nodes that don't support them, with a well-formed error. All seven methods return HTTP 400 outside OCDE (da51761 made create, update, delete and query consistent with the others; before, they returned success: false with HTTP 200), and has_lists is documented.
  3. Document it in the XML. All seven methods are documented and marked ocde-specific (a7cb0f0, in the <infotags> form @stefopl pointed out in Issue #601 fieldnotes #630).

New since that review: the tests.

Tested with the suite from #653 (this branch, including #654 and #655), on an OCDE installation and two OCPL installations (the official 2018 devel dump with all updates, on MariaDB 10.11 and on MariaDB 10.0), PHP 8.2-FPM behind Apache:

read-only --write
OCDE 13 passed, 0 failed 18 passed, 0 failed
OCPL, MariaDB 10.11 12 passed, 0 failed 15 passed, 0 failed
OCPL, MariaDB 10.0 12 passed, 0 failed 15 passed, 0 failed

On OCPL the list check is skipped, since the installation doesn't report has_lists. All changed PHP files pass php -l on PHP 7.4. No database changes.

@kojoty, @jrmajor, @andrixnet, @stefopl: could you review this? It changes OKAPI itself, so it stays open for review and gives OCPL time to look before it is merged.

Closes #627. Part of #368 (not covered here: a cachelists field in the geocache methods, and bookmarking other users' lists with a password).

@hxdimpf

hxdimpf commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

This is the change from #631, reviewed by @kojoty in May 2026; his three points are addressed (see the review history above), and only the tests are new. Unless someone raises an objection, I'll merge this on Monday, 2 November 2026, right after #654 and #655, rebased onto them. Reviews of the new parts are welcome until then.

@hxdimpf
hxdimpf marked this pull request as draft October 19, 2026 14:37
@hxdimpf

hxdimpf commented Oct 19, 2026

Copy link
Copy Markdown
Contributor Author

Change of plan, after @jrmajor's comment in #657: the diffs of the stacked PRs are too large to review, because they include the PRs before them. This PR is now a draft. It comes up for review once #655 is merged, and then shows only its own changes. The 2 November date above no longer applies to it; I'll give a new date when it's out of draft.

$result['has_lists'] = Settings::get('OC_BRANCH') == 'oc.de';
if (Settings::get('OC_BRANCH') == 'oc.de') {
$result['cache_types'] = Okapi::get_local_cachetypes();
$result['log_types'] = Okapi::get_submittable_logtype_names();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what makes these two OCDE specific?
or should I rephrase: why should these be OCDE specific?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

These flags tell a client what an installation supports. A client such as c:geo reads them from apisrv/installation and, where a flag is false, doesn't call those methods and hides the feature in its UI for that site.

Both features exist only on the OCDE website: the OCPL website has no field notes (drafts) and no cache lists, so has_draft_logs and has_lists are false there and clients won't offer them. If OCPL gets either feature, the flag becomes true there as soon as the service supports it, and clients pick it up without any change on their side.

cache_types and log_types belong to the draft logs package (#655) and are returned only with it. On OCPL they would be misleading as they stand: OKAPI has one fixed cache type list for all OCPL nodes, while each node configures its own types (#579), and the log type list includes "Archived", which can't be logged on the OCPL website. Making them correct per node would be part of #579.

case 'attrnames': /* handled separately */ break;
case 'latest_logs': /* handled separately */ break;
case 'my_notes': /* handles separately */ break;
case 'user_coords': /* handled separately */ break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this apparently contains the user_coords commits as we

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@hxdimpf

hxdimpf commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

I built a small client against the lists methods (create a list from a cache, add and remove caches offline and send them later, edit, delete) and compared each method with what the website's own list form does. That turned up bugs and a few things that didn't match the docs. Commit ecb0341 fixes them; the PR is still a draft, so nothing outside changes.

Bugs

  • Descriptions were stored unescaped. The website keeps list descriptions as HTML and runs them through HTMLPurifier. The OKAPI methods stored the text as given, so HTML sent through OKAPI showed up as HTML on the website's list page. list_description is now plain text, stored HTML-escaped with <br /> for line breaks.
  • add_caches failed on every watched list. OCDE's trigger on cache_list_items updates caches (watch statistics) when the list is watched, and MySQL refuses that inside an INSERT … SELECT … FROM caches (error 1442). The cache ids are now looked up first. remove_caches is changed the same way.
  • create ignored list_watch: the code read a parameter is_watched.
  • update couldn't remove a description (empty() skipped an empty value).

Same rules as the website (cachelist.class.php)

  • List names: trimmed, at most 80 characters, unique among the user's lists, at least 10 characters for a public list.
  • add_caches adds only caches OKAPI shows (Available, Temporarily unavailable, Archived); the website also adds only caches the user may see.
  • Passwords: up to 80 characters as on the website (the code cut them to 16), only for private lists.

Results (as discussed for save_user_coords in #654)

  • No success/message fields any more; HTTP 200 means success.
  • query returns an array, as its docs always said. is_public is now status (0/2/3, the same values as list_status). New: the user's own is_watched, the password of a private list, and include_caches=true, which adds cache_codes to every list, so a client gets all lists with their caches in one request.
  • get_caches returns cache_codes as an array, like the search methods.
  • create and delete return list_id; update returns the list after the change.

Docs rewritten: the old ones linked with ::services/…, which OKAPI doesn't expand. They now also say that last_modified changes on every add, remove and edit (also on the website), so a client that keeps lists offline only needs to re-read the lists that changed.

Tests: the suite's lists check now covers the name rules, the query shape, the escaped description, the add/remove counts, update and delete. OCDE: lists check passes (the two status-log checks fail on this base as before, fixed upstream by #671); OCPL and OCPL on MariaDB 10.0: 12/0 and 16/0 (has_lists is false there, lists skipped). PHP 7.4 lint OK. #657 is rebased on top.

- services/draftlogs/upload_fieldnotes takes a field notes file as written by
  Garmin devices and apps (GC log type names, records of other platforms
  included), maps the log types to the website's draft types and stores the
  OC records as drafts; it returns their draft_ids.
- services/draftlogs/query and services/draftlogs/delete list and remove the
  user's drafts.
- services/apisrv/installation: has_draft_logs, and on OCDE cache_types and
  log_types.

OCDE only: OCPL has no draft logs table, so the services refuse to run there
and has_draft_logs is false. Tests: query on the read-only level; upload,
query and delete on --write.
log_types is the list services/logs/submit accepts, the same on every
installation, not what can be submitted there; field notes use their
own log type names. The cache type example is Multi, not Multi-cache.
services/lists/create, update, delete, query, add_caches, remove_caches and
get_caches manage the user's cache lists, as on the OCDE website.
services/apisrv/installation reports has_lists.

OCDE only (the services refuse to run elsewhere; has_lists is false there).
Tests: --write creates a list, adds and removes the cache, deletes the list.
…without success flags

- ListsCommon: ownership check, the website's name rules (unique per user, 80 characters,
  10 for public lists), plain-text description stored escaped (the website keeps HTML),
  password up to 80 characters for private lists, pipe-separated codes
- query: an array as documented; status (0/2/3) instead of is_public, the user's own
  is_watched, the password of a private list, optional include_caches with cache_codes
- create: list_watch (the code read is_watched), list_id only
- update: parameters left out keep their value, an empty description removes it, the name
  rules also on a status change; returns the updated list
- add_caches: only caches OKAPI shows, as the website allows only visible caches
- get_caches: cache_codes as an array
- docs rewritten (links via methodref), suite check extended
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Please add services/lists functions

3 participants