Faulty 'text_list' update
Support › MB Custom Table › Faulty 'text_list' updateResolved
- This topic has 3 replies, 2 voices, and was last updated 4 years, 5 months ago by
Long Nguyen.
-
AuthorPosts
-
November 25, 2020 at 7:53 PM #23063
Antonius CezarHegyes
ParticipantHello!
I created a table like this (relevant columns shown only):
MB_Custom_Table_API::create( "{$wpdb->prefix}_characters", array( 'height_known' => 'BOOLEAN', 'height_imperial' => 'TEXT', 'height_metric' => 'DECIMAL(5, 2) UNSIGNED NOT NULL', ), array() );
And then I created a metabox like this (relevant custom fields only):
$meta_boxes[] = array( 'title' => esc_html__( 'Characters Extra Info', 'my_text_domain' ), 'id' => 'characters-extra-info', 'post_types' => array( CHARACTER_CPT_SLUG ), 'context' => 'normal', 'priority' => 'high', 'autosave' => true, 'storage_type' => 'custom_table', 'table' => "{$wpdb->prefix}_characters", 'fields' => [ [ 'id' => 'height_known', 'type' => 'switch', 'name' => esc_html__( 'Height known?', 'my_text_domain' ), 'std' => 0, 'style' => 'square', 'on_label' => 'Yes', 'off_label' => 'No', 'columns' => 4, 'tab' => 'biological-tab', ], [ 'id' => 'height_imperial', 'type' => 'text_list', 'name' => esc_html__( 'Imperial height', 'my_text_domain' ), 'options' => [ 'ft' => '', 'in' => '', ], 'columns' => 4, 'tab' => 'biological-tab', 'visible' => [ 'when' => [['height_known', '=', 1]], 'relation' => 'and', ], ], [ 'id' => 'height_metric', 'type' => 'text', 'name' => esc_html__( 'Metric height', 'my_text_domain' ), 'placeholder' => esc_html__( 'cm', 'my_text_domain' ), 'columns' => 4, 'readonly' => 1, 'tab' => 'biological-tab', 'visible' => [ 'when' => [['height_known', '=', 1]], 'relation' => 'and', ], ], ], 'tab_style' => 'default', 'tab_wrapper' => true, 'tabs' => array( 'biological-tab' => [ 'label' => 'Biological', 'icon' => 'dashicons-admin-users', ], ),
Here's the problem: the first time I set the 'height_imperial' field, everything is fine. The database column is NULL and it all works out nicely. For values "5 feet 7 inches", the database column will be:
a:2:{i:0;s:1:"5";i:1;s:1:"7";}
The next time I update the post, regardless of whether I change the values or not, the database changes to:
a:3:{i:0;s:0:"";i:1;s:1:"5";i:2;s:1:"7";}
That extra "0" at the beginning of the array causes the values to shift and the field is not displayed properly anymore, and it's saved wrongly from now on.
I was able to confirm with the filter 'rmwb_height_imperial_value' that the values passed on is correct, namely array(5,7) AND that it all works out perfectly if I disable the custom table storage.
November 30, 2020 at 7:03 PM #23116Antonius CezarHegyes
ParticipantI found the problem!
Since the 'text_list' field has the parameter 'multiple' set to true automatically by MetaBox, in the file /meta-box/inc/field.php, in the function 'save', the "Save cloned fields as multiple values instead serialized array" block is being called (lines 314-321).
Inside that function, there is a call to $storage->delete( $post_id, $name ).
Now, moving back to the MetaBox Custom Table plugin, in the function /inc/class-rwmb-table-storage.php there is the function "delete" around line 100. Inside, there is an "if" check for "$delete_all || ! $meta_value || $row[ $meta_key ] === $meta_value" and in there there is an assignment: $row[ $meta_key ] = "";
Because of that assignment to "", the function "add" a few lines above fails. Namely, when it calls $this->get( $object_id, $meta_key ) because there is an array conversion happening. The exact line is (array) $this->get( $object_id, $meta_key );
In this case, the "" value gets converted to [""] which is NOT an empty array. All the other values from the text_list get appended and thus the first value is always wrong.
The solution is one of two:
a) in the "delete" function, instead of assigning "", assign an empty array [] if the field accepts multiple entries
b) in the "add" function, rewrite the line $values = (array) $this->get( $object_id, $meta_key ) to:
$values = $this->get( $object_id, $meta_key ); if ( $values === '' ) { $values = array(); } else { $values = (array) $values; }
November 30, 2020 at 9:08 PM #23118Long Nguyen
ModeratorHi,
Thank you for your effort. I will send all information to the developer team to cover this case.
December 1, 2020 at 9:41 PM #23389Long Nguyen
Moderator -
AuthorPosts
- You must be logged in to reply to this topic.