2021-09-21 15:01:08 +02:00
< ? php
2021-09-24 18:39:19 +02:00
if ( ! defined ( 'ABSPATH' ) ) {
exit ; // Exit if accessed directly
}
2021-09-21 15:01:08 +02:00
2021-09-24 18:39:19 +02:00
if ( ! class_exists ( 'acf_form_customizer' ) ) :
2021-09-21 15:01:08 +02:00
2021-09-24 18:39:19 +02:00
class acf_form_customizer {
/*
* __construct
*
* This function will setup the class functionality
*
* @ type function
* @ date 5 / 03 / 2014
* @ since 5.0 . 0
*
* @ param n / a
* @ return n / a
*/
function __construct () {
// vars
$this -> preview_values = array ();
$this -> preview_fields = array ();
$this -> preview_errors = array ();
// actions
add_action ( 'customize_controls_init' , array ( $this , 'customize_controls_init' ) );
add_action ( 'customize_preview_init' , array ( $this , 'customize_preview_init' ), 1 , 1 );
add_action ( 'customize_save' , array ( $this , 'customize_save' ), 1 , 1 );
// save
add_filter ( 'widget_update_callback' , array ( $this , 'save_widget' ), 10 , 4 );
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/*
* admin_enqueue_scripts
*
* This action is run after post query but before any admin script / head actions .
* It is a good place to register all actions .
*
* @ type action ( admin_enqueue_scripts )
* @ date 26 / 01 / 13
* @ since 3.6 . 0
*
* @ param N / A
* @ return N / A
*/
function customize_controls_init () {
// load acf scripts
acf_enqueue_scripts (
array (
'context' => 'customize_controls' ,
)
);
// actions
add_action ( 'acf/input/admin_footer' , array ( $this , 'admin_footer' ), 1 );
}
/*
* save_widget
*
* This function will hook into the widget update filter and save ACF data
*
* @ type function
* @ date 27 / 05 / 2015
* @ since 5.2 . 3
*
* @ param $instance ( array ) widget settings
* @ param $new_instance ( array ) widget settings
* @ param $old_instance ( array ) widget settings
* @ param $widget ( object ) widget info
* @ return $instance
*/
function save_widget ( $instance , $new_instance , $old_instance , $widget ) {
// bail ealry if not valid (customize + acf values + nonce)
if ( ! isset ( $_POST [ 'wp_customize' ] ) || ! isset ( $new_instance [ 'acf' ] ) || ! acf_verify_nonce ( 'widget' ) ) {
return $instance ;
}
2021-09-21 15:01:08 +02:00
// vars
2021-09-24 18:39:19 +02:00
$data = array (
'post_id' => " widget_ { $widget -> id } " ,
'values' => array (),
'fields' => array (),
);
// append values
$data [ 'values' ] = $new_instance [ 'acf' ];
// append fields (name => key relationship) - used later in 'acf/get_field_reference' for customizer previews
foreach ( $data [ 'values' ] as $k => $v ) {
// get field
$field = acf_get_field ( $k );
// continue if no field
if ( ! $field ) {
continue ;
}
// update
$data [ 'fields' ][ $field [ 'name' ] ] = $field [ 'key' ];
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
// append data to instance
$instance [ 'acf' ] = $data ;
// return
return $instance ;
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/*
* settings
*
* This function will return an array of cutomizer settings that include ACF data
* similar to `$customizer->settings();`
*
* @ type function
* @ date 22 / 03 / 2016
* @ since 5.3 . 2
*
* @ param $customizer ( object )
* @ return $value ( mixed )
*/
function settings ( $customizer ) {
// vars
$data = array ();
$settings = $customizer -> settings ();
// bail ealry if no settings
if ( empty ( $settings ) ) {
return false ;
}
// loop over settings
foreach ( $settings as $setting ) {
// vars
$id = $setting -> id ;
// verify settings type
if ( substr ( $id , 0 , 6 ) == 'widget' || substr ( $id , 0 , 7 ) == 'nav_menu' ) {
// allow
} else {
continue ;
}
// get value
$value = $setting -> post_value ();
// bail early if no acf
if ( ! is_array ( $value ) || ! isset ( $value [ 'acf' ] ) ) {
continue ;
}
// set data
$setting -> acf = $value [ 'acf' ];
// append
$data [] = $setting ;
}
// bail ealry if no settings
if ( empty ( $data ) ) {
return false ;
}
// return
return $data ;
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/*
* customize_preview_init
*
* This function is called when customizer preview is initialized
*
* @ type function
* @ date 22 / 03 / 2016
* @ since 5.3 . 2
*
* @ param $customizer ( object )
* @ return n / a
*/
function customize_preview_init ( $customizer ) {
// get customizer settings (widgets)
$settings = $this -> settings ( $customizer );
// bail ealry if no settings
if ( empty ( $settings ) ) {
return ;
}
// append values
foreach ( $settings as $setting ) {
// get acf data
$data = $setting -> acf ;
// append acf_value to preview_values
$this -> preview_values [ $data [ 'post_id' ] ] = $data [ 'values' ];
$this -> preview_fields [ $data [ 'post_id' ] ] = $data [ 'fields' ];
}
// bail ealry if no preview_values
if ( empty ( $this -> preview_values ) ) {
return ;
}
// add filters
add_filter ( 'acf/pre_load_value' , array ( $this , 'pre_load_value' ), 10 , 3 );
add_filter ( 'acf/pre_load_reference' , array ( $this , 'pre_load_reference' ), 10 , 3 );
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/**
* pre_load_value
*
* Used to inject preview value
*
* @ date 2 / 2 / 18
* @ since 5.6 . 5
*
* @ param type $var Description . Default .
* @ return type Description .
*/
function pre_load_value ( $value , $post_id , $field ) {
// check
if ( isset ( $this -> preview_values [ $post_id ][ $field [ 'key' ] ] ) ) {
return $this -> preview_values [ $post_id ][ $field [ 'key' ] ];
}
// return
return $value ;
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/**
* pre_load_reference
*
* Used to inject preview value
*
* @ date 2 / 2 / 18
* @ since 5.6 . 5
*
* @ param type $var Description . Default .
* @ return type Description .
*/
function pre_load_reference ( $field_key , $field_name , $post_id ) {
// check
if ( isset ( $this -> preview_fields [ $post_id ][ $field_name ] ) ) {
return $this -> preview_fields [ $post_id ][ $field_name ];
}
// return
return $field_key ;
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/*
* customize_save
*
* This function is called when customizer saves a widget .
* Normally , the widget_update_callback filter would be used , but the customizer disables this and runs a custom action
* class - customizer - settings . php will save the widget data via the function set_root_value which uses update_option
*
* @ type function
* @ date 22 / 03 / 2016
* @ since 5.3 . 2
*
* @ param $customizer ( object )
* @ return n / a
*/
function customize_save ( $customizer ) {
// get customizer settings (widgets)
$settings = $this -> settings ( $customizer );
// bail ealry if no settings
if ( empty ( $settings ) ) {
return ;
}
// append values
foreach ( $settings as $setting ) {
// get acf data
$data = $setting -> acf ;
// save acf data
acf_save_post ( $data [ 'post_id' ], $data [ 'values' ] );
// remove [acf] data from saved widget array
$id_data = $setting -> id_data ();
add_filter ( 'pre_update_option_' . $id_data [ 'base' ], array ( $this , 'pre_update_option' ), 10 , 3 );
}
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
/*
* pre_update_option
*
* this function will remove the [ acf ] data from widget insance
*
* @ type function
* @ date 22 / 03 / 2016
* @ since 5.3 . 2
*
* @ param $post_id ( int )
* @ return $post_id ( int )
*/
function pre_update_option ( $value , $option , $old_value ) {
// bail ealry if no value
if ( empty ( $value ) ) {
return $value ;
}
// loop over widgets
// WP saves all widgets (of the same type) as an array of widgets
foreach ( $value as $i => $widget ) {
// bail ealry if no acf
if ( ! isset ( $widget [ 'acf' ] ) ) {
continue ;
}
// remove widget
unset ( $value [ $i ][ 'acf' ] );
}
// return
return $value ;
}
/*
* admin_footer
*
* This function will add some custom HTML to the footer of the edit page
*
* @ type function
* @ date 11 / 06 / 2014
* @ since 5.0 . 0
*
* @ param n / a
* @ return n / a
*/
function admin_footer () {
?>
2021-09-21 15:01:08 +02:00
< script type = " text/javascript " >
( function ( $ ) {
// customizer saves widget on any input change, so unload is not needed
acf . unload . active = 0 ;
// hack customizer function to remove bug caused by WYSIWYG field using aunique ID
// customizer compares returned AJAX HTML with the HTML of the widget form.
// the _getInputsSignature() function is used to generate a string based of input name + id.
// because ACF generates a unique ID on the WYSIWYG field, this string will not match causing the preview function to bail.
// an attempt was made to remove the WYSIWYG unique ID, but this caused multiple issues in the wp-admin and altimately doesn't make sense with the tinymce rule that all editors must have a unique ID.
// source: wp-admin/js/customize-widgets.js
// vars
var WidgetControl = wp . customize . Widgets . WidgetControl . prototype ;
// backup functions
WidgetControl . __getInputsSignature = WidgetControl . _getInputsSignature ;
WidgetControl . __setInputState = WidgetControl . _setInputState ;
// modify __getInputsSignature
WidgetControl . _getInputsSignature = function ( inputs ) {
// vars
var signature = this . __getInputsSignature ( inputs );
safe = [];
// split
signature = signature . split ( ';' );
// loop
for ( var i in signature ) {
// vars
var bit = signature [ i ];
// bail ealry if acf is found
if ( bit . indexOf ( 'acf' ) !== - 1 ) continue ;
// append
safe . push ( bit );
}
// update
signature = safe . join ( ';' );
// return
return signature ;
};
// modify _setInputState
// this function deosn't seem to run on widget title/content, only custom fields
// either way, this function is not needed and will break ACF fields
WidgetControl . _setInputState = function ( input , state ) {
return true ;
};
})( jQuery );
</ script >
2021-09-24 18:39:19 +02:00
< ? php
}
2021-09-21 15:01:08 +02:00
}
2021-09-24 18:39:19 +02:00
new acf_form_customizer ();
2021-09-21 15:01:08 +02:00
endif ;
2021-09-24 18:39:19 +02:00
?>