Skip to content

Developer reference

PressFlow hooks: names, arguments and examples

The complete emitted PressFlow hook inventory for 1.25.3, with return contracts and safe examples.

PressFlow 1.25.3 · 3 min read

PressFlow 1.25.3 emits three custom filters and one custom action. The following table covers those emitted hooks, rather than every WordPress/WooCommerce hook the plugin subscribes to. Register the correct accepted-argument count.

HookKind / argumentsReturn or timing
pfw_from_price_hooksFilter: $places (array), 1 argumentPlacement array; resolved at init.
pfw_from_price_valuesFilter: $values (array or null), $product (WC_Product), $config (array), 3 argumentsStarting values array, or preserve the incoming value. Engine validates it.
pfw_from_price_htmlFilter: $html (string), $product (WC_Product), $result (array or null), $context (string), 4 argumentsFinal starting-price/quote-label HTML string.
pfw_quote_createdAction: $quote_id (integer), $snapshot (array), 2 argumentsAfter the private quote is stored and its staff notification has been attempted.

WordPress filters return a value; actions do not transform one. See add_filter and add_action for registration behavior.

Move the starting-price block

Default placements are single at woocommerce_single_product_summary, priority 6, and catalog at woocommerce_shop_loop_item_title, priority 15. Each entry is an array with hook and priority; use false to disable a placement.

<?php
defined('ABSPATH') || exit;

add_filter('pfw_from_price_hooks', static function (array $places): array {
    $places['single'] = [
        'hook' => 'woocommerce_single_product_summary',
        'priority' => 11,
    ];
    return $places;
});

Register this before init. A template using its own price renderer can disable the corresponding automatic placement, then render [pressflow_from_price] or pressflow_from_price() once.

This filter changes those automatic action placements. It does not disable the separate WooCommerce price-HTML or Product Price block integration.

Supply a deliberate starting specification

Prefer the admin-defined starting configuration for ordinary shops. A filter can supply dynamically chosen reference values without enumerating every possible specification on an archive request.

<?php
defined('ABSPATH') || exit;

add_filter('pfw_from_price_values', static function ($values, $product, $config) {
    if ($product->get_id() !== 123) {
        return $values;
    }
    // Example for a custom product whose only required field is "stock".
    // Replace 123 and all IDs/values with that product's actual configuration.
    return ['copies' => 100, 'stock' => 'silk'];
}, 10, 3);

Use stable field/choice IDs, not display labels. Include all required values, valid dimensions for area/band pricing and a valid quantity. Returning an invalid array results in no valid starting amount. Quote-only mode remains quote-only.

The incoming value is the stored custom starting values, or null for automatic selection. Returning null is not an instruction to erase a stored custom reference; preserve the incoming value when you are not changing it. The reference calculation caches its raw engine result for one hour using configuration/version/date/precision inputs; tax and coupon preview are evaluated separately for the viewer.

Change final markup

pfw_from_price_html receives null $result for quote-only/no-safe-reference labels. Contexts used by the built-in callers include single, catalog, block, shortcode and price; custom renderers can supply another string.

Retain .pfw-from-price, .pfw-from-amount, the starting-specification tooltip, quantity/dimension description and “per print job”. Preserve paired VAT markup and render “From” only once. Escape any added text/attributes and do not replace an unavailable-price label with a nominal WC amount. A markup filter does not change the calculated basket price.

<?php
defined('ABSPATH') || exit;

add_filter('pfw_from_price_html', static function ($html, $product, $result, $context) {
    if ($context !== 'single' || !is_array($result)) {
        return $html;
    }
    return $html . '<small class="myshop-price-guidance">'
        . esc_html('Choose your specification below.') . '</small>';
}, 10, 4);

This adds guidance only to the priced single-product starting block, preserving the original amount and wrappers. It leaves quote/configure labels and other contexts unchanged.

Record a quote-created integration marker

<?php
defined('ABSPATH') || exit;

add_action('pfw_quote_created', static function ($quote_id, array $snapshot): void {
    // A local marker for your own bounded background integration.
    // Do not publish the snapshot or private quote contact/artwork metadata.
    update_post_meta((int) $quote_id, '_myshop_pressflow_export_pending', 'yes');
}, 20, 2);

Keep callbacks short and failure-contained. Queue external work through your own authorised background integration; implement its retry/idempotency behavior there. This action does not mean the customer accepted an offer or paid. An exception in an extension can interrupt the request after the quote has already been created.

Theme hooks are a different contract

PressFlow subscribes to pressflow_product_offer and pressflow_native_sale_badge. They are theme-defined filters, not emitted pfw_* hooks. The theme's pressflow_catalogue_price contract requires an optional custom adapter in this release; it is not registered by PressFlow itself. See VAT and promotions integration.

Related: Developer overview, Shortcodes, Testing.

Example files

Reference examples for adapting to your shop. PHP examples are not plugin installers; review the guide and replace sample IDs before using them.

Need a hand?

Contact the PressFlow team with details of what you are trying to do.