feat: #3631523: Record where each Mapillary API call was made from

Adds a "Location" column to the report of Mapillary API calls, so each entry says where the call was made from: the path of the page request, or the script and command on the command line.

Changes

  • mapillary_logs_api_call gets a location column: varchar(255), not null, default ''.
  • MapillaryApiCallLog::record() fills it itself. MapillaryApiCallEvent, the client methods and MapillaryLogsService::logApiCall() keep their signatures.
    • In a page request: the path from request_stack, without the query string, so tokens or codes in query parameters are not stored.
    • On the command line: the script and the command, for example drush mapillary:thumbnails-refresh, read from $_SERVER['argv'] since Drush is not a dependency. The command is the first argument that is not an option, a site alias or the value of a Drush global option given as the next argument: drush --uri example.com cron gives drush cron. The options are those that take a value in Drush's PreflightArgs::optionsWithValues() (-r, --root, -l, --uri, -c, --config, --alias-path, --include, --drush-coverage, --strict), which Drush uses to find the command before its container is built. As in Drush, the next argument is not taken as a value when it is an option itself.
    • Queue items processed by drush cron or drush queue:run get the command, items processed by a cron URL get its path, and items processed by Automated Cron get the path of the page after which cron ran. The cron key is part of the cron URL path; dblog stores it too, and both reports need "View site reports".
  • request_stack is a new optional fourth constructor argument of MapillaryApiCallLog. A container built before the update passes three arguments; only the location of a page request then stays empty, the command line location does not need the request stack.
  • record() checks once per request whether the column exists and leaves it out of the insert while it is missing, for the same reason it checks the table: a failed insert would abort an open PostgreSQL transaction.
  • Views data for location: field, string filter, argument and sort. The shipped view views.view.mapillary_api_calls shows it after "Endpoint".
  • CHANGELOG.md has an "Added" entry under [Unreleased]; AGENTS.md describes the column.

Upgrade

  • mapillary_logs_update_11102() adds the column with a frozen copy of its definition. Existing entries keep an empty location.
  • mapillary_logs_post_update_api_call_location() adds the field to an existing mapillary_api_calls view when Views is on and the view has no location field yet. It takes the field and its table column settings from the shipped view and inserts them after "Endpoint", or at the end when the site removed the endpoint field. The rest of the view, including changes made by the site, is kept.
  • On a site coming from 1.0.0-alpha5 or older, mapillary_logs_update_11101() still creates the table with the 1.0.0-alpha6 definition and 11102 adds the column; the view installed by mapillary_logs_post_update_api_call_report() already has the field, so the new post update skips it.
  • Both functions report when there is nothing to do, so a second run changes nothing.

Testing

ApiCallReportTest gets four tests:

  • testLocationOfPageRequest(): the path without the query string.
  • testLocationOnCommandLine(): the Drush script as vendor/bin/drush and as drush.php, a command without arguments, options with their values in the next argument and with =, an option whose value is missing, and a command followed by its own argument.
  • testRecordingWithoutLocationColumn(): a call is recorded, with no error logged, before the column exists.
  • testLocationUpdatePath(): from the 1.0.0-alpha6 table and view, with an endpoint label changed by the site. Checks the column, the order of the fields and of the table columns and info, the kept label, and a second run.

MapillaryLogsAdminFunctionalTest::testApiCallReport() checks the "Location" table header.

Run locally on Drupal 11 with PostgreSQL: the unit, kernel and functional tests of mapillary_logs pass. The deprecations they report come from Geofield's @Constraint annotation and from core, not from this change. phpcs (Drupal, DrupalPractice) and PHPStan level 6 report nothing new on the changed files.

Not run locally: the rest of the suite, Drupal 12, and the update rehearsal from 1.0.0-alpha6.

Closes #3631523

Merge request reports

Loading
Loading