Skip to content

Releases: Awebbtx/Production_SchoolBooth_WP_plugin

v3.4.1

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 11:04

Schoolbooth Photo Manager v3.4.1

Bug-fix release on top of v3.4.0.

Fixed

  • Download All / Delete All buttons on the portal were inert. Both buttons
    now work. They iterate the visible photo cards and reuse the existing
    per-photo download URLs / schoolbooth_delete_photo endpoint, so no new
    server endpoints or permissions were added.
    • "Download All" spaces the per-photo downloads ~800 ms apart so browsers
      don't suppress the burst, shows a live (done/total) progress label,
      then refreshes the page so download-remaining counters update.
    • "Delete All" requires a confirmation (Delete ALL photos for this access code? This cannot be undone.), then fires the existing single-photo
      AJAX delete for each card. Still admin-only (manage_options).

Compatibility

Fully backward compatible with v3.4.0. No data model changes, no migration.

v3.4.0

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 10:17

Schoolbooth Photo Manager v3.4.0

Multi-photo sessions (WP foundation)

This release adds server-side support for grouping photos into open-ended
sessions. The corresponding photobooth client changes ("Single shot" /
"Multi shot" mode toggle + "Start New Session" button) will land in the
next photobooth build; v3.4.0 is the WordPress data-model + audit-grouping
groundwork and is fully backward compatible with single-shot uploads.

How sessions are represented

The existing one-access-code-per-photo data model is unchanged. A new
optional session_id field tags each photo with the session it was
captured in. The booth controls the session lifetime entirely:

  • Single-shot mode: photos are uploaded with no session_id -- v3.3.x
    behavior preserved exactly.
  • Multi-shot mode: the booth generates a session_id once, reuses one
    shared access code
    for every photo in the session, and tags every
    upload with the same session_id. The session ends when the operator
    presses "Start New Session" on the booth, at which point the booth
    prints one session QR (no per-photo QRs) and rotates to a new
    session_id + access code.

Because the access code is shared, the existing portal get_photos_data()
already returns the whole session as a gallery -- no template changes
needed. Consent is keyed by the access code, so one consent covers all
session photos automatically.

What changed in WordPress

  • POST /schoolbooth/v1/ingest accepts a new optional session_id
    field. Format: ^[a-z0-9_]{1,64}$ (lowercase alphanumeric + underscore,
    max 64 chars). Invalid values are silently dropped.
  • access_codes.json records now persist session_id when supplied.
  • All audit events related to a photo now carry session_id in
    their data payload when known: upload, access_code_gen,
    download_attempt (success + every failure reason), form_submission
    (success + validation_failed), manual_delete.
  • Audit Log viewer shows a clickable session_id chip on every row
    that has one -- clicking it filters the log to just that session's
    events (uses the existing free-text search filter).
  • CSV export now includes a session_id column.

What does NOT change

  • Single-shot uploads remain identical at the wire level and in the
    data file.
  • No data migration required. Existing photos have no session_id and
    continue to work as today.
  • Consent cookie keying is unchanged (still keyed by access code).
  • Per-photo download counters and limits are unchanged. In a multi-shot
    session, each photo retains its own counter.

Upgrade

Upload v3.4.0 over v3.3.0 from Plugins -> Add New -> Upload Plugin.
No reconfiguration needed.

Next: photobooth client (separate release)

The booth-side changes (capture-mode toggle, open-ended multi-shot loop,
"Start New Session" button, single-QR print layout) will ship in a
photobooth update. Until then, the booth continues to upload as
single-shot and v3.4.0 behaves exactly like v3.3.0.

v3.3.0

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:53

Schoolbooth Photo Manager v3.3.0

Auditing is now stable. This release removes the diagnostic
scaffolding from v3.2.7-v3.2.9 and ships a real, full-featured audit
log viewer.

What is new

Searchable, filterable event log

The All Events tab now has a filter bar with:

  • Free-text search across the entire event payload (file name,
    access code, consent name / email, IP, reason, source, JSON data).
  • Event type dropdown (upload, access code generated, download
    attempt, consent form submission, manual delete, auto delete).
  • Status dropdown (success / failure).
  • Date range (From / To, calendar pickers).
  • Reset button to clear all filters.
  • Live "N matching events" count.

