spivurno
1/12/2014 - 6:49 AM

Gravity Wiz // Multi-file Merge Tag for Post Content Templates

Gravity Wiz // Multi-file Merge Tag for Post Content Templates

<?php

# Basic Usage: 
# Applies default markup to all forms
gw_multi_file_merge_tag()->register_settings();

# Exclude Form(s): 
# Applies default markup to all forms excluding the specified forms
gw_multi_file_merge_tag()->register_settings( array(
    'exclude_forms' => 2 // multiple forms: array( 2, 4 )
) );

# Specific Form
# Applies default markup to a specific form
gw_multi_file_merge_tag()->register_settings( array(
    'form_id' => 402
) );

# Specific Form w/ Custom Markup
# Applies custom markup to a specific form
gw_multi_file_merge_tag()->register_settings( array(
    'form_id' => 402,
    'markup' => array(
        array(
            'file_types' => array( 'jpg', 'jpeg', 'png', 'gif' ),
            'markup' => '<div class="gw-image"><a href="{url}" class="gw-image-link"><img src="{url}" width="100%" /></a><span>{filename}</span></div>'
        ),
        array(
            'file_types' => array( 'mp4', 'ogg', 'webm' ),
            'markup' => '<video width="320" height="240" controls>
                            <source src="{url}" type="video/{ext}">
                            Your browser does not support the video tag.
                         </video>'
        )
    )
) );

# Specific Field, Specific Form
# Applies default markup to a specific field on a specific form.
gw_multi_file_merge_tag()->register_settings( array(
    'form_id' => 123,
    'field_ids' => array( 1 ),
) );
<?php
/**
* Gravity Wiz // Multi-File Merge Tag for Post Content Templates
* 
* Enhance the merge tag for multi-file upload fields by adding support for outputting markup that corresponds to the 
* uploaded file. Example: image files will be wrapped in an <img> tag. Out of the box, this snippet only supports 
* images and is limited to the 'jpg', 'png', and 'gif'.
* 
* The default merge tag for the multi-file upload field will output the URL for each of the files.
* 
* @version   1.4
* @author    David Smith <david@gravitywiz.com>
* @license   GPL-2.0+
* @link      http://gravitywiz.com/...
* @copyright 2018 Gravity Wiz, LLC.
*/
class GW_Multi_File_Merge_Tag {
    
    private static $instance = null;

    /**
     * Temporarily stores the values of the 'gform_merge_tag_filter' filter for use in the 'gform_replace_merge_tags' filter.
     *
     * @var array
     */
    private $_merge_tag_args = array();
    private $_settings = array();
    
    private function __construct() {
        add_filter( 'gform_pre_replace_merge_tags', array( $this, 'replace_merge_tag' ), 10, 7 );
    }
    
    public static function get_instance() {
        
        if( null == self::$instance )
            self::$instance = new self;
            
        return self::$instance;
    }

    public function get_default_args() {
        return array(
            'form_id' => false,
            'field_ids' => array(),
            'exclude_forms' => array(),
            'default_markup' => '<li><a href="{url}">{filename}.{ext}</a></li>',
            'markup' => array(
                array(
                    'file_types' => array( 'jpg', 'png', 'gif' ),
                    'markup' => '<img src="{url}" width="33%" />'
                ),
                array(
                    'file_types' => array( 'mp4', 'ogg', 'webm' ),
                    'markup' => '<video width="320" height="240" controls>
                                    <source src="{url}" type="video/{ext}">
                                    Your browser does not support the video tag.
                                 </video>'
                ),
                array(
                    'file_types' => array( 'ogv' ),
                    'markup' => '<video width="320" height="240" controls>
                                    <source src="{url}" type="video/ogg">
                                    Your browser does not support the video tag.
                                 </video>'
                )
            )
        );
    }

    public function register_settings( $args = array() ) {

        $args = wp_parse_args( $args, $this->get_default_args() );

        if( ! $args['form_id'] ) {
            $this->_settings['global'] = $args;
        } else {
            $this->_settings[$args['form_id']] = $args;
        }

    }
    
