PATH:
home
/
letacommog
/
winwithd
/
wp-content
/
plugins
/
profile-builder-pro
/
features
/
conditional-fields
<?php /* Description: Conditional Fields */ Class PB_Conditional_Fields { /* * The id of the last deleted field * */ public $deleted_element_id = null; public $wppb_manage_fields = null; /* * Constructor * */ public function __construct() { /* initialize the property with what we store in the 'wppb_manage_fields' option */ $this->wppb_manage_fields = get_option( 'wppb_manage_fields' ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) ); add_filter( 'wppb_manage_fields', array( $this, 'add_conditional_fields' ) ); add_action( 'wck_ajax_add_form_wppb_manage_fields', array( $this, 'set_js_wppb_manage_fields' ) ); add_action( 'wck_refresh_list_wppb_manage_fields', array( $this, 'set_js_wppb_manage_fields' ) ); add_action( 'wck_refresh_entry_wppb_manage_fields', array( $this, 'set_js_wppb_manage_fields' ) ); add_filter( 'wck_metabox_content_wppb_manage_fields', array( $this, 'set_js_wppb_manage_fields' ) ); add_action( 'wck_after_adding_form_wppb_manage_fields', array( $this, 'init_conditional_logic_option' ) ); /* frontend handling */ add_action( 'wp_footer', array( $this, 'frontend_conditional_handle' ) ); /** * add required check filters for every field */ if( !empty( $this->wppb_manage_fields ) ) { foreach( $this->wppb_manage_fields as $field ) { /* add it on a later priority */ add_filter( 'wppb_check_form_field_' . Wordpress_Creation_Kit_PB::wck_generate_slug($field['field']), array( $this, 'bypass_required_if_needed' ), 20, 4 ); } } add_action( 'wck_before_remove_meta', array( $this, 'cache_deleted_element_id' ), 10, 3 ); add_filter( 'pre_update_option', array( $this, 'remove_field_from_rules' ), 10, 3 ); add_filter( 'wck_pre_displayed_value_wppb_manage_fields_element_conditional-logic-enabled', array( $this, 'conditional_logic_icon' ) ); } /* * Enqueue scripts in the admin area * */ public function enqueue_admin_scripts() { if( !empty( $_GET['page'] ) && $_GET['page'] == 'manage-fields' && defined( 'PROFILE_BUILDER_VERSION' ) ) { wp_enqueue_script( 'pb-conditional-fields', plugin_dir_url( __FILE__ ) . 'assets/js/conditional-fields.js', array( 'jquery', 'wppb-manage-fields-live-change' ) ); wp_enqueue_style( 'pb-conditional-fields', plugin_dir_url( __FILE__ ) . 'assets/css/conditional-fields.css' ); } } /* * Adds the field options for the conditional logic enable/disable checkbox and for the conditional logic rules * * @param array $fields - fields in manage fields * */ public function add_conditional_fields( $fields ) { array_push( $fields, array( 'type' => 'checkbox', 'slug' => 'conditional-logic-enabled', 'title' => __( 'Conditional Logic', 'profile-builder' ), 'options' => array( '%Enable conditional logic%yes' ) ) ); array_push( $fields, array( 'type' => 'text', 'slug' => 'conditional-logic', 'title' => __( 'Conditional Rules', 'profile-builder' ) ) ); return $fields; } /* * Gets fields saved in the manage_fields option and adds them to the JS conditional logic object * */ public function set_js_wppb_manage_fields( $fields_or_id ) { $wppb_manage_fields = apply_filters( 'wppb_cf_form_fields', get_option( apply_filters( 'wppb_cf_option_meta', 'wppb_manage_fields' ), array() ) ); // Don't allow all fields to be available $fields_not_allowed = apply_filters( 'wppb_conditional_fields_not_allowed', array( 'WooCommerce Customer Billing Address', 'WooCommerce Customer Shipping Address', 'Default - Name (Heading)', 'Default - Contact Info (Heading)', 'Default - About Yourself (Heading)', 'Default - Password', 'Default - Repeat Password', 'Heading', 'WYSIWYG', 'Checkbox (Terms and Conditions)', 'Upload', 'Avatar', 'reCAPTCHA', 'HTML', 'Map' ), $wppb_manage_fields ); if( !empty( $wppb_manage_fields ) ) { foreach( $wppb_manage_fields as $key => $field ) { if( in_array( $field['field'], $fields_not_allowed ) ) unset( $wppb_manage_fields[$key] ); } } // Set the manage fields in JS $return = '<script type="text/javascript">wppb_conditional_logic.set_manage_fields(' . json_encode( $wppb_manage_fields ) . ');</script>'; if( $fields_or_id === 0 ) echo $return; else return $fields_or_id . $return; } /* * Initializes the conditional logic options in JS for a field when the edit form of the field gets rendered * */ public function init_conditional_logic_option( $id ) { echo '<script type="text/javascript"> jQuery("#container_wppb_manage_fields input[name=conditional-logic-enabled]").each( function() { wppb_conditional_logic.show_conditional_option( jQuery(this) ) });</script>'; } /* function that handles the js on the front end for fields */ function frontend_conditional_handle(){ global $wppb_shortcode_on_front; if( !empty( $wppb_shortcode_on_front ) && $wppb_shortcode_on_front === true ){ if( !empty( $this->wppb_manage_fields ) ){ /* output the js rules */ echo '<script type="text/javascript"> function wppbHideActions( liElement ){ jQuery( "input[type=\'text\'], input[type=\'email\'], input[type=\'number\'], input[type=\'hidden\'], textarea, select option, input[type=\'checkbox\'], input[type=\'radio\']", jQuery( liElement ) ).each( function(){ if( jQuery( this )[0].hasAttribute("value") ){ jQuery( this ).attr( "conditional-value", jQuery( this ).attr("value") ); jQuery( this ).removeAttr("value"); jQuery( this ).trigger("change"); } else{ jQuery( this ).attr( "conditional-value", jQuery( this ).text() ); jQuery( this ).trigger("change"); } // Trigger a custom event that will remove the HTML attribute -required- for hidden fields. This is necessary for browsers to allow form submission. jQuery( this ).trigger( "wppbRemoveRequiredAttributeEvent" ); } ) } function wppbShowActions( liElement ){ jQuery( "input[type=\'text\'], input[type=\'email\'], input[type=\'number\'], input[type=\'hidden\'], textarea, select option, input[type=\'checkbox\'], input[type=\'radio\']", jQuery( liElement ) ).each( function(){ if( jQuery( this )[0].hasAttribute("conditional-value") ){ jQuery( this ).attr( "value", jQuery( this ).attr("conditional-value") ); jQuery( this ).removeAttr("conditional-value"); jQuery( this ).trigger("change"); // Trigger a custom event that will add the HTML attribute -required- back again, for previously hidden fields. jQuery( this ).trigger( "wppbAddRequiredAttributeEvent" ); } } ) } </script>'; foreach( $this->wppb_manage_fields as $field ){ if( !empty( $field["conditional-logic-enabled"] ) && !empty( $field["conditional-logic"] ) && $field["conditional-logic-enabled"] === 'yes' ){ $field_conditional_logic = json_decode( $field["conditional-logic"], true ); $check_fields_in_DOM = array(); $check_fields_change = array(); $check_fields_conditions = array(); if( !empty( $field_conditional_logic['rules'] ) ){ foreach( $field_conditional_logic['rules'] as $rule ){ if( $rule['operator'] == 'is' ) $operator = '!='; else if( $rule['operator'] == 'is not' ) $operator = '=='; /* check if field in DOM */ $check_fields_in_DOM[] = 'jQuery( "#wppb-form-element-'. $rule['field'] .'" ).length != 0'; /* js string for field change */ $check_fields_change[] = '#wppb-form-element-'. $rule['field'] .' input, #wppb-form-element-'. $rule['field'] .' textarea, #wppb-form-element-'. $rule['field'] .' select'; /* js string to check if the condition is met */ $check_fields_conditions[] = 'jQuery.inArray( "'. $rule['value'] .'", jQuery( "#wppb-form-element-'. $rule['field'] .' input[type=\"text\"], #wppb-form-element-'. $rule['field'] .' input[type=\"email\"], #wppb-form-element-'. $rule['field'] .' input[type=\"number\"], #wppb-form-element-'. $rule['field'] .' input[type=\"hidden\"], #wppb-form-element-'. $rule['field'] .' textarea, #wppb-form-element-'. $rule['field'] .' select option:selected, #wppb-form-element-'. $rule['field'] .' input[type=\"checkbox\"]:checked, #wppb-form-element-'. $rule['field'] .' input[type=\"radio\"]:checked" ).map(function(){return jQuery(this).val(); }).get() ) '. $operator .' -1'; } } /* combine all the rules together */ if( $field_conditional_logic['logic_type'] == 'all' ){ $check_fields_in_DOM_all = implode( ' && ', $check_fields_in_DOM ); $check_fields_conditions_all = implode( ' && ', $check_fields_conditions ); } else if( $field_conditional_logic['logic_type'] == 'any' ){ $check_fields_in_DOM_all = implode( ' || ', $check_fields_in_DOM ); $check_fields_conditions_all = implode( ' || ', $check_fields_conditions ); } $check_fields_change_all = implode( ', ', $check_fields_change ); /* output the js rules */ echo '<script type="text/javascript"> if( jQuery( "#wppb-form-element-'. $field['id'] .'" ).length != 0 ){ if( '. $check_fields_in_DOM_all .' ){ if( "show" == "'. $field_conditional_logic['action_type'] .'" ){ jQuery( "#wppb-form-element-'. $field['id'] .'" ).hide( 0, function(){ wppbHideActions(this) }); } if( '. $check_fields_conditions_all .' ){ if( "show" == "'. $field_conditional_logic['action_type'] .'" ){ jQuery( "#wppb-form-element-'. $field['id'] .'" ).show( 0, function(){ wppbShowActions(this) }); } else if( "hide" == "'. $field_conditional_logic['action_type'] .'" ){ jQuery( "#wppb-form-element-'. $field['id'] .'" ).hide( 0, function(){ wppbHideActions(this) }); } } jQuery( "'. $check_fields_change_all .'" ).on( "change keyup", function(){ if( '. $check_fields_conditions_all .' ){ if( "show" == "'. $field_conditional_logic['action_type'] .'" ){ jQuery( "#wppb-form-element-'. $field['id'] .'" ).show( 0, function(){ wppbShowActions(this) }); } else if( "hide" == "'. $field_conditional_logic['action_type'] .'" ){ jQuery( "#wppb-form-element-'. $field['id'] .'" ).hide( 0, function(){ wppbHideActions(this) }); } } else{ if( "show" == "'. $field_conditional_logic['action_type'] .'" ){ if( jQuery( "#wppb-form-element-'. $field['id'] .'" ).css("display") != "none" ) jQuery( "#wppb-form-element-'. $field['id'] .'" ).hide( 0, function(){ wppbHideActions(this) }); } else if( "hide" == "'. $field_conditional_logic['action_type'] .'" ){ if( jQuery( "#wppb-form-element-'. $field['id'] .'" ).css("display") == "none" ) jQuery( "#wppb-form-element-'. $field['id'] .'" ).show( 0, function(){ wppbShowActions(this) }); } } }); } } </script>'; } } } } } /** * if the field is hidden by conditional fields when submitted then we don't test the error check on it (required) */ function bypass_required_if_needed( $message, $field, $request_data, $form_location ){ /* if we are not on the default form then get the fields that are present in the form */ if( !empty( $request_data['form_name'] ) && $request_data['form_name'] != 'unspecified' ){ $form_id = Profile_Builder_Form_Creator::wppb_get_form_id_from_form_name( $request_data['form_name'], $form_location ); if( !empty( $form_id ) ){ if( $form_location == 'register' ) $meta = 'wppb_rf_fields'; else if ( $form_location == 'edit_profile' ) $meta = 'wppb_epf_fields'; $form_fields = get_post_meta( $form_id, $meta, true ); } } /* go ahead if we have conditional enabled on the field */ if( !empty( $field["conditional-logic-enabled"] ) && !empty( $field["conditional-logic"] ) && $field["conditional-logic-enabled"] === 'yes' ) { $field_conditional_logic = json_decode($field["conditional-logic"], true); /* set initial conditions based on action_type. if action type is show then it means that at the begging it is hidden */ if( $field_conditional_logic['action_type'] == 'show' ) $hide_field = true; else if( $field_conditional_logic['action_type'] == 'hide' ) $hide_field = false; /* if all the rules must be met then we start with a true value and pass through all of them and if one is not true then we invalidate them */ if ($field_conditional_logic['logic_type'] == 'all') { $all_conditions = true; } if (!empty($field_conditional_logic['rules'])) { foreach ($field_conditional_logic['rules'] as $rule) { $request_name = $this->get_field_meta_name_from_id($rule['field']); /* we are in multi forms case so see if the field in the rule is present in the form */ if( !empty( $form_fields ) && $field_conditional_logic['logic_type'] == 'all' ){ $found = false; foreach( $form_fields as $form_field ){ if( $form_field['id'] == $rule['field'] ){ $found = true; break; } } if( !$found ) return $message; } elseif( !empty( $form_fields ) && $field_conditional_logic['logic_type'] == 'any' ){ /* if none of the fields from the rules are present in the form we should return the original message */ foreach ($field_conditional_logic['rules'] as $any_rule){ $rule_fields_ids[] = $any_rule['field']; } foreach( $form_fields as $any_form_field ){ $form_fields_ids[] = $any_form_field['id']; } if( !empty( $rule_fields_ids ) && !empty( $form_fields_ids ) ){ $common_fields = array_intersect( $rule_fields_ids, $form_fields_ids ); if( empty( $common_fields ) ) return $message; } } if (!empty($request_name)) { /* if the field in the rule is not present in the form don't do anything and return the initial message */ if (isset($request_data[wppb_handle_meta_name($request_name)])) { if( !is_array( $request_data[wppb_handle_meta_name($request_name)] ) ) $request_value = array( $request_data[wppb_handle_meta_name($request_name)] ); else $request_value = $request_data[wppb_handle_meta_name($request_name)]; if ($rule['operator'] == 'is' && in_array( $rule['value'], $request_value ) ) { if ($field_conditional_logic['logic_type'] == 'any') { $hide_field = !$hide_field; break; } } else if ($rule['operator'] == 'is' && !in_array( $rule['value'], $request_value ) ) { if ($field_conditional_logic['logic_type'] == 'all') { $all_conditions = false; break; } } if( $rule['operator'] == 'is not' && !in_array( $rule['value'], $request_value ) ){ if ($field_conditional_logic['logic_type'] == 'any') { $hide_field = !$hide_field; break; } } else if( $rule['operator'] == 'is not' && in_array( $rule['value'], $request_value ) ){ if ($field_conditional_logic['logic_type'] == 'all') { $all_conditions = false; break; } } } else{ if ($field_conditional_logic['logic_type'] == 'all') { $all_conditions = false; } } } } } /* if all the rules must be valid and the boolean is still true then the inital state of the field changed */ if( $field_conditional_logic['logic_type'] == 'all' && $all_conditions ) $hide_field = !$hide_field; /* after checking all the rules and the field is hidden then don't test it */ if( $hide_field ) return ''; } return $message; } /** * function that returns the field meta name based on the field id */ function get_field_meta_name_from_id( $id ){ if( !empty( $this->wppb_manage_fields ) ) { foreach ($this->wppb_manage_fields as $field) { if( $field['id'] === $id ) { if( !empty( $field['meta-name'] ) ) return $field['meta-name']; else{ switch ( Wordpress_Creation_Kit_PB::wck_generate_slug( $field['field'] ) ){ case 'default-username': return 'username'; break; case 'default-display-name-publicly-as': return "display_name"; break; case 'default-e-mail': return 'email'; break; case 'default-website': return 'website'; break; } } } } } return ''; } /* * Displays an icon in the manage fields list for fields that have conditional logic enabled * * @param string $display_value * * @return string * */ function conditional_logic_icon( $display_value ) { if( strpos( $display_value, 'yes' ) !== false ) return '<span title="' . __( 'This field has conditional logic enabled.', 'profile-builder' ) . '" class="wppb-manage-fields-dashicon dashicons dashicons-randomize"></span>'; return $display_value; } /* * Hooks in WCK to cache the element_id of the row that is being removed by the admin * * @param string $meta - the name of the option that is being handled * @param int $id - the post id * @param int $element_id - the id of the element that is being removed * */ function cache_deleted_element_id( $meta, $id, $element_id ) { // If the meta is not manage fields, exit if( $meta != 'wppb_manage_fields' ) return; // Go on only if we have an element id passed if( empty( $element_id ) ) return; // We know we want the option, not post_meta, so we'll exit if a post id is provided if( !empty( $id ) ) return; $this->deleted_element_id = $element_id; } /* * Remove the field that is being deleted from all the conditional rules set * * @param array $value - the value that will be saved in the DB * @param string $option - the name of the option being handled * @param array $old_value - the value that is currently saved in the DB * * @return array * */ public function remove_field_from_rules( $value, $option, $old_value ) { if( $option != 'wppb_manage_fields' ) return $value; if( $this->deleted_element_id == null ) return $value; // Grab the field that will be deleted $deleted_field = $old_value[ $this->deleted_element_id ]; // Return the value to its initial state $this->deleted_element_id = null; if( !empty( $value ) ) { foreach( $value as $field_key => $field ) { // Jump to the next field if this element doesn't have any conditional logic saved if( empty( $field['conditional-logic'] ) ) continue; // Decode the conditional logic $cl = json_decode( $field['conditional-logic'], ARRAY_A ); // As we want to remove all rules that have in them the field that is being deleted, // we'll just skip fields that don't have any rules set if( empty( $cl['rules'] ) ) continue; // Go through each rule and remove the ones where the deleted field appears foreach( $cl['rules'] as $key => $rule ) { if( $rule['field'] == $deleted_field['id'] ) unset( $cl['rules'][$key] ); } // Reset the keys $cl['rules'] = array_values( $cl['rules'] ); // Encode the conditional logic as it was $value[$field_key]['conditional-logic'] = json_encode( $cl ); } } return $value; } } // Let's get this party started new PB_Conditional_Fields;
[+]
..
[+]
assets
[-] conditional-fields.php
[edit]