ACF compatibility
While ACF is active
While ACF (or ACF PRO, or Secure Custom Fields) is active, WP Freeform Fields leaves it alone:
- ACF-named functions are not defined, and
acf/…hooks are not fired; acf-jsonfolders are not read, and blocks whoseblock.jsonhas only anacfkey stay ACF's;- an admin notice explains how to finish the switch.
Without ACF
The compatibility layer is on. Turn it off with WPFF_ACF_COMPAT or the wpff/acf_compat filter.
- Functions are defined on
setup_theme, before the theme'sfunctions.php. If the active theme bundles its own copy of ACF, they are not defined at all, so the theme's ACF can load (filter:wpff/theme_bundles_acf). - Hooks: each of these runs as
wpff/…and then asacf/…, with ACF's arguments and/type=,/name=,/key=variants where ACF has them:init,include_fields,load_field,load_value,format_value,update_value,validate_value,prepare_field,load_field_groups,save_post,pre_save_post,submit_form,settings/{name},fields/{post_object|relationship|page_link|taxonomy|user}/query,input/admin_enqueue_scripts. Duringacf/save_post,$_POST['acf']holds the submitted values, as ACF callbacks expect. - Extra functions:
get_field_objects(),acf_get_field(),acf_get_fields(),acf_get_field_group(),acf_get_field_groups(),acf_add_local_field(),update_sub_field(),delete_sub_field(),acf_esc_html(),acf_get_options_page(),acf_get_options_pages(),acf_form_head(),acf_form(). Theirwpff_versions:wpff_get_field_objects(),wpff_get_field_settings(),wpff_get_group_fields(),wpff_get_field_groups(),wpff_update_sub_field(),wpff_delete_sub_field(). - Raw values (
get_field( $name, $id, false ),get_fields( $id, false )) have ACF's shape: group, repeater and flexible content values are keyed by field keys, and empty rows arefalse. - Before migration, field groups and options pages saved in ACF's tables are read from there (read-only,
sourceisacf). Turn it off with thewpff/read_acf_groupsfilter. The list is cached in a transient that changes when ACF's groups change. - ACF to REST API: while the
acf-to-rest-apiplugin is active and ACF is not, itsacf/v3/{rest_base}/{id}[/{field}]andacf/v3/options/{id}[/{field}]routes and theacfproperty inwp/v2are served from WP Freeform Fields. Only fields of the groups shown on the object are served, never other meta or options, and Password fields are left out. Posts, terms and users follow the core REST API's visibility rules. Options page fields need the page's capability unless their group is shown in REST; thewpff/acf_to_rest_api/public_optionsfilter makes them public, as in the original. Filter:wpff/emulate_acf_to_rest_api.
Front-end forms
acf_form() takes ACF's settings: id, post_id ('new_post' with new_post args creates a post), field_groups, fields, post_title, post_content, return (%post_id%, %post_url%), html_before_fields, html_after_fields, submit_value, updated_message, honeypot, kses and others. Submissions are saved on template_redirect, so acf_form_head() is optional.
The form settings travel signed: a visitor cannot point the form at another post. As in ACF, the template decides who sees the form. Validation runs on the server, and rejected fields are highlighted on the returned page.
See also Known differences.