    public function replace_merge_tag( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format ) {

        preg_match_all( '/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $text, $matches, PREG_SET_ORDER );
        
        foreach( $matches as $match ) {
            
            $input_id = $match[1];
            $field = GFFormsModel::get_field( $form, $input_id );
            
            if( ! $this->is_applicable_field( $field ) ) {
	            continue;
            }
            
            if( $format != 'html' ) {
                
                $value = $this->_merge_tag_args['value'];
                
            } else {

	            if( $entry['id'] == null && is_callable( array( 'GWPreviewConfirmation', 'preview_image_value' ) ) ) {
		            $files = GWPreviewConfirmation::preview_image_value( 'input_' . $field->id, $field, $form, $entry );
	            } else {
		            $value = GFFormsModel::get_lead_field_value( $entry, $field );
		            $files = empty( $value ) ? array() : json_decode( $value, true );
	            }

                $value = '';
                if( $files ) {
                    foreach( $files as &$file ) {
                        $value .= $this->get_file_markup( $file, $form['id'] );
                        $value = str_replace( $file, $field->get_download_url( $file, false ), $value );
                    }
                }

            }

	        $has_value = ! empty( $value );

            // Replace each instance of our merge tag individually so we can check if it is part of a [gf conditional]
	        // shortcode; if so, replace the value with 1 so it can correctly evaluate as having a value.
            do {
	            $pos = strpos( $text, $match[0] );
	            if ( $pos !== false ) {
		            $replace = substr( $text, $pos - 11, 10 ) == 'merge_tag=' ? $has_value : $value;
		            $text = substr_replace( $text, $replace, $pos, strlen( $match[0] ));
	            }
            } while( $pos !== false );
            
        }

        return $text;
    }
    
    public function get_file_markup( $file, $form_id ) {
        
        $value = str_replace( " ", "%20", $file );
        $file_info = pathinfo( $value );
        
        extract( $file_info ); // gives us $dirname, $basename, $extension, $filename

        if( ! $extension )
            return $value;

        $markup_settings = $this->get_markup_settings( $form_id );
        if( empty( $markup_settings ) )
            return $value;

        $markup_found = false;

        foreach( $markup_settings as $file_type_markup ) {

            $file_types = array_map( 'strtolower', $file_type_markup['file_types'] );
            if( ! in_array( strtolower( $extension ), $file_types ) )
                continue;

            $markup_found = true;
            $markup = $file_type_markup['markup'];

            $tags = array(
                '{url}' => $file,
                '{filename}' => $filename,
                '{basename}' => $basename,
                '{ext}' => $extension
            );

            foreach( $tags as $tag => $tag_value ) {
                $markup = str_replace( $tag, $tag_value, $markup );
            }

            $value = $markup;
            break;
        }

        if( ! $markup_found && $default_markup = $this->get_default_markup( $form_id ) ) {

            $tags = array(
                '{url}' => $file,
                '{filename}' => $filename,
                '{basename}' => $basename,
                '{ext}' => $extension
            );

            foreach( $tags as $tag => $tag_value ) {
                $default_markup = str_replace( $tag, $tag_value, $default_markup );
            }

            $value = $default_markup;

        }
        
        return $value;
    }

    public function get_markup_settings( $form_id ) {

        $form_markup_settings = rgars( $this->_settings, "$form_id/markup" ) ? rgars( $this->_settings, "$form_id/markup" ) : array();
        $global_markup_settings = rgars( $this->_settings, 'global/markup' ) ? rgars( $this->_settings, 'global/markup' ) : array();

        return array_merge( $form_markup_settings, $global_markup_settings );
    }

    public function get_default_markup( $form_id ) {

        $default_markup = rgars( $this->_settings, "$form_id/default_markup" );
        if( ! $default_markup )
            $default_markup = rgars( $this->_settings, 'global/default_markup' );

        return $default_markup;
    }

    public function is_excluded_form( $form_id ) {

        $has_global_settings = isset( $this->_settings['global'] );
        $excluded_forms = (array) rgars( $this->_settings, 'global/exclude_forms' );

        $explicity_excluded = $has_global_settings && in_array( $form_id, $excluded_forms );
        $passively_excluded = ! $has_global_settings && ! isset( $this->_settings[$form_id] );

        return $explicity_excluded || $passively_excluded;
    }

    public function is_applicable_field( $field ) {

    	$field_ids = rgars( $this->_settings, "{$field->formId}/field_ids" );

        $is_valid_form = ! $this->is_excluded_form( $field['formId'] );
        $is_matching_field_id = empty( $field_ids ) || in_array( $field->id, $field_ids );
        $is_file_upload_filed = GFFormsModel::get_input_type( $field ) == 'fileupload';
        $is_multi = rgar( $field, 'multipleFiles' );

        return $is_valid_form && $is_matching_field_id && $is_file_upload_filed && $is_multi;
    }
    
}

function gw_multi_file_merge_tag() {
    return GW_Multi_File_Merge_Tag::get_instance();
}

# Usage

gw_multi_file_merge_tag()->register_settings();