| 1 |
<?php |
| 2 |
|
| 3 |
namespace JFB_Modules\Option_Field; |
| 4 |
|
| 5 |
use Jet_Form_Builder\Generators\Base_V2; |
| 6 |
use Jet_Form_Builder\Generators\Registry; |
| 7 |
use Jet_Form_Builder\Blocks\Render\Base; |
| 8 |
|
| 9 |
// If this file is called directly, abort. |
| 10 |
if ( ! defined( 'WPINC' ) ) { |
| 11 |
die; |
| 12 |
} |
| 13 |
|
| 14 |
/** |
| 15 |
* HTML Attributes Injector for Auto-Update Feature. |
| 16 |
* |
| 17 |
* Injects data attributes into option field HTML for auto-update functionality. |
| 18 |
* These attributes are read by the frontend JavaScript watcher system. |
| 19 |
*/ |
| 20 |
class Html_Attributes_Injector { |
| 21 |
|
| 22 |
/** |
| 23 |
* Field types that support auto-update. |
| 24 |
* |
| 25 |
* @var array |
| 26 |
*/ |
| 27 |
private static $supported_types = array( |
| 28 |
'select-field', |
| 29 |
'checkbox-field', |
| 30 |
'radio-field', |
| 31 |
); |
| 32 |
|
| 33 |
/** |
| 34 |
* Initialize hooks. |
| 35 |
*/ |
| 36 |
public function __construct() { |
| 37 |
foreach ( self::$supported_types as $type ) { |
| 38 |
add_filter( |
| 39 |
"jet-form-builder/render/{$type}", |
| 40 |
array( $this, 'inject_attributes' ), |
| 41 |
10, |
| 42 |
2 |
| 43 |
); |
| 44 |
} |
| 45 |
} |
| 46 |
|
| 47 |
/** |
| 48 |
* Inject auto-update attributes into field args. |
| 49 |
* |
| 50 |
* This filter is called before the field template is rendered, |
| 51 |
* allowing us to add data attributes that will be applied via |
| 52 |
* $this->add_attribute() in the template. |
| 53 |
* |
| 54 |
* @param array $args Field render args. |
| 55 |
* @param Base $render_base Render instance. |
| 56 |
* |
| 57 |
* @return array Modified args with injected attributes. |
| 58 |
*/ |
| 59 |
public function inject_attributes( $args, $render_base ) { |
| 60 |
// Only proceed if generator_auto_update is enabled |
| 61 |
if ( empty( $args['generator_auto_update'] ) ) { |
| 62 |
return $args; |
| 63 |
} |
| 64 |
|
| 65 |
// Only proceed if field uses generator |
| 66 |
if ( empty( $args['field_options_from'] ) || 'generate' !== $args['field_options_from'] ) { |
| 67 |
return $args; |
| 68 |
} |
| 69 |
|
| 70 |
// Only proceed if generator is set |
| 71 |
if ( empty( $args['generator_function'] ) ) { |
| 72 |
return $args; |
| 73 |
} |
| 74 |
|
| 75 |
// Build data attributes array |
| 76 |
$data_attrs = array(); |
| 77 |
$generator = Registry::instance()->get( $args['generator_function'] ); |
| 78 |
|
| 79 |
// Core auto-update identification |
| 80 |
$data_attrs['data-jfb-auto-update'] = '1'; |
| 81 |
$data_attrs['data-generator-id'] = $args['generator_function']; |
| 82 |
$data_attrs['data-field-name'] = $args['name']; |
| 83 |
$data_attrs['data-field-type'] = $render_base->get_name(); |
| 84 |
|
| 85 |
// Listen field configuration |
| 86 |
if ( ! empty( $args['generator_listen_field'] ) ) { |
| 87 |
$listen_to = $args['generator_listen_field']; |
| 88 |
|
| 89 |
// Support both string (single field) and array (multiple fields) |
| 90 |
if ( is_array( $listen_to ) ) { |
| 91 |
// Multiple fields: store as JSON |
| 92 |
$data_attrs['data-listen-to'] = wp_json_encode( $listen_to ); |
| 93 |
$data_attrs['data-listen-to-multiple'] = '1'; |
| 94 |
} else { |
| 95 |
// Single field: store as string (backwards compat) |
| 96 |
$data_attrs['data-listen-to'] = $listen_to; |
| 97 |
} |
| 98 |
} |
| 99 |
|
| 100 |
// Require all listened fields to be filled before triggering update. |
| 101 |
// Also check legacy attribute name for backward compatibility with saved forms. |
| 102 |
if ( ! empty( $args['generator_require_all_filled'] ) || ! empty( $args['generator_listen_all'] ) ) { |
| 103 |
$data_attrs['data-require-all-filled'] = '1'; |
| 104 |
} |
| 105 |
|
| 106 |
// Button trigger configuration |
| 107 |
if ( ! empty( $args['generator_update_on_button'] ) ) { |
| 108 |
$data_attrs['data-update-on-button'] = $args['generator_update_on_button']; |
| 109 |
} |
| 110 |
|
| 111 |
if ( ! empty( $args['generator_update_on_button_class'] ) ) { |
| 112 |
$data_attrs['data-update-on-button-class'] = $args['generator_update_on_button_class']; |
| 113 |
} |
| 114 |
|
| 115 |
if ( $generator instanceof Base_V2 ) { |
| 116 |
$settings = ! empty( $args['generator_args'] ) && is_array( $args['generator_args'] ) |
| 117 |
? $generator->parse_generator_args( $args['generator_args'] ) |
| 118 |
: $generator->parse_settings( $args ); |
| 119 |
|
| 120 |
$data_attrs['data-empty-context-action'] = $generator->should_clear_on_empty_auto_update_context( $settings ) |
| 121 |
? 'clear' |
| 122 |
: 'fallback'; |
| 123 |
} |
| 124 |
|
| 125 |
// Cache timeout (in seconds) |
| 126 |
$cache_timeout = isset( $args['generator_cache_timeout'] ) ? absint( $args['generator_cache_timeout'] ) : 60; |
| 127 |
$data_attrs['data-cache-timeout'] = $cache_timeout; |
| 128 |
|
| 129 |
// Form ID for REST API calls |
| 130 |
$form_id = $render_base->form_id ?? 0; |
| 131 |
if ( $form_id ) { |
| 132 |
$data_attrs['data-form-id'] = absint( $form_id ); |
| 133 |
} |
| 134 |
|
| 135 |
// Store data attributes in args for template access |
| 136 |
if ( ! isset( $args['_jfb_data_attrs'] ) ) { |
| 137 |
$args['_jfb_data_attrs'] = array(); |
| 138 |
} |
| 139 |
$args['_jfb_data_attrs'] = array_merge( $args['_jfb_data_attrs'], $data_attrs ); |
| 140 |
|
| 141 |
// Enqueue the auto-update script when a field uses it |
| 142 |
$module = \Jet_Form_Builder\Plugin::instance()->module( 'option-field' ); |
| 143 |
if ( $module ) { |
| 144 |
wp_enqueue_script( $module->get_handle( 'auto-update' ) ); |
| 145 |
if ( wp_style_is( $module->get_handle( 'auto-update' ), 'registered' ) ) { |
| 146 |
wp_enqueue_style( $module->get_handle( 'auto-update' ) ); |
| 147 |
} |
| 148 |
} |
| 149 |
|
| 150 |
return $args; |
| 151 |
} |
| 152 |
|
| 153 |
/** |
| 154 |
* Helper method to render data attributes in template. |
| 155 |
* Can be called from field templates if needed. |
| 156 |
* |
| 157 |
* @param array $args Field render args. |
| 158 |
* |
| 159 |
* @return string HTML attributes string. |
| 160 |
*/ |
| 161 |
public static function render_data_attributes( array $args ): string { |
| 162 |
if ( empty( $args['_jfb_data_attrs'] ) ) { |
| 163 |
return ''; |
| 164 |
} |
| 165 |
|
| 166 |
$attrs = array(); |
| 167 |
|
| 168 |
foreach ( $args['_jfb_data_attrs'] as $key => $value ) { |
| 169 |
if ( '' !== $value ) { |
| 170 |
$attrs[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) ); |
| 171 |
} |
| 172 |
} |
| 173 |
|
| 174 |
return implode( ' ', $attrs ); |
| 175 |
} |
| 176 |
} |
| 177 |
|