Results are paginated 50 per page. Every row has a + toggle that
expands the full event JSON inline, including digests, prev_digest,
data payload, and post ID.

CSV export

The Export CSV button on the filter bar exports the currently
filtered set
(not all events, not just the visible page) to a UTF-8
CSV with a BOM so Excel opens it cleanly. Columns:

post_id, timestamp_utc, event_type, status, user_id, ip_address, file, access_code, consent_name, consent_email, email_domain, reason, source, downloads_used, digest, prev_digest, data_json

Capability check: only users with manage_options or
schoolbooth_audit_read can export. Nonce-protected
(admin-post.php).

Cleanup of v3.2.7-v3.2.9 diagnostics

  • The "Diagnostic Log" admin tab is removed.
  • The fallback file logger no longer writes a copy of every event.
    It now only writes a line if wp_insert_post() AND the direct
    $wpdb->insert() fallback both fail (i.e. the event was
    unrecoverable). This file is rare/empty in normal operation.
  • All _via, _inserted_post_id, and per-event success markers
    are gone.

The audit CPT slug fix from v3.2.9 (sb_audit_log, 12 chars) and
the direct-$wpdb insert fallback from v3.2.8 are kept.

Upgrade

Upload v3.3.0 over v3.2.9 from Plugins -> Add New -> Upload
Plugin
. No data migration needed -- v3.2.9 already migrated the
legacy 21-char rows.

v3.2.9

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:43

Schoolbooth Photo Manager v3.2.9

Real fix: shorten the audit log post_type slug to fit WP's 20-char limit

v3.2.8 surfaced the actual error from WordPress:

Processing the value for the following field failed: post_type.
The supplied value may be too long or contains invalid data.

The audit log custom post type was registered as
schoolbooth_audit_log -- which is 21 characters. WordPress
enforces a hard 20-character maximum on post_type values
(wpdb::process_field() and register_post_type()). Every
wp_insert_post() call was being rejected by that check, and
WP_Query was refusing to return rows whose post_type value
violated the same check (which is why even though v3.2.8's direct
$wpdb->insert() did persist rows, the All Events tab was empty).

Changes

  • Renamed the audit CPT slug from schoolbooth_audit_log (21 chars)
    to sb_audit_log (12 chars).
  • Added a one-time, idempotent migration that runs on first plugin
    load and renames any legacy rows already in wp_posts from the
    21-char slug to the new slug. Records the migration in
    wp_options (schoolbooth_audit_cpt_migrated_v1) so it never
    re-runs.
  • The fallback file logger and direct-$wpdb->insert() path from
    v3.2.7/v3.2.8 are kept as belt-and-suspenders.

After upgrade

  1. Install v3.2.9 and activate.
  2. Visit Schoolbooth -> Photo Audit Log -> All Events. The 5
    rows logged under v3.2.8 should appear, plus any new ones from
    subsequent uploads/consents/downloads.
  3. The Diagnostic Log tab should now show
    _via: wp_insert_post (no longer falling back to direct_wpdb).

If new events still go through direct_wpdb after upgrading, paste
the diagnostic log -- there may be a second filter blocking writes
that we haven't seen yet.

v3.2.8

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:39

Schoolbooth Photo Manager v3.2.8

Fix: bypass the third-party filter that was killing audit inserts

The v3.2.7 diagnostic log proved that wp_insert_post() was returning
"Could not insert post into the database." for every audit event. The
fallback file logger captured the events fine, but the CPT row never
materialized.

Most common cause on managed WordPress hosts: a security plugin or
custom mu-plugin installs a filter (wp_insert_post_data,
pre_post_status, wp_insert_post_empty_content, etc.) that blocks
wp_insert_post() for anonymous (user_id = 0) requests, which is
exactly what our REST upload + AJAX consent + frontend download
endpoints look like.

Fix

