CoolCMS API

CartManager
in package

FinalYes

Holds the cart content and the in-progress checkout.

The only class components (Cart, CartWidget, Checkout) and presenters may inject: the manager is the only model layer visible outside; the lower layers (CartService, mappers, repositories) are used only by it.

It carries all business logic (quantity cap, case-insensitive voucher dedup, checkout merge, token, order ownership) and is the only one allowed to touch other managers/framework services directly: User (who is logged in) and Session (token and order ownership). Items, vouchers and checkout are delegated to CartService, which only decides the storage (session or DB).

IMPORTANT: the one-time step-3 token and the order ownership (confirmation page of a guest) always stay in the session, in both storage variants. They are bound to the browser and one form submit, not to the cart content, so a service/mapper/repository abstraction makes no sense for them.

Invariant: the storage holds no price, rate or discount, only identifiers and customer texts. Prices are always computed by the server (OrderCheckoutManager).

Table of Contents

Constants

MAX_QUANTITY  : int = 999
Quantity cap of one item; guards against typos and nonsensical requests.
KEY_ORDER_BY_TOKEN  : string = 'orderByToken'
KEY_ORDERS  : string = 'orders'
KEY_TOKEN  : string = 'token'
SECTION  : string = 'eshop.cart'
TOKEN_ORDER_HISTORY  : int = 5
How many token to order pairs the session remembers ({@see rememberOrderForToken()}).

Properties

$service  : CartService
$session  : Session
$snapshot  : CartSnapshot|null
$snapshotUserId  : int|null
User active at the last snapshot load; detects a login in the middle of a request (see {@see snapshot()}).
$user  : User

Methods

__construct()  : mixed
add()  : void
Adds the quantity to an existing row (repeated "add to cart" sums instead of overwriting).
addVoucherCode()  : bool
Returns false when the code is already in the cart (case-insensitive; the `code` collation is case-insensitive).
clearAfterOrder()  : void
Empties the cart, codes and in-progress checkout after a successful submit.
consumeToken()  : bool
Returns true when the token was valid and has just been burned; false when it does not match or was already used.
getCheckout()  : array<string, mixed>
getCheckoutValue()  : mixed
getItems()  : array<int, int>
getLines()  : array<int, array{setId: int, quantity: int}>
getOwnedOrderIds()  : array<int, int>
getTotalQuantity()  : int
Returns the number of pieces in the cart (for the header badge), not the number of rows.
getVoucherCodes()  : array<int, string>
isEmpty()  : bool
issueToken()  : string
Issues the one-time token when step 3 is displayed.
mergeCheckout()  : void
orderForToken()  : int|null
Returns the order created by the submit with this token, or `null` (the token created nothing).
ownsOrder()  : bool
registerOrder()  : void
Remembers an order created by this session.
rememberOrderForToken()  : void
Remembers which order the submit with this (already burned) token created.
remove()  : void
removeMany()  : void
removeVoucherCode()  : void
setQuantity()  : void
Sets the absolute quantity; `<= 0` removes the row.
clampQuantity()  : int
currentUserId()  : int|null
orderTokenMap()  : array<string, int>
persist()  : void
section()  : SessionSection
snapshot()  : CartSnapshot
Reads the logged-in state live and reloads the snapshot when it differs from the last load.
writeItems()  : void
writeVouchers()  : void

Constants

MAX_QUANTITY

Quantity cap of one item; guards against typos and nonsensical requests.

public int MAX_QUANTITY = 999

KEY_ORDER_BY_TOKEN

private string KEY_ORDER_BY_TOKEN = 'orderByToken'

TOKEN_ORDER_HISTORY

How many token to order pairs the session remembers ({@see rememberOrderForToken()}).

private int TOKEN_ORDER_HISTORY = 5

Properties

$snapshotUserId

User active at the last snapshot load; detects a login in the middle of a request (see {@see snapshot()}).

private int|null $snapshotUserId = null

Methods

add()

Adds the quantity to an existing row (repeated "add to cart" sums instead of overwriting).

public add(int $setId[, int $quantity = 1 ]) : void
Parameters
$setId : int
$quantity : int = 1

addVoucherCode()

Returns false when the code is already in the cart (case-insensitive; the `code` collation is case-insensitive).

public addVoucherCode(string $code) : bool
Parameters
$code : string
Return values
bool

