Skip to content

Default series toggle#893

Merged
zahardev merged 8 commits intodevelopfrom
version/3.16.0-default-series-toggle
May 4, 2026
Merged

Default series toggle#893
zahardev merged 8 commits intodevelopfrom
version/3.16.0-default-series-toggle

Conversation

@zahardev
Copy link
Copy Markdown
Collaborator

@zahardev zahardev commented May 4, 2026

Summary

Allow admins to change the default podcast directly from the single series edit page, replacing the need for the SSA plugin's "Change Default Podcast" action.

Requirements

  • Non-default series edit page should display a toggle labeled "Set as default podcast"
  • Toggling on and saving should update the ss_podcasting_default_series option to the current series
  • The current default series should display a text label ("This is the default podcast") instead of a toggle
  • Requires manage_podcast capability

Summary by CodeRabbit

  • New Features

    • Added a "Default Podcast" toggle in series settings.
  • Style

    • New styles for the default-podcast label and a custom toggle control.
  • Bug Fixes

    • Image delete now clears all associated fields.
    • Membership sync moved to queued single-sync processing and avoids conflicting add/revoke operations for more reliable syncing.
  • Tests

    • Added tests covering membership sync queuing, merging, reconciliation, and edge cases.

#838

Replace delete_option() with race-safe reconciliation that re-reads the
option from DB and only removes processed users whose data hasn't changed,
preserving entries written by concurrent requests (Scenario E).

Co-Authored-By: Claude via AIContext
Co-Authored-By: Claude via AIContext
The delete handler only cleared the URL field, leaving the attachment
ID intact so the player kept showing stale artwork.

Co-Authored-By: Claude via AIContext
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

📝 Walkthrough

Walkthrough

Adds a default-podcast toggle UI and related server-side handling; introduces a single-sync queue processor and helpers for WooCommerce Memberships integration (enqueue, process, reconcile, clean IDs); small sync_user overlap resolution; minor JS and CSS/SCSS updates; plugin version bump and accompanying tests for the memberships integrator.

Changes

Default Podcast UI & Series Handling

Layer / File(s) Summary
Data Shape / Template
templates/settings/podcast-default-toggle.php
New template renders a "Default Podcast" row with either static text (when already default) or a checkbox toggle (name="ssp_default_podcast").
Styles
assets/admin/scss/_admin.scss, assets/admin/css/admin.css
Adds .ssp-default-podcast-label and full .ssp-toggle slider styles (hidden checkbox, slider track/knob, checked and focus states).
Client Behavior
assets/js/admin.js
.ssp-image-delete click handler now also clears .<field>_id and triggers change events for both fields.
Controller Wiring
php/classes/controllers/class-series-controller.php
Renders the default-podcast toggle in edit_series_term_meta_fields(), adds show_default_podcast_toggle() and maybe_set_default_series(); save_series_meta() invokes maybe_set_default_series before Castos sync.
Versioning
seriously-simple-podcasting.php
Plugin header and SSP_VERSION updated to 3.16.0-alpha.

WooCommerce Memberships Single-Sync Queue

Layer / File(s) Summary
Small sync behavior fix
php/classes/integrations/class-abstract-integrator.php
sync_user() now removes any IDs from $revoke_series_ids that also appear in $add_series_ids so adds take precedence.
Enqueueing
php/classes/integrations/woocommerce/class-wc-memberships-integrator.php
Adds sync_membership( $membership ) to enqueue per-membership single-sync items (adds vs revokes depending on status).
Queue processor
php/classes/integrations/woocommerce/class-wc-memberships-integrator.php
Introduces process_single_sync() as the scheduled worker that snapshots the option, processes per-user revoke/add lists (excluding series still allowed by other active memberships), calls sync_user() for each, and reschedules or clears the option when done.
Reconciliation & helpers
php/classes/integrations/woocommerce/class-wc-memberships-integrator.php
Adds reconcile_sync_data() to reload DB option bypassing object cache and only remove processed entries that still match the snapshot; replaces array_unique(array_merge(...)) with clean_id_list() to filter, dedupe, and reindex IDs. Also replaces anonymous SINGLE_SYNC_EVENT handler with a direct process_single_sync() callback.
Hook wiring
php/classes/integrations/woocommerce/class-wc-memberships-integrator.php
Updates wc_memberships_user_membership_saved callback to call sync_membership() instead of inline branching.
Tests
tests/WPUnit/WCMembershipsIntegratorTest.php
New unit tests exercising enqueueing, prepare/merge/clean behavior, and reconciliation/race scenarios for the single-sync queue.