SCHOOLBOOTH_Audit_Logger::log_event() now:

  1. Tries wp_insert_post() first (normal path).
  2. If that fails (WP_Error or 0), captures $wpdb->last_error
    into the diagnostic log so we know the real MySQL message.
  3. Falls back to a direct $wpdb->insert() against wp_posts with
    every column populated explicitly. This bypasses all
    wp_insert_post_* filters and the post-modification cap checks.
  4. Logs whether each event landed via wp_insert_post or
    direct_wpdb so we can confirm the fix is actually working.

Direct $wpdb->insert() is safe here: every value is parameter-bound
through $wpdb->prepare()-style placeholders, the post content is
JSON we just generated, and the audit CPT is private/non-public so
there's no front-end render path to worry about.

After upgrade

  • Trigger one full upload -> consent -> download cycle.
  • Open Schoolbooth -> Photo Audit Log -> All Events -- rows
    should now appear.
  • The Diagnostic Log tab will show _via: wp_insert_post
    (host's filters didn't block) or _via: direct_wpdb (filter was
    blocking; we worked around it).

If a value other than those two appears, paste it back to me.

v3.2.7

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:34

Schoolbooth Photo Manager v3.2.7

Diagnostic release: surface why audit events are not appearing

v3.2.6's fix didn't help on your host -- events still aren't landing in
the CPT. Rather than guess again, this release adds a fallback log
file
that captures every audit event independently of the database,
plus a Diagnostic Log tab in the admin viewer to read it.

Behavior changes

  • Every call to log_event() now writes one JSON line to
    wp-content/uploads/schoolbooth/data/audit-fallback.log before
    attempting wp_insert_post().
  • If wp_insert_post() fails (returns WP_Error or 0), the failure
    reason is appended to the same file as a _error entry.
  • If wp_insert_post() succeeds, an _inserted_post_id confirmation
    is appended.
  • New tab Schoolbooth -> Photo Audit Log -> Diagnostic Log shows
    the last 200 lines of that file.

How to use after upgrade

  1. Install v3.2.7 and activate.
  2. Take one photo on the photobooth, scan the QR, complete the
    consent form, download the image (the same flow as before).
  3. Visit Schoolbooth -> Photo Audit Log and click the
    Diagnostic Log tab.

You will see one of three patterns:

  • Lines for upload, access_code_gen, form_submission,
    download_attempt, plus an _inserted_post_id after each one.

    Then the All Events tab is the bug -- send me a screenshot of the
    Diagnostic Log and I will fix the viewer query.
  • Lines for the events but _error entries instead of
    _inserted_post_id.
    That tells us exactly why
    wp_insert_post() is failing on your host (capability filter,
    database error, etc.). Send me the _error text.
  • No lines at all (empty file or "file does not exist"). That
    means log_event() is never being called. Likely cause: the
    upload / consent / download flows are bypassing the plugin code
    entirely -- send a screenshot and I will trace the call sites.

No code paths other than auditing have changed.

v3.2.6

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:24

Schoolbooth Photo Manager v3.2.6

Fix: audit log was not capturing events on some hosts

The audit logger registers a custom post type (schoolbooth_audit_log)
on init and writes events into it via wp_insert_post(). On hosts
where the audit logger was constructed during the same init action
(common when other plugins/themes preload our bootstrap), the CPT was
not yet registered when the first events tried to log, and
wp_insert_post() silently returned 0 -- so events vanished without
any error.

What changed

  • Audit logger now registers the CPT immediately if init has
    already fired, and on init priority 0 otherwise (before any other
    code tries to log an event).
  • Before each wp_insert_post() call, the logger verifies the CPT is
    registered and registers it on the spot if not.
  • All wp_insert_post() failures are now written to PHP's
    error_log() (visible in wp-content/debug.log when WP_DEBUG_LOG
    is on) so future regressions are not silent.

No upgrade dance required

Same plugin slug, same data layout. Upload v3.2.6 over v3.2.5 from
WordPress -> Plugins -> Add New -> Upload Plugin and activate.

New events going forward will appear in Schoolbooth -> Photo Audit
Log
. (Pre-3.2.6 events that failed to insert cannot be recovered --
they were never written to the database.)

v3.2.5

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:18

Schoolbooth Photo Manager v3.2.5

