PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / trunk
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More vtrunk
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/helpers/FrmFieldGridHelper.php +65 -27 6.3 → trunk View file →
@@ -4,8 +4,11 @@
4 4 }
5 5
6 6 class FrmFieldGridHelper {
7 7
8 + /**
9 + * @var bool
10 + */
8 11 private $parent_li;
9 12
10 13 /**
11 14 * @var int
@@ -27,34 +30,40 @@
27 30 */
28 31 private $active_field_size;
29 32
30 33 /**
31 - * @var bool $is_frm_first flagged while calling get_field_layout_class, true if classes contain frm_first class.
34 + * @var bool flagged while calling get_field_layout_class, true if classes contain frm_first class.
32 35 */
33 36 private $is_frm_first;
34 37
35 38 /**
36 - * @var stdClass
39 + * @var stdClass|null
37 40 */
38 41 private $field;
39 42
40 43 /**
41 - * @var FrmFieldGridHelper $section_helper
44 + * @var FrmFieldGridHelper|null
42 45 */
43 46 private $section_helper;
44 47
45 48 /**
46 - * @var bool $nested
49 + * @var bool
47 50 */
48 51 private $nested;
49 52
50 53 /**
51 - * @var int $section_size
54 + * @var int
52 55 */
53 56 private $section_size;
54 57
58 + /**
59 + * @var bool
60 + */
55 61 private $section_is_open = false;
56 62
63 + /**
64 + * @param bool $nested
65 + */
57 66 public function __construct( $nested = false ) {
58 67 $this->parent_li = false;
59 68 $this->current_list_size = 0;
60 69 $this->current_field_count = 0;
@@ -68,9 +77,9 @@
68 77 */
69 78 public function set_field( $field ) {
70 79 $this->field = $field;
71 80
72 - if ( ! empty( $this->section_helper ) && 'end_divider' !== $field->type ) {
81 + if ( $this->section_helper && 'end_divider' !== $field->type ) {
73 82 $this->section_helper->set_field( $field );
74 83 return;
75 84 }
76 85
@@ -80,16 +89,18 @@
80 89 $this->section_is_open = false;
81 90 $this->maybe_close_section_helper();
82 91 } else {
83 92 $this->field_layout_class = $this->get_field_layout_class();
84 - $this->active_field_size = $this->get_size_of_class( $this->field_layout_class );
93 + $this->active_field_size = self::get_size_of_class( $this->field_layout_class );
85 94 }
86 95
87 - if ( 'divider' === $field->type && empty( $this->nested ) ) {
88 - $this->section_size = $this->active_field_size;
89 - $this->active_field_size = 0;
90 - $this->section_helper = new self( true );
96 + if ( 'divider' !== $field->type || $this->nested ) {
97 + return;
91 98 }
99 +
100 + $this->section_size = $this->active_field_size;
101 + $this->active_field_size = 0;
102 + $this->section_helper = new self( true );
92 103 }
93 104
94 105 /**
95 106 * @return void
@@ -94,9 +105,9 @@
94 105 /**
95 106 * @return void
96 107 */
97 108 private function maybe_close_section_helper() {
98 - if ( empty( $this->section_helper ) ) {
109 + if ( ! $this->section_helper ) {
99 110 return;
100 111 }
101 112 $this->section_helper->force_close_field_wrapper();
102 113 $this->section_helper = null;
@@ -113,11 +124,10 @@
113 124 }
114 125
115 126 $split = explode( ' ', $field['classes'] );
116 127 $this->is_frm_first = in_array( 'frm_first', $split, true );
117 - $classes = self::get_grid_classes();
118 128
119 - foreach ( $classes as $class ) {
129 + foreach ( self::get_grid_classes() as $class ) {
120 130 if ( in_array( $class, $split, true ) ) {
121 131 return $class;
122 132 }
123 133 }
@@ -136,9 +146,9 @@
136 146 if ( false === $this->parent_li && 'end_divider' !== $this->field->type ) {
137 147 $this->begin_field_wrapper();
138 148 }
139 149
140 - if ( ! empty( $this->section_helper ) && $this->section_is_open ) {
150 + if ( $this->section_helper && $this->section_is_open ) {
141 151 $this->section_helper->maybe_begin_field_wrapper();
142 152 }
143 153 }
144 154
@@ -145,14 +155,29 @@
145 155 /**
146 156 * @return bool
147 157 */
148 158 private function should_first_close_the_active_field_wrapper() {
149 - if ( false === $this->parent_li || ! empty( $this->section_helper ) ) {
159 + if ( false === $this->parent_li ) {
150 160 return false;
151 161 }
162 +
163 + /**
164 + * Fields that sit inside an open section are wrapped by that section's own helper, so the
165 + * row here is not theirs to close. set_field() opens the section helper for the section
166 + * field itself, one step ahead of this check, and section_is_open is not set until
167 + * sync_list_size() runs afterwards. Testing both is what keeps the section field subject to
168 + * the width check below rather than being treated as though it were already inside itself.
169 + *
170 + * @see https://github.com/Strategy11/formidable-pro/issues/3820
171 + */
172 + if ( $this->section_helper && $this->section_is_open ) {
173 + return false;
174 + }
175 +
152 176 if ( 'end_divider' === $this->field->type ) {
153 177 return false;
154 178 }
179 +
155 180 return ! $this->can_support_current_layout() || $this->is_frm_first;
156 181 }
157 182
158 183 /**
@@ -166,8 +191,9 @@
166 191 }
167 192
168 193 /**
169 194 * @param string $class
195 + *
170 196 * @return int
171 197 */
172 198 private static function get_size_of_class( $class ) {
173 199 switch ( $class ) {
@@ -184,10 +210,11 @@
184 210 case 'frm_sixth':
185 211 return 2;
186 212 }
187 213
188 - if ( 0 === strpos( $class, 'frm' ) ) {
214 + if ( str_starts_with( $class, 'frm' ) ) {
189 215 $substr = substr( $class, 3 );
216 +
190 217 if ( is_numeric( $substr ) ) {
191 218 return (int) $substr;
192 219 }
193 220 }
@@ -199,9 +226,9 @@
199 226 /**
200 227 * @return void
201 228 */
202 229 public function sync_list_size() {
203 - if ( ! isset( $this->field ) ) {
230 + if ( ! $this->field ) {
204 231 return;
205 232 }
206 233
207 234 if ( 'divider' === $this->field->type ) {
@@ -207,23 +234,28 @@
207 234 if ( 'divider' === $this->field->type ) {
208 235 $this->section_is_open = true;
209 236 }
210 237
211 - if ( ! empty( $this->section_helper ) ) {
238 + if ( $this->section_helper ) {
212 239 $this->section_helper->sync_list_size();
240 +
213 241 if ( 'end_divider' === $this->field->type ) {
214 242 $this->maybe_close_section_helper();
215 243 }
244 +
216 245 return;
217 246 }
218 247
219 - if ( false !== $this->parent_li ) {
220 - $this->current_field_count ++;
221 - $this->current_list_size += $this->active_field_size;
222 - if ( 12 === $this->current_list_size ) {
223 - $this->close_field_wrapper();
224 - }
248 + if ( false === $this->parent_li ) {
249 + return;
225 250 }
251 +
252 + ++$this->current_field_count;
253 + $this->current_list_size += $this->active_field_size;
254 +
255 + if ( 12 === $this->current_list_size ) {
256 + $this->close_field_wrapper();
257 + }
226 258 }
227 259
228 260 /**
229 261 * It is possible that there was still space for another field so the wrapper could still be open after looping the fields.
@@ -240,9 +272,14 @@
240 272 /**
241 273 * @return void
242 274 */
243 275 private function close_field_wrapper() {
244 - $this->maybe_close_section_helper();
276 + // Only an open section has a nested wrapper to close. A section helper that set_field() has
277 + // just created belongs to the section about to start, so closing this row must leave it alone.
278 + if ( $this->section_is_open ) {
279 + $this->maybe_close_section_helper();
280 + }
281 +
245 282 echo '</ul></li>';
246 283 $this->parent_li = false;
247 284 $this->current_list_size = 0;
248 285 $this->current_field_count = 0;
@@ -259,12 +296,13 @@
259 296 }
260 297
261 298 /**
262 299 * @param string $class
300 + *
263 301 * @return bool
264 302 */
265 303 private function can_support_an_additional_layout( $class ) {
266 - $size = $this->get_size_of_class( $class );
304 + $size = self::get_size_of_class( $class );
267 305 return $this->current_list_size + $size <= 12;
268 306 }
269 307
270 308 /**