Skip to main content

BuyupPriceRepository

\Benecaster\Membership\BuyupPriceRepository

Class Premium

Data access for benecaster_buyup_prices: one row per buy-up per billing cadence, the buy-up counterpart of MembershipPriceRepository. Each row carries a label, an interval unit and count, an amount in minor units, a currency, a Stripe Price ID per keyset, a default flag and a sort order.

A row priced at 0 is a real price, not a missing one: it is the free, auto-granted offer. Absence of a row is what “no price” means, so find_for_interval() returning null is the offer’s answer (this buy-up is not sold at that cadence), not an error.

Changing a row’s amount or currency clears both of its Stripe Price IDs, the same rule as MembershipPriceRepository::update(). Stripe Prices cannot be edited, and clearing the IDs is what makes Benecaster mint a replacement, because a Price is minted only for a row with no Price ID for the keyset. A Price ID written on its own survives, since that is the provisioner recording what it minted. One written alongside an amount change is discarded, because it was minted for the old amount.

Only one row per buy-up is the default, enforced here rather than by a database index. A row cannot be moved to a different buy-up.

Methods

Method Visibility Since Description
insert( array $data ): int Public — Inserts a row and returns its id, or 0 on failure. Requires buyup_id, cadence_label, interval_unit, amount_cents and currency. Marking it default demotes the buy-up's other rows.
update( int $id, array $changes ): bool Public — Updates the mutable fields. An amount or currency change clears both Stripe Price IDs, as described above. buyup_id is not writable.
delete( int $id ): bool Public — Deletes one row and fires benecaster_buyup_price_deleted with its id. The action is what cancels a pending price change on the row: without it, holders who were already sent a notice would wait for a rise that never comes.
delete_by_buyup( int $buyup_id ): int Public — Deletes every row for a buy-up and returns the count. Deliberately fires no per-row action: its caller is the buy-up delete, whose benecaster_buyup_definition_deleted already carries the rows, and firing both would cancel each change, and email each holder, twice.
find( int $id ): ?array Public — One row by id, or null.
find_by_buyup( int $buyup_id ): array Public — A buy-up's rows in display order.
find_by_buyups( array $buyup_ids ): array Public — Rows for several buy-ups in one query, grouped by buyup_id. Used to attach prices to a list of buy-ups without a query per buy-up.
find_for_interval( int $buyup_id, string $interval_unit, int $interval_count, string $currency ): ?array Public — The row at an exact cadence and currency, preferring the default row, or null when the buy-up is not sold there. Null is the offer's answer, not a missing price.
find_default_for_buyup( int $buyup_id ): ?array Public — The default row, falling back to the first row when none is flagged, so a buy-up stays sellable after its default row is deleted.
set_default_for_buyup( int $price_id ): bool Public — Makes a row the default and demotes its siblings. False when the row does not exist.

Hooks Fired

Notes

amount_cents is in minor units, unlike the decimal(10,2) major-unit price column on benecaster_buyups that this table replaced. See 07-data-model.md → benecaster_buyup_prices.