FlashBuddy

admin-page-class.php

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