Skip to content

Commit 458f7e1

Browse files
committed
Merge pull request #442 from alleyinteractive/bugfix-empty-repeatable-multiselect
fix handling for repeatable multiple select fields #352
2 parents befb3c2 + 86f4f7f commit 458f7e1

4 files changed

+121
-0
lines changed

php/class-fieldmanager-options.php

+15
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,21 @@ public function option_selected( $current_option, $options, $attribute ) {
184184
else return '';
185185
}
186186

187+
/**
188+
* Override presave_all to handle special cases associated with multiple options fields.
189+
* @input mixed[] $values
190+
* @return mixed[] sanitized values
191+
*/
192+
public function presave_all( $values, $current_values ) {
193+
// Multiple select and radio fields with no values chosen are left out of
194+
// the post request altogether, requiring special case handling.
195+
if ( 1 !== $this->limit && '' === $values ) {
196+
$values = null;
197+
}
198+
199+
return parent::presave_all( $values, $current_values );
200+
}
201+
187202
/**
188203
* Presave function, which handles sanitization and validation
189204
* @param mixed $value If a single field expects to manage an array, it must override presave()

tests/php/test-fieldmanager-checkboxes-field.php

+21
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,25 @@ public function test_datasource_default_value_all() {
169169
}
170170
}
171171

172+
public function test_repeatable_checkboxes_save() {
173+
$fm = new Fieldmanager_Checkboxes( array(
174+
'name' => 'base_field',
175+
'multiple' => true,
176+
'limit' => 0,
177+
'options' => array( 'one', 'two', 'three' ),
178+
) );
179+
180+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, array( 'two' ) );
181+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
182+
$this->assertSame( array( 'two' ), $saved_value );
183+
184+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, array( 'two', 'three' ) );
185+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
186+
$this->assertSame( array( 'two', 'three' ), $saved_value );
187+
188+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, '' );
189+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
190+
$this->assertEquals( null, $saved_value );
191+
}
192+
172193
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/**
4+
* Tests the Fieldmanager Radio Field
5+
*
6+
* @group field
7+
* @group radio
8+
*/
9+
class Test_Fieldmanager_Radios_Field extends WP_UnitTestCase {
10+
public $post_id;
11+
public $post;
12+
public $custom_datasource;
13+
14+
public function setUp() {
15+
parent::setUp();
16+
Fieldmanager_Field::$debug = true;
17+
18+
$this->post_id = $this->factory->post->create( array( 'post_title' => rand_str(), 'post_date' => '2009-07-01 00:00:00' ) );
19+
$this->post = get_post( $this->post_id );
20+
21+
$this->custom_datasource = new Fieldmanager_Datasource( array(
22+
'options' => array( 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' )
23+
) );
24+
}
25+
26+
/**
27+
* Helper which returns the post meta box HTML for a given field;
28+
*
29+
* @param object $field Some Fieldmanager_Field object.
30+
* @param array $test_data Data to save (and use when rendering)
31+
* @return string Rendered HTML
32+
*/
33+
private function _get_html_for( $field, $test_data = null ) {
34+
ob_start();
35+
$context = $field->add_meta_box( 'test meta box', $this->post );
36+
if ( $test_data ) {
37+
$context->save_to_post_meta( $this->post_id, $test_data );
38+
}
39+
$context->render_meta_box( $this->post );
40+
return ob_get_clean();
41+
}
42+
43+
public function test_repeatable_save() {
44+
$fm = new Fieldmanager_Radios( array(
45+
'name' => 'base_field',
46+
'limit' => 0,
47+
'options' => array( 'one', 'two', 'three' ),
48+
) );
49+
50+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, array( 'two' ) );
51+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
52+
$this->assertSame( array( 'two' ), $saved_value );
53+
54+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, array( 'two', 'three' ) );
55+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
56+
$this->assertSame( array( 'two', 'three' ), $saved_value );
57+
58+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, '' );
59+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
60+
$this->assertEquals( null, $saved_value );
61+
}
62+
63+
64+
}

tests/php/test-fieldmanager-select-field.php

+21
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,27 @@ public function test_multiselect_save() {
149149
);
150150
}
151151

152+
public function test_repeatable_multiselect_save() {
153+
$fm = new Fieldmanager_Select( array(
154+
'name' => 'base_field',
155+
'multiple' => true,
156+
'limit' => 0,
157+
'options' => array( 'one', 'two', 'three' ),
158+
) );
159+
160+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, array( 'two' ) );
161+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
162+
$this->assertSame( array( 'two' ), $saved_value );
163+
164+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, array( 'two', 'three' ) );
165+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
166+
$this->assertSame( array( 'two', 'three' ), $saved_value );
167+
168+
$fm->add_meta_box( 'base_field', $this->post->post_type )->save_to_post_meta( $this->post->ID, '' );
169+
$saved_value = get_post_meta( $this->post->ID, 'base_field', true );
170+
$this->assertEquals( null, $saved_value );
171+
}
172+
152173
public function test_repeatable_render() {
153174
$fm = new Fieldmanager_Select( array(
154175
'name' => 'base_field',

0 commit comments

Comments
 (0)