· 9 years ago · Jan 09, 2017, 11:28 AM
1<?php
2/**
3 * Admin Page Class
4 *
5 * The Admin Page Class is used by including it in your plugin files and using its methods to
6 * create custom Admin Pages. It is meant to be very simple and
7 * straightforward.
8 *
9 * This class is derived from My-Meta-Box (https://github.com/bainternet/My-Meta-Box script) which is
10 * a class for creating custom meta boxes for WordPress.
11 *
12 *
13 * @version 1.3.0
14 * @copyright 2012 - 2014
15 * @author Ohad Raz (email: admin@bainternet.info)
16 * @link http://en.bainternet.info
17 *
18 * @license GNU General Public LIcense v3.0 - license.txt
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 *
27 * @package Admin Page Class
28 *
29 * @Last Revised
30 */
31
32if ( ! class_exists( 'BF_Admin_Page_Class') ) :
33
34/**
35 * Admin Page Class
36 *
37 * @package Admin Page Class
38 * @since 0.1
39 *
40 * @todo Nothing.
41 */
42
43 class BF_Admin_Page_Class {
44
45 /**
46 * Contains all saved data for a page
47 *
48 * @access protected
49 * @var array
50 * @since 0.1
51 */
52 protected $_saved;
53
54 /**
55 * Contains all arguments needed to build the page itself
56 *
57 * @access protected
58 * @var array
59 * @since 0.1
60 */
61 protected $args;
62
63 /**
64 * Contains Options group name
65 * @access protected
66 * @var array
67 * @since 0.1
68 */
69 protected $option_group;
70
71 /**
72 * Contains all the information needed to build the form structure of the page
73 *
74 * @access public
75 * @var array
76 * @since 0.1
77 */
78 public $_fields;
79
80 /**
81 * True if the table is opened, false if it is not opened
82 *
83 * @access protected
84 * @var boolean
85 * @since 0.1
86 */
87 protected $table = false;
88
89 /**
90 * True if the tab div is opened, false if it is not opened
91 *
92 * @access protected
93 * @var boolean
94 * @since 0.1
95 */
96 protected $tab_div = false;
97
98 /**
99 * Contains the menu_slug for the current TopLeve-Menu
100 *
101 * @access public
102 * @var string
103 * @since 0.1
104 */
105 public $Top_Slug;
106
107 /**
108 * Contains the menu_slug for the current page
109 *
110 * @access public
111 * @var string
112 * @since 0.1
113 */
114 public $_Slug;
115
116 /**
117 * Contains all the information needed to build the Help tabs
118 *
119 * @access public
120 * @var array
121 * @since 0.1
122 */
123 public $_help_tabs;
124
125 /**
126 * Use html table row or div for each field, true for row, false for div
127 *
128 * @access public
129 * @var boolean
130 * @since 0.1
131 */
132 public $_div_or_row;
133
134 /**
135 * saved flag
136 * @var boolean
137 * @since 0.6
138 */
139 public $saved_flag = false;
140
141 /**
142 * use google fonts for typo filed?
143 * @var boolean
144 * @since 0.9.9
145 * @access public
146 */
147 public $google_fonts = false;
148
149 /**
150 * Holds used field types
151 * @var boolean
152 * @since 1.1.3
153 * @access public
154 */
155 public $field_types = array();
156
157 /**
158 * Holds validation Errors
159 * @var boolean
160 * @since 1.1.9
161 * @access public
162 */
163 public $errors = array();
164
165 /**
166 * Holds Errors flag
167 * @var boolean
168 * @since 1.1.9
169 * @access public
170 */
171 public $errors_flag = false;
172
173 /**
174 * data_type holds type of data (options, post_meta, tax_meta, user_meta)
175 * @var string
176 * @since
177 */
178 public $data_type = 'options';
179 /**
180 * Builds a new Page
181 * @param $args (string|mixed array) -
182 *
183 * Possible keys within $args:
184 * > menu (array|string) - (string) -> this the name of the parent Top-Level-Menu or a TopPage object to create
185 * this page as a sub menu to.
186 * (array) -> top - Slug for the New Top level Menu page to create.
187 * > page_title (string) - The name of this page (good for Top level and sub menu pages)
188 * > capability (string) (optional) - The capability needed to view the page (good for Top level and sub menu pages)
189 * > menu_title (string) - The name of the Top-Level-Menu (Top level Only)
190 * > menu_slug (string) - A unique string identifying your new menu (Top level Only)
191 * > icon_url (string) (optional) - URL to the icon, decorating the Top-Level-Menu (Top level Only)
192 * > position (string) (optional) - The position of the Menu in the ACP (Top level Only)
193 * > option_group (string) (required) - the name of the option to create in the database
194 *
195 *
196 */
197 public function __construct($args) {
198 if(is_array($args)) {
199 if (isset($args['option_group'])){
200 $this->option_group = $args['option_group'];
201 }
202 $this->args = $args;
203 } else {
204 $array['page_title'] = $args;
205 $this->args = $array;
206 }
207
208 //add hooks for export download
209 add_action('template_redirect',array($this, 'admin_redirect_download_files'));
210 add_filter('init', array($this,'add_query_var_vars'));
211
212 // If we are not in admin area exit.
213 if ( ! is_admin() )
214 return;
215
216 //load translation
217 $this->load_textdomain();
218
219 //set defaults
220 $this->_div_or_row = true;
221 $this->saved = false;
222 //store args
223 $this->args = $args;
224 //google_fonts
225 $this->google_fonts = isset($args['google_fonts'])? true : false;
226
227 //sub $menu
228 if(!is_array($args['menu'])) {
229 if(is_object($args['menu'])) {
230 $this->Top_Slug = $args['menu']->Top_Slug;
231 }else{
232 switch($args['menu']) {
233 case 'posts':
234 $this->Top_Slug = 'edit.php';
235 break;
236 case 'dashboard':
237 $this->Top_Slug = 'index.php';
238 break;
239 case 'media':
240 $this->Top_Slug = 'upload.php';
241 break;
242 case 'links':
243 $this->Top_Slug = 'link-manager.php';
244 break;
245 case 'pages':
246 $this->Top_Slug = 'edit.php?post_type=page';
247 break;
248 case 'comments':
249 $this->Top_Slug = 'edit-comments.php';
250 break;
251 case 'theme':
252 $this->Top_Slug = 'themes.php';
253 break;
254 case 'plugins':
255 $this->Top_Slug = 'plugins.php';
256 break;
257 case 'users':
258 $this->Top_Slug = 'users.php';
259 break;
260 case 'tools':
261 $this->Top_Slug = 'tools.php';
262 break;
263 case 'settings':
264 $this->Top_Slug = 'options-general.php';
265 break;
266 default:
267 if(post_type_exists($args['menu'])) {
268 $this->Top_Slug = 'edit.php?post_type='.$args['menu'];
269 } else {
270 $this->Top_Slug = $args['menu'];
271 }
272 }
273 }
274 add_action('admin_menu', array($this, 'AddMenuSubPage'));
275 }else{
276 //top page
277 $this->Top_Slug = $args['menu']['top'];
278 add_action('admin_menu', array($this, 'AddMenuTopPage'));
279 }
280
281
282 // Assign page values to local variables and add it's missed values.
283 $this->_Page_Config = $args;
284 $this->_fields = $this->_Page_Config['fields'];
285 $this->_Local_images = (isset($args['local_images'])) ? true : false;
286 $this->_div_or_row = (isset($args['div_or_row'])) ? $args['div_or_row'] : false;
287 $this->add_missed_values();
288 if (isset($args['use_with_theme'])){
289 if ($args['use_with_theme'] === true){
290 $this->SelfPath = get_stylesheet_directory_uri() . '/admin-page-class';
291 }elseif($args['use_with_theme'] === false){
292 $this->SelfPath = plugins_url( 'admin-page-class', plugin_basename( dirname( __FILE__ ) ) );
293 }else{
294 $this->SelfPath = $args['use_with_theme'];
295 }
296 }else{
297 $this->SelfPath = plugins_url( 'admin-page-class', plugin_basename( dirname( __FILE__ ) ) );
298 }
299
300 // Load common js, css files
301 // Must enqueue for all pages as we need js for the media upload, too.
302
303
304 //add_action('admin_head', array($this, 'loadScripts'));
305 add_filter('attribute_escape',array($this,'edit_insert_to_post_text'),10,2);
306
307 // Delete file via Ajax
308 add_action( 'wp_ajax_apc_delete_mupload', array( $this, 'wp_ajax_delete_image' ) );
309 //import export
310 add_action( 'wp_ajax_apc_import_'.$this->option_group, array( $this, 'import' ) );
311 add_action( 'wp_ajax_apc_export_'.$this->option_group, array( $this, 'export' ) );
312
313 //plupload ajax
314 add_action('wp_ajax_plupload_action', array( $this,"Handle_plupload_action"));
315
316 }
317
318
319 /**
320 * Does all the complicated stuff to build the menu and its first page
321 *
322 * @since 0.1
323 * @access public
324 */
325 public function AddMenuTopPage() {
326 $default = array(
327 'capability' => 'edit_themes',
328 'menu_title' => '',
329 'id' => 'id',
330 'icon_url' => '',
331 'position' => null
332 );
333
334 $this->args = array_merge($default, $this->args);
335 $id = add_menu_page($this->args['page_title'], $this->args['page_title'], $this->args['capability'], $this->args['id'], array($this, 'DisplayPage'), $this->args['icon_url'], $this->args['position']);
336 $page = add_submenu_page($id, $this->args['page_title'], $this->args['page_title'], $this->args['capability'], $this->args['id'], array($this, 'DisplayPage'));
337 if ($page){
338 $this->_Slug = $page;
339 // Adds my_help_tab when my_admin_page loads
340 add_action('load-'.$page, array($this,'Load_page_hooker'));
341 }
342 }
343
344 /**
345 * Does all the complicated stuff to build the page
346 *
347 * @since 0.1
348 * @access public
349 */
350 public function AddMenuSubPage() {
351 $default = array(
352 'capability' => 'edit_themes',
353 );
354 $this->args = array_merge($default, $this->args);
355 $page = add_submenu_page($this->Top_Slug, $this->args['page_title'], $this->args['page_title'], $this->args['capability'], $this->createSlug(), array($this, 'DisplayPage'));
356 if ($page){
357 $this->_Slug = $page;
358 add_action('load-'.$page, array($this,'Load_page_hooker'));
359 }
360 }
361
362 /**
363 * loads scripts and styles for the page
364 *
365 * @author ohad raz
366 * @since 0.1
367 * @access public
368 */
369 public function Load_page_hooker(){
370 $page = $this->_Slug;
371 //help tabs
372 add_action('admin_head-'.$page, array($this,'admin_add_help_tab'));
373 //pluploader code
374 add_action('admin_head-'.$page, array($this,'plupload_head_js'));
375 //scripts and styles
376 add_action( 'admin_print_styles', array( $this, 'load_scripts_styles' ) );
377 //panel script
378 add_action('admin_footer-' . $page, array($this,'panel_script'));
379 //add mising scripts
380 //add_action('admin_enqueue_scripts',array($this,'Finish'));
381
382 if(isset($_POST['action']) && $_POST['action'] == 'save') {
383 do_action('WP_EX_before_save',$this);
384 $this->save();
385 $this->saved_flag = true;
386 do_action('WP_EX_after_save',$this);
387 }
388 }
389
390 public function plupload_head_js(){
391 if ($this->has_field('plupload')){
392 $plupload_init = array(
393 'runtimes' => 'html5,silverlight,flash,html4',
394 'browse_button' => 'plupload-browse-button', // will be adjusted per uploader
395 'container' => 'plupload-upload-ui', // will be adjusted per uploader
396 'drop_element' => 'drag-drop-area', // will be adjusted per uploader
397 'file_data_name' => 'async-upload', // will be adjusted per uploader
398 'multiple_queues' => true,
399 'max_file_size' => wp_max_upload_size() . 'b',
400 'url' => admin_url('admin-ajax.php'),
401 'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
402 'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
403 'filters' => array(array('title' => __('Allowed Files','apc'), 'extensions' => '*')),
404 'multipart' => true,
405 'urlstream_upload' => true,
406 'multi_selection' => false, // will be added per uploader
407 // additional post data to send to our ajax hook
408 'multipart_params' => array(
409 '_ajax_nonce' => "", // will be added per uploader
410 'action' => 'plupload_action', // the ajax action name
411 'imgid' => 0 // will be added per uploader
412 )
413 );
414 echo '<script type="text/javascript">'."\n".'var base_plupload_config=';
415 echo json_encode($plupload_init)."\n".'</script>';
416 }
417 }
418
419 /**
420 * Creates an unique slug out of the page_title and the current menu_slug
421 *
422 * @since 0.1
423 * @access private
424 */
425 private function createSlug() {
426 $slug = $this->args['page_title'];
427 $slug = strtolower($slug);
428 $slug = str_replace(' ','_',$slug);
429 return $this->Top_Slug.'_'.$slug;
430 }
431
432 /** add Help Tab
433 *
434 * @since 0.1
435 * @access public
436 * @param $args (mixed|array) contains everything needed to build the field
437 *
438 * Possible keys within $args:
439 * > id (string) (required)- Tab ID. Must be HTML-safe and should be unique for this menu
440 * > title (string) (required)- Title for the tab.
441 * > content (string) (required)- Help tab content in plain text or HTML.
442 *
443
444 *
445 * Will only work on wordpres version 3.3 and up
446 */
447 public function HelpTab($args){
448 $this->_help_tabs[] = $args;
449 }
450
451 /* print Help Tabs for current screen
452 *
453 * @access public
454 * @since 0.1
455 * @author Ohad
456 *
457 * Will only work on wordpres version 3.3 and up
458 */
459 public function admin_add_help_tab(){
460 $screen = get_current_screen();
461 /*
462 * Check if current screen is My Admin Page
463 * Don't add help tab if it's not
464 */
465
466 if ( $screen->id != $this->_Slug )
467 return;
468 // Add help_tabs for current screen
469
470 foreach((array)$this->_help_tabs as $tab){
471
472 $screen->add_help_tab($tab);
473 }
474 }
475
476 /* print out panel Script
477 *
478 * @access public
479 * @since 0.1
480 */
481 public function panel_script(){
482 ?>
483 <script>
484
485 /* cookie stuff */
486 function setCookie(name,value,days) {
487 if (days) {
488 var date = new Date();
489 date.setTime(date.getTime()+(days*24*60*60*1000));
490 var expires = "; expires="+date.toGMTString();
491 }
492 else var expires = "";
493 document.cookie = name+"="+value+expires+"; path=/";
494 }
495
496 function getCookie(name) {
497 var nameEQ = name + "=";
498
499 var ca = document.cookie.split(";");
500 for(var i=0;i < ca.length;i++) {
501 var c = ca[i];
502 while (c.charAt(0)==' ') c = c.substring(1,c.length);
503 if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
504 }
505 return null;
506 }
507
508 function eraseCookie(name) {setCookie(name,"",-1);}
509
510 var last_tab = getCookie("apc_<?php echo $this->option_group; ?>last");
511 if (last_tab) {
512 var last_tab = last_tab;
513 }else{
514 var last_tab = null;
515 }
516 jQuery(document).ready(function() {
517 function show_tab(li){
518 if (!jQuery(li).hasClass("active_tab")){
519 //hide all
520 jQuery(".setingstab").hide("slow");
521 jQuery(".panel_menu li").removeClass("active_tab");
522 tab = jQuery(li).find("a").attr("href");
523 jQuery(li).addClass("active_tab");
524 jQuery(tab).show("fast");
525 setCookie("apc_<?php echo $this->option_group; ?>last",tab);
526 }
527 }
528 //hide all
529 jQuery(".setingstab").hide();
530
531 //set first_tab as active if no cookie found
532 if (last_tab == null){
533 jQuery(".panel_menu li:first").addClass("active_tab");
534 var tab = jQuery(".panel_menu li:first a").attr("href");
535 jQuery(tab).show();
536 }else{
537 show_tab(jQuery('[href="' + last_tab + '"]').parent());
538 }
539
540 //bind click on menu action to show the right tab.
541 jQuery(".panel_menu li").bind("click", function(event){
542 event.preventDefault()
543 show_tab(jQuery(this));
544
545 });
546 <?php
547 if ($this->has_Field('upload')){
548 ?>
549 function load_images_muploader(){
550 jQuery(".mupload_img_holder").each(function(i,v){
551 if (jQuery(this).next().next().val() != ""){
552 jQuery(this).append('<img src="' + jQuery(this).next().next().val() + '" style="height: 150px;width: 150px;" />');
553 jQuery(this).next().next().next().val("Delete");
554 jQuery(this).next().next().next().removeClass("apc_upload_image_button").addClass("apc_delete_image_button");
555 }
556 });
557 }
558 //upload button
559 var formfield1;
560 var formfield2;
561 jQuery("#image_button").click(function(e){
562 if(jQuery(this).hasClass("apc_upload_image_button")){
563 formfield1 = jQuery(this).prev();
564 formfield2 = jQuery(this).prev().prev();
565 tb_show("", "media-upload.php?type=image&apc=insert_file&TB_iframe=true");
566 return false;
567 }else{
568 var field_id = jQuery(this).attr("rel");
569 var at_id = jQuery(this).prev().prev();
570 var at_src = jQuery(this).prev();
571 var t_button = jQuery(this);
572 data = {
573 action: "apc_delete_mupload",
574 _wpnonce: $("#nonce-delete-mupload_" + field_id).val(),
575 field_id: field_id,
576 attachment_id: jQuery(at_id).val()
577 };
578
579 $.post(ajaxurl, data, function(response) {
580 if ("success" == response.status){
581 jQuery(t_button).val("Upload Image");
582 jQuery(t_button).removeClass("apc_delete_image_button").addClass("apc_upload_image_button");
583 //clear html values
584 jQuery(at_id).val("");
585 jQuery(at_src).val("");
586 jQuery(at_id).prev().html("");
587 load_images_muploader();
588 }else{
589 alert(response.message);
590 }
591 }, "json");
592 return false;
593 }
594 });
595
596
597
598 //store old send to editor function
599 window.restore_send_to_editor = window.send_to_editor;
600 //overwrite send to editor function
601 window.send_to_editor = function(html) {
602 imgurl = jQuery("img",html).attr("src");
603 img_calsses = jQuery("img",html).attr("class").split(" ");
604 att_id = "";
605 jQuery.each(img_calsses,function(i,val){
606 if (val.indexOf("wp-image") != -1){
607 att_id = val.replace("wp-image-", "");
608 }
609 });
610
611 jQuery(formfield2).val(att_id);
612 jQuery(formfield1).val(imgurl);
613 load_images_muploader();
614 tb_remove();
615 //restore old send to editor function
616 window.send_to_editor = window.restore_send_to_editor;
617 }
618 <?php
619 }
620 ?>
621 });
622 </script>
623 <?php
624 }
625
626
627
628 //rename insert to post button
629 /**
630 * edit_insert_to_post_text
631 *
632 * @author ohad raz
633 * @since 0.1
634 * @param string $input insert to post text
635 * @return string
636 */
637 public function edit_insert_to_post_text( $safe_text, $text ) {
638 if( is_admin() && 'Insert into Post' == $safe_text){
639 if (isset($_REQUEST['apc']) && 'insert_file' == $_REQUEST['apc'] )
640 return str_replace(__('Insert into Post'), __('Use this File','apc'), $safe_text);
641 else
642 return str_replace(__('Insert into Post'), __('Use this Image','apc'), $safe_text);
643 }
644 return $safe_text;
645 }
646
647 /* print out panel Style (deprecated)
648 *
649 * @access public
650 * @since 0.1
651 */
652 public function panel_style(){
653 //echo '<style></style>';
654 }
655
656 /**
657 * Outputs all the HTML needed for the new page
658 *
659 * @access public
660 * @param $args (mixed|array) contains everything needed to build the field
661 * @param $repeater (boolean)
662 * @since 0.1
663 */
664 public function DisplayPage() {
665 do_action('admin_page_class_before_page');
666 echo '<div class="wrap">'."\n";
667 echo '<form method="post" name="'.apply_filters('apc_form_name', 'admin_page_class',$this).'" class="'.apply_filters('apc_form_class', 'admin_page_class',$this).'" id="'.apply_filters('apc_form_id', 'admin_page_class',$this).'" action="" enctype="multipart/form-data">
668 '."\n".'<div class="header_wrap">'."\n".'
669 <div style="float:left">'."\n";
670 // echo apply_filters('admin_page_class_before_title','');
671 echo '<h2>'.apply_filters('admin_page_class_h2',$this->args['page_title']).'</h2>'."\n".((isset($this->args['page_header_text']))? $this->args['page_header_text'] : '').'
672 </div>'."\n".'
673 <div class="header-save-button" style="float:right;margin:32px 0 0 0">'."\n".'
674 <input type="submit" value="'.esc_attr(__('Save Changes','apc')).'" name="Submit" class="'.apply_filters('admin_page_class_submit_class', 'btn-info').' btn">
675 </div>'. '
676 </div>'."\n";
677 wp_nonce_field( basename(__FILE__), 'BF_Admin_Page_Class_nonce' );
678
679 if ($this->saved_flag){
680 echo '<div class="update-status">'."\n";
681 $this->errors = apply_filters('admin_page_class_errors', $this->errors,$this);
682 if (is_array($this->errors) && count($this->errors) > 0 ){
683 $this->errors_flag = true;
684 $this->displayErrors();
685 }else{
686 echo '<div class="alert alert-success"><button data-dismiss="alert" class="close" type="button">×</button><strong>'.__('Settings saved.','apc').'</strong></div>'."\n";
687 }
688 echo '</div>'."\n";
689 }
690
691
692 $saved = get_option($this->option_group);
693 $this->_saved = $saved;
694 $skip = array('title','paragraph','subtitle','TABS','CloseDiv','TABS_Listing','OpenTab','custom','import_export');
695
696 foreach($this->_fields as $field) {
697 if (!in_array($field['type'],$skip)){
698 if(!$this->table) {
699 if ($this->_div_or_row){
700 echo '<table class="form-table">'."\n";
701 $this->table = true;
702 }else{
703 echo '<div class="form-table">'."\n";
704 $this->table = true;
705 }
706 }
707 }else{
708 if($this->table) {
709 if ($this->_div_or_row){echo '</table>'."\n";}else{echo '</div>'."\n";}
710 $this->table = false;
711 }
712 }
713 $data = '';
714 if(!$this->saved_flag && $saved === false)
715 $data = isset($field['std'])? $field['std'] : '';
716
717 if (isset($saved[$field['id']]))
718 $data = $saved[$field['id']];
719
720 if (method_exists($this,'show_field_' . $field['type'])){
721 if ($this->_div_or_row){echo '<td>'."\n";}else{echo apply_filters('admin_page_class_field_container_open','<div class="field">'."\n",$field);}
722 call_user_func ( array( $this, 'show_field_' . $field['type'] ), $field, $data );
723 if ($this->_div_or_row){echo '</td>'."\n";}else{echo apply_filters('admin_page_class_field_container_close','</div>'."\n",$field);}
724 }else{
725 switch($field['type']) {
726 case 'TABS':
727 echo '<div id="tabs">'."\n";
728 break;
729 case 'CloseDiv':
730 $this->tab_div = false;
731 echo '</div>'."\n";
732 break;
733 case 'TABS_Listing':
734 echo '<div class="panel_menu">'."\n".'<ul>'."\n";
735 echo apply_filters('admin_page_class_before_title','');
736 foreach($field['links'] as $id => $name){
737 $extra_classes = strtolower(str_replace(' ','-',$name)).' '.strtolower(str_replace(' ','-',$id));
738 echo '<li class="'.apply_filters('APC_tab_li_extra_class',$extra_classes).'">'."\n\t".'<a class="nav_tab_link" href="#'.$id.'">'.$name.'</a>'."\n".'</li>'."\n";
739 }
740 echo '</ul>'."\n".'</div>'."\n".'<div class="sections">'."\n";
741 break;
742 case 'OpenTab':
743 $this->tab_div = true;
744 echo '<div class="setingstab" id="'.$field['id'].'">'."\n";
745 do_action('admin_page_class_after_tab_open');
746 break;
747 case 'title':
748 echo '<h2>'.$field['label'].'</h2>'."\n";
749 break;
750 case 'subtitle':
751 echo '<h3>'.$field['label'].'</h3>'."\n";
752 break;
753 case 'paragraph':
754 echo '<p>'.$field['text'].'</p>'."\n";
755 break;
756 case 'repeater':
757 do_action('admin_page_class_before_repeater');
758 $this->output_repeater_fields($field,$data);
759 do_action('admin_page_class_after_repeater');
760 break;
761 case 'import_export':
762 $this->show_import_export();
763 do_action('admin_page_class_import_export_tab');
764 break;
765 }
766 }
767 if (!in_array($field['type'],$skip)){ echo '</tr>'."\n";}
768 }
769 if($this->table) echo '</table>'."\n";
770 if($this->tab_div) echo '</div>'."\n";
771 echo '</div>'."\n".'<div style="clear:both"></div>'."\n".'<div class="footer_wrap">'."\n".'
772 <input type="submit" name="Submit" class="'.apply_filters('admin_page_class_submit_class', 'btn-info').' btn" value="'.esc_attr(__('Save Changes','apc')).'" />'.'
773 </div>'."\n";
774 echo '<input type="hidden" name="action" value="save" />'."\n";
775 echo '</form>'."\n".'</div>'."\n".'</div>'."\n";
776 do_action('admin_page_class_after_page');
777 }
778
779 /**
780 * Adds tabs current page
781 *
782 * @access public
783 * @param $args (mixed|array) contains everything needed to build the field
784 * @since 0.1
785 */
786 public function OpenTabs_container($text= null) {
787 $args['type'] = 'TABS';
788 $text = (null == $text)? '': $text;
789 $args['text'] = $text;
790 $args['id'] = 'TABS';
791 $args['std'] = '';
792 $this->SetField($args);
793 }
794
795 /**
796 * Close open Div
797 *
798 * @access public
799 * @param $args (mixed|array) contains everything needed to build the field
800 * @param $repeater (boolean)
801 * @since 0.1
802 */
803 public function CloseDiv_Container() {
804 $args['type'] = 'CloseDiv';
805 $args['id'] = 'CloseDiv';
806 $args['std'] = '';
807 $this->SetField($args);
808 }
809
810 /**
811 * Adds tabs listing in ul li
812 *
813 * @access public
814 * @param $args (mixed|array) contains everything needed to build the field
815 * @param $repeater (boolean)
816 * @since 0.1
817 */
818 public function TabsListing($args) {
819 $args['type'] = 'TABS_Listing';
820 $args['id'] = 'TABS_Listing';
821 $args['std'] = '';
822 $this->SetField($args);
823 }
824
825 /**
826 * Opens a Div
827 *
828 * @access public
829 * @param $args (mixed|array) contains everything needed to build the field
830 * @param $repeater (boolean)
831 * @since 0.1
832 */
833 public function OpenTab($name) {
834 $args['type'] = 'OpenTab';
835 $args['id'] = $name;
836 $args['std'] = '';
837 $this->SetField($args);
838 }
839
840 /**
841 * close a Div
842 *
843 * @access public
844 * @since 0.1
845 */
846 public function CloseTab() {
847 $args['type'] = 'CloseDiv';
848 $args['id'] = 'CloseDiv';
849 $args['std'] = '';
850 $this->SetField($args);
851 }
852
853 /**
854 * Does the repetive tasks of adding a field
855 *
856 * @param $args (mixed|array) contains everything needed to build the field
857 * @param $repeater (boolean)
858 * @since 0.1
859 *
860 * @access private
861 */
862 private function SetField($args) {
863 $default = array(
864 'std' => '',
865 'id' => ''
866 );
867 $args = array_merge($default, $args);
868 $this->buildOptions($args);
869 $this->_fields[] = $args;
870 }
871
872 /**
873 * Builds all the options with their std values
874 *
875 * @access public
876 * @param $args (mixed|array) contains everything needed to build the field
877 * @since 0.1
878 * @access private
879 */
880 private function buildOptions($args) {
881 $default = array(
882 'std' => '',
883 'id' => ''
884 );
885 $args = array_merge($default, $args);
886 $saved = get_option($this->option_group);
887 if (isset($saved[$args['id']])){
888 if($saved[$args['id']] === false) {
889 $saved[$args['id']] = $args['std'];
890 update_option($this->args['option_group'],$saved);
891 }
892 }
893 }
894
895 /**
896 * Adds a heading to the current page
897 *
898 * @access public
899 * @param $args (mixed|array) contains everything needed to build the field
900 * @param $repeater (boolean)
901 * @since 0.1
902 *
903 * @param string $label simply the text for your heading
904 */
905 public function Title($label,$repeater = false) {
906 $args['type'] = 'title';
907 $args['std'] = '';
908 $args['label'] = $label;
909 $args['id'] = 'title'.$label;
910 $this->SetField($args);
911 }
912
913 /**
914 * Adds a sub-heading to the current page
915 *
916 * @access public
917 * @param $args (mixed|array) contains everything needed to build the field
918 * @param $repeater (boolean)
919 * @since 0.1
920 *
921 * @param string $label simply the text for your heading
922 */
923 public function Subtitle($label,$repeater = false) {
924 $args['type'] = 'subtitle';
925 $args['label'] = $label;
926 $args['id'] = 'title'.$label;
927 $args['std'] = '';
928 $this->SetField($args);
929 }
930
931 /**
932 * Adds a paragraph to the current page
933 *
934 * @access public
935 * @param $args (mixed|array) contains everything needed to build the field
936 * @param $repeater (boolean)
937 * @since 0.1
938 *
939 * @param string $text the text you want to display
940 */
941 public function Paragraph($text,$repeater = false) {
942 $args['type'] = 'paragraph';
943 $args['text'] = $text;
944 $args['id'] = 'paragraph';
945 $args['std'] = '';
946 $this->SetField($args);
947 }
948
949
950 /**
951 * Load all Javascript and CSS
952 *
953 * @since 0.1
954 * @access public
955 */
956 public function load_scripts_styles() {
957
958 // Get Plugin Path
959 $plugin_path = $this->SelfPath;
960
961 //this replaces the ugly check fields methods calls
962 foreach (array('upload','color','date','time','code','select','editor','plupload') as $type) {
963 call_user_func ( array( $this, 'check_field_' . $type ));
964 }
965
966 wp_enqueue_script('common');
967 if ($this->has_Field('TABS')){
968 wp_print_scripts('jquery-ui-tabs');
969 }
970
971 // Enqueue admin page Style
972 wp_enqueue_style( 'Admin_Page_Class', $plugin_path . '/css/Admin_Page_Class.css' );
973 wp_enqueue_style('iphone_checkbox',$plugin_path. '/js/FancyCheckbox/FancyCheckbox.css');
974
975 // Enqueue admin page Scripts
976 wp_enqueue_script( 'Admin_Page_Class', $plugin_path . '/js/Admin_Page_Class.js', array( 'jquery' ), null, true );
977 wp_enqueue_script('iphone_checkbox',$plugin_path. '/js/FancyCheckbox/FancyCheckbox.js',array('jquery'),null,true);
978
979 wp_enqueue_script('utils');
980 wp_enqueue_script( 'jquery-ui-sortable' );
981 wp_enqueue_script( 'jquery-ui-dialog' );
982 }
983
984
985 /**
986 * Check Field code editor
987 *
988 * @since 0.1
989 * @access public
990 */
991 public function check_field_code() {
992
993 if ( $this->has_field( 'code' ) && $this->is_edit_page() ) {
994 $plugin_path = $this->SelfPath;
995 // Enqueu codemirror js and css
996 wp_enqueue_style( 'at-code-css', $plugin_path .'/js/codemirror/codemirror.css',array(),null);
997 wp_enqueue_style( 'at-code-css-dark', $plugin_path .'/js/codemirror/solarizedDark.css',array(),null);
998 wp_enqueue_style( 'at-code-css-light', $plugin_path .'/js/codemirror/solarizedLight.css',array(),null);
999 wp_enqueue_script('at-code-js',$plugin_path .'/js/codemirror/codemirror.js',array('jquery'),false,true);
1000 wp_enqueue_script('at-code-js-xml',$plugin_path .'/js/codemirror/xml.js',array('jquery'),false,true);
1001 wp_enqueue_script('at-code-js-javascript',$plugin_path .'/js/codemirror/javascript.js',array('jquery'),false,true);
1002 wp_enqueue_script('at-code-js-css',$plugin_path .'/js/codemirror/css.js',array('jquery'),false,true);
1003 wp_enqueue_script('at-code-js-clike',$plugin_path .'/js/codemirror/clike.js',array('jquery'),false,true);
1004 wp_enqueue_script('at-code-js-php',$plugin_path .'/js/codemirror/php.js',array('jquery'),false,true);
1005 }
1006 }
1007
1008
1009
1010 /**
1011 * Check For editor field to enqueue editor scripts
1012 * @since 1.1.3
1013 * @access public
1014 */
1015 public function check_field_editor(){
1016 if ($this->has_Field('editor')){
1017 global $wp_version;
1018 if ( version_compare( $wp_version, '3.2.1' ) < 1 ) {
1019 wp_print_scripts('tiny_mce');
1020 wp_print_scripts('editor');
1021 wp_print_scripts('editor-functions');
1022 }
1023 }
1024 }
1025
1026 /**
1027 * Check For select field to enqueue Select2 #see http://goo.gl/3pjY8
1028 * @since 1.1.3
1029 * @access public
1030 */
1031 public function check_field_select(){
1032 if ($this->has_field_any(array('select','typo')) && $this->is_edit_page()) {
1033 $plugin_path = $this->SelfPath;
1034 // Enqueu JQuery chosen library, use proper version.
1035 wp_enqueue_style('at-multiselect-chosen-css', $plugin_path . '/js/select2/select2.css', array(), null);
1036
1037 wp_enqueue_script('at-multiselect-chosen-js', $plugin_path . '/js/select2/select2.js', array('jquery'), false, true);
1038 }
1039 }
1040
1041 /**
1042 * Check Field Plupload
1043 *
1044 * @since 0.9.7
1045 * @access public
1046 */
1047 public function check_field_plupload(){
1048 if ( $this->has_field( 'plupload' ) && $this->is_edit_page() ) {
1049 $plugin_path = $this->SelfPath;
1050 wp_enqueue_script('plupload-all');
1051 wp_register_script('myplupload', $plugin_path .'/js/plupload/myplupload.js', array('jquery'));
1052 wp_enqueue_script('myplupload');
1053 wp_register_style('myplupload', $plugin_path .'/js/plupload/myplupload.css');
1054 wp_enqueue_style('myplupload');
1055 }
1056 }
1057
1058
1059 /**
1060 * Check the Field Upload, Add needed Actions
1061 *
1062 * @since 0.1
1063 * @access public
1064 */
1065 public function check_field_upload() {
1066
1067 // Check if the field is an image or file. If not, return.
1068 if ( ! $this->has_field_any(array('image','file')) )
1069 return;
1070
1071 // Add data encoding type for file uploading.
1072 add_action( 'post_edit_form_tag', array( $this, 'add_enctype' ) );
1073
1074 if( wp_style_is( 'wp-color-picker', 'registered' ) ){ //since WordPress 3.5
1075 wp_enqueue_media();
1076 wp_enqueue_script('media-upload');
1077 }else{
1078 // Make upload feature work event when custom post type doesn't support 'editor'
1079 wp_enqueue_script( 'media-upload' );
1080 add_thickbox();
1081 wp_enqueue_script( 'jquery-ui-core' );
1082 wp_enqueue_script( 'jquery-ui-sortable' );
1083 }
1084
1085
1086 // Add filters for media upload.
1087 add_filter( 'media_upload_gallery', array( $this, 'insert_images' ) );
1088 add_filter( 'media_upload_library', array( $this, 'insert_images' ) );
1089 add_filter( 'media_upload_image', array( $this, 'insert_images' ) );
1090
1091 // Delete all attachments when delete custom post type.
1092 add_action( 'wp_ajax_at_delete_file', array( $this, 'delete_file' ) );
1093 add_action( 'wp_ajax_at_reorder_images', array( $this, 'reorder_images' ) );
1094 // Delete file via Ajax
1095 add_action( 'wp_ajax_at_delete_mupload', array( $this, 'wp_ajax_delete_image' ) );
1096 }
1097
1098 /**
1099 * Add data encoding type for file uploading
1100 *
1101 * @since 0.1
1102 * @access public
1103 */
1104 public function add_enctype () {
1105 echo ' enctype="multipart/form-data"';
1106 }
1107
1108 /**
1109 * Process images added to meta field.
1110 *
1111 * Modified from Faster Image Insert plugin.
1112 *
1113 * @return void
1114 * @author Cory Crowley
1115 */
1116 public function insert_images() {
1117
1118 // If post variables are empty, return.
1119 if ( ! isset( $_POST['at-insert'] ) || empty( $_POST['attachments'] ) )
1120 return;
1121
1122 // Security Check
1123 check_admin_referer( 'media-form' );
1124
1125 // Create Security Nonce
1126 $nonce = wp_create_nonce( 'at_ajax_delete' );
1127
1128 // Get Post Id and Field Id
1129 $id = $_POST['field_id'];
1130
1131 // Modify the insertion string
1132 $html = '';
1133 foreach( $_POST['attachments'] as $attachment_id => $attachment ) {
1134
1135 // Strip Slashes
1136 $attachment = stripslashes_deep( $attachment );
1137
1138 // If not selected or url is empty, continue in loop.
1139 if ( empty( $attachment['selected'] ) || empty( $attachment['url'] ) )
1140 continue;
1141
1142 $li = "<li id='item_{$attachment_id}'>";
1143 $li .= "<img src='{$attachment['url']}' alt='image_{$attachment_id}' />";
1144 //$li .= "<a title='" . __( 'Delete this image' ) . "' class='at-delete-file' href='#' rel='{$nonce}|{$post_id}|{$id}|{$attachment_id}'>" . __( 'Delete' ) . "</a>";
1145 $li .= "<a title='" . __( 'Delete this image','apc' ) . "' class='at-delete-file' href='#' rel='{$nonce}|{$post_id}|{$id}|{$attachment_id}'><img src='" . $this->SelfPath. "/images/delete-16.png' alt='" . __( 'Delete' ,'apc') . "' /></a>";
1146 $li .= "<input type='hidden' name='{$id}[]' value='{$attachment_id}' />";
1147 $li .= "</li>";
1148 $html .= $li;
1149
1150 } // End For Each
1151
1152 return media_send_to_editor( $html );
1153
1154 }
1155
1156 /**
1157 * Delete attachments associated with the post.
1158 *
1159 * @since 0.1
1160 * @access public
1161 *
1162 */
1163 public function delete_attachments( $post_id ) {
1164
1165 // Get Attachments
1166 $attachments = get_posts( array( 'numberposts' => -1, 'post_type' => 'attachment', 'post_parent' => $post_id ) );
1167
1168 // Loop through attachments, if not empty, delete it.
1169 if ( ! empty( $attachments ) ) {
1170 foreach ( $attachments as $att ) {
1171 wp_delete_attachment( $att->ID );
1172 }
1173 }
1174
1175 }
1176
1177
1178 /**
1179 * Ajax callback for deleting files.
1180 * Modified from a function used by "Verve Meta Boxes" plugin (http://goo.gl/LzYSq)
1181 * @since 0.1
1182 * @access public
1183 */
1184 public function wp_ajax_delete_image() {
1185 $field_id = isset( $_GET['field_id'] ) ? $_GET['field_id'] : 0;
1186 $attachment_id = isset( $_GET['attachment_id'] ) ? intval( $_GET['attachment_id'] ) : 0;
1187 $ok = false;
1188 $remove_meta_only = apply_filters("apc_delete_image",true);
1189 if (strpos($field_id, '[') === false){
1190 check_admin_referer( "at-delete-mupload_".urldecode($field_id));
1191 $temp = get_option($this->args['option_group']);
1192 unset($temp[$field_id]);
1193 update_option($this->args['option_group'],$temp);
1194 if (!$remove_meta_only)
1195 $ok = wp_delete_attachment( $attachment_id );
1196 else
1197 $ok = true;
1198 }else{
1199 $f = explode('[',urldecode($field_id));
1200 $f_fiexed = array();
1201 foreach ($f as $k => $v){
1202 $f[$k] = str_replace(']','',$v);
1203 }
1204 $temp = get_option($this->args['option_group']);
1205
1206 /**
1207 * repeater block
1208 * $f[0] = repeater id
1209 * $f[1] = repeater item number
1210 * $f[2] = actuall in repeater item image field id
1211 *
1212 * conditional block
1213 * $f[0] = conditional id
1214 * $f[1] = actuall in conditional block image field id
1215 */
1216 $saved = $temp[$f[0]];
1217 if (isset($f[2]) && isset($saved[$f[1]][$f[2]])){ //delete from repeater block
1218 unset($saved[$f[1]][$f[2]]);
1219 $temp[$f[0]] = $saved;
1220 update_option($this->args['option_group'],$temp);
1221 if (!$remove_meta_only)
1222 $ok = wp_delete_attachment( $attachment_id );
1223 else
1224 $ok = true;
1225 }elseif(isset($saved[$f[1]]['src'])){ //delete from conditional block
1226 unset($saved[$f[1]]);
1227 $temp[$f[0]] = $saved;
1228 update_option($this->args['option_group'],$temp);
1229 if (!$remove_meta_only)
1230 $ok = wp_delete_attachment( $attachment_id );
1231 else
1232 $ok = true;
1233 }
1234 }
1235
1236 if ( $ok ){
1237 echo json_encode( array('status' => 'success' ));
1238 die();
1239 }else{
1240 echo json_encode(array('message' => __( 'Cannot delete file. Something\'s wrong.','apc')));
1241 die();
1242 }
1243 }
1244
1245 /**
1246 * Ajax callback for reordering Images.
1247 *
1248 * @since 0.1
1249 * @access public
1250 */
1251 public function reorder_images() {
1252
1253 if ( ! isset( $_POST['data'] ) )
1254 die();
1255
1256 list( $order, $post_id, $key, $nonce ) = explode( '|', $_POST['data'] );
1257
1258 if ( ! wp_verify_nonce( $nonce, 'at_ajax_reorder' ) )
1259 die( '1' );
1260
1261 parse_str( $order, $items );
1262 $items = $items['item'];
1263 $order = 1;
1264 foreach ( $items as $item ) {
1265 wp_update_post( array( 'ID' => $item, 'post_parent' => $post_id, 'menu_order' => $order ) );
1266 $order++;
1267 }
1268
1269 die( '0' );
1270
1271 }
1272
1273 /**
1274 * Check Field Color
1275 *
1276 * @since 0.1
1277 * @access public
1278 */
1279 public function check_field_color() {
1280
1281 if ( $this->has_field_any(array('color' ,'typo' )) && $this->is_edit_page() ) {
1282 if( wp_style_is( 'wp-color-picker', 'registered' ) ) {
1283 wp_enqueue_style( 'wp-color-picker' );
1284 wp_enqueue_script( 'wp-color-picker' );
1285 }else{
1286 // Enqueu built-in script and style for color picker.
1287 wp_enqueue_style( 'farbtastic' );
1288 wp_enqueue_script( 'farbtastic' );
1289 }
1290 }
1291
1292 }
1293
1294 /**
1295 * Check Field Date
1296 *
1297 * @since 0.1
1298 * @access public
1299 */
1300 public function check_field_date() {
1301
1302 if ( $this->has_field( 'date' ) && $this->is_edit_page() ) {
1303 $plugin_path = $this->SelfPath;
1304 // Enqueu JQuery UI, use proper version.
1305 wp_enqueue_style( 'jquery-ui-css', $plugin_path.'/css/jquery-ui.css' );
1306 wp_enqueue_script( 'jquery-ui');
1307 wp_enqueue_script( 'jquery-ui-datepicker');
1308 }
1309
1310 }
1311
1312 /**
1313 * Check Field Time
1314 *
1315 * @since 0.1
1316 * @access public
1317 */
1318 public function check_field_time() {
1319
1320 if ( $this->has_field( 'time' ) && $this->is_edit_page() ) {
1321 $plugin_path = $this->SelfPath;
1322
1323 wp_enqueue_style( 'jquery-ui-css', $plugin_path.'/css/jquery-ui.css' );
1324 wp_enqueue_script( 'jquery-ui');
1325 wp_enqueue_script( 'at-timepicker', $plugin_path . '/js/time-and-date/jquery-ui-timepicker-addon.js', array( 'jquery-ui-slider','jquery-ui-datepicker' ), null, true );
1326
1327 }
1328
1329 }
1330
1331 /**
1332 * Add Meta Box for multiple post types.
1333 *
1334 * @since 0.1
1335 * @access public
1336 */
1337 public function add() {
1338
1339 // Loop through array
1340 foreach ( $this->_meta_box['pages'] as $page ) {
1341 add_meta_box( $this->_meta_box['id'], $this->_meta_box['title'], array( $this, 'show' ), $page, $this->_meta_box['context'], $this->_meta_box['priority'] );
1342 }
1343
1344 }
1345
1346 /**
1347 * Callback function to show fields in Page.
1348 *
1349 * @since 0.1
1350 * @access public
1351 */
1352 public function show() {
1353
1354 global $post;
1355 wp_nonce_field( basename(__FILE__), 'BF_Admin_Page_Class_nonce' );
1356 echo '<table class="form-table">'."\n";
1357 foreach ( $this->_fields as $field ) {
1358 $meta = get_post_meta( $post->ID, $field['id'], !$field['multiple'] );
1359 $meta = ( $meta !== '' ) ? $meta : $field['std'];
1360 if ('image' != $field['type'] && $field['type'] != 'repeater')
1361 $meta = is_array( $meta ) ? array_map( 'esc_attr', $meta ) : esc_attr( $meta );
1362 echo '<tr>'."\n";
1363
1364 // Call Separated methods for displaying each type of field.
1365 call_user_func ( array( $this, 'show_field_' . $field['type'] ), $field, $meta );
1366 echo '</tr>'."\n";
1367 }
1368 echo '</table>'."\n";
1369 }
1370
1371 /**
1372 * Show Repeater Fields.
1373 *
1374 * @param string $field
1375 * @param string $meta
1376 * @since 0.1
1377 * @modified at 0.4 added sortable option
1378 * @access public
1379 */
1380 public function show_field_repeater( $field, $meta ) {
1381 // Get Plugin Path
1382 $plugin_path = $this->SelfPath;
1383 $this->show_field_begin( $field, $meta );
1384 $class = '';
1385 if ($field['sortable'])
1386 $class = " repeater-sortable";
1387 $jsid = ltrim(strtolower(str_replace(' ','',$field['id'])), '0123456789');
1388 echo "<div class='at-repeat".$class."' id='{$jsid}'>\n";
1389
1390 $c = 0;
1391 $temp_div_row = $this->_div_or_row;
1392 $this->_div_or_row = true;
1393 $meta = isset($this->_saved[$field['id']])? $this->_saved[$field['id']]: '';
1394
1395 if (count($meta) > 0 && is_array($meta) ){
1396 foreach ($meta as $me){
1397 //for labling toggles
1398 $mmm = isset($me[$field['fields'][0]['id']])? $me[$field['fields'][0]['id']]: "";
1399 $mmm = (in_array($field['fields'][0]['type'],array('image','file'))? '' : $mmm);
1400 echo '<div class="at-repater-block">'.$mmm.'<br/><table class="repeater-table" style="display: none;">';
1401 if ($field['inline']){
1402 echo '<tr class="at-inline" VALIGN="top">';
1403 }
1404 foreach ($field['fields'] as $f){
1405 //reset var $id for repeater
1406 $id = '';
1407 $id = $field['id'].'['.$c.']['.$f['id'].']';
1408 $m = isset($me[$f['id']])? $me[$f['id']]: '';
1409 if ( $m !== '' ) {
1410 $m = $m;
1411 }else{
1412 $m = isset($f['std'])? $f['std'] : '';
1413 }
1414 if ('image' != $f['type'] && $f['type'] != 'repeater')
1415 $m = is_array( $m) ? array_map( 'esc_attr', $m ) : esc_attr( $m);
1416 if (in_array($f['type'],array('text','textarea')))
1417 $m = stripslashes($m);
1418 //set new id for field in array format
1419 $f['id'] = $id;
1420 if (!$field['inline']){
1421 echo '<tr>';
1422 }
1423 call_user_func ( array( $this, 'show_field_' . $f['type'] ), $f, $m);
1424 if (!$field['inline']){
1425 echo '</tr>';
1426 }
1427 }
1428 if ($field['inline']){
1429 echo '</tr>';
1430 }
1431 echo '</table>
1432 <span class="at-re-toggle"><img src="';
1433 if ($this->_Local_images){
1434 echo $plugin_path.'/images/edit.png';
1435 }else{
1436 echo 'http://i.imgur.com/ka0E2.png';
1437 }
1438 echo '" alt="Edit" title="Edit"/></span>
1439 <img src="';
1440 if ($this->_Local_images){
1441 echo $plugin_path.'/images/remove.png';
1442 }else{
1443 echo 'http://i.imgur.com/g8Duj.png';
1444 }
1445 echo '" alt="'.__('Remove','apc').'" title="'.__('Remove','apc').'" id="remove-'.$field['id'].'"></div>';
1446 $c = $c + 1;
1447
1448 }
1449 }
1450
1451 echo '<img src="';
1452 if ($this->_Local_images){
1453 echo $plugin_path.'/images/add.png';
1454 }else{
1455 echo 'http://i.imgur.com/w5Tuc.png';
1456 }
1457 echo '" alt="'.__('Add','apc').'" title="'.__('Add','apc').'" id="add-'.$jsid.'"><br/></div>';
1458
1459 //create all fields once more for js function and catch with object buffer
1460 ob_start();
1461 echo '<div class="at-repater-block"><table class="repeater-table">'."\n";
1462 if ($field['inline']){
1463 echo '<tr class="at-inline" VALIGN="top">'."\n";
1464 }
1465 foreach ($field['fields'] as $f){
1466 //reset var $id for repeater
1467 $id = '';
1468
1469 $id = $field['id'].'[CurrentCounter]['.$f['id'].']';
1470 $f['id'] = $id;
1471 if (!$field['inline']){
1472 echo '<tr>'."\n";
1473 }
1474 $m = isset($f['std'])? $f['std'] : '';
1475 call_user_func ( array( $this, 'show_field_' . $f['type'] ), $f, $m);
1476 if (!$field['inline']){
1477 echo '</tr>'."\n";
1478 }
1479 }
1480 if ($field['inline']){
1481 echo '</tr>'."\n";
1482 }
1483 echo '</table><img src="';
1484 if ($this->_Local_images){
1485 echo $plugin_path.'/images/remove.png';
1486 }else{
1487 echo 'http://i.imgur.com/g8Duj.png';
1488 }
1489
1490 echo '" alt="'.__('Remove','apc').'" title="'.__('Remove','apc').'" id="remove-'.$jsid.'"></div>'."\n";
1491 $counter = 'countadd_'.$jsid;
1492 $js_code = ob_get_clean ();
1493 $js_code = str_replace("'","\"",$js_code);
1494 //$js_code = str_replace("CurrentCounter","' + ".$counter." + '",$js_code);
1495 echo "\n".'<script type="text/template" id="'.$jsid.'-template">'.$js_code.'</script>'."\n";
1496 echo '<script>
1497 jQuery(document).ready(function($) {
1498 var '.$counter.' = '.$c.';
1499 $(document).on("click","#add-'.$jsid.'", function() {
1500 '.$counter.' = '.$counter.' + 1;
1501 var rep = $("#'.$jsid.'-template").html().replace(new RegExp("CurrentCounter", "g"), '.$counter.');
1502 $(this).before(rep);
1503 apc_init();
1504 });
1505 $(document).on("click","#remove-'.$jsid.'", function() {
1506 $(this).parent().remove();
1507 });
1508 });
1509 </script>'."\n";
1510 echo '<br/><style>
1511.at-inline{line-height: 1 !important;}
1512.at-inline .at-field{border: 0px !important;}
1513.at-inline .at-label{margin: 0 0 1px !important;}
1514.at-inline .at-text{width: 70px;}
1515.at-inline .at-textarea{width: 100px; height: 75px;}
1516.at-repater-block{background-color: #FFFFFF;border: 1px solid;margin: 2px;}
1517</style>';
1518
1519 $this->_div_or_row = $temp_div_row;
1520 $this->show_field_end($field, $meta);
1521 }
1522
1523 /**
1524 * Begin Field.
1525 *
1526 * @param string $field
1527 * @param string $meta
1528 * @since 0.1
1529 * @access public
1530 */
1531 public function show_field_begin( $field, $meta) {
1532 if ($this->_div_or_row){
1533 echo "<td class='at-field'>\n";
1534 }
1535
1536 //check for errors
1537 if ($this->saved_flag && $this->errors_flag && isset($field['validate']) && isset($field['id']) && $this->has_error($field['id'])){
1538 echo '<div class="alert alert-error field-validation-error"><button data-dismiss="alert" class="close" type="button">×</button>';
1539 $ers = $this->getFieldErrors($field['id']);
1540 foreach ((array)$ers['m'] as $m) {
1541 echo "{$m}</br />";
1542 }
1543 echo '</div>'."\n";
1544 }
1545
1546 if ( $field['name'] != '' || $field['name'] != FALSE )
1547 echo "<div class='at-label'><label for='{$field['id']}'>{$field['name']}</label></div>\n";
1548 }
1549
1550 /**
1551 * End Field.
1552 *
1553 * @param string $field
1554 * @param string $meta
1555 * @since 0.1
1556 * @access public
1557 */
1558 public function show_field_end( $field, $meta=NULL ,$group = false) {
1559 if ( isset($field['desc']) && $field['desc'] != '' )
1560 echo "<div class='desc-field'>{$field['desc']}</div>\n";
1561
1562 if ($this->_div_or_row)
1563 echo "</td>\n";
1564
1565
1566 }
1567
1568 /**
1569 * Show Sortable Field
1570 * @author Ohad Raz
1571 * @since 0.4
1572 * @access public
1573 * @param (array) $field
1574 * @param (array) $meta
1575 * @return void
1576 */
1577 public function show_field_sortable( $field, $meta ) {
1578
1579 $this->show_field_begin( $field, $meta );
1580 $re = '<div class="at-sortable-con"><ul class="at-sortable">'."\n";
1581 $i = 0;
1582 if ( ! is_array( $meta ) || empty($meta) ){
1583 foreach ( $field['options'] as $value => $label ) {
1584 $re .= '<li class="widget-sort at-sort-item_'.$i.'">'.$label.'<input type="hidden" value="'.$label.'" name="'.$field['id'].'['.$value.']">'."\n";
1585 }
1586 }
1587 else{
1588 foreach ( $meta as $value => $label ) {
1589 $re .= '<li class="widget-sort at-sort-item_'.$i.'">'.$label.'<input type="hidden" value="'.$label.'" name="'.$field['id'].'['.$value.']">'."\n";
1590 }
1591 }
1592 $re .= '</ul>'."\n".'</div>'."\n";
1593 echo $re;
1594 $this->show_field_end( $field, $meta );
1595 }
1596
1597 /**
1598 * Show Field Text.
1599 *
1600 * @param string $field
1601 * @param string $meta
1602 * @since 0.1
1603 * @access public
1604 */
1605 public function show_field_text( $field, $meta) {
1606 ?><div class="<?php echo $field['id']; ?>"><?php
1607
1608 $this->show_field_begin( $field, $meta );
1609 echo "<input type='text' class='at-text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' value='".stripslashes($meta)."' size='30' />"."\n";
1610 $this->show_field_end( $field, $meta );
1611
1612 ?></div><?php
1613 }
1614
1615 /**
1616 * Show Field Plupload.
1617 *
1618 * @param string $field
1619 * @param string $meta
1620 * @since 0.9.7
1621 * @access public
1622 */
1623 public function show_field_plupload( $field, $meta) {
1624
1625 $this->show_field_begin($field,$meta);
1626 $id = $field['id']; // this will be the name of form field. Image url(s) will be submitted in $_POST using this key. So if $id == “img1†then $_POST[“img1â€] will have all the image urls
1627 $multiple = $field['multiple']; // allow multiple files upload
1628 $m1 = ($multiple)? 'plupload-upload-uic-multiple':'';
1629 $m2 = ($multiple)? 'plupload-thumbs-multiple':'';
1630 $width = $field['width']; // If you want to automatically resize all uploaded images then provide width here (in pixels)
1631 $height = $field['height']; // If you want to automatically resize all uploaded images then provide height here (in pixels)
1632 $html = '
1633 <input type="hidden" name="'.$id.'" id="'. $id.'" value="'.$meta .'" />
1634 <div class="plupload-upload-uic hide-if-no-js '.$m1.'" id="'.$id.'plupload-upload-ui">
1635 <input id="'.$id.'plupload-browse-button" type="button" value="'.__('Select Files','apc').'" class="button" />
1636 <span class="ajaxnonceplu" id="ajaxnonceplu'.wp_create_nonce($id . 'pluploadan').'"></span>';
1637 if ($width && $height){
1638 $html .= '<span class="plupload-resize"></span><span class="plupload-width" id="plupload-width'.$width.'"></span>
1639 <span class="plupload-height" id="plupload-height'.$height.'"></span>';
1640 }
1641 $html .= '<div class="filelist"></div>
1642 </div>
1643 <div class="plupload-thumbs '.$m2.'" id="'.$id.'plupload-thumbs">
1644 </div>
1645 <div class="clear"></div>';
1646 echo $html;
1647 $this->show_field_end($field,$meta);
1648 }
1649
1650 /**
1651 * Show Field code editor.
1652 *
1653 * @param string $field
1654 * @author Ohad Raz
1655 * @param string $meta
1656 * @since 0.1
1657 * @access public
1658 */
1659 public function show_field_code( $field, $meta) {
1660 $this->show_field_begin( $field, $meta );
1661 echo "<textarea class='code_text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' data-lang='{$field['syntax']}' data-theme='{$field['theme']}'>".stripslashes($meta)."</textarea>";
1662 $this->show_field_end( $field, $meta );
1663 }
1664
1665
1666 /**
1667 * Show Field hidden.
1668 *
1669 * @param string $field
1670 * @param string|mixed $meta
1671 * @since 0.1
1672 * @access public
1673 */
1674 public function show_field_hidden( $field, $meta) {
1675 echo "<input type='hidden' class='at-hidden".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' value='{$meta}'/>";
1676 }
1677
1678 /**
1679 * Show Field Paragraph.
1680 *
1681 * @param string $field
1682 * @since 0.1
1683 * @access public
1684 */
1685 public function show_field_paragraph( $field) {
1686 echo '<p>'.$field['value'].'</p>'."\n";
1687 }
1688
1689 /**
1690 * Show Field Textarea.
1691 *
1692 * @param string $field
1693 * @param string $meta
1694 * @since 0.1
1695 * @access public
1696 */
1697 public function show_field_textarea( $field, $meta ) {
1698 $this->show_field_begin( $field, $meta );
1699 echo "<textarea class='at-textarea large-text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' cols='60' rows='10'>".stripslashes($meta)."</textarea>"."\n";
1700 $this->show_field_end( $field, $meta );
1701 }
1702
1703 /**
1704 * Show Field Select.
1705 *
1706 * @param string $field
1707 * @param string $meta
1708 * @since 0.1
1709 * @access public
1710 */
1711 public function show_field_select( $field, $meta ) {
1712
1713 if ( ! is_array( $meta ) )
1714 $meta = (array) $meta;
1715 ?><div class="<?php echo $field['id']; ?>"><?php
1716 $this->show_field_begin( $field, $meta );
1717 echo "<select class='at-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ((isset($field['multiple']) && $field['multiple']) ? "[]' id='{$field['id']}' multiple='multiple'" : "'" ) . ">\n";
1718 foreach ( $field['options'] as $key => $value ) {
1719 echo "\t<option value='{$key}'" . selected( in_array( $key, $meta ), true, false ) . ">{$value}</option>\n";
1720 }
1721 echo "</select>"."\n";
1722 $this->show_field_end( $field, $meta );
1723 ?></div><?php
1724 }
1725
1726 /**
1727 * Show Radio Field.
1728 *
1729 * @param string $field
1730 * @param string $meta
1731 * @since 0.1
1732 * @access public
1733 */
1734 public function show_field_radio( $field, $meta ) {
1735
1736 if ( ! is_array( $meta ) )
1737 $meta = (array) $meta;
1738
1739 $this->show_field_begin( $field, $meta );
1740 foreach ( $field['options'] as $key => $value ) {
1741 echo "<input type='radio' class='at-radio".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' value='{$key}'" . checked( in_array( $key, $meta ), true, false ) . " /> <span class='at-radio-label'>{$value}</span>"."\n";
1742 }
1743 $this->show_field_end( $field, $meta );
1744 }
1745
1746 /**
1747 * Show Checkbox Field.
1748 *
1749 * @param string $field
1750 * @param string $meta
1751 * @since 0.1
1752 * @access public
1753 */
1754 public function show_field_checkbox( $field, $meta ) {
1755
1756 $this->show_field_begin($field, $meta);
1757 $meta = ($meta == 'on')? true: $meta;
1758 echo "<input type='checkbox' class='rw-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}'" . checked($meta, true, false) . " />"."\n";
1759 $this->show_field_end( $field, $meta );
1760 }
1761
1762 /**
1763 * Show conditinal Checkbox Field.
1764 *
1765 * @param string $field
1766 * @param string $meta
1767 * @since 0.5
1768 * @access public
1769 */
1770 public function show_field_cond( $field, $meta ) {
1771
1772 $this->show_field_begin($field, $meta);
1773 $checked = false;
1774 if (is_array($meta) && isset($meta['enabled']) && $meta['enabled'] == 'on'){
1775 $checked = true;
1776 }
1777 echo "<input type='checkbox' class='conditinal_control' name='{$field['id']}[enabled]' id='{$field['id']}'" . checked($checked, true, false) . " />";
1778 //start showing the fields
1779 $display = ($checked)? '' : ' style="display: none;"';
1780
1781 echo '<div class="conditinal_container"'.$display.'>';
1782 foreach ((array)$field['fields'] as $f){
1783 //reset var $id for cond
1784 $id = '';
1785 $id = $field['id'].'['.$f['id'].']';
1786 $m = '';
1787 $m = (isset($meta[$f['id']])) ? $meta[$f['id']]: '';
1788 $m = ( $m !== '' ) ? $m : (isset($f['std'])? $f['std'] : '');
1789 if ('image' != $f['type'] && $f['type'] != 'repeater')
1790 $m = is_array( $m) ? array_map( 'esc_attr', $m ) : esc_attr( $m);
1791 //set new id for field in array format
1792 $f['id'] = $id;
1793 call_user_func ( array( $this, 'show_field_' . $f['type'] ), $f, $m);
1794 }
1795 echo '</div>';
1796 $this->show_field_end( $field, $meta );
1797 }
1798
1799 /**
1800 * Show Wysiwig Field.
1801 *
1802 * @param string $field
1803 * @param string $meta
1804 * @since 0.1
1805 * @access public
1806 */
1807 public function show_field_wysiwyg( $field, $meta ) {
1808 $this->show_field_begin( $field, $meta );
1809 // Add TinyMCE script for WP version < 3.3
1810 global $wp_version;
1811
1812 if ( version_compare( $wp_version, '3.2.1' ) < 1 ) {
1813 echo "<textarea class='at-wysiwyg theEditor large-text".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' cols='60' rows='10'>{$meta}</textarea>";
1814 }else{
1815 // Use new wp_editor() since WP 3.3
1816 wp_editor( stripslashes(stripslashes(html_entity_decode($meta))), $field['id'], array( 'editor_class' => 'at-wysiwyg'.(isset($field['class'])? " {$field['class']}": "")) );
1817 }
1818 $this->show_field_end( $field, $meta );
1819 }
1820
1821 /**
1822 * Show File Field.
1823 *
1824 * @param string $field
1825 * @param string $meta
1826 * @since 0.1
1827 * @access public
1828 */
1829 public function show_field_file( $field, $meta ) {
1830
1831 global $post;
1832
1833 if ( ! is_array( $meta ) )
1834 $meta = (array) $meta;
1835
1836 $this->show_field_begin( $field, $meta );
1837 echo "{$field['desc']}<br />";
1838
1839 if ( ! empty( $meta ) ) {
1840 $nonce = wp_create_nonce( 'at_ajax_delete' );
1841 echo '<div style="margin-bottom: 10px"><strong>' . __('Uploaded files','apc') . '</strong></div>';
1842 echo '<ol class="at-upload">';
1843 foreach ( $meta as $att ) {
1844 // if (wp_attachment_is_image($att)) continue; // what's image uploader for?
1845 echo "<li>" . wp_get_attachment_link( $att, '' , false, false, ' ' ) . " (<a class='at-delete-file' href='#' rel='{$nonce}|{$post->ID}|{$field['id']}|{$att}'>" . __( 'Delete' ,'apc') . "</a>)</li>";
1846 }
1847 echo '</ol>';
1848 }
1849
1850 // show form upload
1851 echo "<div class='at-file-upload-label'>";
1852 echo "<strong>" . __( 'Upload new files' ,'apc') . "</strong>";
1853 echo "</div>";
1854 echo "<div class='new-files'>";
1855 echo "<div class='file-input'>";
1856 echo "<input type='file' name='{$field['id']}[]' />";
1857 echo "</div><!-- End .file-input -->";
1858 echo "<a class='at-add-file button' href='#'>" . __( 'Add more files','apc' ) . "</a>";
1859 echo "</div><!-- End .new-files -->";
1860 echo "</td>";
1861 }
1862
1863
1864 public function show_field_media_manager($field,$meta){
1865 $this->show_field_begin( $field, $meta );
1866 $html = wp_nonce_field( "at-delete-mupload_{$field['id']}", "nonce-delete-mupload_".$field['id'], false, false );
1867 $height = (isset($field['preview_height']))? $field['preview_height'] : '150px';
1868 $width = (isset($field['preview_width']))? $field['preview_width'] : '150px';
1869 $multi = (isset($field['multiple']) && $field['multiple'] == true) ? 'true' : 'false';
1870 if (is_array($meta)){
1871 if(isset($meta[0]) && is_array($meta[0]))
1872 $meta = $meta[0];
1873 }
1874 if (is_array($meta) && isset($meta['src']) && $meta['src'] != ''){
1875 $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."'><img src='".$meta['src']."' style='height: ".$height.";width: ".$width.";' /></span>"."\n";
1876 $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='".$meta['id']."' />"."\n";
1877 $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='".$meta['src']."' />"."\n";
1878 $html .= "<input class='at-delete_image_button button' type='button' rel='".$field['id']."' value='".__('Delete Image','apc')."' />"."\n";
1879 }else{
1880 $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."' data-multi='".$multi."'></span>"."\n";
1881 $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='' />"."\n";
1882 $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='' />"."\n";
1883 $html .= "<input class='at-mm-upload_image_button button' type='button' rel='".$field['id']."' value='".__('Upload Image','apc')."' />"."\n";
1884 }
1885 echo $html;
1886 $this->show_field_end( $field, $meta );
1887 }
1888
1889 /**
1890 * Show Image Field.
1891 *
1892 * @param array $field
1893 * @param array $meta
1894 * @since 0.1
1895 * @access public
1896 */
1897 public function show_field_image( $field, $meta ) {
1898 $this->show_field_begin( $field, $meta );
1899 $html = wp_nonce_field( "at-delete-mupload_{$field['id']}", "nonce-delete-mupload_".$field['id'], false, false );
1900 $height = (isset($field['preview_height']))? $field['preview_height'] : '150px';
1901 $width = (isset($field['preview_width']))? $field['preview_width'] : '150px';
1902 $upload_type = (!function_exists('wp_enqueue_media')) ? 'tk' : 'mm';
1903 if (is_array($meta)){
1904 if(isset($meta[0]) && is_array($meta[0]))
1905 $meta = $meta[0];
1906 }
1907 if (is_array($meta) && isset($meta['src']) && $meta['src'] != ''){
1908 $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."'><img src='".$meta['src']."' style='height: ".$height.";width: ".$width.";' /></span>";
1909 $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='".$meta['id']."' />";
1910 $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='".$meta['src']."' />";
1911 $html .= "<input class='at-delete_image_button button' type='button' data-u='".$upload_type."' rel='".$field['id']."' value='".__('Delete Image','apc')."' />";
1912 }else{
1913 $html .= "<span class='mupload_img_holder' data-wi='".$width."' data-he='".$height."'></span>";
1914 $html .= "<input type='hidden' name='".$field['id']."[id]' id='".$field['id']."[id]' value='' />";
1915 $html .= "<input type='hidden' name='".$field['id']."[src]' id='".$field['id']."[src]' value='' />";
1916 $html .= "<input class='at-upload_image_button button' type='button' data-u='".$upload_type."' rel='".$field['id']."' value='".__('Upload Image','apc')."' />";
1917 }
1918 echo $html;
1919 $this->show_field_end( $field, $meta );
1920 }
1921
1922 /**
1923 * Show Typography Field.
1924 *
1925 * @author Ohad Raz
1926 * @param array $field
1927 * @param array $meta
1928 * @since 0.3
1929 * @access public
1930 *
1931 * @last modified 0.4 - faster better selected handeling
1932 */
1933 public function show_field_typo( $field, $meta ) {
1934 $this->show_field_begin( $field, $meta );
1935 if (!is_array($meta)){
1936 $meta = array(
1937 'size' => '',
1938 'face' => '',
1939 'style' => '',
1940 'color' => '#',
1941 'weight' => '',
1942 );
1943 }
1944 $html = '<select class="at-typography at-typography-size" name="' . esc_attr( $field['id'] . '[size]' ) . '" id="' . esc_attr( $field['id'] . '_size' ) . '">'."\n";
1945 $op = '';
1946 for ($i = 9; $i < 71; $i++) {
1947 $size = $i . 'px';
1948 $op .= "\t".'<option value="' . esc_attr( $size ) . '">' . esc_html( $size ) . '</option>'."\n";
1949 }
1950 if (isset($meta['size']))
1951 $op = str_replace('value="'.$meta['size'].'"', 'value="'.$meta['size'].'" selected="selected"', $op);
1952 $html .=$op. '</select>'."\n";
1953
1954 // Font Face
1955 $html .= '<select class="at-typography at-typography-face" name="' . esc_attr( $field['id'] .'[face]' ) . '" id="' . esc_attr( $field['id'] . '_face' ) . '">'."\n";
1956
1957 $faces = $this->get_fonts_family();
1958 $op = '';
1959 foreach ( $faces as $key => $face ) {
1960 $op .= "\t".'<option value="' . esc_attr( $key ) . '">' . esc_html( $face['name'] ) . '</option>'."\n";
1961 }
1962 if (isset($meta['face']))
1963 $op = str_replace('value="'.$meta['face'].'"', 'value="'.$meta['face'].'" selected="selected"', $op);
1964 $html .= $op. '</select>'."\n";
1965
1966 // Font Weight
1967 $html .= '<select class="at-typography at-typography-weight" name="' . esc_attr( $field['id'] .'[weight]' ) . '" id="' . esc_attr( $field['id'] . '_weight' ) . '">'."\n";
1968 $weights = $this->get_font_weight();
1969 $op = '';
1970 foreach ( $weights as $key => $label ) {
1971 $op .= "\t".'<option value="' . esc_attr( $key ) . '">' . esc_html( $label ) . '</option>'."\n";
1972 }
1973 if (isset($meta['weight']))
1974 $op = str_replace('value="'.$meta['weight'].'"', 'value="'.$meta['weight'].'" selected="selected"', $op);
1975 $html .= $op. '</select>'."\n";
1976
1977 /* Font Style */
1978 $html .= '<select class="at-typography at-typography-style" name="'.$field['id'].'[style]" id="'. $field['id'].'_style">'."\n";
1979 $styles = $this->get_font_style();
1980 $op = '';
1981 foreach ( $styles as $key => $style ) {
1982 $op .= "\t".'<option value="' . esc_attr( $key ) . '">'. $style .'</option>'."\n";
1983 }
1984 if (isset($meta['style']))
1985 $op = str_replace('value="'.$meta['style'].'"', 'value="'.$meta['style'].'" selected="selected"', $op);
1986 $html .= $op. '</select>'."\n";
1987
1988 // Font Color
1989 if( wp_style_is( 'wp-color-picker', 'registered' ) ) { //iris color picker since 3.5
1990 $html .= "<input class='at-color-iris' type='text' name='{$field['id']}[color]' id='{$field['id']}[color]' value='".$meta['color']."' size='8' />"."\n";
1991 }else{
1992 $html .= "<input class='at-color' type='text' name='".$field['id']."[color]' id='".$field['id']."[color]' value='".$meta['color'] ."' size='6' />"."\n";
1993 $html .= "<input type='button' class='at-color-select button' rel='".$field['id']."[color]' value='" . __( 'Select a color' ,'apc') . "'/>"."\n";
1994 $html .= "<div style='display:none' class='at-color-picker' rel='".$field['id']."[color]'></div>"."\n";
1995 }
1996
1997 echo $html;
1998 $this->show_field_end( $field, $meta );
1999 }
2000
2001 /**
2002 * Show Color Field.
2003 *
2004 * @param string $field
2005 * @param string $meta
2006 * @since 0.1
2007 * @access public
2008 */
2009 public function show_field_color( $field, $meta ) {
2010 if ( empty( $meta ) )
2011 $meta = '#';
2012 ?>
2013 <div class="<?php echo $field['id']; ?>">
2014 <?php
2015 $this->show_field_begin( $field, $meta );
2016 if( wp_style_is( 'wp-color-picker', 'registered' ) ) { //iris color picker since 3.5
2017 echo "<input class='at-color-iris".(isset($field['class'])? " {$field['class']}": "")."' type='text' name='{$field['id']}' id='{$field['id']}' value='{$meta}' size='8' />";
2018 }else{
2019 echo "<input class='at-color".(isset($field['class'])? " {$field['class']}": "")."' type='text' name='{$field['id']}' id='{$field['id']}' value='{$meta}' size='8' />";
2020 echo "<input type='button' class='at-color-select button' rel='{$field['id']}' value='" . __( 'Select a color' ,'apc') . "'/>";
2021 echo "<div style='display:none' class='at-color-picker' rel='{$field['id']}'></div>";
2022 }
2023 $this->show_field_end($field, $meta);
2024
2025 ?>
2026 </div>
2027 <?php
2028
2029 }
2030
2031 /**
2032 * Show Checkbox List Field
2033 *
2034 * @param string $field
2035 * @param string $meta
2036 * @since 0.1
2037 * @access public
2038 */
2039 public function show_field_checkbox_list( $field, $meta ) {
2040
2041 if ( ! is_array( $meta ) )
2042 $meta = (array) $meta;
2043
2044 $this->show_field_begin($field, $meta);
2045
2046 $html = array();
2047
2048 foreach ($field['options'] as $key => $value) {
2049 $html[] = "<label class='at-checkbox_list-label'><input type='checkbox' class='at-checkbox_list".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='{$key}'" . checked( in_array( $key, $meta ), true, false ) . " />{$value}</label>";
2050 }
2051
2052 echo implode( '<br />' , $html );
2053
2054 $this->show_field_end($field, $meta);
2055
2056 }
2057
2058 /**
2059 * Show Date Field.
2060 *
2061 * @param string $field
2062 * @param string $meta
2063 * @since 0.1
2064 * @access public
2065 */
2066 public function show_field_date( $field, $meta ) {
2067 $this->show_field_begin( $field, $meta );
2068 echo "<input type='text' class='at-date".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' rel='{$field['format']}' value='{$meta}' size='30' />";
2069 $this->show_field_end( $field, $meta );
2070 }
2071
2072 /**
2073 * Show time field.
2074 *
2075 * @param string $field
2076 * @param string $meta
2077 * @since 0.1
2078 * @access public
2079 */
2080 public function show_field_time( $field, $meta ) {
2081 $this->show_field_begin( $field, $meta );
2082 echo "<input type='text' class='at-time".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}' id='{$field['id']}' rel='{$field['format']}' value='{$meta}' size='30' />";
2083 $this->show_field_end( $field, $meta );
2084 }
2085
2086 /**
2087 * Show Posts field.
2088 * used creating a posts/pages/custom types checkboxlist or a select dropdown
2089 * @param string $field
2090 * @param string $meta
2091 * @since 0.1
2092 * @access public
2093 */
2094 public function show_field_posts($field, $meta) {
2095 global $post;
2096 if (!is_array($meta)) $meta = (array) $meta;
2097 $this->show_field_begin($field, $meta);
2098 $options = $field['options'];
2099 $posts = get_posts($options['args']);
2100
2101 // checkbox_list
2102 if ('checkbox_list' == $options['type']) {
2103 foreach ($posts as $p) {
2104 if (isset($field['class']) && $field['class']== 'no-toggle')
2105 echo "<label class='at-posts-checkbox-label'><input type='checkbox' class='at-posts-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$p->ID'" . checked(in_array($p->ID, $meta), true, false) . " /> {$p->post_title}</label>";
2106 else
2107 echo "{$p->post_title}<input type='checkbox' class='at-posts-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$p->ID'" . checked(in_array($p->ID, $meta), true, false) . " />";
2108 }
2109 }
2110 // select
2111 else {
2112 echo "<select class='at-posts-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ($field['multiple'] ? "[]' multiple='multiple' style='height:auto'" : "'") . ">";
2113 foreach ($posts as $p) {
2114 echo "<option value='$p->ID'" . selected(in_array($p->ID, $meta), true, false) . ">$p->post_title</option>";
2115 }
2116 echo "</select>";
2117 }
2118
2119 $this->show_field_end($field, $meta);
2120 }
2121
2122 /**
2123 * Show Taxonomy field.
2124 * used creating a category/tags/custom taxonomy checkboxlist or a select dropdown
2125 * @param string $field
2126 * @param string $meta
2127 * @since 0.1
2128 * @access public
2129 *
2130 * @uses get_terms()
2131 */
2132 public function show_field_taxonomy($field, $meta) {
2133 global $post;
2134
2135 if (!is_array($meta)) $meta = (array) $meta;
2136 $this->show_field_begin($field, $meta);
2137 $options = $field['options'];
2138 $terms = get_terms($options['taxonomy'], $options['args']);
2139
2140 // checkbox_list
2141 if ('checkbox_list' == $options['type']) {
2142 foreach ($terms as $term) {
2143 if (isset($field['class']) && $field['class'] == 'no-toggle')
2144 echo "<label class='at-tax-checkbox-label'><input type='checkbox' class='at-tax-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$term->slug'" . checked(in_array($term->slug, $meta), true, false) . " /> {$term->name}</label>";
2145 else
2146 echo "{$term->name} <input type='checkbox' class='at-tax-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$term->slug'" . checked(in_array($term->slug, $meta), true, false) . " />";
2147 }
2148 }
2149 // select
2150 else {
2151 echo "<select class='at-tax-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ($field['multiple'] ? "[]' multiple='multiple' style='height:auto'" : "'") . ">";
2152 foreach ($terms as $term) {
2153 echo "<option value='$term->slug'" . selected(in_array($term->slug, $meta), true, false) . ">$term->name</option>";
2154 }
2155 echo "</select>";
2156 }
2157
2158 $this->show_field_end($field, $meta);
2159 }
2160
2161 /**
2162 * Show Role field.
2163 * used creating a Wordpress roles list checkboxlist or a select dropdown
2164 * @param string $field
2165 * @param string $meta
2166 * @since 0.1
2167 * @access public
2168 *
2169 * @uses global $wp_roles;
2170 * @uses checked();
2171 */
2172 public function show_field_WProle($field, $meta) {
2173 if (!is_array($meta)) $meta = (array) $meta;
2174 $this->show_field_begin($field, $meta);
2175 $options = $field['options'];
2176 global $wp_roles;
2177 if ( ! isset( $wp_roles ) )
2178 $wp_roles = new WP_Roles();
2179 $names = $wp_roles->get_names();
2180 if ($names){
2181 // checkbox_list
2182 if ('checkbox_list' == $options['type']) {
2183 foreach ($names as $n) {
2184 if (isset($field['class']) && $field['class'] == 'no-toggle')
2185 echo "<label class='at-posts-checkbox-label'><input type='checkbox' class='at-role-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$n'" . checked(in_array($n, $meta), true, false) . " /> ".$n."</label>";
2186 else
2187 echo "{$n} <input type='checkbox' class='at-role-checkbox".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}[]' value='$n'" . checked(in_array($n, $meta), true, false) . " />";
2188 }
2189 }
2190 // select
2191 else {
2192 echo "<select class='at-role-select".(isset($field['class'])? " {$field['class']}": "")."' name='{$field['id']}" . ($field['multiple'] ? "[]' multiple='multiple' style='height:auto'" : "'") . ">";
2193 foreach ($names as $n) {
2194 echo "<option value='$n'" . selected(in_array($n, $meta), true, false) . ">$n</option>";
2195 }
2196 echo "</select>";
2197 }
2198 }
2199 $this->show_field_end($field, $meta);
2200 }
2201
2202 /**
2203 * Save Data from page
2204 *
2205 * @param string $repeater (false )
2206 * @since 0.1
2207 * @access public
2208 */
2209 public function save($repeater = false) {
2210 $saved = get_option($this->option_group);
2211 $this->_saved = $saved;
2212
2213 $post_data = isset($_POST)? $_POST : NULL;
2214
2215 If ($post_data == NULL) return;
2216
2217 $skip = array('title','paragraph','subtitle','TABS','CloseDiv','TABS_Listing','OpenTab','import_export');
2218
2219 //check nonce
2220 if ( ! check_admin_referer( basename( __FILE__ ), 'BF_Admin_Page_Class_nonce') )
2221 return;
2222
2223 foreach ( $this->_fields as $field ) {
2224 if(!in_array($field['type'],$skip)){
2225
2226 $name = $field['id'];
2227 $type = $field['type'];
2228 $old = isset($saved[$name])? $saved[$name]: NULL;
2229 $new = ( isset( $_POST[$name] ) ) ? $_POST[$name] : ( ( isset($field['multiple']) && $field['multiple']) ? array() : '' );
2230
2231
2232 //Validate and senitize meta value
2233 //issue #27
2234 $validationClass = apply_filters('apc_validattion_class_name', 'BF_Admin_Page_Class_Validate',$this);
2235 if ( class_exists( $validationClass ) && isset($field['validate_func']) && method_exists( $validationClass, $field['validate_func'] ) ) {
2236 $new = call_user_func( array( $validationClass, $field['validate_func'] ), $new ,$this);
2237 }
2238
2239 //native validation
2240 if (isset($field['validate'])){
2241 if (!$this->validate_field($field,$new))
2242 $new = $old;
2243 }
2244
2245
2246 // Call defined method to save meta value, if there's no methods, call common one.
2247 $save_func = 'save_field_' . $type;
2248 if ( method_exists( $this, $save_func ) ) {
2249 call_user_func( array( $this, 'save_field_' . $type ), $field, $old, $new );
2250 } else {
2251 $this->save_field( $field, $old, $new );
2252 }
2253
2254 }//END Skip
2255 } // End foreach
2256 update_option($this->args['option_group'],$this->_saved);
2257 }
2258
2259 /**
2260 * Common function for saving fields.
2261 *
2262 * @param string $field
2263 * @param string $old
2264 * @param string|mixed $new
2265 * @since 0.1
2266 * @access public
2267 */
2268 public function save_field( $field, $old, $new ) {
2269 $name = $field['id'];
2270 unset($this->_saved[$name]);
2271 if ( $new === '' || $new === array() && ( !in_array($field['type'],array('text','textarea')) ) )
2272 return;
2273 if ( isset($field['multiple'] ) && $field['multiple'] && $field['type'] != 'plupload') {
2274 foreach ( $new as $add_new ) {
2275 $temp[] = $add_new;
2276 }
2277 $this->_saved[$name] = $temp;
2278 } else {
2279 $this->_saved[$name] = $new;
2280 }
2281 }
2282
2283 /**
2284 * function for saving image field.
2285 *
2286 * @param string $field
2287 * @param string $old
2288 * @param string|mixed $new
2289 * @since 0.1
2290 * @access public
2291 */
2292 public function save_field_image( $field, $old, $new ) {
2293 $name = $field['id'];
2294 unset($this->_saved[$name]);
2295 if ( $new === '' || $new === array() || $new['id'] == '' || $new['src'] == '')
2296 return;
2297
2298 $this->_saved[$name] = $new;
2299 }
2300
2301 /*
2302 * Save Wysiwyg Field.
2303 *
2304 * @param string $field
2305 * @param string $old
2306 * @param string $new
2307 * @since 0.1
2308 * @access public
2309 */
2310 public function save_field_wysiwyg( $field, $old, $new ) {
2311 $this->save_field( $field, $old, htmlentities($new) );
2312 }
2313
2314 /*
2315 * Save checkbox Field.
2316 *
2317 * @param string $field
2318 * @param string $old
2319 * @param string $new
2320 * @since 0.9
2321 * @access public
2322 */
2323 public function save_field_checkbox( $field, $old, $new ) {
2324 if ( $new === '' )
2325 $this->save_field( $field, $old, false );
2326 else
2327 $this->save_field( $field, $old, true );
2328 }
2329
2330 /**
2331 * Save repeater Fields.
2332 *
2333 * @param string $field
2334 * @param string|mixed $old
2335 * @param string|mixed $new
2336 * @since 0.1
2337 * @access public
2338 */
2339 public function save_field_repeater( $field, $old, $new ) {
2340 if (is_array($new) && count($new) > 0){
2341 foreach ($new as $n){
2342 foreach ( $field['fields'] as $f ) {
2343 $type = $f['type'];
2344 switch($type) {
2345 case 'wysiwyg':
2346 $n[$f['id']] = wpautop( $n[$f['id']] );
2347 break;
2348 case 'file':
2349 $n[$f['id']] = $this->save_field_file_repeater($f,'',$n[$f['id']]);
2350 break;
2351 default:
2352 break;
2353 }
2354 }
2355 if(!$this->is_array_empty($n))
2356 $temp[] = $n;
2357 }
2358 if (isset($temp) && count($temp) > 0 && !$this->is_array_empty($temp)){
2359 $this->_saved[$field['id']] = $temp;
2360 }else{
2361 if (isset($this->_saved[$field['id']]))
2362 unset($this->_saved[$field['id']]);
2363 }
2364 }else{
2365 // remove old meta if exists
2366 if (isset($this->_saved[$field['id']]))
2367 unset($this->_saved[$field['id']]);
2368 }
2369 }
2370
2371
2372
2373 /**
2374 * Add missed values for Page.
2375 *
2376 * @since 0.1
2377 * @access public
2378 */
2379 public function add_missed_values() {
2380
2381 // Default values for admin
2382 //$this->_meta_box = array_merge( array( 'context' => 'normal', 'priority' => 'high', 'pages' => array( 'post' ) ), $this->_meta_box );
2383
2384 // Default values for fields
2385 foreach ( $this->_fields as &$field ) {
2386
2387 $multiple = in_array( $field['type'], array( 'checkbox_list', 'file', 'image' ) );
2388 $std = $multiple ? array() : '';
2389 $format = 'date' == $field['type'] ? 'yy-mm-dd' : ( 'time' == $field['type'] ? 'hh:mm' : '' );
2390
2391 $field = array_merge( array( 'multiple' => $multiple, 'std' => $std, 'desc' => '', 'format' => $format, 'validate_func' => '' ), $field );
2392
2393 } // End foreach
2394
2395 }
2396
2397 /**
2398 * Check if field with $type exists.
2399 *
2400 * @param string $type
2401 * @since 0.1
2402 * @access public
2403 */
2404 public function has_field( $type ) {
2405 //faster search in single array.
2406 if (count($this->field_types) > 0){
2407 return in_array($type, $this->field_types);
2408 }
2409
2410 //run once over all fields and store the types in a local array
2411 $temp = array();
2412 foreach ($this->_fields as $field) {
2413 $temp[] = $field['type'];
2414 if ('repeater' == $field['type'] || 'cond' == $field['type']){
2415 foreach((array)$field["fields"] as $repeater_field) {
2416 $temp[] = $repeater_field["type"];
2417 }
2418 }
2419 }
2420
2421 //remove duplicates
2422 $this->field_types = array_unique($temp);
2423 //call this function one more time now that we have an array of field types
2424 return $this->has_field($type);
2425 }
2426
2427 /**
2428 * Check if any of the fields types exists
2429 *
2430 * @since 1.1.3
2431 * @access public
2432 * @param array $types array of field types
2433 * @return boolean
2434 */
2435 public function has_field_any($types){
2436 foreach ((array)$types as $t) {
2437 if ($this->has_field($t))
2438 return true;
2439 }
2440 return false;
2441 }
2442
2443 /**
2444 * Check if current page is edit page.
2445 *
2446 * @since 0.1
2447 * @access public
2448 */
2449 public function is_edit_page() {
2450 //global $pagenow;
2451 return true;
2452 //return in_array( $pagenow, array( 'post.php', 'post-new.php' ) );
2453 }
2454
2455 /**
2456 * Fixes the odd indexing of multiple file uploads.
2457 *
2458 * Goes from the format:
2459 * $_FILES['field']['key']['index']
2460 * to
2461 * The More standard and appropriate:
2462 * $_FILES['field']['index']['key']
2463 *
2464 * @param string $files
2465 * @since 0.1
2466 * @access public
2467 */
2468 public function fix_file_array( &$files ) {
2469
2470 $output = array();
2471
2472 foreach ( $files as $key => $list ) {
2473 foreach ( $list as $index => $value ) {
2474 $output[$index][$key] = $value;
2475 }
2476 }
2477
2478 return $files = $output;
2479
2480 }
2481
2482 /**
2483 * Get proper JQuery UI version.
2484 *
2485 * Used in order to not conflict with WP Admin Scripts.
2486 *
2487 * @since 0.1
2488 * @access public
2489 */
2490 public function get_jqueryui_ver() {
2491
2492 global $wp_version;
2493
2494 if ( version_compare( $wp_version, '3.1', '>=') ) {
2495 return '1.8.10';
2496 }
2497
2498 return '1.7.3';
2499
2500 }
2501
2502 /**
2503 * Add Field to page (generic function)
2504 * @author Ohad Raz
2505 * @since 0.1
2506 * @access public
2507 * @param $id string field id, i.e. the meta key
2508 * @param $args mixed|array
2509 */
2510 public function addField($id,$args){
2511 $new_field = array('id'=> $id,'std' => '','desc' => '','style' =>'');
2512 $new_field = array_merge($new_field, $args);
2513 $this->_fields[] = $new_field;
2514 }
2515
2516 /**
2517 * Add typography Field
2518 *
2519 * @author Ohad Raz
2520 * @since 0.3
2521 *
2522 * @access public
2523 *
2524 * @param $id string id of the field
2525 * @param $args mixed|array
2526 * @param boolean $repeater=false
2527 */
2528 public function addTypo($id,$args,$repeater=false){
2529 $new_field = array(
2530 'type' => 'typo',
2531 'id'=> $id,
2532 'std' => array(
2533 'size' => '12px',
2534 'color' => '#000000',
2535 'face' => 'arial',
2536 'style' => 'normal',
2537 'weight' => 'normal'
2538 ),
2539 'desc' => '',
2540 'style' =>'',
2541 'name'=> 'Typography field'
2542 );
2543 $new_field = array_merge($new_field, $args);
2544 $this->_fields[] = $new_field;
2545 }
2546
2547 /**
2548 * Add Text Field to Page
2549 * @author Ohad Raz
2550 * @since 0.1
2551 * @access public
2552 * @param $id string field id, i.e. the meta key
2553 * @param $args mixed|array
2554 * 'name' => // field name/label string optional
2555 * 'desc' => // field description, string optional
2556 * 'std' => // default value, string optional
2557 * 'style' => // custom style for field, string optional
2558 * 'validate_func' => // validate function, string optional
2559 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2560 */
2561 public function addText($id,$args,$repeater=false){
2562 $new_field = array('type' => 'text','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Text Field');
2563 $new_field = array_merge($new_field, $args);
2564 if(false === $repeater){
2565 $this->_fields[] = $new_field;
2566 }else{
2567 return $new_field;
2568 }
2569 }
2570
2571 /**
2572 * Add Pluploader Field to Page
2573 * @author Ohad Raz
2574 * @since 0.9.7
2575 * @access public
2576 * @param $id string field id, i.e. the meta key
2577 * @param $args mixed|array
2578 * 'name' => // field name/label string optional
2579 * 'desc' => // field description, string optional
2580 * 'std' => // default value, string optional
2581 * 'style' => // custom style for field, string optional
2582 * 'validate_func' => // validate function, string optional
2583 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2584 */
2585 public function addPlupload($id,$args,$repeater=false){
2586 $new_field = array('type' => 'plupload','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'PlUpload Field','width' => null, 'height' => null,'multiple' => false);
2587 $new_field = array_merge($new_field, $args);
2588 if(false === $repeater){
2589 $this->_fields[] = $new_field;
2590 }else{
2591 return $new_field;
2592 }
2593 }
2594
2595 /**
2596 * Add Hidden Field to Page
2597 * @author Ohad Raz
2598 * @since 0.1
2599 * @access public
2600 * @param $id string field id, i.e. the meta key
2601 * @param $args mixed|array
2602 * 'name' => // field name/label string optional
2603 * 'desc' => // field description, string optional
2604 * 'std' => // default value, string optional
2605 * 'style' => // custom style for field, string optional
2606 * 'validate_func' => // validate function, string optional
2607 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2608 */
2609 public function addHidden($id,$args,$repeater=false){
2610 $new_field = array('type' => 'hidden','id'=> $id,'std' => '','desc' => '','style' =>'','name' => '');
2611 $new_field = array_merge($new_field, $args);
2612 if(false === $repeater){
2613 $this->_fields[] = $new_field;
2614 }else{
2615 return $new_field;
2616 }
2617 }
2618
2619 /**
2620 * Add code Editor to page
2621 * @author Ohad Raz
2622 * @since 0.1
2623 * @access public
2624 * @param $id string field id, i.e. the meta key
2625 * @param $args mixed|array
2626 * 'name' => // field name/label string optional
2627 * 'desc' => // field description, string optional
2628 * 'std' => // default value, string optional
2629 * 'style' => // custom style for field, string optional
2630 * 'syntax' => // syntax language to use in editor (php,javascript,css,html)
2631 * 'validate_func' => // validate function, string optional
2632 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2633 */
2634 public function addCode($id,$args,$repeater=false){
2635 $new_field = array('type' => 'code','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Code Editor Field','syntax' => 'php', 'theme' => 'default');
2636 $new_field = array_merge($new_field, (array)$args);
2637 if(false === $repeater){
2638 $this->_fields[] = $new_field;
2639 }else{
2640 return $new_field;
2641 }
2642 }
2643
2644 /**
2645 * Add Paragraph to Page
2646 * @author Ohad Raz
2647 * @since 0.1
2648 * @access public
2649 *
2650 * @param $p paragraph html
2651 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2652 */
2653 public function addParagraph($p,$repeater=false){
2654 $new_field = array('type' => 'paragraph','id'=> '','value' => $p);
2655 if(false === $repeater){
2656 $this->_fields[] = $new_field;
2657 }else{
2658 return $new_field;
2659 }
2660 }
2661
2662 /**
2663 * Add Checkbox Field to Page
2664 * @author Ohad Raz
2665 * @since 0.1
2666 * @access public
2667 * @param $id string field id, i.e. the meta key
2668 * @param $args mixed|array
2669 * 'name' => // field name/label string optional
2670 * 'desc' => // field description, string optional
2671 * 'std' => // default value, string optional
2672 * 'validate_func' => // validate function, string optional
2673 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2674 */
2675 public function addCheckbox($id,$args,$repeater=false){
2676 $new_field = array('type' => 'checkbox','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Checkbox Field');
2677 $new_field = array_merge($new_field, $args);
2678 if(false === $repeater){
2679 $this->_fields[] = $new_field;
2680 }else{
2681 return $new_field;
2682 }
2683 }
2684
2685 /**
2686 * Add Checkbox conditional Field to Page
2687 * @author Ohad Raz
2688 * @since 0.5
2689 * @access public
2690 * @param $id string field id, i.e. the key
2691 * @param $args mixed|array
2692 * 'name' => // field name/label string optional
2693 * 'desc' => // field description, string optional
2694 * 'std' => // default value, string optional
2695 * 'validate_func' => // validate function, string optional
2696 * 'fields' => list of fields to show conditionally.
2697 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2698 */
2699 public function addCondition($id,$args,$repeater=false){
2700 $new_field = array('type' => 'cond','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Conditional Field','fields' => array());
2701 $new_field = array_merge($new_field, $args);
2702 if(false === $repeater){
2703 $this->_fields[] = $new_field;
2704 }else{
2705 return $new_field;
2706 }
2707 }
2708
2709 /**
2710 * Add CheckboxList Field to Page
2711 * @author Ohad Raz
2712 * @since 0.1
2713 * @access public
2714 * @param $id string field id, i.e. the meta key
2715 * @param $options (array) array of key => value pairs for select options
2716 * @param $args mixed|array
2717 * 'name' => // field name/label string optional
2718 * 'desc' => // field description, string optional
2719 * 'std' => // default value, string optional
2720 * 'validate_func' => // validate function, string optional
2721 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2722 *
2723 * @return : remember to call: $checkbox_list = get_post_meta(get_the_ID(), 'meta_name', false);
2724 * which means the last param as false to get the values in an array
2725 */
2726 public function addCheckboxList($id,$options=array(),$args,$repeater=false){
2727 $new_field = array('type' => 'checkbox_list','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Checkbox List Field','options' => $options, 'class' => '');
2728 $new_field = array_merge($new_field, $args);
2729 if(false === $repeater){
2730 $this->_fields[] = $new_field;
2731 }else{
2732 return $new_field;
2733 }
2734 }
2735
2736 /**
2737 * Add Textarea Field to Page
2738 * @author Ohad Raz
2739 * @since 0.1
2740 * @access public
2741 * @param $id string field id, i.e. the meta key
2742 * @param $args mixed|array
2743 * 'name' => // field name/label string optional
2744 * 'desc' => // field description, string optional
2745 * 'std' => // default value, string optional
2746 * 'style' => // custom style for field, string optional
2747 * 'validate_func' => // validate function, string optional
2748 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2749 */
2750 public function addTextarea($id,$args,$repeater=false){
2751 $new_field = array('type' => 'textarea','id'=> $id,'std' => '','desc' => '','style' =>'','name' => 'Textarea Field');
2752 $new_field = array_merge($new_field, $args);
2753 if(false === $repeater){
2754 $this->_fields[] = $new_field;
2755 }else{
2756 return $new_field;
2757 }
2758 }
2759
2760 /**
2761 * Add Select Field to Page
2762 * @author Ohad Raz
2763 * @since 0.1
2764 * @access public
2765 * @param $id string field id, i.e. the meta key
2766 * @param $options (array) array of key => value pairs for select options
2767 * @param $args mixed|array
2768 * 'name' => // field name/label string optional
2769 * 'desc' => // field description, string optional
2770 * 'std' => // default value, (array) optional
2771 * 'multiple' => // select multiple values, optional. Default is false.
2772 * 'validate_func' => // validate function, string optional
2773 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2774 */
2775 public function addSelect($id,$options,$args,$repeater=false){
2776 $new_field = array('type' => 'select','id'=> $id,'std' => array(),'desc' => '','style' =>'','name' => 'Select Field','multiple' => false,'options' => $options);
2777 $new_field = array_merge($new_field, $args);
2778 if(false === $repeater){
2779 $this->_fields[] = $new_field;
2780 }else{
2781 return $new_field;
2782 }
2783 }
2784
2785 /**
2786 * Add Sortable Field to Page
2787 * @author Ohad Raz
2788 * @since 0.4
2789 * @access public
2790 * @param $id string field id, i.e. the meta key
2791 * @param $options (array) array of key => value pairs for sortable options as value => label
2792 * @param $args mixed|array
2793 * 'name' => // field name/label string optional
2794 * 'desc' => // field description, string optional
2795 * 'std' => // default value, (array) optional
2796 * 'validate_func' => // validate function, string optional
2797 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2798 */
2799 public function addSortable($id,$options,$args,$repeater=false){
2800 $new_field = array('type' => 'sortable','id'=> $id,'std' => array(),'desc' => '','style' =>'','name' => 'Select Field','multiple' => false,'options' => $options);
2801 $new_field = array_merge($new_field, $args);
2802 if(false === $repeater){
2803 $this->_fields[] = $new_field;
2804 }else{
2805 return $new_field;
2806 }
2807 }
2808
2809
2810 /**
2811 * Add Radio Field to Page
2812 * @author Ohad Raz
2813 * @since 0.1
2814 * @access public
2815 * @param $id string field id, i.e. the meta key
2816 * @param $options (array) array of key => value pairs for radio options
2817 * @param $args mixed|array
2818 * 'name' => // field name/label string optional
2819 * 'desc' => // field description, string optional
2820 * 'std' => // default value, string optional
2821 * 'validate_func' => // validate function, string optional
2822 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2823 */
2824 public function addRadio($id,$options,$args,$repeater=false){
2825 $new_field = array('type' => 'radio','id'=> $id,'std' => array(),'desc' => '','style' =>'','name' => 'Radio Field','options' => $options,'multiple' => false);
2826 $new_field = array_merge($new_field, $args);
2827 if(false === $repeater){
2828 $this->_fields[] = $new_field;
2829 }else{
2830 return $new_field;
2831 }
2832 }
2833
2834 /**
2835 * Add Date Field to Page
2836 * @author Ohad Raz
2837 * @since 0.1
2838 * @access public
2839 * @param $id string field id, i.e. the meta key
2840 * @param $args mixed|array
2841 * 'name' => // field name/label string optional
2842 * 'desc' => // field description, string optional
2843 * 'std' => // default value, string optional
2844 * 'validate_func' => // validate function, string optional
2845 * 'format' => // date format, default yy-mm-dd. Optional. Default "'d MM, yy'" See more formats here: http://goo.gl/Wcwxn
2846 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2847 */
2848 public function addDate($id,$args,$repeater=false){
2849 $new_field = array('type' => 'date','id'=> $id,'std' => '','desc' => '','format'=>'d MM, yy','name' => 'Date Field');
2850 $new_field = array_merge($new_field, $args);
2851 if(false === $repeater){
2852 $this->_fields[] = $new_field;
2853 }else{
2854 return $new_field;
2855 }
2856 }
2857
2858 /**
2859 * Add Time Field to Page
2860 * @author Ohad Raz
2861 * @since 0.1
2862 * @access public
2863 * @param $id string- field id, i.e. the meta key
2864 * @param $args mixed|array
2865 * 'name' => // field name/label string optional
2866 * 'desc' => // field description, string optional
2867 * 'std' => // default value, string optional
2868 * 'validate_func' => // validate function, string optional
2869 * 'format' => // time format, default hh:mm. Optional. See more formats here: http://goo.gl/83woX
2870 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2871 */
2872 public function addTime($id,$args,$repeater=false){
2873 $new_field = array('type' => 'time','id'=> $id,'std' => '','desc' => '','format'=>'hh:mm','name' => 'Time Field');
2874 $new_field = array_merge($new_field, $args);
2875 if(false === $repeater){
2876 $this->_fields[] = $new_field;
2877 }else{
2878 return $new_field;
2879 }
2880 }
2881
2882 /**
2883 * Add Color Field to Page
2884 * @author Ohad Raz
2885 * @since 0.1
2886 * @access public
2887 * @param $id string field id, i.e. the meta key
2888 * @param $args mixed|array
2889 * 'name' => // field name/label string optional
2890 * 'desc' => // field description, string optional
2891 * 'std' => // default value, string optional
2892 * 'validate_func' => // validate function, string optional
2893 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2894 */
2895 public function addColor($id,$args,$repeater=false){
2896 $new_field = array('type' => 'color','id'=> $id,'std' => '','desc' => '','name' => 'ColorPicker Field');
2897 $new_field = array_merge($new_field, $args);
2898 if(false === $repeater){
2899 $this->_fields[] = $new_field;
2900 }else{
2901 return $new_field;
2902 }
2903 }
2904
2905 /**
2906 * Add Image Field to Page
2907 * @author Ohad Raz
2908 * @since 0.1
2909 * @access public
2910 * @param $id string field id, i.e. the meta key
2911 * @param $args mixed|array
2912 * 'name' => // field name/label string optional
2913 * 'desc' => // field description, string optional
2914 * 'validate_func' => // validate function, string optional
2915 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2916 */
2917 public function addImage($id,$args,$repeater=false){
2918 $new_field = array('type' => 'image','id'=> $id,'desc' => '','name' => 'Image Field');
2919 $new_field = array_merge($new_field, $args);
2920 if(false === $repeater){
2921 $this->_fields[] = $new_field;
2922 }else{
2923 return $new_field;
2924 }
2925 }
2926
2927
2928 /**
2929 * Add WYSIWYG Field to Page
2930 * @author Ohad Raz
2931 * @since 0.1
2932 * @access public
2933 * @param $id string field id, i.e. the meta key
2934 * @param $args mixed|array
2935 * 'name' => // field name/label string optional
2936 * 'desc' => // field description, string optional
2937 * 'std' => // default value, string optional
2938 * 'style' => // custom style for field, string optional Default 'width: 300px; height: 400px'
2939 * 'validate_func' => // validate function, string optional
2940 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2941 */
2942 public function addWysiwyg($id,$args,$repeater=false){
2943 $new_field = array('type' => 'wysiwyg','id'=> $id,'std' => '','desc' => '','style' =>'width: 300px; height: 400px','name' => 'WYSIWYG Editor Field');
2944 $new_field = array_merge($new_field, $args);
2945 if(false === $repeater){
2946 $this->_fields[] = $new_field;
2947 }else{
2948 return $new_field;
2949 }
2950 }
2951
2952 /**
2953 * Add Taxonomy Field to Page
2954 * @author Ohad Raz
2955 * @since 0.1
2956 * @access public
2957 * @param $id string field id, i.e. the meta key
2958 * @param $options mixed|array options of taxonomy field
2959 * 'taxonomy' => // taxonomy name can be category,post_tag or any custom taxonomy default is category
2960 * 'type' => // how to show taxonomy? 'select' (default) or 'checkbox_list'
2961 * 'args' => // arguments to query taxonomy, see http://goo.gl/uAANN default ('hide_empty' => false)
2962 * @param $args mixed|array
2963 * 'name' => // field name/label string optional
2964 * 'desc' => // field description, string optional
2965 * 'std' => // default value, string optional
2966 * 'validate_func' => // validate function, string optional
2967 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2968 */
2969 public function addTaxonomy($id,$options,$args,$repeater=false){
2970 $temp = array('taxonomy'=> 'category','type' => 'select','args'=> array('hide_empty' => 0));
2971 $options = array_merge($temp,$options);
2972 $new_field = array('type' => 'taxonomy','id'=> $id,'desc' => '','name' => 'Taxonomy Field','options'=> $options, 'multiple' => false);
2973 $new_field = array_merge($new_field, $args);
2974 if(false === $repeater){
2975 $this->_fields[] = $new_field;
2976 }else{
2977 return $new_field;
2978 }
2979 }
2980
2981 /**
2982 * Add WP_Roles Field to Page
2983 * @author Ohad Raz
2984 * @since 0.1
2985 * @access public
2986 * @param $id string field id, i.e. the meta key
2987 * @param $options mixed|array options of taxonomy field
2988 * 'type' => // how to show taxonomy? 'select' (default) or 'checkbox_list'
2989 * @param $args mixed|array
2990 * 'name' => // field name/label string optional
2991 * 'desc' => // field description, string optional
2992 * 'std' => // default value, string optional
2993 * 'validate_func' => // validate function, string optional
2994 * @param $repeater bool is this a field inside a repeatr? true|false(default)
2995 */
2996 public function addRoles($id,$options,$args,$repeater=false){
2997 $options = array_merge(array('type'=>'select'),$options);
2998 $new_field = array('type' => 'WProle','id'=> $id,'desc' => '','name' => 'WP Roles Field','options'=> $options, 'multiple' => false);
2999 $new_field = array_merge($new_field, $args);
3000 if(false === $repeater){
3001 $this->_fields[] = $new_field;
3002 }else{
3003 return $new_field;
3004 }
3005 }
3006
3007 /**
3008 * Add posts Field to Page
3009 * @author Ohad Raz
3010 * @since 0.1
3011 * @access public
3012 * @param $id string field id, i.e. the meta key
3013 * @param $options mixed|array options of taxonomy field
3014 * 'post_type' => // post type name, 'post' (default) 'page' or any custom post type
3015 * type' => // how to show posts? 'select' (default) or 'checkbox_list'
3016 * args' => // arguments to query posts, see http://goo.gl/is0yK default ('posts_per_page' => -1)
3017 * @param $args mixed|array
3018 * 'name' => // field name/label string optional
3019 * 'desc' => // field description, string optional
3020 * 'std' => // default value, string optional
3021 * 'validate_func' => // validate function, string optional
3022 * @param $repeater bool is this a field inside a repeatr? true|false(default)
3023 */
3024 public function addPosts($id,$options,$args,$repeater=false){
3025 $temp = array('type'=>'select','args'=>array('posts_per_page' => -1,'post_type' =>'post'));
3026 $options = array_replace_recursive($temp,$options);
3027 $new_field = array('type' => 'posts','id'=> $id,'desc' => '','name' => 'Posts Field','options'=> $options, 'multiple' => false);
3028 $new_field = array_merge($new_field, $args);
3029 if(false === $repeater){
3030 $this->_fields[] = $new_field;
3031 }else{
3032 return $new_field;
3033 }
3034 }
3035
3036 /**
3037 * Add repeater Field Block to Page
3038 * @author Ohad Raz
3039 * @since 0.1
3040 * @access public
3041 * @param $id string field id, i.e. the meta key
3042 * @param $args mixed|array
3043 * 'name' => // field name/label string optional
3044 * 'desc' => // field description, string optional
3045 * 'std' => // default value, string optional
3046 * 'style' => // custom style for field, string optional
3047 * 'validate_func' => // validate function, string optional
3048 * 'fields' => //fields to repeater
3049 * @modified 0.4 added sortable option
3050 */
3051 public function addRepeaterBlock($id,$args){
3052 $new_field = array('type' => 'repeater','id'=> $id,'name' => 'Reapeater Field','fields' => array(),'inline'=> false, 'sortable' => false);
3053 $new_field = array_merge($new_field, $args);
3054 $this->_fields[] = $new_field;
3055 }
3056
3057
3058 /**
3059 * Finish Declaration of Page
3060 * @author Ohad Raz
3061 * @since 0.1
3062 * @access public
3063 * @deprecated 1.1.8
3064 */
3065 public function Finish() {
3066 /*$this->add_missed_values();
3067 $this->check_field_upload();
3068 $this->check_field_plupload();
3069 $this->check_field_color();
3070 $this->check_field_date();
3071 $this->check_field_time();
3072 $this->check_field_code();*/
3073 }
3074
3075 /**
3076 * Helper function to check for empty arrays
3077 * @author Ohad Raz
3078 * @since 0.1
3079 * @access public
3080 * @param $args mixed|array
3081 */
3082 public function is_array_empty($array){
3083 if (!is_array($array))
3084 return true;
3085
3086 foreach ($array as $a){
3087 if (is_array($a)){
3088 foreach ($a as $sub_a){
3089 if (!empty($sub_a) && $sub_a != '')
3090 return false;
3091 }
3092 }else{
3093 if (!empty($a) && $a != '')
3094 return false;
3095 }
3096 }
3097 return true;
3098 }
3099
3100 /**
3101 * Get the list of avialable Fonts
3102 *
3103 * @author Ohad Raz
3104 * @since 0.3
3105 * @access public
3106 *
3107 * @return mixed|array
3108 */
3109 public function get_fonts_family($font = null) {
3110 $fonts = get_option('WP_EX_FONTS_LIST', $default = false);
3111 if ($fonts === false){
3112 $fonts = array(
3113 'arial' => array(
3114 'name' => 'Arial',
3115 'css' => "font-family: Arial, sans-serif;",
3116 ),
3117 'verdana' => array(
3118 'name' => "Verdana, Geneva",
3119 'css' => "font-family: Verdana, Geneva;",
3120 ),
3121 'trebuchet' => array(
3122 'name' => "Trebuchet",
3123 'css' => "font-family: Trebuchet;",
3124 ),
3125 'georgia' => array(
3126 'name' => "Georgia",
3127 'css' => "font-family: Georgia;",
3128 ),
3129 'times' => array(
3130 'name' => "Times New Roman",
3131 'css' => "font-family: Times New Roman;",
3132 ),
3133 'tahoma' => array(
3134 'name' => "Tahoma, Geneva",
3135 'css' => "font-family: Tahoma, Geneva;",
3136 ),
3137 'palatino' => array(
3138 'name' => "Palatino",
3139 'css' => "font-family: Palatino;",
3140 ),
3141 'helvetica' => array(
3142 'name' => "Verdana, Geneva",
3143 'css' => "font-family: Helvetica*;",
3144 ),
3145 );
3146 if ($this->google_fonts){
3147 $api_keys = array(
3148 'AIzaSyDXgT0NYjLhDmUzdcxC5RITeEDimRmpq3s',
3149 'AIzaSyD6j7CsUTblh29PAXN3NqxBjnN-5nuuFGU',
3150 'AIzaSyB8Ua6XIfe-gqbkE8P3XL4spd0x8Ft7eWo',
3151 'AIzaSyDJYYVPLT9JaoMPF8G5cFm1YjTZMjknizE',
3152 'AIzaSyDXt6e2t_gCfhlSfY8ShpR9WpqjMsjEimU'
3153 );
3154 $k = rand(0,count($api_keys) -1 );
3155 $gs = wp_remote_get( 'https://www.googleapis.com/webfonts/v1/webfonts?sort=popularity&key='.$api_keys[$k] ,array('sslverify' => false));
3156 if(! is_wp_error( $gs ) ) {
3157 $fontsSeraliazed = $gs['body'];
3158 $fontArray = json_decode($gs['body']);
3159 $fontArray = $fontArray->items;
3160 foreach ( $fontArray as $f ){
3161 $key = strtolower(str_replace(" ", "_", $f->family));
3162 $fonts[$key] = array(
3163 'name' => $f->family,
3164 'import' => str_replace(" ","+",$f->family),
3165 'css' => 'font-family: '.$f->family .';', //@import url(http://fonts.googleapis.com/css?family=
3166 );
3167 }
3168 }
3169 }
3170 update_option('WP_EX_FONTS_LIST',$fonts);
3171 }
3172 $fonts = apply_filters( 'WP_EX_available_fonts_family', $fonts );
3173 if ($font === null){
3174 return $fonts;
3175 }else{
3176 foreach ($fonts as $f => $value) {
3177 if ($f == $font)
3178 return $value;
3179 }
3180 }
3181 }
3182
3183 /**
3184 * Get list of font faces
3185 *
3186 * @author Ohad Raz
3187 * @since 0.3
3188 * @access public
3189 *
3190 * @return array
3191 */
3192 public function get_font_style(){
3193 $default = array(
3194 'normal' => 'Normal',
3195 'italic' => 'Italic',
3196 'oblique ' => 'Oblique'
3197 );
3198 return apply_filters( 'BF_available_fonts_style', $default );
3199 }
3200
3201 /**
3202 * Get list of font wieght
3203 *
3204 * @author Ohad Raz
3205 * @since 0.9.9
3206 * @access public
3207 *
3208 * @return array
3209 */
3210 public function get_font_weight(){
3211 $default = array(
3212 'normal' => 'Normal',
3213 'bold' => 'Bold',
3214 'bolder' => 'Bolder',
3215 'lighter' => 'Lighter',
3216 '100' => '100',
3217 '200' => '200',
3218 '300' => '300',
3219 '400' => '400',
3220 '500' => '500',
3221 '600' => '600',
3222 '700' => '700',
3223 '800' => '800',
3224 '900' => '900',
3225 'inherit' => 'Inherit'
3226 );
3227 return apply_filters( 'BF_available_fonts_weights', $default );
3228 }
3229
3230 /**
3231 * Export Import Functions
3232 */
3233
3234 /**
3235 * Add import export to Page
3236 * @author Ohad Raz
3237 * @since 0.8
3238 * @access public
3239 *
3240 * @return void
3241 */
3242 public function addImportExport(){
3243 $new_field = array('type' => 'import_export','id'=> '','value' => '');
3244 $this->_fields[] = $new_field;
3245 }
3246
3247
3248 public function show_import_export(){
3249 $this->show_field_begin(array('name' => ''),null);
3250 $ret ='
3251 <div class="apc_ie_panel field">
3252 <div style="padding 10px;" class="apc_export"><h3>'.__('Export','apc').'</h3>
3253 <p>'. __('To export saved settings click the Export button bellow and you will get the export Code in the box bellow, which you can later use to import.','apc').'</p>
3254 <div class="export_code">
3255 <label for="export_code">'. __('Export Code','apc').'</label><br/>
3256 <textarea id="export_code"></textarea>
3257 <input class="button" type="button" value="'. __('Get Export','apc').'" id="apc_export_b" />'.$this->create_export_download_link().'
3258 <div class="export_status" style="display: none;"><img src="http://i.imgur.com/l4pWs.gif" alt="loading..."/></div>
3259 <div class="export_results alert" style="display: none;"></div>
3260 </div>
3261 </div>
3262 <div style="padding 10px;" class="apc_import"><h3>'.__('Import','apc').'</h3>
3263 <p>'. __('To Import saved settings paste the Export output in to the Import Code box bellow and click Import.','apc').'</p>
3264 <div class="import_code">
3265 <label for="import_code">'. __('Import Code','apc').'</label><br/>
3266 <textarea id="import_code"></textarea>
3267 <input class="button" type="button" value="'. __('Import','apc').'" id="apc_import_b" />
3268 <div class="import_status" style="display: none;"><img src="http://i.imgur.com/l4pWs.gif" alt="loading..."/></div>
3269 <div class="import_results alert" style="display: none;"></div>
3270 </div>
3271 </div>
3272 <input type="hidden" id="option_group_name" value="'.$this->option_group.'" />
3273 <input type="hidden" id="apc_import_nonce" name="apc_Import" value="'.wp_create_nonce("apc_import").'" />
3274 <input type="hidden" id="apc_export_nonce" name="apc_export" value="'.wp_create_nonce("apc_export").'" />
3275 ';
3276 echo apply_filters('apc_import_export_panel',$ret);
3277 $this->show_field_end(array('name' => '','desc' => ''),null);
3278 }
3279
3280 /**
3281 * Ajax export
3282 *
3283 * @author Ohad Raz
3284 * @since 0.8
3285 * @access public
3286 *
3287 * @return json object
3288 */
3289 public function export(){
3290 check_ajax_referer( 'apc_export', 'seq' );
3291 if (!isset($_GET['group'])){
3292 $re['err'] = __('error in ajax request! (1)','apc');
3293 $re['nonce'] = wp_create_nonce("apc_export");
3294 echo json_encode($re);
3295 die();
3296 }
3297
3298 $options = get_option($this->option_group,false);
3299 if ($options !== false)
3300 $re['code']= "<!*!* START export Code !*!*>\n".base64_encode(serialize($options))."\n<!*!* END export Code !*!*>";
3301 else
3302 $re['err'] = __('error in ajax request! (2)','apc');
3303
3304 //update_nonce
3305 $re['nonce'] = wp_create_nonce("apc_export");
3306 echo json_encode($re);
3307 die();
3308
3309 }
3310
3311 /**
3312 * Ajax import
3313 *
3314 * @author Ohad Raz
3315 * @since 0.8
3316 * @access public
3317 *
3318 * @return json object
3319 */
3320 public function import(){
3321 check_ajax_referer( 'apc_import', 'seq' );
3322 if (!isset($_POST['imp'])){
3323 $re['err'] = __('error in ajax request! (3)','apc');
3324 $re['nonce'] = wp_create_nonce("apc_import");
3325 echo json_encode($re);
3326 die();
3327 }
3328 $import_code = $_POST['imp'];
3329 $import_code = str_replace("<!*!* START export Code !*!*>\n","",$import_code);
3330 $import_code = str_replace("\n<!*!* END export Code !*!*>","",$import_code);
3331 $import_code = base64_decode($import_code);
3332 $import_code = unserialize($import_code);
3333 if (is_array($import_code)){
3334 update_option($this->option_group,$import_code);
3335 $re['success']= __('Setting imported, make sure you ','apc'). '<input class="button-primary" type="button" value="'. __('Refresh this page','apc').'" id="apc_refresh_page_b" />';
3336 }else{
3337 $re['err'] = __('Could not import settings! (4)','apc');
3338 }
3339 //update_nonce
3340 $re['nonce'] = wp_create_nonce("apc_import");
3341 echo json_encode($re);
3342 die();
3343 }
3344
3345
3346 //then define the function that will take care of the actual download
3347 public function download_file($content = null, $file_name = null){
3348 if (! wp_verify_nonce($_REQUEST['nonce'], 'theme_export_options') )
3349 wp_die('Security check');
3350
3351 //here you get the options to export and set it as content, ex:
3352 $options= get_option($_REQUEST['option_group']);
3353 $content = "<!*!* START export Code !*!*>\n".base64_encode(serialize($options))."\n<!*!* END export Code !*!*>";
3354 $file_name = apply_filters('apc_theme_export_filename', 'options.txt');
3355 header('HTTP/1.1 200 OK');
3356
3357 if ( !current_user_can('edit_themes') )
3358 wp_die('<p>'.__('You do not have sufficient permissions to edit templates for this site.','apc').'</p>');
3359
3360 if ($content === null || $file_name === null){
3361 wp_die('<p>'.__('Error Downloading file.','apc').'</p>');
3362 }
3363 $fsize = strlen($content);
3364 header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
3365 header('Content-Description: File Transfer');
3366 header("Content-Disposition: attachment; filename=" . $file_name);
3367 header("Content-Length: ".$fsize);
3368 header("Expires: 0");
3369 header("Pragma: public");
3370 echo $content;
3371 exit;
3372 }
3373
3374 public function create_export_download_link($echo = false){
3375 $site_url = get_bloginfo('url');
3376 $args = array(
3377 'theme_export_options' => 'safe_download',
3378 'nonce' => wp_create_nonce('theme_export_options'),
3379 'option_group' => $this->option_group
3380 );
3381 $export_url = add_query_arg($args, $site_url);
3382 if ($echo === true)
3383 echo '<a href="'.$export_url.'" target="_blank">'.__('Download Export','apc').'</a>';
3384 elseif ($echo == 'url')
3385 return $export_url;
3386 return '<a class="button" href="'.$export_url.'" target="_blank">'.__('Download Export','apc').'</a>';
3387 }
3388
3389 //first add a new query var
3390 public function add_query_var_vars() {
3391 global $wp;
3392 $wp->add_query_var('theme_export_options');
3393 }
3394
3395 //then add a template redirect which looks for that query var and if found calls the download function
3396 public function admin_redirect_download_files(){
3397 global $wp;
3398 global $wp_query;
3399 //download theme export
3400 if (array_key_exists('theme_export_options', $wp->query_vars) && $wp->query_vars['theme_export_options'] == 'safe_download' && $this->option_group == $_REQUEST['option_group'] ){
3401 $this->download_file();
3402 die();
3403 }
3404 }
3405
3406 public function Handle_plupload_action(){
3407 // check ajax noonce
3408 $imgid = $_POST["imgid"];
3409 check_ajax_referer($imgid . 'pluploadan');
3410
3411 // handle file upload
3412 $status = wp_handle_upload($_FILES[$imgid . 'async-upload'], array('test_form' => true, 'action' => 'plupload_action'));
3413
3414 // send the uploaded file url in response
3415 echo $status['url'];
3416 exit;
3417 }
3418
3419 /**
3420 * load_textdomain
3421 * @author Ohad Raz
3422 * @since 1.0.9
3423 * @return void
3424 */
3425 public function load_textdomain(){
3426 //In themes/plugins/mu-plugins directory
3427 load_textdomain( 'apc', dirname(__FILE__) . '/lang/' . get_locale() .'.mo' );
3428 }
3429
3430 /**
3431 * Validation functions
3432 */
3433
3434 /**
3435 * validate field
3436 * @access public
3437 * @author Ohad Raz <admin@bainternet.info>
3438 * @since 1.1.9
3439 * @param array $field field data
3440 * @param mixed $meta value to validate
3441 * @return boolean
3442 */
3443 public function validate_field($field,$meta){
3444 if (!isset($field['validate']) || !is_array($field['validate'] ))
3445 return true;
3446
3447 $ret = true;
3448 foreach ($field['validate'] as $type => $args) {
3449 if (method_exists($this,'is_' . $type)){
3450 if (call_user_func ( array( $this, 'is_' . $type ), $meta ,$args['param']) === false){
3451 $this->errors_flag = true;
3452 $this->errors[$field['id']]['name'] = $field['name'];
3453 $this->errors[$field['id']]['m'][] = (isset($args['message'])? $args['message'] : __('Not Valid ','apc') . $type);
3454 $ret = false;
3455 }
3456 }
3457 }
3458 return $ret;
3459 }
3460
3461 /**
3462 * displayErrors function to print out validation errors.
3463 * @access public
3464 * @author Ohad Raz <admin@bainternet.info>
3465 * @since 1.1.9
3466 * @return void
3467 */
3468 public function displayErrors(){
3469 if ($this->errors_flag){
3470 echo '<div class="alert alert-error"><button data-dismiss="alert" class="close" type="button">×</button>';
3471 echo '<h4>'.__('Errors in saving changes', 'apc').'</h4>';
3472 foreach ($this->errors as $id => $arr) {
3473 echo "<strong>{$arr['name']}</strong>: ";
3474 foreach ($arr['m'] as $m) {
3475 echo "<br /> {$m}";
3476 }
3477 echo '<br />';
3478 }
3479 echo '</div>';
3480 }
3481 }
3482
3483 /**
3484 * getFieldErrors return field errors
3485 * @access public
3486 * @author Ohad Raz <admin@bainternet.info>
3487 * @since 1.1.9
3488 * @param string $field_id
3489 * @return array
3490 */
3491 public function getFieldErrors($field_id){
3492 if ($this->errors_flag){
3493 if (isset($this->errors[$field_id]))
3494 return $this->errors[$field_id];
3495 }
3496 return __('Unkown Error','apc');
3497 }
3498
3499 /**
3500 * has_error check if a field has errors
3501 * @access public
3502 * @author Ohad Raz <admin@bainternet.info>
3503 * @since 1.1.9
3504 * @param string $field_id field ID
3505 * @return boolean
3506 */
3507 public function has_error($field_id){
3508 //exit if not saved or no validation errors
3509 if (!$this->saved_flag || !$this->errors_flag)
3510 return false;
3511 //check if this field has validation errors
3512 if (isset($this->errors[$field_id]))
3513 return true;
3514 return false;
3515 }
3516
3517 /**
3518 * valid email
3519 * @access public
3520 * @author Ohad Raz <admin@bainternet.info>
3521 * @since 1.1.9
3522 * @param string
3523 * @return boolean
3524 */
3525 public function is_email($val){
3526 return (bool)(preg_match("/^([a-z0-9+_-]+)(.[a-z0-9+_-]+)*@([a-z0-9-]+.)+[a-z]{2,6}$/ix",$val));
3527 }
3528
3529 /**
3530 * check a number optional -,+,. values
3531 * @access public
3532 * @author Ohad Raz <admin@bainternet.info>
3533 * @since 1.1.9
3534 * @param string
3535 * @return boolean
3536 */
3537 public function is_numeric($val){
3538 return (bool)preg_match('/^[-+]?[0-9]*.?[0-9]+$/', (int)$val);
3539 }
3540
3541 /**
3542 * check given number below value
3543 * @access public
3544 * @author Ohad Raz <admin@bainternet.info>
3545 * @since 1.1.9
3546 * @param string
3547 * @return boolean
3548 */
3549 public function is_minvalue($number,$max){
3550 return (bool)((int)$number > (int)$max);
3551 }
3552
3553 /**
3554 * check given number exceeds max values
3555 * @access public
3556 * @author Ohad Raz <admin@bainternet.info>
3557 * @since 1.1.9
3558 * @param string
3559 * @return boolean
3560 */
3561 public function is_maxvalue($number,$max){
3562 return ((int)$number < (int)$max);
3563 }
3564
3565 /**
3566 * Check the string length has minimum length
3567 * @access public
3568 * @author Ohad Raz <admin@bainternet.info>
3569 * @since 1.1.9
3570 * @param string
3571 * @return boolean
3572 */
3573 public function is_minlength($val, $min){
3574 return (strlen($val) >= (int)$min);
3575 }
3576
3577 /**
3578 * check string length exceeds maximum length
3579 * @access public
3580 * @author Ohad Raz <admin@bainternet.info>
3581 * @since 1.1.9
3582 * @param string
3583 * @return boolean
3584 */
3585 public function is_maxlength($val, $max){
3586 return (strlen($val) <= (int)$max);
3587 }
3588
3589 /**
3590 * check for exactly length of string
3591 * @access public
3592 * @author Ohad Raz <admin@bainternet.info>
3593 * @since 1.1.9
3594 * @param string
3595 * @return boolean
3596 */
3597 public function is_length($val, $length){
3598 return (strlen($val) == (int)$length);
3599 }
3600
3601 /**
3602 * Valid URL or web address
3603 * @access public
3604 * @author Ohad Raz <admin@bainternet.info>
3605 * @since 1.1.9
3606 * @param string
3607 * @return boolean
3608 */
3609 public function is_url($val){
3610 return (bool)preg_match('|^http(s)?://[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(/.*)?$|i', $val);
3611 }
3612
3613 /**
3614 * Matches alpha and numbers only
3615 * @access public
3616 * @author Ohad Raz <admin@bainternet.info>
3617 * @since 1.1.9
3618 * @param string
3619 * @return boolean
3620 */
3621 public function is_alphanumeric($val){
3622 return (bool)preg_match("/^([a-zA-Z0-9])+$/i", $val);
3623 }
3624
3625
3626} // End Class
3627
3628endif; // End Check Class Exists