caleb2
1/4/2017 - 4:26 PM

gravityforms-api-integration.php

new gravityforms_api_integration;

add_filter( 'gform_entry_meta', array( 'gravityforms_api_integration', 'filter_gform_entry_meta' ), 1, 2 );

class gravityforms_api_integration {

    const gravityforms_api_integration_version = '0.0.1'; // https://gist.github.com/crstauf/9d63194eb6fd169b110b6301e8519ff3
    const gforms_version = '1.9.18'; // Gravity Forms Version

    const service_name = '';
    const service_slug = '';

    const gform_group_label = '';

    private static $fields = array();
    private static $errors = array();
    private static $failed = false;

    private static $api_urls = array();
    private static $api_keys = array();

    function __construct() {
        if ( is_admin() ) {
            add_filter( 'gform_form_settings',           array( __CLASS__, 'filter_gform_form_settings' ), 10, 2 );
            add_filter( 'gform_pre_form_settings_save',  array( __CLASS__, 'filter_gform_pre_form_settings_save' ) );
            add_action( 'gform_editor_js',               array( __CLASS__, 'action_form_fields_js' ) );
            add_action( 'gform_field_advanced_settings', array( __CLASS__, 'action_gform_field_advanced_settings'), 10, 2 );
            add_filter( 'gform_entries_column_filter',   array( __CLASS__, 'filter_gform_entries_column_filter'), 10, 3 );
            add_action( 'gform_entry_info',              array( __CLASS__, 'action_gform_entry_info' ), 10, 2 );
        } else {
            add_filter( 'gform_validation', array( __CLASS__, 'filter_gform_validation' ) );
            add_action( 'gform_post_submission', array( __CLASS__, 'action_gform_post_submission' ) );
        }
    }

    static function filter_gform_form_settings( $form_settings, $form ) {
        $enabled = rgar( $form, 'is' . self::service_slug );

        $form_settings[self::gform_group_label][self::service_slug] =
            '<tr>' .
                '<th>' . __( self::service_name, 'gravityforms' ) . '</th>' .
                '<td><label>' .
                    '<input type="checkbox" id="gform_enable_' . self::service_slug . '" name="form_enable_' . self::service_slug . '" value="1"' . checked( $enabled, true, false ) . ' /> ' .
                    __( 'Enable ' . self::service_name, 'gravityforms' ) .
                '</td>' .
            '</tr>';

        return $form_settings;
    }

    static function filter_gform_pre_form_settings_save( $form ) {
        $form['is' . self::service_slug] = rgpost( 'form_enable_' . self::service_slug );
        return $form;
    }

    public static function filter_gform_entry_meta( $entry_meta, $form_id ) {
		$entry_meta[self::service_slug] = array(
			'label'							=> self::service_name . ' Status',
			'filter'						=> array(
												'operators' => array( 'is', 'isnot' ),
												'choices' => array(
													array( 'text' => '', 'value' => '' ),
													array( 'text' => 'Unable to send', 'value' => 'unable to send' ),
													array( 'text' => 'Confirmed receipt', 'value' => 'confirmed receipt' ),
													array( 'text' => 'Sent, not received', 'value' => 'sent, not received' ),
												),
											),
			'is_numeric'					=> false,
			'is_default_column'				=> true,
			'update_entry_meta_callback'	=> array( __CLASS__, 'update_entry_meta_callback' )
		);
		return $entry_meta;
	}

        public static function update_entry_meta_callback( $key, $lead, $form ) {
            if (
                !array_key_exists( 'is' . self::service_slug, $form )
                || true != $form['is' . self::service_slug]
            )
                return;

            return self::$failed;
        }

