<?php
/**
 * Plugin Name: Gravity Forms Bootstrap Design
 * Plugin URI: https://www.wpmonks.com
 * Description: Adds Bootstrap styling to Gravity Forms
 * Version: 1.4
 * Author: Sushil Kumar
 * Author URI: https://www.wpmonks.com
 * Text Domain: stlabootstrap
 */
if ( ! defined( 'ABSPATH' ) ) exit;

define( "STLA_BOOTSTRAP_DIR", WP_PLUGIN_DIR . "/" . basename( dirname( __FILE__ ) ) );
define( "STLA_BOOTSTRAP_URL", plugins_url() . "/" . basename( dirname( __FILE__ ) ) );
define( "STLA_BOOTSTRAP_VERSION", "1.4" );

include_once WP_PLUGIN_DIR . "/" . basename( dirname( __FILE__ ) ) . '/update.php';
class Sk_Stla_Bootstrap {
	private $is_frontend = false;
	public function __construct() {
		//modify text, dropdowns, radio, checkbox fields
		add_filter( 'gform_field_content', array( $this, 'add_bootstrap_support' ), 10, 5 );
		add_action( 'gform_enqueue_scripts', array( $this, 'add_gravity_styles_scripts' ), 10, 2 );
		//modify structure of next button
		add_filter( 'gform_next_button', array( $this, 'input_to_button' ), 10, 2 );
		//modify structure of previous button
		add_filter( 'gform_previous_button', array( $this, 'input_to_button' ), 10, 2 );
		//modify structure of submit button
		add_filter( 'gform_submit_button', array( $this, 'input_to_button' ), 10, 2 );
		add_filter( 'gform_pre_render', array( $this, 'before_form_render' ) );
		//modify structure of progress button
		add_filter( 'gform_progress_bar', array( $this, 'modify_progress_bar' ), 10, 3 );
		//modify structure of validation message
		add_filter( 'gform_validation_message', array( $this, 'modify_validation_message' ), 10, 2 );
		//remove error class 
		add_filter( 'gform_field_css_class', array( $this, 'modify_field_css_classes' ), 10, 3 );
		//modify confimation message
		add_filter( 'gform_confirmation', array( $this, 'modify_confirmation_message' ), 10, 4 );
		//add bootstrap section in customizer
		add_action( 'gf_stla_add_theme_section', array( $this, 'gf_stla_add_bootstrap_design_section' ), 14, 2 );
		//hide bootstrap section if form is not selected
		add_action( 'customize_controls_enqueue_scripts', array( $this, 'add_styles_scripts' ), 99, 2 );
		//Check plugin dependency
		add_action( 'admin_notices', array( $this, 'check_plugin_dependencies' ) );
	}

	function add_styles_scripts() {
		wp_enqueue_script( 'gf_stla_bootstrap_customize_control_js', STLA_BOOTSTRAP_URL . '/js/customize-control-script.js', array( 'jquery' ), STLA_BOOTSTRAP_VERSION, true );
	}

	function gf_stla_add_bootstrap_design_section( $wp_customize, $current_form_id ) {

		//Add Bootstrap Design section
		// if ( get_query_var( $this->stla_query_var ) ) {
		$wp_customize->add_section( 'gf_stla_form_id_bootstrap_design' , array(
				'title' => 'Bootstrap Design',
				'panel' => 'gf_stla_panel',
			) );

		//add bootstrap design settings and controls to enable and disable it
		$wp_customize->add_setting( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[enabled]', array(
				'default'     => false,
				//'transport'   => 'postMessage',
				'type' => 'option'
			) );

