Cybo Advanced Field EngineCyboweb Technologies · Documentation · v1.0.2

Transformations

A transformation changes a source value before it is checked and saved. A mapping can have several; they run in order, and a Collection column can have its own.

Built in

Name (name) In the screen Does Options
trim Remove spaces around the text " Villa " → "Villa" -
number Number "1.250,50" → 1250.5; not a number → error decimal_separator: . or ,
boolean Yes / no 1, true, yes, y, on, ja, oui, si, x → true, else false -
date Date from another format "29/09/2026" with d/m/Y → 2026-09-29 (Date), 2026-09-29 00:00:00 (Date and Time, publish date), H:i:s for Time format: a PHP date format, or timestamp
split Split text into a list "a, b, c" → ["a","b","c"] separator (default ,; \n for lines)
map_values Replace values 1=available / 0=sold pairs (one old=new per line); unmatched: keep, leave empty, or error
default_value Use a value when empty empty → the value value
strip_html Remove HTML <b>Hi</b> → Hi -
json Read JSON text '[1,2]' → [1,2] -
first_item First item of a list [5,6] → 5 -

Lookups (one query per batch)

Name In the screen Turns into an ID Options
imported_object Old ID → imported post, term or user the object another migration imported from that record source_key (empty: this migration), object_type
attachment Media library item by ID, URL or file path an attachment -
post Post by slug or ID an existing post post_type, by
term Term by slug, name or ID an existing term (never created) taxonomy, by
user User by e-mail, username or ID an existing user (never created) by

Every lookup has When nothing is found: Report an error (default; the record is not imported) or Leave it out and report a warning. Lists stay lists: [3, 4] → two IDs.

Your own

use Cybo\AdvancedFieldEngine\Connector\Transform\TransformFailed;

add_action( 'cafe_register_migration_transformers', function () {
	cafe_register_migration_transformer(
		'price_cents',
		'Cents → euros',
		function ( $value, array $options, $context ) {
			if ( ! is_numeric( $value ) ) {
				throw new TransformFailed( "“{$value}” is not a number of cents." );
			}

			return round( $value / 100, 2 );
		}
	);
} );
  • $value: the value so far (after the earlier transformations).
  • $options: what the administrator filled in (declare controls with the fourth argument: [ [ 'name' => 'factor', 'label' => 'Factor', 'type' => 'text' ] ]).
  • $context->record: the whole source record ($context->record->get( 'currency' )), $context->row inside a Collection column, $context->field (the target CAFE field or null), $context->target, $context->migration, $context->dry_run, and $context->warnings->add( 'text' ) for a warning that does not stop the record.

Throw TransformFailed (or return a WP_Error) to refuse a value: the record is reported and not written. Any other exception is reported as "The transformation … failed" without internal details. Keep messages free of secrets.

Lookups of your own

A transformation that queries something should implement Cybo\AdvancedFieldEngine\Connector\Transform\BatchTransformerInterface: its prime( $values, $options ) receives all values of a batch before transform() is called, so it can load them with one query. Extending Cybo\AdvancedFieldEngine\Connector\Transform\Lookup\AbstractLookup gives you that plus the When nothing is found option; implement lookup( $keys, $options, $context ) and not_found_message( $key ), and register an instance with cafe_register_migration_transformer( new My_Lookup() ).