    static function action_form_fields_js() {
        ?>

        <script type="text/javascript">
            var temp = ['address','text','checkbox','name','email','phone','number','date','time','textarea','select','hidden','multiselect'];
            for (var i = 0; i < temp.length; i++)
                fieldSettings[temp[i]] += ', .<?php echo self::service_slug ?>_setting';

            jQuery(document).ready(function() {
                console.log(fieldSettings);
                jQuery('.<?php echo self::service_slug ?>_field_names_setting')
            		.on('input propertychange', '.<?php echo self::service_slug ?>_field_name', function(){
            			var inputId = jQuery(this).closest('.<?php echo self::service_slug ?>_field_name_row').data('input_id');
            			SetInput<?php echo self::service_slug ?>FieldName(this.value, inputId);
            		})
            		.on('input', '#field_single_<?php echo self::service_slug ?>_field_name', function(){
            			SetField<?php echo self::service_slug ?>FieldName(this.value);
            		});
            });

            function SetInput<?php echo self::service_slug ?>FieldName(value, inputId){
                var field = GetSelectedField(), $select, elementId, ele;

                if(value)
                    value = value.trim();

                for(var i=0; i<field["inputs"].length; i++){
                    if(field["inputs"][i]["id"] == inputId){
                        field["inputs"][i]["<?php echo self::service_slug ?>FieldName"] = value;
                        jQuery('[name="input_' + inputId + '"], #input_' + inputId.toString().replace('.', '_')).each(function(){
                            return;
                            var type = this.nodeName;
                            if( type == 'INPUT'){
                                jQuery(this).val(value);
                            } else {
                                $select = jQuery(this);
                                value = value.toLowerCase();
                                $select
                                    .val('')
                                    .children()
                                    .each(function () {
                                        if(this.value.toLowerCase() == value){
                                            $select.val(this.value);
                                            return false;
                                        }
                                    });
                            }
                        });
                        return;
                    }
                }
            }

            function SetField<?php echo self::service_slug ?>FieldName(fieldName){
                jQuery(".field_selected > div > input:visible").val(fieldName);
                SetFieldProperty('<?php echo self::service_slug ?>FieldName', fieldName);
            }

            jQuery(document).on('gform_load_field_settings',function() {
                Create<?php echo self::service_slug ?>FieldNamesUI(field);
            });

            function Create<?php echo self::service_slug ?>FieldNamesUI(field) {
        		var field_str, defaultValue, inputName, inputId, id, inputs;

        		if (!field['inputs']) {
        			field_str = "<label for='field_single_<?php echo self::service_slug ?>_field_name' class='inline'>" + <?php echo json_encode( esc_html__( 'Field Name:', 'gravityforms' ) ); ?> + "&nbsp;</label>";
        			defaultValue = typeof field["<?php echo self::service_slug ?>FieldName"] != 'undefined' ? field["<?php echo self::service_slug ?>FieldName"] : '';
        			field_str += "<input type='text' value='" + defaultValue + "' id='field_single_<?php echo self::service_slug ?>_field_name'/>";
        		} else {
        			field_str = "<table class='<?php echo self::service_slug ?>_field_names'><tr><td><strong>Field</strong></td><td><strong>" + <?php echo json_encode( esc_html__( 'Field Name', 'gravityforms' ) ); ?> + "</strong></td></tr>";
        			for (var i = 0; i < field["inputs"].length; i++) {
        				id = field["inputs"][i]["id"];
        				inputName = 'input_' + id.toString();
        				inputId = inputName.replace('.', '_');
        				if (!document.getElementById(inputId) && jQuery('[name="' + inputName + '"]').length == 0) {
        					continue;
        				}
        				field_str += "<tr class='<?php echo self::service_slug ?>_field_name_row' data-input_id='" + id + "' id='input_<?php echo self::service_slug ?>_field_name_row_" + inputId + "'><td><label for='field_<?php echo self::service_slug ?>_field_name_" + id + "' class='inline'>" + field["inputs"][i]["label"] + "</label></td>";
        				fieldName = typeof field["inputs"][i]["<?php echo self::service_slug ?>FieldName"] != 'undefined' ? field["inputs"][i]["<?php echo self::service_slug ?>FieldName"] : '';
        				field_str += "<td><input class='<?php echo self::service_slug ?>_field_name' type='text' value='" + fieldName + "' id='field_<?php echo self::service_slug ?>_field_name_" + id + "' /></td></tr>";
        			}
        		}
        		jQuery("#field_<?php echo self::service_slug ?>_field_names_container").html(field_str);
        	}
        </script>

        <?php
    }

    static function action_gform_field_advanced_settings( $priority, $form_id ) {
        $form = GFAPI::get_form( $form_id );
        if (
            !array_key_exists( 'is' . self::service_slug, $form )
            || false == $form['is' . self::service_slug]
            || (-1) != $priority
        )
            return;
        ?>

        <li class="<?php echo self::service_slug ?>_field_names_setting <?php echo self::service_slug ?>_setting field_setting">

            <label><?php _e( self::service_name . ' Field Name(s)', 'gravityforms' ) ?></label>
            <div id="field_<?php echo self::service_slug ?>_field_names_container">
                <!-- dynamically created -->
            </div>

        </li>

        <?php
    }

    static function filter_gform_entries_column_filter( $value, $form_id, $field_id ) {
        $form = GFAPI::get_form( $form_id );

        if ( true != $form['is' . self::service_slug] )
            return $value;

        if ( false == $value && self::service_slug === $field_id )
            return 'Successful';

        return $value;
    }

    static function action_gform_entry_info( $form_id, $entry ) {
        $form = GFAPI::get_form( $form_id );

        if ( true != $form['is' . self::service_slug] )
            return;

        if ( array_key_exists( self::service_slug, $entry ) )
            $status = $entry[self::service_slug];

        if ( false == $status )
            $status = 'Successful';

        echo self::service_name . ' Status: ' . esc_html( $status ) . '<br /><br />';
    }

