Skip to content

Commit 6b29ec4

Browse files
committed
Normalize fields when unparse meta box.
- Always keep it as a numeric array. - Remove prefix from field IDs for the settings, that can be used for export, builder, local JSON. - Add prefix to field IDs for parsed meta box, that's ready for registering.
1 parent 8934d35 commit 6b29ec4

File tree

2 files changed

+68
-33
lines changed

2 files changed

+68
-33
lines changed

src/Prefixer.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
namespace MBBParser;
3+
4+
class Prefixer {
5+
public static function add( array &$fields, string $prefix ): void {
6+
if ( ! $prefix ) {
7+
return;
8+
}
9+
foreach ( $fields as &$field ) {
10+
if ( ! empty( $field['id'] ) && ! str_starts_with( $field['id'], $prefix ) ) {
11+
$field['id'] = $prefix . $field['id'];
12+
}
13+
if ( ! empty( $field['fields'] ) && is_array( $field['fields'] ) ) {
14+
self::add( $field['fields'], $prefix );
15+
}
16+
}
17+
}
18+
19+
public static function remove( array &$fields, string $prefix ): void {
20+
if ( ! $prefix ) {
21+
return;
22+
}
23+
foreach ( $fields as &$field ) {
24+
if ( ! empty( $field['id'] ) && str_starts_with( $field['id'], $prefix ) ) {
25+
$field['id'] = substr( $field['id'], strlen( $prefix ) );
26+
}
27+
if ( isset( $field['fields'] ) && is_array( $field['fields'] ) ) {
28+
self::remove( $field['fields'], $prefix );
29+
}
30+
}
31+
}
32+
}

src/Unparsers/MetaBox.php

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
namespace MBBParser\Unparsers;
33

4+
use MBBParser\Prefixer;
5+
46
/**
57
* This class is the inverse of the parser.
68
* We convert the parsed data back to the format that can be saved to the database.
@@ -92,35 +94,14 @@ public function to_minimal_format() {
9294

9395
// Strip prefix from field IDs before exporting to JSON (minimal format)
9496
if ( ! empty( $settings['fields'] ) && is_array( $settings['fields'] ) ) {
95-
$prefix = $settings['prefix'] ?? '';
96-
97-
if ( $prefix ) {
98-
$this->strip_prefix_from_fields( $settings['fields'], $prefix );
99-
}
97+
Prefixer::remove( $settings['fields'], $settings['prefix'] ?? '' );
10098
}
10199

102100
ksort( $settings );
103101

104102
return $settings;
105103
}
106104

107-
/**
108-
* Recursively strip prefix from field IDs (for export)
109-
*/
110-
private function strip_prefix_from_fields( array &$fields, string $prefix ): void {
111-
foreach ( $fields as &$field ) {
112-
// Strip prefix from field ID
113-
if ( isset( $field['id'] ) && str_starts_with( $field['id'], $prefix ) ) {
114-
$field['id'] = substr( $field['id'], strlen( $prefix ) );
115-
}
116-
117-
// Recursively strip from sub-fields (for group fields)
118-
if ( ! empty( $field['fields'] ) && is_array( $field['fields'] ) ) {
119-
$this->strip_prefix_from_fields( $field['fields'], $prefix );
120-
}
121-
}
122-
}
123-
124105
public function unparse_schema() {
125106
$schema = $this->lookup( [ '$schema' ], '' );
126107
if ( ! empty( $schema ) ) {
@@ -281,22 +262,53 @@ public function unparse_modified() {
281262
return $this;
282263
}
283264

284-
public function unparse_meta_box() {
265+
/**
266+
* Unparse the meta box.
267+
*
268+
* For fields:
269+
* - Always keep it as a numeric array.
270+
* - Remove prefix from field IDs for the settings, that can be used for export, builder, local JSON.
271+
* - Add prefix to field IDs for parsed meta box, that's ready for registering.
272+
*/
273+
public function unparse_meta_box(): static {
285274
// If not meta box, return
286275
if ( $this->detect_post_type() !== 'meta-box' ) {
287276
return $this;
288277
}
289278

279+
$prefix = $this->lookup( [ 'prefix', 'settings.prefix' ], '' );
280+
281+
// If meta box is already parsed, normalize the fields array.
290282
if ( isset( $this->meta_box ) && is_array( $this->meta_box ) ) {
291283
// Fix: error on earlier versions that saved fields as object
292-
$fields = array_values( $this->meta_box['fields'] ?? [] );
284+
$fields = $this->meta_box['fields'] ?? [];
285+
$fields = array_values( $fields );
286+
287+
// Remove prefix from field IDs for the settings, that can be used for export, builder, local JSON.
288+
Prefixer::remove( $fields, $prefix );
289+
$this->fields = $fields;
290+
291+
// Add prefix to field IDs for parsed meta box, that's ready for registering.
292+
Prefixer::add( $fields, $prefix );
293293
$this->settings['meta_box']['fields'] = $fields;
294294

295295
return $this;
296296
}
297297

298+
// If meta box is not parsed, normalize the fields array.
299+
$fields = $this->fields ?: [];
300+
$fields = array_values( $fields );
301+
302+
// Remove prefix from field IDs for the settings, that can be used for export, builder, local JSON.
303+
Prefixer::remove( $fields, $prefix );
304+
$this->fields = $fields;
305+
298306
$meta_box = $this->get_settings();
299307

308+
// Add prefix to field IDs for parsed meta box, that's ready for registering.
309+
Prefixer::add( $fields, $prefix );
310+
$meta_box['fields'] = $fields;
311+
300312
foreach ( $this->get_unneeded_keys() as $key ) {
301313
unset( $meta_box[ $key ] );
302314
}
@@ -475,21 +487,12 @@ public function unparse_fields() {
475487
}
476488

477489
public function convert_fields_for_builder( $fields = [] ): array {
478-
// Get prefix to strip from field IDs during export
479-
$prefix = $this->settings['settings']['prefix'] ?? '';
480-
481490
foreach ( $fields as $id => $field ) {
482491
$unparser = new Field( $field );
483492
$unparser->unparse();
484493

485494
$field = $unparser->get_settings();
486495

487-
// Strip prefix from field ID for clean export
488-
if ( $prefix && isset( $field['id'] ) && str_starts_with( $field['id'], $prefix ) ) {
489-
$field['id'] = substr( $field['id'], strlen( $prefix ) );
490-
}
491-
492-
// Recursively process sub-fields
493496
if ( isset( $field['fields'] ) && is_array( $field['fields'] ) ) {
494497
$field['fields'] = $this->convert_fields_for_builder( $field['fields'] );
495498
}

0 commit comments

Comments
 (0)