acf_form_front::merge_form_meta │ protected │ ACF 6.8.4
Folds metadata from _acf_form_meta[] inputs into the primary form configuration so the multi-acf_form()-in-one-outer-<form> pattern works.
Non-field request-level args (post_id, return, new_post, kses) stay "last wins" via the primary form.
Метод класса: acf_form_front{}
Возвращает
array. The primary form with allowed-key extras and OR'd title/content flags.
Использование
// protected - в коде основоного (родительского) или дочернего класса
$result = $this->merge_form_meta( $form ): array;
- $form(массив) (обязательный)
- The primary form configuration loaded from
_acf_form.
Список изменений
Код acf_form_front::merge_form_meta() acf form front::merge form meta
ACF 6.8.8
protected function merge_form_meta( array $form ): array {
// phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified above in check_submit_form().
if ( empty( $_POST['_acf_form_meta'] ) || ! is_array( $_POST['_acf_form_meta'] ) ) {
return $form;
}
if ( empty( $_POST['_acf_render_id'] ) || ! is_scalar( $_POST['_acf_render_id'] ) ) {
return $form;
}
$expected_render_id = sanitize_text_field( wp_unslash( $_POST['_acf_render_id'] ) );
// wp_unslash only — sanitize_text_field would desync from the raw
// $acf_form_value hashed render-side.
$primary_form_value = ( isset( $_POST['_acf_form'] ) && is_scalar( $_POST['_acf_form'] ) )
? (string) wp_unslash( $_POST['_acf_form'] ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Must match render-side bytes hashed into the form anchor.
: '';
$expected_anchor = hash( 'sha256', $primary_form_value );
$primary_post_id = isset( $form['post_id'] ) ? (string) $form['post_id'] : '';
/**
* Filters how long a `_acf_form_meta[]` payload remains valid after the page that
* emitted it was rendered.
*
* @since 6.8.4
*
* @param int $ttl Allowed age of a meta payload, in seconds.
*/
$ttl = (int) apply_filters( 'acf/form/meta_ttl', DAY_IN_SECONDS );
$now = time();
$valid_metas = array();
$primary_present = false;
foreach ( $_POST['_acf_form_meta'] as $token ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Each $token is sanitized below before use.
if ( ! is_scalar( $token ) ) {
continue;
}
$decoded = json_decode( acf_decrypt( sanitize_text_field( $token ) ), true );
if ( ! is_array( $decoded ) ) {
continue;
}
if ( empty( $decoded['render_id'] ) || ! is_string( $decoded['render_id'] ) ) {
continue;
}
if ( ! hash_equals( $expected_render_id, $decoded['render_id'] ) ) {
continue;
}
if ( ! isset( $decoded['issued_at'] ) || ! is_numeric( $decoded['issued_at'] ) ) {
continue;
}
if ( ( $now - (int) $decoded['issued_at'] ) >= $ttl ) {
continue;
}
if ( ! empty( $decoded['form_anchor'] )
&& is_string( $decoded['form_anchor'] )
&& hash_equals( $expected_anchor, $decoded['form_anchor'] )
) {
$primary_present = true;
}
$valid_metas[] = $decoded;
}
if ( ! $primary_present ) {
return $form;
}
$extra_keys = array();
foreach ( $valid_metas as $decoded ) {
$target_post_id = isset( $decoded['target_post_id'] ) ? (string) $decoded['target_post_id'] : '';
if ( ! hash_equals( $primary_post_id, $target_post_id ) ) {
continue;
}
if ( ! empty( $decoded['allowed_field_keys'] ) && is_array( $decoded['allowed_field_keys'] ) ) {
foreach ( $decoded['allowed_field_keys'] as $key ) {
if ( is_scalar( $key ) ) {
$extra_keys[] = (string) $key;
}
}
}
if ( ! empty( $decoded['post_title'] ) ) {
$form['post_title'] = true;
}
if ( ! empty( $decoded['post_content'] ) ) {
$form['post_content'] = true;
}
}
// phpcs:enable WordPress.Security.NonceVerification.Missing
if ( $extra_keys ) {
$form['_additional_allowed_field_keys'] = array_values( array_unique( $extra_keys ) );
}
return $form;
}