    static function filter_gform_validation( $result ) {
        if ( true != $result['form']['is' . self::service_slug] )
            return $result;

        $is_valid = true;
        foreach( $result['form']['fields'] as $i => $field ) {

            $fieldName = self::service_slug . 'FieldName';

            if (
                $field->enablePasswordInput
                && !empty( $field->{$fieldName} )
            ) {
                $password = rgpost( 'input_' . $field->id);
                if ( strlen( $password ) < 7 ) {
                    $result['form']['fields'][$i]->failed_validation = true;
                    $result['form']['fields'][$i]->validation_message .= ( empty( $result['form']['fields'][$i]->validation_message ) ? '' : ' ' ) . 'Must be at least six characters.';
                }
            }

            if (
                !isset( $field->{$fieldName} )
                || empty( $field->{$fieldName} )
            )
                continue;
            else if ( true == $field->failed_validation )
                $is_valid = false;

            self::$fields[$field->{$fieldName}] = rgpost( 'input_' . $field->id );
            if ( 'checkbox' == $field->type && empty( self::$fields[$field->{$fieldName}] ) ) {
                $checkboxes = preg_grep( '/^input_' . $field->id . '_[0-9]+$/', array_keys( $_POST ) );
                if ( count( $checkboxes ) ) {
                    if ( 1 === count( $field->choices ) ) {
                        $field_id = reset( $checkboxes );
                        self::$fields[$field->{$fieldName}] = $_POST[$field_id];
                    } else {
                        $values = array();
                        foreach ( $checkboxes as $POST_key )
                            $values[] = $POST_key;
                        self::$fields[$field->{$fieldName}] = $values;
                    }
                } else if ( $field->isRequired ) {
                    $is_valid = false;
                    $result['form']['fields'][$i]->failed_validation = true;
                }
            }
        }

        if ( false === $is_valid )
            return $result;

        $result['form'] = self::post_to_service( $result['form'] );

        if ( array_key_exists( 'failed_' . self::service_slug, $result['form'] ) && true === $result['form']['failed_' . self::service_slug] ) {
            $result['is_valid'] = false;
            return $result;
        }

        foreach( $result['form']['fields'] as $i => $field )
            if ( $field->enablePasswordInput && !empty( $field->{$fieldName} ) && !empty( rgpost( 'input_' . $field->id ) ) )
                $_POST['input_' . $field->id] = '******';

        return $result;
    }

        static function post_to_service( $form ) {

            $authentication_fields = array();

            $result = wp_remote_post( self::$api_urls[''], array(
                'method' => 'POST',
                'timeout' => 45,
                'redirection' => 5,
                'httpversion' => '1.0',
                'blocking' => true,
                'headers' => array(
                    'Content-Type' => 'application/json'
                ),
                'body' => json_encode( $authentication_fields ),
                'cookies' => array(),
            ) );

            if (
                is_wp_error( $result )
                || !array_key_exists( 'body', $result )
                || '[]' !== $result['body']
            ) {
                self::$failed = $form['failed_' . self::service_slug] = 'Could not authenticate';
                return $form;
            }

            $result = wp_remote_post( self::$api_urls[''], array(
                'method' => 'POST',
                'timeout' => 45,
                'redirection' => 5,
                'httpversion' => '1.0',
                'blocking' => true,
                'headers' => array(
                    'Content-Type' => 'application/json'
                ),
                'body' => json_encode( array_merge( self::$fields, $authentication_fields ) ),
                'cookies' => array(),
            ) );

            if (
                is_wp_error( $result )
                || !array_key_exists( 'body', $result )
            ) {
                self::$failed = $form['failed_' . self::service_slug] = 'Could not send submission';
                return $form;
            }

            $body = json_decode( $result['body'] );

            if ( isset( $body->errors ) ) {
                self::$failed = $form['failed_' . self::service_slug] = true;
                self::$errors = $body->errors;
                add_filter( 'gform_validation_message', array( __CLASS__, 'filter_gform_validation_message' ) );
                return $form;
            }

            self::$failed = $form['failed_' . self::service_slug] = false;

            return $form;
        }

            static function filter_gform_validation_message( $message ) {
                return '<div class="validation_error">' .
                    'There was a problem with your submission. Please check all required fields are filled in correctly, and try again.' .
                    '<ul style="margin: 15px 30px 5px !important;"><li style="list-style: disc !important;">' .
                        implode( '</li><li style="margin-top: 0; list-style: disc !important;">', self::$errors ) .
                    '</li></ul>' .
                '</div>';
            }

}