Skip to content

Add check-in for RSVPs - #2064

Open
wppoland wants to merge 4 commits into
GatherPress:developfrom
wppoland:feat/rsvp-check-in
Open

Add check-in for RSVPs#2064
wppoland wants to merge 4 commits into
GatherPress:developfrom
wppoland:feat/rsvp-check-in

Conversation

@wppoland

Copy link
Copy Markdown
Contributor

Fixes #2061

Depends on #2063, and is branched on top of it: the check-in bulk actions are unreachable from a browser until that nonce fix lands. Happy to rebase onto develop once it does, or to fold the two together if you would rather review one change.

Proposed changes:

  • New Rsvp\Check_In singleton recording which RSVPs actually turned up, in a gatherpress_checked_in comment meta holding the GMT arrival time. Absent means not checked in, so no existing RSVP needs backfilling and nothing changes for sites that never use it.
  • The RSVPs screen gains a Checked in column and Check in / Clear check-in bulk actions, gated on the same Rsvp::CAPABILITY as the moderation actions.

API, so nothing has to read the meta key directly: check_in(), clear(), is_checked_in(), get_check_in_time(), count_checked_in(). Two actions, gatherpress_rsvp_checked_in and gatherpress_rsvp_check_in_cleared, both documented in the docblocks.

Behaviour decisions, both raised in the issue:

  • No status gate. Someone who answered Not Attending and then showed up is exactly the case worth recording, and a gate would make the flow fail confusingly at the door.
  • Timestamp, not a boolean. Arrival times are free to keep and impossible to reconstruct later. A repeated check-in keeps the first time rather than moving it, because a second scan at the door is a duplicate, not a later arrival.
  • count_checked_in() counts approved RSVPs only, matching what the attendee list shows.

Deliberately out of scope here, as follow-ups if you want them: a block showing the checked-in count, a WP-CLI command, and per-attendee check-in from the event screen rather than the list.

Other information:

  • Have you written new tests for your changes, if applicable?

Test_Check_In adds 8 tests covering hooks, recording an arrival, the repeated check-in case, clearing, both writers refusing non-RSVP comments and IDs that do not exist, the approved-only count, the delete sweep, and both actions. Test_List_Table gains 3 more for the column in both states and the two bulk actions. Locally: 85 tests / 141 assertions green across those two classes, full suite unchanged at the 27 failures my single-site environment already produces on a clean checkout, PHPCS and PHPStan clean.

Testing instructions:

  1. On an event with two or more RSVPs, go to Events > RSVPs. The new Checked in column shows a dash for each.
  2. Tick both rows, choose Check in, click Apply. Both rows now show an arrival time in the site's timezone.
  3. Apply Check in again to the same rows and confirm the times do not move.
  4. Tick one row, choose Clear check-in, and confirm only that row goes back to a dash.
  5. As a user without moderate_comments, confirm the bulk actions are not offered.

Verified by hand on WP 7.0.2 / PHP 8.2.29 with 0.35.0-beta.1: bulk check-in from the browser wrote 2026-07-30 10:05:48 to both RSVPs, count_checked_in() returned 2, clearing removed both, and debug.log stayed empty throughout.

Credit (for release notes)

My WordPress.org username: motylanogha

display() emitted wp_nonce_field( Rsvp::COMMENT_TYPE ) before delegating
to parent::display(), which emits core's bulk-<plural> nonce under the
same default _wpnonce name. A browser sends both and PHP keeps the last,
so the handler saw core's nonce, accepted neither of its two known
actions, and returned early. Approve, Unapprove, Mark as Spam, Not Spam
and Delete all did nothing, with no notice explaining why.

process_bulk_action now accepts core's bulk nonce alongside the
comment-type one, and the row-action nonce for delete as before. The
comment-type field also moves to its own name so it can no longer shadow
core's, the way the sibling action nonce already did.
@github-actions

github-actions Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props motylanogha, mauteri.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown
Contributor

Test Coverage Report

Coverage checks need attention

PHP Coverage
PHP coverage check did not run.
JavaScript Coverage
JavaScript coverage check did not run.

This comment is automatically updated on each push.

wppoland and others added 3 commits July 31, 2026 14:16
…lk nonce

- Delete the display() override: both hidden nonce fields it emitted are
  redundant now that process_bulk_action() accepts core's bulk-<plural>
  nonce. _gatherpress_rsvp_action_nonce was read by nothing;
  _gatherpress_rsvp_nonce duplicated core's _wpnonce on the same form.
- Simplify nonce collection to read only _wpnonce, which every path (bulk
  form, view links, row-action delete) already carries.
- Test: derive bulk-<plural> from the table args instead of hardcoding it;
  drop the now-obsolete gatherpress-nonce-field and display() tests.
An RSVP records who intended to come. Nothing recorded who turned up, so
the gap between the two, which is the number organizers actually use
afterwards, was not available anywhere.

Check-In stores a GMT arrival timestamp in comment meta, so an absent
value means not checked in and no existing RSVP needs backfilling. A
repeated check-in keeps the first arrival time; clearing removes it. The
count is scoped to approved RSVPs, matching the attendee list.

The RSVPs screen gains a Checked in column and Check in / Clear check-in
bulk actions, gated on the same capability as the moderation actions.
The spell checker reads "mis-tap" as a typo, and the constructor only
runs during plugin bootstrap, so coverage never sees it. Resetting the
stored instance lets the test build one inside the coverage window.
@wppoland
wppoland force-pushed the feat/rsvp-check-in branch from 3de9df3 to 23c0959 Compare July 31, 2026 14:20
@mauteri mauteri added this to the 0.36.0 milestone Aug 3, 2026
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.

No record of who actually attended an event (check-in)

2 participants