		$wp_customize->add_control( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[enabled]',   array(
				'type' => 'checkbox',
				'priority' => 10, // Within the section.
				'section' => 'gf_stla_form_id_bootstrap_design', // Required, core or custom.
				'label' => __( 'Enable Bootstrap Design' ),

			) );
		// Option to select Theme
		$wp_customize->add_setting( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[theme]', array(
				'default'     => '#66afe9',
				//'transport'   => 'postMessage',
				'type' => 'option'
			) );

		$wp_customize->add_control(
			new WP_Customize_Color_Control(
				$wp_customize, // WP_Customize_Manager
				'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[theme]', // Setting id
				array( // Args, including any custom ones.
					'label' => __( 'Theme Color' ),
					'section' => 'gf_stla_form_id_bootstrap_design',
				)
			)
		);

		//Option to add stipes in progress bar
		$wp_customize->add_setting( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[progress-stripes]', array(
				'default'     => 'no',
				//'transport'   => 'postMessage',
				'type' => 'option'
			) );

		$wp_customize->add_control( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[progress-stripes]',   array(
				'type' => 'radio',
				'priority' => 10, // Within the section.
				'section' => 'gf_stla_form_id_bootstrap_design', // Required, core or custom.
				'label' => __( 'Add Stripes to progress bar' ),
				'choices' => array( 'yes' => 'Yes', 'no' => 'No' ),

			) );

			$wp_customize->add_setting( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[progress-animate-stripes]', array(
				'default'     => 'no',
				//'transport'   => 'postMessage',
				'type' => 'option'
			) );

		$wp_customize->add_control( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[progress-animate-stripes]',   array(
				'type' => 'radio',
				'priority' => 10, // Within the section.
				'section' => 'gf_stla_form_id_bootstrap_design', // Required, core or custom.
				'label' => __( 'Animate Stripes (Stripes should be enabled)' ),
				'choices' => array( 'yes' => 'Yes', 'no' => 'No' ),

			) );

		//add bootstrap design settings to enable border buttons
		$wp_customize->add_setting( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[border-button]', array(
				'default'     => 'no',
				'type' => 'option'
			) );

		$wp_customize->add_control( 'gf_stla_form_id_bootstrap_design_' . $current_form_id . '[border-button]',   array(
			'type' => 'radio',
			'priority' => 10, // Within the section.
			'section' => 'gf_stla_form_id_bootstrap_design', // Required, core or custom.
			'label' => __( 'Colored Border Buttons' ),
			'choices' => array( 'yes' => 'Yes', 'no' => 'No' ),

			) );

	}

	//modify confirmation message
	function modify_confirmation_message( $confirmation, $form, $entry, $ajax ) {
		$form_id = $form['id'];
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		if ( ! $enabled ) {
			return $confirmation;
		}
		$confirmation = str_replace( 'gform_confirmation_wrapper', 'alert alert-success', $confirmation );
		return $confirmation;
	}

	//find and remove css classes
	function modify_field_css_classes( $classes, $field, $form ) {
		$form_id = $form['id'];
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		if ( ! $enabled ) {
			return $classes;
		}
		//var_dump($classes);
		$classes = str_replace( 'gfield_error', '', $classes );
		$classes .= ' stla-bootstrap';
		return $classes;
	}

	//check if frontend view

	function before_form_render( $form ) {
		$this->is_frontend = true;
		return $form;
	}
	//modify_validation_message

	function modify_validation_message( $message, $form ) {
		$form_id = $form['id'];
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		if ( ! $enabled ) {
			return $message;
		}
		$dom = new DOMDocument;
		$dom->loadHTML( $message );
		$get_div = $dom->getElementsByTagName( 'div' );
		foreach ( $get_div as $div ) {
			$div->setAttribute( 'class',  'alert alert-danger' );
		}
		$message = $dom->saveHTML();
		return $message;
	}


	//modify markup of progress bar
	function modify_progress_bar( $progress_bar, $form, $confirmation_message ) {
		// var_dump( $progress_bar );
		$form_id = $form['id'];
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		if ( ! $enabled ) {
			return $progress_bar;
		}
		$stripes_enabled = isset( $bootstrap_options['progress-stripes'] ) && $bootstrap_options['progress-stripes'] === 'yes' ? true: false;
		$animate_stripes = isset( $bootstrap_options['progress-animate-stripes'] ) && $bootstrap_options['progress-animate-stripes'] === 'yes' ? true: false;
		// str_replace('gf_progressbar', 'progress', $progress_bar);
		// str_replace('gf_progressbar_percentage percentbar_blue', 'progress-bar', $progress_bar);
		$dom = new DOMDocument;
		$dom->loadHTML( $progress_bar );
		$get_element = $dom->getElementsByTagName( 'div' );
		foreach ( $get_element as $element ) {
			$current_element_classes = $element->getAttribute( 'class' );
			if ( preg_match( '/^gf_progressbar$/', $current_element_classes ) ) {
				$element->setAttribute( 'class', 'progress' );
			}
			if ( strpos( $current_element_classes, 'gf_progressbar_percentage' ) !== false ) {
				$current_element_classes = str_replace( 'gf_progressbar_percentage percentbar_blue', '', $current_element_classes );
				if( $stripes_enabled){
					if( $animate_stripes ){
						$current_element_classes .= ' progress-bar-animated';
					}
					$current_element_classes .= ' progress-bar-striped';
				}
				$element->setAttribute( 'class', $current_element_classes . ' progress-bar' );
			}
			if ( preg_match( '/^gf_progressbar_wrapper$/', $current_element_classes ) ) {
				$element->setAttribute( 'class', $element->getAttribute( 'class' ) . ' stla-bootstrap' );
			}
		}
		$progress_bar = utf8_decode( $dom->saveHTML( $dom->documentElement ) );
		//$progress_bar = $dom->saveHTML();
		//var_dump($progress_bar);
		return $progress_bar;
	}

	//add styles and scripts which loads only if gravity forms is present on page
	function add_gravity_styles_scripts( $form, $is_ajax ) {
		$form_id = $form['id'];
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		if ( ! $enabled ) {
			return ;
		}

		//wp_enqueue_style( 'stla_bootstrap_frontend', STLA_BOOTSTRAP_URL . '/css/stla-bootstrap.css' );
		
		wp_enqueue_style( 'stla_bootstrap_frontend', STLA_BOOTSTRAP_URL . '/css/bootstrap.css', '', STLA_BOOTSTRAP_VERSION );
		wp_enqueue_style( 'stla_bootstrap_custom', STLA_BOOTSTRAP_URL . '/css/custom.css', array('stla_bootstrap_frontend'), STLA_BOOTSTRAP_VERSION );
		// wp_enqueue_script( 'stla_bootstrap_frontend', STLA_BOOTSTRAP_URL . '/js/frontend.js' , array( 'jquery' ) );
		// wp_enqueue_script( 'stla_bootstrap_popper', 'https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js' , array( 'jquery' ) );
		wp_enqueue_script( 'stla_bootstrap', STLA_BOOTSTRAP_URL . '/js/bootstrap.bundle.min.js', array( 'jquery'), STLA_BOOTSTRAP_VERSION );
		include_once STLA_BOOTSTRAP_DIR.'/css/theming.php' ;
		// wp_enqueue_script( 'stla_bootstrap_frontend', STLA_BOOTSTRAP_URL . '/js/bootstrap.min.js' );

	}

	//change submit/next/previous input tags to buttons
	function input_to_button( $button, $form ) {
		$form_id = $form['id'];
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		$border_button = isset($bootstrap_options['border-button']) ? $bootstrap_options['border-button'] : '' ;

		if ( ! $enabled ) {
			return $button;
		}
		$dom = new DOMDocument();
		$dom->loadHTML( $button );
		$input = $dom->getElementsByTagName( 'input' )->item( 0 );
		$new_button = $dom->createElement( 'button' );
		$new_button->appendChild( $dom->createTextNode( $input->getAttribute( 'value' ) ) );
		$input->removeAttribute( 'value' );
		foreach ( $input->attributes as $attribute ) {
			if ( $attribute->name == 'class' ) {
					if($border_button === 'yes'){
						$border_button_class = $attribute->value .' btn stla-outline-border';
					}
					else{
						$border_button_class = $attribute->value .' btn';
					}
				$new_button->setAttribute( $attribute->name, $border_button_class );
			}
			else {
				$new_button->setAttribute( $attribute->name, $attribute->value );
			}
		}
		$input->parentNode->replaceChild( $new_button, $input );
		//create container for button
		$new_button_container = $dom->createElement( 'span' );
		$new_button_container->setAttribute( 'class', 'stla-bootstrap' );
		$new_button_container->appendChild( $new_button );

		$content = utf8_decode( $dom->saveHTML( $new_button_container ) );
		//return $dom->saveHtml( $new_button_container );
		return $content;
	}

	//modify the html structure of gravity form fields to support bootstrap
	function add_bootstrap_support( $content, $field, $value, $lead_id, $form_id ) {
		// var_dump( $field->type);
		$bootstrap_options = get_option( 'gf_stla_form_id_bootstrap_design_' . $form_id );
		$enabled = isset( $bootstrap_options['enabled'] )? $bootstrap_options['enabled']: false;
		if ( ! $enabled ) {
			return $content;
		}
		if ( $this->is_frontend ) {
			
			$input_fields = array( 'text', 'number', 'email', 'website', 'phone', 'post_title', 'post_tags', 'quantity', 'post_custom_field', 'name', 'post_image', 'product' ) ;
			$select_fields = array( 'select', 'post_tags', 'post_custom_field', 'post_category', 'quantity', 'option', 'shipping', 'name', 'address', 'time', 'product', 'quiz' );
			$checkbox_fields = array( 'checkbox', 'post_tags', 'post_custom_field', 'post_category', 'quantity', 'option', 'consent', 'quiz' );
			$radio_fields = array( 'radio', 'post_tags', 'post_custom_field', 'post_category', 'option', 'shipping', 'product', 'quiz' );
			$textarea_fields = array( 'textarea', 'post_content', 'post_excerpt' );
			$complex_fields = array( 'name', 'address' );
			$multiselect_fields = array( 'multiselect', 'post_tags', 'post_custom_field', 'post_category' );
			$email_confirmation = array( 'email' );
			$date_field = array( 'date' );
			$list_field = array( 'list' );
			//replace &nbsp; with @nbsp so that it isn't changed into space by phpdom ( which is creating an issue)
			$all_supported_fields = array_merge( $input_fields, $select_fields, $checkbox_fields, $radio_fields, $complex_fields, $multiselect_fields, $email_confirmation, $date_field, $textarea_fields, $list_field );
			if( ! in_array( $field->type, $all_supported_fields) ){
				return $content;
			}
			$content = str_replace ( '&nbsp;', '@nbsp;', $content );
			$dom = new DOMDocument;

			$dom->loadHTML( $content );
			include STLA_BOOTSTRAP_DIR . '/includes/multiselect.php' ;
			include STLA_BOOTSTRAP_DIR . '/includes/input.php' ;
			include STLA_BOOTSTRAP_DIR . '/includes/radio.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/checkbox.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/dropdown.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/complex.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/list.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/textarea.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/time.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/field-description.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/email-confirmation.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/date.php' ; 
			include STLA_BOOTSTRAP_DIR . '/includes/upload.php' ; 
		}

		//replace back @nbsp; with &nbsp;
		$content = str_replace ('@nbsp;', '&nbsp;', $content);
		return $content;
	}

	/**
	 * Check if Styles & Layouts is installed or not
	 *
	 * @return void
	 */
	function check_plugin_dependencies() {
		if ( ! class_exists( 'Gravity_customizer_admin' ) ) {
			$class = 'notice notice-error';
			$styles_layouts_url = admin_url( 'plugin-install.php?s=styles+and+layouts+for+gravity+forms&tab=search&type=term');
			$message = '<a href="'.$styles_layouts_url.'">Styles & Layouts for Gravity Forms </a>is not installed. <strong>Gravity Forms Bootstrap Design</strong> can\'t work without it.';

			printf( '<div class="%1$s"><p>%2$s</p></div>', esc_attr( $class ),  $message  );
		}
	}

} // class ends here



add_action( 'plugins_loaded', 'sk_stla_bootstrap' );

function sk_stla_bootstrap() {
	new Sk_Stla_Bootstrap();
}
