Support Log in

50. Calculation Field & Cross-Post Aggregation

Developer Guide
Prefer video? Watch the Field Forge tutorials 8 short guides covering every feature Watch

Overview

The calculation field type (PRO) is a read-only numeric field whose value is computed either from a formula referencing sibling top-level fields, or by summing a numeric sub-field across all rows of a sibling repeater. The value is recomputed on every read via the fieldforge/load_value filter and is also stored into wp_fieldforge_values on save_post (priority 20), so plain SQL queries, REST responses, and GraphQL can return the pre-computed number without additional processing.

Cross-post aggregation (summing a field across all posts of a given type) is split by tier: the shortcode and PHP helper are free; the REST endpoint and GraphQL query are PRO.

Field Definition Keys

Register or retrieve a calculation field using the standard field-group array. Keys specific to the calculation type:

KeyTypeValues / DefaultDescription
typestring'calculation'Field type identifier
formulastring''Math expression with {field_name} tokens. Used when sum_source is 'self'.
sum_sourcestring'self' 'repeater''self' evaluates the formula; 'repeater' sums a sub-field across rows.
sum_repeaterstring''Name of the sibling repeater field. Required when sum_source = 'repeater'.
sum_fieldstring''Name of the numeric sub-field to sum. Stored in wp_fieldforge_values as ::.
output_formatstring'number''number' 'currency' 'percentage'
decimal_placesint2Number of decimal places in the formatted output.
currency_symbolstring'$'Symbol string for output_format = 'currency'.
symbol_positionstring'prefix''prefix' (symbol before value) or 'suffix' (symbol after value).
thousands_sepstring','Character used to separate thousands in the formatted number.
decimal_sepstring'.'Character used as the decimal point in the formatted number.
Example: formula-based field definition
php
fieldforge_add_local_field_group( [
    'key'    => 'group_order',
    'title'  => 'Order',
    'fields' => [
        [ 'key' => 'field_price', 'label' => 'Unit Price', 'name' => 'price', 'type' => 'number' ],
        [ 'key' => 'field_qty',   'label' => 'Quantity',   'name' => 'qty',   'type' => 'number' ],
        [
            'key'            => 'field_total',
            'label'          => 'Total',
            'name'           => 'order_total',
            'type'           => 'calculation',
            'sum_source'     => 'self',
            'formula'        => '{price} * {qty}',
            'output_format'  => 'currency',
            'decimal_places' => 2,
            'currency_symbol' => '$',
            'symbol_position' => 'prefix',
            'thousands_sep'  => ',',
            'decimal_sep'    => '.',
        ],
    ],
    'location' => [ [ [ 'param' => 'post_type', 'operator' => '==', 'value' => 'order' ] ] ],
] );
Example: repeater line-item total
php
[
    'key'          => 'field_grand_total',
    'label'        => 'Grand Total',
    'name'         => 'grand_total',
    'type'         => 'calculation',
    'sum_source'   => 'repeater',
    'sum_repeater' => 'line_items',      // sibling repeater name
    'sum_field'    => 'row_total',       // numeric sub-field name
    'output_format' => 'currency',
    'currency_symbol' => '$',
    'decimal_places'  => 2,
],

Reading a Calculation Field Value

get_field() returns the raw numeric value (a float/int) — never the formatted string.
php
$total = get_field( 'order_total', $post_id );
// Returns: 149.97 (float)

// Display formatted:
echo esc_html( get_field( 'order_total', $post_id ) ); // "149.97"

To apply the output formatting defined in the field settings, use:

php
$total    = get_field( 'order_total', $post_id );           // raw float
$settings = get_field_object( 'order_total', $post_id );    // field definition array
$formatted = fieldforge_format_calc_value( $total, $settings );
// Returns: '$149.97'
echo esc_html( $formatted );
fieldforge_format_calc_value( $value, $settings )
ParameterTypeDescription
$valuefloatintnullRaw numeric value returned by get_field().
$settingsarrayField definition array (from get_field_object() or your own array with the keys listed above).