Sequence Diagram(s)

sequenceDiagram
    participant Membership as Membership System
    participant WP as WordPress (option DB / cron)
    participant Integrator as WC_Memberships_Integrator
    participant Abstract as Abstract_Integrator (sync_user)
    participant External as Remote Sync API

    Membership->>Integrator: membership saved (wc_memberships_user_membership_saved)
    Integrator->>WP: prepare_single_sync() -> update option (enqueue)
    WP->>WP: schedule SINGLE_SYNC_EVENT
    WP->>Integrator: SINGLE_SYNC_EVENT fired (process_single_sync)
    Integrator->>WP: read snapshot option (bypass cache)
    loop per user in snapshot
        Integrator->>Integrator: compute revoke/add (exclude series allowed elsewhere)
        Integrator->>Abstract: sync_user(user, revoke_ids, add_ids)
        Abstract->>External: call remote revoke/add APIs
        External-->>Abstract: remote responses
        Abstract-->>Integrator: success/failure
    end
    Integrator->>WP: reconcile_sync_data(snapshot, pending) -> persist or reschedule option
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • #846 — Modifies WC_Memberships_Integrator (hook registration and early-return checks); highly related to queue/processor changes.
  • #856 — Also touched SSP_VERSION in seriously-simple-podcasting.php; related at the versioning/header level.
  • #848 — Another change to the plugin version constant (SSP_VERSION); related to the same header update.

Poem

"I nibble code in evening's light,
A toggle glows, a queue takes flight.
I hop through CSS and PHP bright,
Syncs align — all users right.
🐇✨ — from the rabbit, cheers to new might!"

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 80.65% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title "Default series toggle" accurately describes the main feature introduced in this changeset—adding a toggle UI for admins to set a series as the default podcast.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch version/3.16.0-default-series-toggle

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@php/classes/integrations/woocommerce/class-wc-memberships-integrator.php`:
- Around line 249-255: sync_membership currently assumes $membership is always
an object and calls $membership->get_status(), which will fatal if
get_user_membership returned null; add a guard at the start of sync_membership
to detect a missing/invalid membership (e.g., if null or not an object or
missing get_status) and bail out or call prepare_single_sync with safe params so
the sync fails gracefully. Locate the sync_membership method in
class-wc-memberships-integrator.php and implement a simple early-return check
before using get_status(), leaving the existing prepare_single_sync calls
unchanged when a valid membership is present.

In `@templates/settings/podcast-default-toggle.php`:
- Around line 16-22: The checkbox input named "ssp_default_podcast" is not
programmatically associated with the visible text "Set as default podcast" which
harms accessibility; fix by adding a unique id on the input (e.g.,
id="ssp_default_podcast") and associate the text span with that id using a
corresponding <label for="..."> or by moving the visible text inside the
existing <label class="ssp-toggle"> so the input and label are properly linked;
update the markup around the input and the element with class
"ssp-toggle__label" to reference the id so assistive tech can read the label.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c73dc4c2-f2e2-434d-86cf-d7efdcf306bb

📥 Commits

Reviewing files that changed from the base of the PR and between 89626a3 and e3549d0.

📒 Files selected for processing (9)
  • assets/admin/css/admin.css
  • assets/admin/scss/_admin.scss
  • assets/js/admin.js
  • php/classes/controllers/class-series-controller.php
  • php/classes/integrations/class-abstract-integrator.php
  • php/classes/integrations/woocommerce/class-wc-memberships-integrator.php
  • seriously-simple-podcasting.php
  • templates/settings/podcast-default-toggle.php
  • tests/WPUnit/WCMembershipsIntegratorTest.php

Comment thread templates/settings/podcast-default-toggle.php Outdated
zahardev added 3 commits May 4, 2026 12:51
sync_membership() now guards against null membership lookups.
process_single_sync() clears the queue option at the retry cap.
Toggle checkbox is now properly associated with its label.

Co-Authored-By: Claude via AIContext
@zahardev zahardev changed the title Version/3.16.0 default series toggle Default series toggle May 4, 2026
@zahardev zahardev merged commit 6ef2d72 into develop May 4, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request May 4, 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.

1 participant