Skip to main content

PriceChangesController

\Benecaster\REST\PriceChangesController

Class Premium

The podcaster’s view of pending and past price changes — see and cancel what is pending. Admin REST controller for GET /price-changes, POST /price-changes/{id}/cancel and POST /price-changes/{id}/retry. GET /price-changes lists changes newest first (superseded rows are bookkeeping and always hidden — the change that replaced them is what the podcaster needs to see), each with a counts breakdown and a cancellable flag. Cancel answers 409 price_change_not_cancellable once the notice period has ended or the change is no longer pending. Retry re-queues the change’s failed rows and, when an applier is wired in, applies the change immediately rather than waiting for the next scheduled pass — skipped subscribers are not retried. Backed by PriceChangeRepository.

Constructor Dependencies

Type Description
\Benecaster\Membership\PriceChange\PriceChangeRepository Reads price-change rows and per-status subscriber counts.
\Benecaster\Membership\PriceChange\PriceChangeScheduler Cancels a pending change and re-queues failed rows on retry.
\Benecaster\Membership\PriceChange\PriceChangeApplier Optional, defaults to null. When present, retry_change() applies the re-queued change immediately instead of leaving it for the next scheduled pass.

Methods

Method Visibility Since Description
register_routes(): void Public — Registers GET /price-changes, POST /price-changes/{id}/cancel, and POST /price-changes/{id}/retry, all permission_callback_admin.
list_changes( WP_REST_Request $request ): WP_REST_Response|WP_Error Public — GET /price-changes. Requires show_id (400 invalid_param otherwise); optional tier_id narrows to one tier. Optional target_type + target_id filter to one specific tier or buy-up target. Always drops rows with status PriceChangeRepository::STATUS_SUPERSEDED before returning. Returns {items: [...]}, each projected through project().
cancel_change( WP_REST_Request $request ): WP_REST_Response|WP_Error Public — POST /price-changes/{id}/cancel. 404 when the change doesn't exist; 403 rest_forbidden when the current user cannot edit_post the change's show. Cancels the change; on failure returns 409 price_change_not_cancellable (notice period ended, or the change is no longer pending). On success, notified subscribers receive the cancellation email (via the scheduler) and the response is the re-fetched, re-projected change.
retry_change( WP_REST_Request $request ): WP_REST_Response|WP_Error Public — POST /price-changes/{id}/retry. Same 404/403 checks as cancel_change(). Puts subscribers a Stripe error left on the old price back in line for the change; skipped subscribers are not retried. When retry_failed() reports rows retried AND a PriceChangeApplier was injected, applies the change immediately (apply_change() with the current time) rather than waiting for the scheduled pass. Returns the projected change plus a retried count.
project( array $change ): array — — Maps a raw price-change row to its REST shape: formats old/new amounts as money, converts created_at/effective_at/completed_at to ISO 8601 with an explicit UTC offset (via iso()) so the admin renders each in the viewer's own timezone rather than guessing the stored clock, computes whether the change is still cancellable, and attaches the per-status subscriber counts from PriceChangeRepository::count_subscribers_by_status().
iso( string $utc ): string — — Converts a stored UTC datetime string to ISO 8601 with an explicit offset via strtotime( \$utc . ' UTC' ) then gmdate('c', ...). Returns '' on an unparseable value.

Notes

Extends the plugin's internal RestController base — not part of the public API; its own docblock tells add-on developers not to extend it, and to register independent routes on rest_api_init with the public benecaster_rest_permission_admin() function instead. Inherits register() (hooks register_routes() onto rest_api_init), the permission_callback_admin / permission_callback_editor / permission_callback_subscriber callbacks, rest_error(), and not_found().

See Buy-ups Admin REST API for the buy-up-scoped POST /buyups/{id}/migrate shorthand, which retries only a buy-up's latest change.