PluginProbe
Advanced Custom Fields (ACF®) / 3.3.1
Advanced Custom Fields (ACF®) v3.3.1
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / core / fields / flexible_content.php
flexible_content.php
743 lines 19.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class acf_Flexible_content extends acf_Field
4 {
5
6 /*--------------------------------------------------------------------------------------
7 *
8 * Constructor
9 * - $parent is passed buy reference so you can play with the acf functions
10 *
11 * @author Elliot Condon
12 * @since 2.2.0
13 *
14 *-------------------------------------------------------------------------------------*/
15
16 function __construct($parent)
17 {
18 parent::__construct($parent);
19
20 $this->name = 'flexible_content';
21 $this->title = __("Flexible Content",'acf');
22
23 }
24
25
26 /*--------------------------------------------------------------------------------------
27 *
28 * create_field
29 * - called in lots of places to create the html version of the field
30 *
31 * @author Elliot Condon
32 * @since 2.2.0
33 *
34 *-------------------------------------------------------------------------------------*/
35
36 function create_field($field)
37 {
38 $button_label = ( isset($field['button_label']) && $field['button_label'] != "" ) ? $field['button_label'] : __("+ Add Row",'acf');
39 $layouts = array();
40 foreach($field['layouts'] as $l)
41 {
42 $layouts[$l['name']] = $l;
43 }
44
45 ?>
46 <div class="acf_flexible_content">
47
48 <div class="no_value_message" <?php if($field['value']){echo 'style="display:none;"';} ?>>
49 <?php _e("Click the \"$button_label\" button below to start creating your layout",'acf'); ?>
50 </div>
51
52 <div class="clones">
53 <?php $i = -1; ?>
54 <?php foreach($layouts as $layout): $i++; ?>
55
56 <div class="layout" data-layout="<?php echo $layout['name']; ?>">
57
58 <ul class="hl actions">
59 <li><a class="order" href="#"></a></li>
60 <li><a class="delete" href="#"></a></li>
61 </ul>
62
63 <p class="layout-label"><?php echo $layout['label']; ?></p>
64
65 <table class="widefat">
66
67 <tbody>
68 <tr><?php
69
70 if($layout['display'] == 'row'):
71 ?><td><?php
72 endif;
73
74 $l = 0;
75 foreach($layout['sub_fields'] as $sub_field):
76
77 $l++;
78
79 if($layout['display'] == 'table'):
80 ?><td style="width:<?php echo 100/count($layout['sub_fields']); ?>%;"><?php
81 else:
82 ?><div class="row-layout-field"><?php
83 endif;
84
85 ?><p class="label">
86 <label><?php echo $sub_field['label']; ?></label><?php
87
88 if(!isset($sub_field['instructions']))
89 $sub_field['instructions'] = "";
90
91 echo $sub_field['instructions'];
92
93 ?></p>
94
95 <input type="hidden" name="<?php echo $field['name']; ?>[999][acf_fc_layout]" value="<?php echo $layout['name']; ?>" />
96 <?php
97
98 // add value
99 $sub_field['value'] = isset($sub_field['default_value']) ? $sub_field['default_value'] : false;
100
101 // add name
102 $sub_field['name'] = $field['name'] . '[999][' . $sub_field['key'] . ']';
103
104 // create field
105 $this->parent->create_field($sub_field);
106
107
108 if($layout['display'] == 'table'):
109 ?></td><?php
110 else:
111 ?></div><?php
112 endif;
113
114 endforeach;
115
116 if($layout['display'] == 'row'):
117 ?></td><?php
118 endif;
119
120 ?></tr>
121 </tbody>
122
123 </table>
124 </div>
125 <?php endforeach; ?>
126 </div>
127 <div class="values">
128 <?php if($field['value']): ?>
129 <?php foreach($field['value'] as $i => $value):?>
130
131
132 <?php if(!isset($layouts[$value['acf_fc_layout']])) continue; ?>
133 <?php $layout = $layouts[$value['acf_fc_layout']]; ?>
134
135
136 <div class="layout" data-layout="<?php echo $layout['name']; ?>">
137
138 <ul class="hl actions">
139 <li><a class="order" href="#"></a></li>
140 <li><a class="delete" href="#"></a></li>
141 </ul>
142
143 <p class="layout-label"><?php echo $layout['label']; ?></p>
144
145 <table class="widefat">
146
147 <tbody>
148 <tr>
149 <?php if($layout['display'] == 'row'): ?><td><?php endif; ?>
150
151 <?php $l = 0; foreach($layout['sub_fields'] as $sub_field): $l++; ?>
152
153 <?php if($layout['display'] == 'table'): ?><td style="width:<?php echo 100/count($layout['sub_fields']); ?>%;"><?php endif; ?>
154
155 <p class="label">
156 <label><?php echo $sub_field['label']; ?></label>
157 <?php
158
159 if(!isset($sub_field['instructions']))
160 $sub_field['instructions'] = "";
161
162 echo $sub_field['instructions'];
163
164 ?>
165 </p>
166
167 <input type="hidden" name="<?php echo $field['name'] ?>[<?php echo $i ?>][acf_fc_layout]" value="<?php echo $layout['name']; ?>" />
168 <?php
169 // add value
170 $sub_field['value'] = isset($value[$sub_field['name']]) ? $value[$sub_field['name']] : '';
171
172 // add name
173 $sub_field['name'] = $field['name'] . '[' . $i . '][' . $sub_field['key'] . ']';
174
175 // create field
176 $this->parent->create_field($sub_field);
177 ?>
178
179 <?php if($layout['display'] == 'table'): ?></td><?php endif; ?>
180
181 <?php endforeach; ?>
182
183 <?php if($layout['display'] == 'row'): ?></td><?php endif; ?>
184 </tr>
185 </tbody>
186
187 </table>
188 </div>
189
190
191 <?php endforeach; ?>
192 <?php endif; ?>
193 <?php // values here ?>
194 </div>
195
196 <ul class="hl clearfix flexible-footer">
197 <li class="right">
198 <a href="javascript:;" class="add-row-end acf-button"><?php echo $button_label; ?></a>
199 <div class="acf-popup">
200 <ul>
201 <?php foreach($field['layouts'] as $layout): $i++; ?>
202 <li><a href="javascript:;" data-layout="<?php echo $layout['name']; ?>"><?php echo $layout['label']; ?></a></li>
203 <?php endforeach; ?>
204 </ul>
205 <div class="bit"></div>
206 </div>
207 </li>
208 </ul>
209
210 </div>
211 <?php
212 }
213
214
215 /*--------------------------------------------------------------------------------------
216 *
217 * create_options
218 * - called from core/field_meta_box.php to create special options
219 *
220 * @params : $key (int) - neccessary to group field data together for saving
221 * $field (array) - the field data from the database
222 * @author Elliot Condon
223 * @since 2.2.0
224 *
225 *-------------------------------------------------------------------------------------*/
226
227 function create_options($key, $field)
228 {
229 // vars
230 $fields_names = array();
231 $field['layouts'] = isset($field['layouts']) ? $field['layouts'] : array();
232 $field['button_label'] = (isset($field['button_label']) && $field['button_label'] != "") ? $field['button_label'] : __("+ Add Row",'acf');
233
234 // load default layout
235 if(empty($field['layouts']))
236 {
237 $field['layouts'][] = array(
238 'name' => '',
239 'label' => '',
240 'display' => 'table',
241 'sub_fields' => array(),
242 );
243 }
244
245 // get name of all fields for use in field type
246 foreach($this->parent->fields as $f)
247 {
248 $fields_names[$f->name] = $f->title;
249 }
250 //unset($fields_names['repeater']);
251 unset($fields_names['flexible_content']);
252
253 // loop through layouts and create the options for them
254 if($field['layouts']):
255 foreach($field['layouts'] as $layout_key => $layout):
256
257 // add clone field
258 $layout['sub_fields'][999] = array(
259 'label' => __("New Field",'acf'),
260 'name' => 'new_field',
261 'type' => 'text',
262 'order_no' => '1',
263 'instructions' => '',
264 );
265 ?>
266 <tr class="field_option field_option_<?php echo $this->name; ?>">
267 <td class="label">
268 <label><?php _e("Layout",'acf'); ?></label>
269 <p class="desription">
270 <span><a class="acf_fc_reorder" title="<?php _e("Reorder Layout",'acf'); ?>" href="javascript:;"><?php _e("Reorder",'acf'); ?></a> | </span>
271 <span><a class="acf_fc_add" title="<?php _e("Add New Layout",'acf'); ?>" href="javascript:;"><?php _e("Add New",'acf'); ?></a> | </span>
272 <span><a class="acf_fc_delete" title="<?php _e("Delete Layout",'acf'); ?>" href="javascript:;"><?php _e("Delete",'acf'); ?></a>
273 </p>
274 </td>
275 <td>
276 <div class="repeater">
277
278 <table class="acf_cf_meta">
279 <body>
280 <tr>
281 <td class="acf_fc_label" style="padding-left:0;">
282 <label><?php _e('Label','acf'); ?></label>
283 <?php
284 $this->parent->create_field(array(
285 'type' => 'text',
286 'name' => 'fields['.$key.'][layouts][' . $layout_key . '][label]',
287 'value' => $layout['label'],
288 ));
289 ?>
290 </td>
291 <td class="acf_fc_name">
292 <label><?php _e('Name','acf'); ?></label>
293 <?php
294 $this->parent->create_field(array(
295 'type' => 'text',
296 'name' => 'fields['.$key.'][layouts][' . $layout_key . '][name]',
297 'value' => $layout['name'],
298 ));
299 ?>
300 </td>
301 <td style="padding-right:0;">
302 <label><?php _e('Display','acf'); ?></label>
303 <?php
304 $this->parent->create_field(array(
305 'type' => 'select',
306 'name' => 'fields['.$key.'][layouts][' . $layout_key . '][display]',
307 'value' => $layout['display'],
308 'choices' => array(
309 'table' => __("Table",'acf'),
310 'row' => __("Row",'acf')
311 )
312 ));
313 ?>
314 </td>
315 </tr>
316 </body>
317 </table>
318
319 <div class="fields_header">
320 <table class="acf widefat">
321 <thead>
322 <tr>
323 <th class="field_order"><?php _e('Field Order','acf'); ?></th>
324 <th class="field_label"><?php _e('Field Label','acf'); ?></th>
325 <th class="field_name"><?php _e('Field Name','acf'); ?></th>
326 <th class="field_type"><?php _e('Field Type','acf'); ?></th>
327 </tr>
328 </thead>
329 </table>
330 </div>
331 <div class="fields">
332
333 <div class="no_fields_message" <?php if(count($layout['sub_fields']) > 1){ echo 'style="display:none;"'; } ?>>
334 <?php _e("No fields. Click the \"+ Add Sub Field button\" to create your first field.",'acf'); ?>
335 </div>
336
337 <?php foreach($layout['sub_fields'] as $key2 => $sub_field): ?>
338 <div class="<?php if($key2 == 999){echo "field_clone";}else{echo "field";} ?> sub_field" data-id="<?php echo $key2; ?>">
339
340 <?php if(isset($sub_field['key'])): ?>
341 <input type="hidden" name="fields[<?php echo $key; ?>][sub_fields][<?php echo $key2; ?>][key]" value="<?php echo $sub_field['key']; ?>" />
342 <?php endif; ?>
343
344 <div class="field_meta">
345 <table class="acf widefat">
346 <tr>
347 <td class="field_order"><span class="circle"><?php echo ($key2+1); ?></span></td>
348 <td class="field_label">
349 <strong>
350 <a class="acf_edit_field" title="<?php _e("Edit this Field",'acf'); ?>" href="javascript:;"><?php echo $sub_field['label']; ?></a>
351 </strong>
352 <div class="row_options">
353 <span><a class="acf_edit_field" title="<?php _e("Edit this Field",'acf'); ?>" href="javascript:;"><?php _e("Edit",'acf'); ?></a> | </span>
354 <span><a title="<?php _e("Read documentation for this field",'acf'); ?>" href="http://www.advancedcustomfields.com/docs/field-types/" target="_blank"><?php _e("Docs",'acf'); ?></a> | </span>
355 <span><a class="acf_duplicate_field" title="<?php _e("Duplicate this Field",'acf'); ?>" href="javascript:;"><?php _e("Duplicate",'acf'); ?></a> | </span>
356 <span><a class="acf_delete_field" title="<?php _e("Delete this Field",'acf'); ?>" href="javascript:;"><?php _e("Delete",'acf'); ?></a>
357 </div>
358 </td>
359 <td class="field_name"><?php echo $sub_field['name']; ?></td>
360 <td class="field_type"><?php echo $sub_field['type']; ?></td>
361 </tr>
362 </table>
363 </div>
364
365 <div class="field_form_mask">
366 <div class="field_form">
367 <table class="acf_input widefat">
368 <tbody>
369 <tr class="field_label">
370 <td class="label">
371 <label><span class="required">*</span><?php _e("Field Label",'acf'); ?></label>
372 <p class="description"><?php _e("This is the name which will appear on the EDIT page",'acf'); ?></p>
373 </td>
374 <td>
375 <?php
376 $this->parent->create_field(array(
377 'type' => 'text',
378 'name' => 'fields['.$key.'][layouts][' . $layout_key . '][sub_fields]['.$key2.'][label]',
379 'value' => $sub_field['label'],
380 'class' => 'label',
381 ));
382 ?>
383 </td>
384 </tr>
385 <tr class="field_name">
386 <td class="label">
387 <label><span class="required">*</span><?php _e("Field Name",'acf'); ?></label>
388 <p class="description"><?php _e("Single word, no spaces. Underscores and dashes allowed",'acf'); ?></p>
389 </td>
390 <td>
391 <?php
392 $this->parent->create_field(array(
393 'type' => 'text',
394 'name' => 'fields['.$key.'][layouts][' . $layout_key . '][sub_fields]['.$key2.'][name]',
395 'value' => $sub_field['name'],
396 'class' => 'name',
397 ));
398 ?>
399 </td>
400 </tr>
401 <tr class="field_type">
402 <td class="label"><label><span class="required">*</span><?php _e("Field Type",'acf'); ?></label></td>
403 <td>
404 <?php
405 $this->parent->create_field(array(
406 'type' => 'select',
407 'name' => 'fields['.$key.'][layouts][' . $layout_key . '][sub_fields]['.$key2.'][type]',
408 'value' => $sub_field['type'],
409 'class' => 'type',
410 'choices' => $fields_names
411 ));
412 ?>
413 </td>
414 </tr>
415 <?php
416
417 $this->parent->fields[$sub_field['type']]->create_options($key.'][layouts][' . $layout_key . '][sub_fields]['.$key2, $sub_field);
418
419 ?>
420 <tr class="field_save">
421 <td class="label">
422 <!-- <label><?php _e("Save Field",'acf'); ?></label> -->
423 </td>
424 <td>
425 <ul class="hl clearfix">
426 <li>
427 <a class="acf_edit_field acf-button grey" title="<?php _e("Close Field",'acf'); ?>" href="javascript:;"><?php _e("Close Sub Field",'acf'); ?></a>
428 </li>
429 </ul>
430 </td>
431 </tr>
432 </tbody>
433 </table>
434 </div><!-- End Form -->
435 </div><!-- End Form Mask -->
436
437 </div>
438 <?php endforeach; ?>
439 </div>
440 <div class="table_footer">
441 <div class="order_message"><?php _e('Drag and drop to reorder','acf'); ?></div>
442 <a href="javascript:;" id="add_field" class="acf-button"><?php _e('+ Add Sub Field','acf'); ?></a>
443 </div>
444 </div>
445 </td>
446 </tr><?php endforeach; endif; ?>
447 <tr class="field_option field_option_<?php echo $this->name; ?>">
448 <td class="label">
449 <label><?php _e("Button Label",'acf'); ?></label>
450 </td>
451 <td>
452 <?php
453 $this->parent->create_field(array(
454 'type' => 'text',
455 'name' => 'fields['.$key.'][button_label]',
456 'value' => $field['button_label'],
457 ));
458 ?>
459 </td>
460 </tr><?php
461 }
462
463
464
465 /*--------------------------------------------------------------------------------------
466 *
467 * admin_print_scripts / admin_print_styles
468 *
469 * @author Elliot Condon
470 * @since 3.0.0
471 *
472 *-------------------------------------------------------------------------------------*/
473
474 function admin_print_scripts()
475 {
476 wp_enqueue_script(array(
477
478 'jquery-ui-sortable',
479
480 ));
481 }
482
483 function admin_print_styles()
484 {
485
486 }
487
488
489 /*--------------------------------------------------------------------------------------
490 *
491 * update_value
492 *
493 * @author Elliot Condon
494 * @since 2.2.0
495 *
496 *-------------------------------------------------------------------------------------*/
497
498 function update_value($post_id, $field, $value)
499 {
500 $sub_fields = array();
501
502 foreach($field['layouts'] as $layout)
503 {
504 foreach($layout['sub_fields'] as $sub_field)
505 {
506 $sub_fields[$sub_field['key']] = $sub_field;
507 }
508 }
509
510 $total = array();
511
512 if($value)
513 {
514 // remove dummy field
515 unset($value[999]);
516
517 $i = -1;
518
519 // loop through rows
520 foreach($value as $row)
521 {
522 $i++;
523
524 // increase total
525 $total[] = $row['acf_fc_layout'];
526 unset($row['acf_fc_layout']);
527
528 // loop through sub fields
529 foreach($row as $field_key => $value)
530 {
531 $sub_field = $sub_fields[$field_key];
532
533 // update full name
534 $sub_field['name'] = $field['name'] . '_' . $i . '_' . $sub_field['name'];
535
536 // save sub field value
537 $this->parent->update_value($post_id, $sub_field, $value);
538 }
539 }
540 }
541
542 parent::update_value($post_id, $field, $total);
543
544 }
545
546
547 /*--------------------------------------------------------------------------------------
548 *
549 * pre_save_field
550 * - called just before saving the field to the database.
551 *
552 * @author Elliot Condon
553 * @since 2.2.0
554 *
555 *-------------------------------------------------------------------------------------*/
556
557 function pre_save_field($field)
558 {
559
560 // format sub_fields
561 if($field['layouts'])
562 {
563
564 $layouts = array();
565
566 // loop through and save fields
567 foreach($field['layouts'] as $l)
568 {
569 // remove dummy field
570 unset($l['sub_fields'][999]);
571
572 // loop through and save fields
573 $i = -1;
574
575 $sub_fields = array();
576
577 if($l['sub_fields'])
578 {
579 foreach($l['sub_fields'] as $f)
580 {
581 $i++;
582
583 // each field has a unique id!
584 if(!isset($f['key'])) $f['key'] = 'field_' . uniqid();
585
586 // order
587 $f['order_no'] = $i;
588
589 // format
590 $f = $this->parent->pre_save_field($f);
591
592 $sub_fields[] = $f;
593 }
594 }
595 $l['sub_fields'] = $sub_fields;
596
597 $layouts[] = $l;
598
599 }
600
601 $field['layouts'] = $layouts;
602
603 }
604
605 // return updated repeater field
606 return $field;
607
608 }
609
610
611 /*--------------------------------------------------------------------------------------
612 *
613 * get_value
614 * - called from the input edit page to get the value.
615 *
616 * @author Elliot Condon
617 * @since 2.2.0
618 *
619 *-------------------------------------------------------------------------------------*/
620
621 function get_value($post_id, $field)
622 {
623 $layouts = array();
624 foreach($field['layouts'] as $l)
625 {
626 $layouts[$l['name']] = $l;
627 }
628
629 // vars
630 $values = array();
631 $layout_order = false;
632
633
634 // get total rows
635 if( is_numeric($post_id) )
636 {
637 $layout_order = get_post_meta($post_id, $field['name'], true);
638 }
639 else
640 {
641 $layout_order = get_option( $post_id . '_' . $field['name'] );
642 }
643
644
645 if( !empty( $layout_order) )
646 {
647 $i = -1;
648 // loop through rows
649 foreach($layout_order as $layout)
650 {
651 $i++;
652 $values[$i]['acf_fc_layout'] = $layout;
653
654 // check if layout still exists
655 if(isset($layouts[$layout]))
656 {
657 // loop through sub fields
658 foreach($layouts[$layout]['sub_fields'] as $sub_field)
659 {
660 // store name
661 $field_name = $sub_field['name'];
662
663 // update full name
664 $sub_field['name'] = $field['name'] . '_' . $i . '_' . $field_name;
665
666 $values[$i][$field_name] = $this->parent->get_value($post_id, $sub_field);
667 }
668 }
669 }
670 }
671 else
672 {
673 $values = false;
674 }
675
676 return $values;
677 }
678
679
680 /*--------------------------------------------------------------------------------------
681 *
682 * get_value_for_api
683 *
684 * @author Elliot Condon
685 * @since 3.0.0
686 *
687 *-------------------------------------------------------------------------------------*/
688
689 function get_value_for_api($post_id, $field)
690 {
691 $layouts = array();
692 foreach($field['layouts'] as $l)
693 {
694 $layouts[$l['name']] = $l;
695 }
696
697 // vars
698 $values = array();
699 $layout_order = false;
700
701
702 // get total rows
703 if( is_numeric($post_id) )
704 {
705 $layout_order = get_post_meta($post_id, $field['name'], true);
706 }
707 else
708 {
709 $layout_order = get_option( $post_id . '_' . $field['name'] );
710 }
711
712
713 if($layout_order)
714 {
715 $i = -1;
716 // loop through rows
717 foreach($layout_order as $layout)
718 {
719 $i++;
720 $values[$i]['acf_fc_layout'] = $layout;
721
722 // loop through sub fields
723 foreach($layouts[$layout]['sub_fields'] as $sub_field)
724 {
725 // store name
726 $field_name = $sub_field['name'];
727
728 // update full name
729 $sub_field['name'] = $field['name'] . '_' . $i . '_' . $field_name;
730
731 $values[$i][$field_name] = $this->parent->get_value_for_api($post_id, $sub_field);
732 }
733 }
734
735 return $values;
736 }
737
738 return array();
739 }
740
741 }
742
743 ?>