Skip to main content
FlowInterface is the contract every UTB flow must satisfy. It lives in UTB\ProductBuilder\Flows and is implemented by AbstractFlow and any custom flow class you create.
namespace UTB\ProductBuilder\Flows;

interface FlowInterface {
    public function get_id(): string;
    public function get_name(): string;
    public function get_description(): string;
    public function get_icon(): string;
    public function init(): void;
    public function applies_to_product(int $product_id): bool;
    public function get_shortcodes(): array;
    public function get_ajax_endpoints(): array;
    public function validate_cart_data(array $post_data);
    public function prepare_cart_metadata(array $post_data): array;
    public function calculate_dynamic_price(array $cart_item_data): ?float;
}

Identity methods

get_id(): string

Returns the unique machine identifier for this flow. Used as the _utb_flow_id cart and order item meta key, and as the key in FlowRegistry.
public function get_id(): string
{
    return 'my_custom_flow';
}

get_name(): string

Returns a human-readable display name shown in the WordPress admin flow selector.
public function get_name(): string
{
    return 'My Custom Flow';
}

get_description(): string

Returns a short description shown in the admin panel next to the flow name.
public function get_description(): string
{
    return 'Handles custom product enrollment with dynamic pricing.';
}

get_icon(): string

Returns a Dashicons class name (including the dashicons- prefix) used to represent the flow in the admin UI.
public function get_icon(): string
{
    return 'dashicons-awards';
}

Lifecycle methods

init(): void

Registers all WordPress and WooCommerce hooks needed by this flow. Called once during plugin initialization. AbstractFlow provides a complete implementation; override only when you need to register additional hooks beyond what the base class provides.
public function init(): void;

applies_to_product(int $product_id): bool

Returns true if this flow is assigned to the given WooCommerce product ID. The base implementation in AbstractFlow delegates to FlowRegistry::get_flow_for_product().
product_id
integer
required
The WooCommerce product ID to check.
public function applies_to_product(int $product_id): bool;

Registration methods

get_shortcodes(): array

Returns an associative array mapping shortcode tag names to method names on the flow class. AbstractFlow::init() iterates this array and calls add_shortcode() for each entry.
public function get_shortcodes(): array
{
    return [
        'my_flow_form' => 'render_form_shortcode',
    ];
}
Return valueDescription
array<string, string>Keys are shortcode tags; values are method names on $this.

get_ajax_endpoints(): array

Returns an associative array mapping WordPress AJAX action names to method names on the flow class. AbstractFlow::init() registers each entry for both wp_ajax_{action} and wp_ajax_nopriv_{action}, making all endpoints available to authenticated and unauthenticated users.
public function get_ajax_endpoints(): array
{
    return [
        'my_flow_validate' => 'handle_ajax_validate',
        'my_flow_get_price' => 'handle_ajax_price',
    ];
}
Return valueDescription
array<string, string>Keys are AJAX action names; values are method names on $this.

Cart integration methods

validate_cart_data(array $post_data)

Validates the form submission before the product is added to the cart. Called by AbstractFlow::validate_add_to_cart() which is hooked to woocommerce_add_to_cart_validation.
post_data
array
required
The raw $_POST data submitted with the add-to-cart request.
Return value: true if validation passes; a string containing an error message if validation fails. The error string is passed to wc_add_notice() and displayed to the user.
public function validate_cart_data(array $post_data)
{
    if (empty($post_data['selected_program'])) {
        return 'Please select a program before adding to cart.';
    }
    return true;
}

prepare_cart_metadata(array $post_data): array

Builds the metadata array that will be merged into the cart item data and eventually saved as WooCommerce order item meta. Called by AbstractFlow::add_cart_item_data_filter() which is hooked to woocommerce_add_cart_item_data. The base class automatically appends _utb_unique_key (to prevent cart item merging) and _utb_flow_id.
post_data
array
required
The raw $_POST data from the add-to-cart request.
Return value: An associative array of metadata. Keys prefixed with _utb_ are automatically persisted to order item meta by AbstractFlow::save_order_item_meta().
public function prepare_cart_metadata(array $post_data): array
{
    return [
        '_utb_form_data'     => json_encode(['selected_program' => $post_data['selected_program']]),
        '_utb_program_code'  => sanitize_text_field($post_data['selected_program']),
    ];
}

calculate_dynamic_price(array $cart_item_data): ?float

Returns a dynamic price for a cart item. Called by AbstractFlow::apply_dynamic_pricing() which is hooked to woocommerce_before_calculate_totals. Return null to leave the product’s configured price unchanged.
cart_item_data
array
required
The full WooCommerce cart item array, including all metadata keys set by prepare_cart_metadata().
Return value: A float price in the store’s base currency, or null to skip dynamic pricing for this item.
public function calculate_dynamic_price(array $cart_item_data): ?float
{
    $program_code = $cart_item_data['_utb_program_code'] ?? null;
    if (!$program_code) {
        return null;
    }
    $program = $this->programs_repo->get_by_codigo($program_code);
    return $program ? (float) $program['precio'] : null;
}

Build docs developers (and LLMs) love