PluginProbe
WP Ultimate Post Grid / 1.7.2
WP Ultimate Post Grid v1.7.2
4.1.1 trunk 1.5 1.6 1.7 1.7.1 1.7.2 1.8 1.9 2.0 2.1 2.2 2.3 2.4.0 2.5.0 2.6.0 2.7.0 2.8.0 2.8.2 3.0.0 3.3.0 3.4.0 3.5.0 3.6.0 3.7.0 All 32 releases
wp-ultimate-post-grid / vendor / vafpress / classes / metabox / alchemy.php

alchemy.php in WP Ultimate Post Grid 1.7.2, at vendor/vafpress/classes/metabox/alchemy.php

700 lines 16.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Extended version of WPAlchemy Class
5 * so that it can process metabox using an array specification
6 * and compatible with all Vafpress Framework Option Controls.
7 */
8
9 /////////////////////////////////////////
10 // Include original WPAlchemy Class //
11 /////////////////////////////////////////
12 if(!class_exists('WPAlchemy_MetaBox'))
13 {
14 require_once VP_FileSystem::instance()->resolve_path('includes', 'wpalchemy/MetaBox');
15 }
16
17 class VP_MetaBox_Alchemy extends WPAlchemy_MetaBox
18 {
19
20 /**
21 * Used to setup the meta box content template
22 *
23 * @since 1.0
24 * @access private
25 * @see _init()
26 */
27 function _setup()
28 {
29 $this->in_template = TRUE;
30
31 // also make current post data available
32 global $post;
33
34 // shortcuts
35 $mb =& $this;
36 $metabox =& $this;
37 $id = $this->id;
38 $meta = $this->_meta(NULL, TRUE);
39
40 // use include because users may want to use one template for multiple meta boxes
41 if( !is_array($this->template) and file_exists($this->template) )
42 {
43 include $this->template;
44 }
45 else
46 {
47 $fields = $this->_enfactor($this->template);
48 $this->_enbind($fields);
49 $fields = $this->_endep($fields);
50
51 echo '<div class="vp-metabox">';
52 $this->_enview($fields);
53 echo '</div>';
54 }
55
56 // create a nonce for verification
57 echo '<input type="hidden" name="'. $this->id .'_nonce" value="' . wp_create_nonce($this->id) . '" />';
58
59 $this->in_template = FALSE;
60 }
61
62 // return all field types
63 function get_field_types()
64 {
65 $types = array();
66
67 if(!function_exists('inner_build'))
68 {
69 function inner_build($fields, &$types)
70 {
71 $rules = VP_Util_Config::instance()->load('dependencies', 'rules');
72 foreach ($fields as $field)
73 {
74 if($field['type'] == 'group')
75 {
76 inner_build($field['fields'], $types);
77 }
78 else
79 {
80 if( ! in_array($field['type'], $types) )
81 $types[] = $field['type'];
82 }
83 }
84 }
85 }
86
87 inner_build($this->template, $types);
88
89 return $types;
90 }
91
92 function _enfactor($arr)
93 {
94 $mb =& $this;
95 $fields = $arr;
96 $field_objects = array();
97
98 foreach ($fields as $field)
99 {
100 if($field['type'] == 'group' and $field['repeating'])
101 {
102 $field_objects[$field['name']] = $this->_enfactor_group($field, $mb, true);
103 }
104 else if($field['type'] == 'group' and !$field['repeating'])
105 {
106 $field_objects[$field['name']] = $this->_enfactor_group($field, $mb, false);
107 }
108 else
109 {
110 $field_objects[$field['name']] = $this->_enfactor_field($field, $mb);
111 }
112 }
113
114 return $field_objects;
115 }
116
117 function _enbind($fields)
118 {
119 foreach ($fields as $name => $field)
120 {
121 if(is_array($field))
122 {
123 foreach ($field['groups'] as $group)
124 {
125 $this->_enbind($group['childs']);
126 }
127 }
128 else
129 {
130 $bind = $field->get_binding();
131 $val = $field->get_value();
132 if(!empty($bind) and is_null($val))
133 {
134 $bind = explode('|', $bind);
135 $func = $bind[0];
136 $params = $bind[1];
137 $params = preg_split('/[\s,]+/', $params);
138 $values = array();
139 foreach ($params as $param)
140 {
141 if(array_key_exists($param, $fields))
142 {
143 $values[] = $fields[$param]->get_value();
144 }
145 }
146 $result = call_user_func_array($func, $values);
147
148 if(VP_Util_Reflection::is_multiselectable($field))
149 {
150 $result = (array) $result;
151 }
152 else
153 {
154 if(is_array($result))
155 {
156 $result = reset($result);
157 }
158 $result = (String) $result;
159 }
160 $field->set_value($result);
161 }
162 if($field instanceof VP_Control_FieldMulti)
163 {
164 $bind = $field->get_items_binding();
165 if(!empty($bind))
166 {
167 $bind = explode('|', $bind);
168 $func = $bind[0];
169 $params = $bind[1];
170 $params = explode(',', $params);
171 $values = array();
172 foreach ($params as $param)
173 {
174 if(array_key_exists($param, $fields))
175 {
176 $values[] = $fields[$param]->get_value();
177 }
178 }
179 $items = call_user_func_array($func, $values);
180 $field->add_items_from_array($items);
181 }
182 }
183 }
184 }
185 }
186
187 function _endep($fields)
188 {
189
190 if(!function_exists('loop_fields'))
191 {
192 function loop_fields(&$fields)
193 {
194 foreach ($fields as &$field)
195 {
196 if(is_array($field))
197 {
198 foreach ($field['groups'] as &$group)
199 {
200 loop_fields($group['childs']);
201 }
202 }
203
204 $dependency = '';
205 if($field instanceof VP_Control_Field)
206 {
207 $dependency = $field->get_dependency();
208 if(!empty($dependency))
209 {
210 $dependency = explode('|', $dependency);
211 $func = $dependency[0];
212 $params = $dependency[1];
213 }
214 }
215 else
216 {
217 if(isset($field['dependency']))
218 {
219 if(!empty($field['dependency']))
220 {
221 $dependency = $field['dependency'];
222 $func = $dependency['function'];
223 $params = $dependency['field'];
224 }
225 }
226 }
227
228 if(!empty($dependency))
229 {
230 $params = explode(',', $params);
231 $values = array();
232 foreach ($params as $param)
233 {
234 if(array_key_exists($param, $fields))
235 {
236 $values[] = $fields[$param]->get_value();
237 }
238 }
239 $result = call_user_func_array($func, $values);
240 if(!$result)
241 {
242 if($field instanceof VP_Control_Field)
243 {
244 $field->is_hidden(true);
245 if($field->is_hidden())
246 $field->add_container_extra_classes('vp-hide');
247
248 $field->add_container_extra_classes('vp-dep-inactive');
249 }
250 else
251 {
252 $field['is_hidden'] = true;
253 if($field['is_hidden'])
254 $field['container_extra_classes'][] = 'vp-hide';
255
256 $field['container_extra_classes'][] = 'vp-dep-inactive';
257 }
258 }
259 }
260 }
261 }
262 }
263
264 loop_fields($fields);
265
266 return $fields;
267 }
268
269 function _enfactor_field($field, $mb, $in_group = false)
270 {
271 $is_multi = VP_Util_Reflection::is_multiselectable($field['type']);
272
273 if( !$is_multi )
274 {
275 $mb->the_field($field['name']);
276 }
277 else
278 {
279 $mb->the_field($field['name'], WPALCHEMY_FIELD_HINT_CHECKBOX_MULTI);
280 }
281 $field['name'] = $mb->get_the_name();
282
283 // create the object
284 $make = VP_Util_Reflection::field_class_from_type($field['type']);
285 $vp_field = call_user_func("$make::withArray", $field);
286
287 // get value from mb
288 $value = $mb->get_the_value();
289 // get default from array
290 $default = $vp_field->get_default();
291
292 // if tocopy always assign default
293 if( $mb->is_parent_multi() and $mb->is_in_multi_last() )
294 {
295 $value = $default;
296 }
297 else
298 {
299 // if value is null and default exist, use default
300 if( is_null($value) and !is_null($default) and empty($this->meta) )
301 {
302 $value = $default;
303 }
304 // if not then set up value from mb
305 else
306 {
307 if( VP_Util_Reflection::is_multiselectable($field['type']) )
308 {
309 if( !is_array($value) )
310 $value = array( $value );
311 }
312 }
313 }
314 $vp_field->set_value($value);
315
316 if (!$in_group)
317 {
318 $vp_field->add_container_extra_classes(array('vp-meta-single'));
319 }
320
321 return $vp_field;
322 }
323
324 function _enfactor_group($field, $mb, $repeating)
325 {
326 $ignore = array('type', 'length', 'fields');
327 $groups = array();
328 $indexed_name = '';
329 $level = null;
330 if($repeating)
331 {
332 while($mb->have_fields_and_multi($field['name']))
333 {
334 if ($indexed_name === '') $indexed_name = $mb->get_the_loop_group_id();
335 if (is_null($level)) $level = $mb->get_the_loop_level();
336 $fields = array();
337 foreach ($field['fields'] as $f)
338 {
339 if($f['type'] === 'group')
340 $fields[$f['name']] = $this->_enfactor_group($f, $mb, $f['repeating']);
341 else
342 $fields[$f['name']] = $this->_enfactor_field($f, $mb, true);
343 }
344 $groups[] = array(
345 'name' => $mb->get_the_loop_group_name(true),
346 'childs' => $fields
347 );
348 }
349 }
350 else
351 {
352 $length = isset($field['length']) ? $field['length'] : 1;
353 while($mb->have_fields($field['name'], $length))
354 {
355 if ($indexed_name === '') $indexed_name = $mb->get_the_loop_group_id();
356 if (is_null($level)) $level = $mb->get_the_loop_level();
357 $fields = array();
358 foreach ($field['fields'] as $f)
359 {
360 if($f['type'] === 'group')
361 $fields[$f['name']] = $this->_enfactor_group($f, $mb, $f['repeating']);
362 else
363 $fields[$f['name']] = $this->_enfactor_field($f, $mb, true);
364 }
365 $groups[] = array(
366 'name' => $mb->get_the_loop_group_name(true),
367 'childs' => $fields
368 );
369 }
370 }
371 // assign groups
372 $group['groups'] = $groups;
373 $group['indexed_name'] = $indexed_name;
374 $group['level'] = $level;
375
376 // assign other information
377 $keys = array_keys($field);
378 foreach ($keys as $key)
379 {
380 if(!in_array($key, $ignore))
381 {
382 $group[$key] = $field[$key];
383 }
384 }
385
386 // sortable
387 if(isset($group['sortable']) and $group['sortable'])
388 $group['container_extra_classes'][] = 'vp-sortable';
389
390 return $group;
391 }
392
393 function _enview($fields)
394 {
395 foreach ($fields as $name => $field)
396 {
397 if( is_array($field) and $field['repeating'] )
398 {
399 echo $this->_render_repeating_group($field);
400 }
401 else if( is_array($field) and !$field['repeating'] )
402 {
403 echo $this->_render_group($field);
404 }
405 else
406 {
407 echo $this->_render_field($field);
408 }
409 }
410 }
411
412 function _render_field($field)
413 {
414 return $field->render();
415 }
416
417 function _render_group($group)
418 {
419 $name = $group['name'];
420 $uid = $group['indexed_name'];
421 $oddity = ($group['level'] % 2 === 0) ? 'even' : 'odd';
422 $dependency = isset($group['dependency']) ? $group['dependency']['function'] . '|' . $group['dependency']['field'] : '';
423
424 $html = '';
425 $html .= '<div id="wpa_loop-' . $uid
426 . '" class="vp-wpa-loop level-' . $oddity . ' wpa_loop wpa_loop-' . $name . ' vp-fixed-loop vp-meta-group'
427 . (isset($group['container_extra_classes']) ? (' ' . implode(' ', $group['container_extra_classes'])) : '')
428 . '"'
429 . VP_Util_Text::return_if_exists(isset($dependency) ? $dependency : '', 'data-vp-dependency="%s"')
430 . '>';
431
432 $icon = '';
433 if(isset($group['sortable']) and $group['sortable'])
434 $icon = '<i class="fa fa-move"></i> ';
435
436 foreach ($group['groups'] as $g)
437 {
438 $is_first = false;
439 if ($g === reset($group['groups'])){ $is_first = true;}
440
441 $html .= '<div id="'. $g['name'] .'" class="vp-wpa-group wpa_group wpa_group-' . $name . '">';
442 $html .= '<div class="vp-wpa-group-heading"><a href="#" class="vp-wpa-group-title">' . $icon . $group['title'] . '</a></div>';
443 $html .= '<div class="vp-controls' . ((!$is_first) ? ' vp-hide' : '') . '">';
444
445 foreach ($g['childs'] as $f)
446 {
447
448 if( is_array($f) and $f['repeating'] )
449 $html .= $this->_render_repeating_group($f);
450 else if( is_array($f) and !$f['repeating'] )
451 $html .= $this->_render_group($f);
452 else
453 $html .= $this->_render_field($f);
454 }
455
456 $html .= '</div>';
457 $html .= '</div>';
458 }
459
460 $html .= '</div>';
461
462 return $html;
463 }
464
465 function _render_repeating_group($group)
466 {
467 $name = $group['name'];
468 $uid = $group['indexed_name'];
469 $oddity = ($group['level'] % 2 === 0) ? 'even' : 'odd';
470 $dependency = isset($group['dependency']) ? $group['dependency']['function'] . '|' . $group['dependency']['field'] : '';
471
472 $html = '';
473 $html .= '<div id="wpa_loop-' . $uid
474 . '" class="vp-wpa-loop level-' . $oddity . ' wpa_loop wpa_loop-' . $name . ' vp-repeating-loop vp-meta-group'
475 . (isset($group['container_extra_classes']) ? (' ' . implode(' ', $group['container_extra_classes'])) : '')
476 . '"'
477 . VP_Util_Text::return_if_exists(isset($dependency) ? $dependency : '', 'data-vp-dependency="%s"')
478 . '>';
479
480 $icon = '';
481 if(isset($group['sortable']) and $group['sortable'])
482 $icon = '<i class="fa fa-move"></i> ';
483
484 foreach ($group['groups'] as $g)
485 {
486 $class = '';
487 $is_first = false;
488 $is_last = false;
489 if ($g === end($group['groups'])){ $is_last = true; $class = ' last tocopy';}
490 if ($g === reset($group['groups'])){ $is_first = true; $class = ' first';}
491
492 $html .= '<div id="'. $g['name'] .'" class="vp-wpa-group wpa_group wpa_group-' . $name . $class . '">';
493 $html .= '<div class="vp-wpa-group-heading"><a href="#" class="vp-wpa-group-title">' . $icon . $group['title'] . '</a><a href="#" class="dodelete vp-wpa-group-remove" title="'. __('Remove', 'wp-ultimate-recipe') .'"><i class="fa fa-times"></i> '. __('Remove', 'wp-ultimate-recipe') .'</a></div>';
494 $html .= '<div class="vp-controls' . ((!$is_first) ? ' vp-hide' : '') . '">';
495 if ($g === end($group['groups']))
496 {
497 $tocopy = $g['name'] . '[tocopy]';
498 $html .= '<input type="hidden" class="tocopy-hidden" name="' . $tocopy . '" value="1">';
499 }
500 foreach ($g['childs'] as $f)
501 {
502
503 if( is_array($f) and $f['repeating'] )
504 $html .= $this->_render_repeating_group($f);
505 else if( is_array($f) and !$f['repeating'] )
506 $html .= $this->_render_group($f);
507 else
508 $html .= $this->_render_field($f);
509 }
510 $html .= '</div>';
511 $html .= '</div>';
512 }
513
514 $html .= '<div class="vp-wpa-group-add">';
515 $html .= '<a href="#" class="button button-large docopy-' . $name . '">'. __('Add More', 'wp-ultimate-recipe') . '' . $group['title'] . '</a>';
516 $html .= '</div>';
517
518 $html .= '</div>';
519
520 return $html;
521 }
522
523 function _save($post_id)
524 {
525 // skip saving if dev mode is on
526 $dev_mode = VP_Util_Config::instance()->load('metabox', 'dev_mode');
527 if($dev_mode)
528 return;
529
530 $real_post_id = isset($_POST['post_ID']) ? $_POST['post_ID'] : NULL ;
531
532 // check autosave
533 if (defined('DOING_AUTOSAVE') AND DOING_AUTOSAVE AND !$this->autosave) return $post_id;
534
535 // make sure data came from our meta box, verify nonce
536 $nonce = isset($_POST[$this->id.'_nonce']) ? $_POST[$this->id.'_nonce'] : NULL ;
537 if (!wp_verify_nonce($nonce, $this->id)) return $post_id;
538
539 // check user permissions
540 if ($_POST['post_type'] == 'page')
541 {
542 if (!current_user_can('edit_page', $post_id)) return $post_id;
543 }
544 else
545 {
546 if (!current_user_can('edit_post', $post_id)) return $post_id;
547 }
548
549 // authentication passed, save data
550 $new_data = isset( $_POST[$this->id] ) ? $_POST[$this->id] : NULL ;
551
552 // clean to copy and reset array indexes
553 $this->_clean_tocopy($new_data);
554
555 if (empty($new_data))
556 {
557 $new_data = NULL;
558 }
559
560 // filter: save
561 if ($this->has_filter('save'))
562 {
563 $new_data = $this->apply_filters('save', $new_data, $real_post_id);
564
565 /**
566 * halt saving
567 * @since 1.3.4
568 */
569 if (FALSE === $new_data) return $post_id;
570
571 $this->_clean_tocopy($new_data);
572 }
573
574 // get current fields, use $real_post_id (checked for in both modes)
575 $current_fields = get_post_meta($real_post_id, $this->id . '_fields', TRUE);
576
577 if ($this->mode == WPALCHEMY_MODE_EXTRACT)
578 {
579 $new_fields = array();
580
581 if (is_array($new_data))
582 {
583 foreach ($new_data as $k => $v)
584 {
585 $field = $this->prefix . $k;
586
587 array_push($new_fields,$field);
588
589 $new_value = $new_data[$k];
590
591 if (is_null($new_value))
592 {
593 delete_post_meta($post_id, $field);
594 }
595 else
596 {
597 update_post_meta($post_id, $field, $new_value);
598 }
599 }
600 }
601
602 $diff_fields = array_diff((array)$current_fields,$new_fields);
603
604 if (is_array($diff_fields))
605 {
606 foreach ($diff_fields as $field)
607 {
608 delete_post_meta($post_id,$field);
609 }
610 }
611
612 delete_post_meta($post_id, $this->id . '_fields');
613
614 if ( ! empty($new_fields))
615 {
616 add_post_meta($post_id,$this->id . '_fields', $new_fields, TRUE);
617 }
618
619 // keep data tidy, delete values if previously using WPALCHEMY_MODE_ARRAY
620 delete_post_meta($post_id, $this->id);
621 }
622 else
623 {
624 if (is_null($new_data))
625 {
626 delete_post_meta($post_id, $this->id);
627 }
628 else
629 {
630 update_post_meta($post_id, $this->id, $new_data);
631 }
632
633 // keep data tidy, delete values if previously using WPALCHEMY_MODE_EXTRACT
634 if (is_array($current_fields))
635 {
636 foreach ($current_fields as $field)
637 {
638 delete_post_meta($post_id, $field);
639 }
640
641 delete_post_meta($post_id, $this->id . '_fields');
642 }
643 }
644
645 // action: save
646 if ($this->has_action('save'))
647 {
648 $this->do_action('save', $new_data, $real_post_id);
649 }
650
651 return $post_id;
652 }
653
654 private function _clean_tocopy(&$arr)
655 {
656 if(is_array($arr))
657 {
658 foreach ($arr as $key => $value)
659 {
660 if(is_array($value))
661 {
662 $this->_clean_tocopy($arr[$key]);
663 if(array_key_exists('tocopy', $value))
664 {
665 unset($arr[$key]);
666 }
667 }
668 }
669 if (!count($arr))
670 {
671 $arr = array();
672 }
673 else
674 {
675 $keys = array_keys($arr);
676
677 $is_numeric = TRUE;
678
679 foreach ($keys as $key)
680 {
681 if (!is_numeric($key))
682 {
683 $is_numeric = FALSE;
684 break;
685 }
686 }
687
688 if ($is_numeric)
689 {
690 $arr = array_values($arr);
691 }
692 }
693 }
694 }
695
696 }
697
698 /**
699 * EOF
700 */