Returns string. If $value is null or non-numeric, returns '0' (or formatted '$0.00' etc.).

Security note: Field Forge never executes formula strings with eval() or any PHP dynamic evaluation. The shunting-yard parser accepts only digits, decimal points, and the operators + - * / ( ). Any other character causes the formula result to be 0. The posted raw total from the metabox hidden input is also never trusted — the server recomputes and overwrites on save.

PHP Aggregation Helper (Free)

php
fieldforge_aggregate_field(
    string $field,
    string $post_type = 'post',
    string $status    = 'publish',
    string $op        = 'sum'
) : float|int

Reads wp_fieldforge_values directly and returns an aggregate. A parent_id = 0 guard on the query prevents repeater sub-field rows from being counted more than once.

ParameterValuesDescription
$fieldfield name stringThe field name (slug), not the key.
$post_typeany post type slugDefault: 'post'.
$status'publish', 'any', etc.Default: 'publish'.
$op'sum' 'avg' 'min' 'max' 'count'Aggregation operation.
php
// Total donations across all published campaign posts
$total = fieldforge_aggregate_field( 'donation', 'campaign', 'publish', 'sum' );
echo '$' . number_format( $total, 2 );

// Average product rating
$avg = fieldforge_aggregate_field( 'star_rating', 'product', 'publish', 'avg' );

// Number of entries
$count = fieldforge_aggregate_field( 'donation', 'campaign', 'publish', 'count' );

Shortcode (Free)

Place in any post, page, or widget area.

Attributes:
AttributeRequiredDefaultDescription
fieldYesField name to aggregate.
post_typeNo'post'Post type slug.
statusNo'publish'Post status filter.
opNo'sum'sum avg min max count
formatNo'number''number' 'currency' 'percentage'
symbolNo'$'Currency or percentage symbol.
decimalsNo'2'Number of decimal places.
Examples:
text
0
text
0
text
0.00

REST /aggregate Endpoint (PRO)

Requires: rest_api_fields Pro capability. Default permission: editor-tier read (WP capability edit_posts). Request:
text
GET /wp-json/fieldforge/v1/aggregate?field=donation&post_type=campaign&op=sum&format=currency&symbol=$&decimals=2
Query parameterRequiredDescription
fieldYesField name. Missing → 400.
post_typeNoDefault 'post'.
statusNoDefault 'publish'.
opNosum avg min max count. Default 'sum'.
formatNo'number' 'currency' 'percentage'. Default 'number'.
decimalsNoDefault 2.
symbolNoDefault '$'.
Response (200):
json
{
  "field":     "donation",
  "post_type": "campaign",
  "status":    "publish",
  "op":        "sum",
  "value":     4250.00,
  "formatted": "$4,250.00"
}
Error responses: 400 — missing field parameter ('A field name is required.'). 401 — unauthenticated request (default; login required). 403 — authenticated but insufficient capability. Permission filter:
php
// Allow subscribers to read the aggregate endpoint (example)
add_filter( 'fieldforge/rest/aggregate_permission', function( $cap ) {
    return 'read'; // WP capability string
} );

The filter receives the current required capability string and must return a capability string.

GraphQL fieldForgeAggregate (PRO)

Requires: graphql Pro capability and WPGraphQL active. Query:
graphql
query GetDonationTotal {
  fieldForgeAggregate(
    fieldName: "donation"
    postType:  "campaign"
    status:    "publish"
  ) {
    fieldName
    postType
    sum
    avg
    min
    max
    count
  }
}
Response:
json
{
  "data": {
    "fieldForgeAggregate": {
      "fieldName": "donation",
      "postType":  "campaign",
      "sum":   4250.00,
      "avg":   354.17,
      "min":   10.00,
      "max":   1000.00,
      "count": 12
    }
  }
}

All five aggregate values (sum, avg, min, max, count) are always returned in a single query — select only the fields you need.

Forge AI Assistant Online

Hi! I'm the Field Forge AI assistant. Ask me anything about the plugin — setup, features, troubleshooting, or development.

Just now
Powered by Forge AI · Browse docs