clearAfterOrder()

Empties the cart, codes and in-progress checkout after a successful submit.

public clearAfterOrder() : void

The list of owned orders is deliberately kept so that the customer can reach the confirmation page even after a refresh.

consumeToken()

Returns true when the token was valid and has just been burned; false when it does not match or was already used.

public consumeToken(string|null $token) : bool
Parameters
$token : string|null
Return values
bool

getCheckout()

public getCheckout() : array<string, mixed>
Return values
array<string, mixed>

getCheckoutValue()

public getCheckoutValue(string $key[, mixed $default = null ]) : mixed
Parameters
$key : string
$default : mixed = null

getItems()

public getItems() : array<int, int>
Return values
array<int, int> —

setId => quantity (in insertion order)

getLines()

public getLines() : array<int, array{setId: int, quantity: int}>
Return values
array<int, array{setId: int, quantity: int}> —

shape expected by api/eshop/order/checkout

getOwnedOrderIds()

public getOwnedOrderIds() : array<int, int>
Return values
array<int, int>

getTotalQuantity()

Returns the number of pieces in the cart (for the header badge), not the number of rows.

public getTotalQuantity() : int
Return values
int

getVoucherCodes()

public getVoucherCodes() : array<int, string>
Return values
array<int, string>

isEmpty()

public isEmpty() : bool
Return values
bool

issueToken()

Issues the one-time token when step 3 is displayed.

public issueToken() : string

The form carries it in a hidden field; consumeToken() burns it on submit, so a second submit (double click, reload, back button) does not create another order. The PHP session lock serializes concurrent requests of the same session, so a double click cannot pass both branches at once.

Return values
string

mergeCheckout()

public mergeCheckout(array<string, mixed> $values) : void
Parameters
$values : array<string, mixed>

merged with the stored ones (a step overwrites only its own fields)

orderForToken()

Returns the order created by the submit with this token, or `null` (the token created nothing).

public orderForToken(string|null $token) : int|null
Parameters
$token : string|null
Return values
int|null

ownsOrder()

public ownsOrder(int $orderId) : bool
Parameters
$orderId : int
Return values
bool

registerOrder()

Remembers an order created by this session.

public registerOrder(int $orderId) : void

A guest has no account, so this is the only way to show them the confirmation page and not to show it to anyone who types a foreign id into the URL.

Parameters
$orderId : int

rememberOrderForToken()

Remembers which order the submit with this (already burned) token created.

public rememberOrderForToken(string $token, int $orderId) : void

A double click or reload then leads exactly to it, not to "the last order the session owns". The difference shows after a failed submit: the token is burned, no order was created, and without this link the customer would see an old unrelated order of the same session as the confirmation.

The map is kept short (self::TOKEN_ORDER_HISTORY); only the window between submit and leaving step 3 matters.

Parameters
$token : string
$orderId : int

remove()

public remove(int $setId) : void
Parameters
$setId : int

removeMany()

public removeMany(array<int, int> $setIds) : void
Parameters
$setIds : array<int, int>

bulk removal ("remove selected" in the cart)

removeVoucherCode()

public removeVoucherCode(string $code) : void
Parameters
$code : string

setQuantity()

Sets the absolute quantity; `<= 0` removes the row.

public setQuantity(int $setId, int $quantity) : void
Parameters
$setId : int
$quantity : int

clampQuantity()

private clampQuantity(int $quantity) : int
Parameters
$quantity : int
Return values
int

currentUserId()

private currentUserId() : int|null
Return values
int|null

orderTokenMap()

private orderTokenMap() : array<string, int>
Return values
array<string, int>

section()

private section() : SessionSection
Return values
SessionSection

snapshot()

Reads the logged-in state live and reloads the snapshot when it differs from the last load.

private snapshot() : CartSnapshot

A login changes which cart is the right one (merge), so the state is never cached; the reload also merges through CartService. A normal request logs in through a different action (PRG redirect), so in practice this branch runs once; it also protects future code that would use CartManager both before and after User::login() in one request.

Return values
CartSnapshot

writeItems()

private writeItems(array<int, int> $items) : void
Parameters
$items : array<int, int>

writeVouchers()

private writeVouchers(array<int, string> $vouchers) : void
Parameters
$vouchers : array<int, string>
On this page

Search results