Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"psr-4": {"MBBParser\\": "src/"}
},
"require": {
"php": ">=7.4",
"wpmetabox/support": "dev-master",
"riimu/kit-phpencoder": "^2.4"
}
Expand Down
18 changes: 18 additions & 0 deletions src/SettingsTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,41 @@

/**
* Use overloading magic methods for short syntax.
* Property accesses are recorded so unparse_custom_settings() can detect
* which keys were touched (= natively handled) vs untouched (= potentially custom).
*/
trait SettingsTrait {
protected $settings;

/**
* Keys accessed via __get / __set / __isset during this object's lifetime.
* Used by unparse_custom_settings() to detect natively-handled keys.
*
* @var string[]
*/
private array $accessed_keys = [];

public function get_settings(): array {
return $this->settings;
}

/** Return all keys that were accessed (touched) so far. */
public function get_accessed_keys(): array {
return $this->accessed_keys;
}

public function __get( string $key ) {
$this->accessed_keys[] = $key;
return $this->settings[ $key ] ?? null;
}

public function __set( string $key, $value ): void {
$this->accessed_keys[] = $key;
$this->settings[ $key ] = $value;
}

public function __isset( string $key ): bool {
$this->accessed_keys[] = $key;
return isset( $this->settings[ $key ] );
}

Expand Down
59 changes: 57 additions & 2 deletions src/Unparsers/Field.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,23 @@ class Field extends Base {

private $choice_types = [ 'select', 'radio', 'checkbox_list', 'select_advanced', 'button_group', 'image_select', 'autocomplete' ];

/**
* Native keys that no unparse_* method accesses via $this->key (magic method),
* so they are never auto-tracked by SettingsTrait. List them explicitly here to
* prevent unparse_custom_settings() from mis-classifying them as custom attributes.
*
* Every other native key is auto-tracked the moment any method reads or writes
* $this->key — no need to list those here.
*/
private const STRUCTURAL_KEYS = [
'type', 'id', '_id', 'name', 'std', 'placeholder',
'columns', 'field_name', '_state', 'input_attributes',
'multiple', 'fields', 'tab', 'validation',
'custom_settings', '_callback', 'options',
'limit', 'limit_type',
];


/**
* This is revert of parse method. While parse method converts to the minimal format,
* this method converts back to the original format.
Expand All @@ -33,13 +50,17 @@ public function unparse() {
->unparse_text_limiter()
->unparse_conditional_logic()
->unparse_tooltip()
->unparse_admin_columns()
->ensure_boolean( 'save_field' );
->unparse_admin_columns();

// Field-type handler must run BEFORE unparse_custom_settings() so its
// property accesses are tracked and not mis-classified as custom attributes.
$func = "unparse_field_{$this->type}";
if ( method_exists( $this, $func ) ) {
$this->$func();
}

$this->unparse_custom_settings();
$this->ensure_boolean( 'save_field' );
Comment thread
rilwis marked this conversation as resolved.
}

private function unparse_datalist() {
Expand Down Expand Up @@ -206,6 +227,40 @@ private function unparse_admin_columns() {
return $this;
}

/**
* Detect unknown top-level keys and move them into the custom_settings
* format `{ uid: { id, key, value } }` that the Builder UI renders in
* the "Custom Settings" tab.
*
* "Known" = auto-tracked by SettingsTrait + STRUCTURAL_KEYS pass-through list.
*/
private function unparse_custom_settings(): self {
$known = array_merge( $this->get_accessed_keys(), self::STRUCTURAL_KEYS );
$custom = $this->custom_settings ?? [];

foreach ( $this->settings as $key => $value ) {
if ( in_array( $key, $known, true ) ) {
continue;
}
Comment thread
rilwis marked this conversation as resolved.

$uid = uniqid();
$custom[ $uid ] = [
'id' => $uid,
'key' => $key,
'value' => ( is_array( $value ) || is_object( $value ) )
? wp_json_encode( $value )
: (string) $value,
];
unset( $this->settings[ $key ] );
}

if ( ! empty( $custom ) ) {
$this->custom_settings = $custom;
}

return $this;
}

public function unparse_default_values() {
$this->id = $this->id ?? uniqid();
$this->_id = $this->_id ?? $this->id;
Expand Down
Loading