Skip to content

Commit 8a31fe3

Browse files
committed
chore: sync Settings API v2.9.0 — add helper methods, fix sensitive field sanitization, update Tom Select
1 parent 72cedad commit 8a31fe3

7 files changed

Lines changed: 170 additions & 519 deletions

includes/admin/settings/class-settings-api.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
/**
1919
* Settings API wrapper class
2020
*
21-
* @version 2.8.2
21+
* @version 2.9.0
2222
*/
2323
class Settings_API {
2424

@@ -27,7 +27,7 @@ class Settings_API {
2727
*
2828
* @var string
2929
*/
30-
public const VERSION = '2.8.2';
30+
public const VERSION = '2.9.0';
3131

3232
/**
3333
* Settings Key.

includes/admin/settings/class-settings-form.php

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -197,45 +197,47 @@ protected function get_allowed_html(): array {
197197

198198
$form_tags = array(
199199
'input' => array(
200-
'type' => true,
201-
'name' => true,
202-
'id' => true,
203-
'value' => true,
204-
'class' => true,
205-
'style' => true,
206-
'checked' => true,
207-
'disabled' => true,
208-
'readonly' => true,
209-
'required' => true,
210-
'placeholder' => true,
211-
'size' => true,
212-
'min' => true,
213-
'max' => true,
214-
'step' => true,
215-
'multiple' => true,
216-
'autocomplete' => true,
200+
'type' => true,
201+
'name' => true,
202+
'id' => true,
203+
'value' => true,
204+
'class' => true,
205+
'style' => true,
206+
'checked' => true,
207+
'disabled' => true,
208+
'readonly' => true,
209+
'required' => true,
210+
'placeholder' => true,
211+
'size' => true,
212+
'min' => true,
213+
'max' => true,
214+
'step' => true,
215+
'multiple' => true,
216+
'autocomplete' => true,
217217
// Tom Select data attributes (built-in Settings API feature).
218-
'data-wp-prefix' => true,
219-
'data-wp-action' => true,
220-
'data-wp-nonce' => true,
221-
'data-wp-endpoint' => true,
222-
'data-ts-config' => true,
218+
'data-wp-prefix' => true,
219+
'data-wp-action' => true,
220+
'data-wp-nonce' => true,
221+
'data-wp-endpoint' => true,
222+
'data-ts-config' => true,
223+
'data-wp-extra-fields' => true,
223224
),
224225
'select' => array(
225-
'id' => true,
226-
'name' => true,
227-
'class' => true,
228-
'style' => true,
229-
'disabled' => true,
230-
'multiple' => true,
231-
'size' => true,
232-
'autocomplete' => true,
226+
'id' => true,
227+
'name' => true,
228+
'class' => true,
229+
'style' => true,
230+
'disabled' => true,
231+
'multiple' => true,
232+
'size' => true,
233+
'autocomplete' => true,
233234
// Tom Select data attributes (built-in Settings API feature).
234-
'data-wp-prefix' => true,
235-
'data-wp-action' => true,
236-
'data-wp-nonce' => true,
237-
'data-wp-endpoint' => true,
238-
'data-ts-config' => true,
235+
'data-wp-prefix' => true,
236+
'data-wp-action' => true,
237+
'data-wp-nonce' => true,
238+
'data-wp-endpoint' => true,
239+
'data-ts-config' => true,
240+
'data-wp-extra-fields' => true,
239241
),
240242
'option' => array(
241243
'value' => true,

includes/admin/settings/class-settings-sanitize.php

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,13 @@ public function sanitize_sensitive_field( $value, $key ) {
277277

278278
$stored_encrypted_key = $this->get_option( $key );
279279

280+
// Empty input clears the stored value.
281+
if ( '' === (string) $value ) {
282+
return '';
283+
}
284+
280285
// If input is masked, return existing encrypted key.
281-
if ( empty( $value ) || strpos( $value, '**' ) !== false ) {
286+
if ( is_string( $value ) && strpos( $value, '**' ) !== false ) {
282287
return $stored_encrypted_key;
283288
}
284289

@@ -355,12 +360,18 @@ public function sanitize_repeater_field( $value, $field = array() ) {
355360
// Get the field type from the subfield configuration.
356361
$field_type = isset( $field_config['type'] ) ? $field_config['type'] : 'text';
357362

358-
// Preserve existing encrypted sensitive values when form submits masked/empty value.
359-
if ( 'sensitive' === $field_type && ( empty( $field_value ) || ( is_string( $field_value ) && false !== strpos( $field_value, '**' ) ) ) ) {
360-
if ( $existing_row && isset( $existing_row['fields'][ $field_key ] ) ) {
361-
$sanitized_row['fields'][ $field_key ] = $existing_row['fields'][ $field_key ];
363+
// For sensitive fields, distinguish empty (clear) from masked (preserve).
364+
if ( 'sensitive' === $field_type ) {
365+
if ( '' === (string) $field_value ) {
366+
$sanitized_row['fields'][ $field_key ] = '';
367+
continue;
368+
}
369+
if ( is_string( $field_value ) && false !== strpos( $field_value, '**' ) ) {
370+
if ( $existing_row && isset( $existing_row['fields'][ $field_key ] ) ) {
371+
$sanitized_row['fields'][ $field_key ] = $existing_row['fields'][ $field_key ];
372+
}
373+
continue;
362374
}
363-
continue;
364375
}
365376

366377
// Call the appropriate sanitization method.

includes/admin/settings/js/tom-select-init.js

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,46 @@
176176
return;
177177
}
178178

179+
// Build base payload.
180+
const payload = {
181+
action: action,
182+
nonce: nonce,
183+
q: query,
184+
endpoint: endpoint
185+
};
186+
187+
// Optional: harvest sibling fields from the closest repeater
188+
// row and merge them into the payload. Declared on the input
189+
// as data-wp-extra-fields='{"row_pat":"pat","row_id":"row_id"}'
190+
// — meaning send the closest row's `[pat]` input as `row_pat`
191+
// and `[row_id]` as `row_id`.
192+
const extraAttr = element.getAttribute('data-wp-extra-fields');
193+
if (extraAttr) {
194+
try {
195+
const map = JSON.parse(extraAttr);
196+
const row = element.closest('.wz-repeater-item');
197+
if (row && map && typeof map === 'object') {
198+
Object.keys(map).forEach(function (key) {
199+
const suffix = map[key];
200+
if (!suffix) {
201+
return;
202+
}
203+
const sibling = row.querySelector('[name$="[' + suffix + ']"]');
204+
if (sibling && typeof sibling.value === 'string') {
205+
payload[key] = sibling.value;
206+
}
207+
});
208+
}
209+
} catch (e) {
210+
console.error('Error parsing data-wp-extra-fields:', extraAttr, e);
211+
}
212+
}
213+
179214
$.ajax({
180215
url: ajaxurl,
181216
type: 'POST',
182217
dataType: 'json',
183-
data: {
184-
action: action,
185-
nonce: nonce,
186-
q: query,
187-
endpoint: endpoint
188-
},
218+
data: payload,
189219
error: function () {
190220
callback();
191221
},

includes/admin/settings/js/tom-select-init.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)