spivurno
8/31/2013 - 4:32 PM

MOD: Better Limit Submissions Per Time Period by User or IP (without hiding form & spanning limit across a group of forms)

MOD: Better Limit Submissions Per Time Period by User or IP (without hiding form & spanning limit across a group of forms)

<?php
/**
* MOD: Better Limit Submissions Per Time Period by User or IP (without hiding form & spanning limit across a group of forms)
* 
* Based On: http://gravitywiz.com/2012/05/12/limit-ip-to-one-submission-per-time-period
* Video:    http://screencast.com/t/I11vWq02Qswn
* 
* Note: This mod does not require the original snippet. Most of the parameters still function the same as the snippet it
* is based on. The only exception is the 'form_id' parameter which now accepts an array of form IDs rather than a single
* form ID. 
*   
*   // span the limit across forms 1, 2, and 3
*   'form_id' => array( 1, 2, 3 )
* 
*   // span the limit across ALL forms EXCEPT forms 2 and 4
*   'form_id' => array( -2, -4 )
* 
*/
    
class GWSubmissionLimit_YvesSandyck {
    
    function __construct( $args ) {
        
        $this->_args = wp_parse_args( $args, array(
            'form_id' => false,
            'limit' => 1,
            'time_period' => 60 * 60 * 24, // must be provided in seconds: 60 seconds in a minute, 60 minutes in an hour, 24 hours in a day
            'limit_message' => __('Sorry, you have reached the submission limit for this form.'),
            'limit_by' => 'ip' // also accepts "user_id"
            ));
        
        if( is_array( $args['form_id'] ) ) {
            
            $form_ids = $args['form_id'];
            $all_forms = wp_list_pluck( GFFormsModel::get_forms( true ), 'id' );
            
            // check if array is a list of excepted form IDs or included form IDs, will be negative if excepted
            if( $form_ids[0] < 0 ) {
                
                $form_ids = array_map( 'abs', $form_ids );
                $filtered_form_ids = array();
                foreach( $all_forms as $form_id ) {
                    if( ! in_array( $form_id, $form_ids ) )
                        $filtered_form_ids[] = $form_id;
                }
                $this->_args['form_id'] = $filtered_form_ids;
                
            }
            
        } else {
            
            $this->_args['form_id'] = array( $args['form_id'] );
            
        }
        
        add_filter( 'gform_pre_render', array( $this, 'pre_render' ) );
        
    }
    
    function pre_render( $form ) {
        
        // skip forms that are not registered with this snippet
        if( ! in_array( $form['id'], $this->_args['form_id'] ) )
            return $form;
        
        if( ! $this->is_limit_reached( $form['id'] ) )
            return $form;
    
        $submission_info = rgar( GFFormDisplay::$submission, $form['id'] );
        
        if( ! $submission_info || ! rgar( $submission_info, 'is_valid' ) )
            add_filter( 'gform_get_form_filter', array( $this, 'display_limit_message' ) );
         
        return $form;
    }
    
    public function display_limit_message( $form_string ) {
        remove_filter( 'gform_get_form_filter', array( $this, 'display_limit_message' ) );
        return '<div class="limit-message">' . $this->_args['limit_message'] . '</div>' . $form_string;
    }
    
    public function is_limit_reached($form_id) {
        global $wpdb;
        
        $limit_by = is_array($this->_args['limit_by']) ? $this->_args['limit_by'] : array($this->_args['limit_by']);
        $where = array();
        
        foreach($limit_by as $limiter) {
            switch($limiter) {
            case 'user_id':
                $where[] = $wpdb->prepare('created_by = %s', get_current_user_id());
                break;
            case 'embed_url':
                $where[] = $wpdb->prepare('source_url = %s', RGFormsModel::get_current_page_url());
                break;
            default:
                $where[] = $wpdb->prepare('ip = %s', RGFormsModel::get_ip());
            }
        }
        
        if( count( $this->_args['form_id'] ) <= 1 ) {
            $where[] = $wpdb->prepare('form_id = %d', $this->_args['form_id'][0] );
        } else {
            $form_ids_str = '"' . implode( '", "', $this->_args['form_id'] ) . '"';
            $where[] = "form_id IN( $form_ids_str )";
        }
        
        $where[] = $wpdb->prepare('date_created BETWEEN DATE_SUB(utc_timestamp(), INTERVAL %d SECOND) AND utc_timestamp()', $this->_args['time_period']);
        $where = implode(' AND ', $where);
        
        $sql = "SELECT count(id)
                FROM {$wpdb->prefix}rg_lead
                WHERE $where";
        
        $entry_count = $wpdb->get_var($sql);
        
        return $entry_count >= $this->_args['limit'];
    }
    
}

new GWSubmissionLimit_YvesSandyck( array(
    'form_id' => array( -242, -282, -117 ),
    'limit' => 1,
    'time_period' => 60 * 60 * 24 * 1,
    'limit_message' => 'You are all maxed out! Try again in a couple days.',
    'limit_by' => 'user_id',
    ) );