Re-release with a more aggressively-correct zip layout. No code changes
relative to v3.2.3 / v3.2.4.

Why another release?

Some WordPress hosts use PHP's PclZip fallback (rather than the native
ZipArchive extension) for plugin uploads. PclZip on certain hosts will
extract zip entries with embedded / characters as flat files with
literal slashes in their filename
rather than creating the folder
hierarchy. The v3.2.4 zip had no explicit directory entries, which
appears to have triggered this on at least one production host.

v3.2.5 ships explicit directory entries in the zip (sorted before
the file entries) so PclZip is forced to create the folder hierarchy
before writing files. This is the layout that other WordPress.org
plugins use.

The zip is also now built with Python's zipfile module instead of
PowerShell, eliminating any platform-specific quirks.

Carried over from v3.2.3

  • QR scan with no consent now redirects to the download portal
    (renders the consent form) instead of dying with
    "You must complete the permissions form before downloading".
  • Permissions form errors surface the actual server message instead of
    a generic "An error occurred while processing your form".
  • A failed audit-log write no longer blocks valid consent submissions.

Installation -- IMPORTANT if you tried v3.2.3 or v3.2.4 already

Old broken extractions left literal-backslash filenames in
wp-content/plugins/. Before installing v3.2.5, delete every file
and folder under wp-content/plugins/ whose name starts with
schoolbooth-photo-manager
(use SFTP or cPanel File Manager).
Otherwise WordPress's plugin scanner will keep tripping on the
leftovers.

After cleanup, upload schoolbooth-photo-manager-v3.2.5.zip via
Plugins -> Add New -> Upload Plugin and activate.

v3.2.4

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 09:06

Schoolbooth Photo Manager v3.2.4

Re-release of v3.2.3 with a corrected installable zip. No code changes
relative to v3.2.3.

If you tried to install v3.2.3 via Plugins -> Add New -> Upload Plugin
and got "plugin does not exist", please use this v3.2.4 zip instead.
The v3.2.3 zip was built with PowerShell's Compress-Archive, which on
Windows writes ZIP entries with backslash separators that WordPress's
unzipper can't navigate.

Carried over from v3.2.3

  • QR scan with no consent now redirects to the download portal (which
    renders the consent form) instead of dying with
    "You must complete the permissions form before downloading".
  • Permissions form errors surface the actual server message instead of
    a generic "An error occurred while processing your form".
  • A failed audit-log write no longer blocks valid consent submissions;
    consent is still recorded and the user proceeds to their photos.

Installation note

If a previous install (failed or otherwise) created a
wp-content/plugins/schoolbooth-photo-manager/ directory on your
server, WordPress will refuse to upload over the top of it. Either:

  • Use the existing plugin's auto-update path, or
  • Delete the directory via SFTP/cPanel before uploading the zip, or
  • Deactivate + delete the previous install via Plugins -> Installed Plugins.

v3.2.3

Choose a tag to compare

@Awebbtx Awebbtx released this 13 Jun 08:48

Schoolbooth Photo Manager v3.2.3

Bug fixes

QR code scan: "You must complete the permissions form before downloading"

Scanning a photo's QR code took users straight to a wp_die() error
page telling them to complete the form first, but never sent them to
the form. The download handler now redirects to the download portal
when the permissions form hasn't been completed — the portal renders
the consent form automatically, so the user just sees the form and can
fill it out without hitting a dead end.

"An error occurred while processing your form. Please try again"

Two problems:

  1. JS swallowed real server errors. jQuery routes every non-2xx
    HTTP response (400 validation, 403 nonce, 429 rate limit, 500 server
    error) into its error: callback, and our handler ignored
    xhr.responseJSON, so users saw a generic "An error occurred"
    regardless of what actually happened. Now the JS parses
    responseJSON and surfaces the real server message ("Please correct
    the errors below", "Security verification failed", validation
    details, etc.).

  2. Audit log write failures killed valid consent submissions. If
    the audit custom post type couldn't be written (DB error,
    permissions, plugin conflict), the form returned 500 even though
    consent had been validly given. We now log the audit failure to
    error_log and continue setting the consent cookie so the user can
    proceed to their photos.