Gravity Forms does not support the concept of inventory out of the box. This snippet (which improves upon the Simple Ticket Inventory snippet) provides an easy method for setting up simple, one-off inventory limits on a per field basis.
Updated on November 11, 2012 to fix issue where database prefix was not applied via $wpdb->prefix.
Let’s dive into the code first.
/*** Better Inventory with Gravity Forms / Limit by Sum of Field Values* http://gravitywiz.com/2012/09/19/better-inventory-with-gravity-forms/*/
class GWLimitBySum { private $_args; function __construct($args) { $this->_args = wp_parse_args($args, array( 'form_id' => false, 'field_id' => false, 'limit' => 20, 'limit_message' => __('Sorry, this item is sold out.'), 'validation_message' => __('You ordered %1$s of this item. There are only %2$s of this item left.'), 'approved_payments_only' => false, 'hide_form' => false )); $this->_args['input_id'] = $this->_args['field_id']; extract($this->_args); add_filter("gform_pre_render_$form_id", array(&$this, 'limit_by_field_values')); add_filter("gform_validation_$form_id", array(&$this, 'limit_by_field_values_validation')); if($approved_payments_only) add_filter('gwlimitbysum_query', array(&$this, 'limit_by_approved_only')); } public function limit_by_field_values($form) { $sum = self::get_field_values_sum($form['id'], $this->_args['input_id']); if($sum < $this->_args['limit']) return $form; if($this->_args['hide_form']) { add_filter('gform_get_form_filter', create_function('', 'return "' . $this->_args['limit_message'] . '";')); } else { add_filter('gform_field_input', array(&$this, 'hide_field'), 10, 2); } return $form; }
public function limit_by_field_values_validation($validation_result) { extract($this->_args); $form = $validation_result['form']; $exceeded_limit = false; foreach($form['fields'] as &$field) { if($field['id'] != intval($input_id)) continue; $requested_value = rgpost("input_" . str_replace('.', '_', $input_id)); $field_sum = self::get_field_values_sum($form['id'], $input_id); if($field_sum + $requested_value <= $limit) continue; $exceeded_limit = true; $number_left = $limit - $field_sum >= 0 ? $limit - $field_sum : 0; $field['failed_validation'] = true; $field['validation_message'] = sprintf($validation_message, $requested_value, $number_left); } $validation_result['form'] = $form; $validation_result['is_valid'] = !$validation_result['is_valid'] ? false : !$exceeded_limit; return $validation_result; }
public function hide_field($field_content, $field) { if($field['id'] == intval($this->_args['input_id'])) return "<div class="ginput_container">{$this->_args['limit_message']}</div>"; return $field_content; } public static function get_field_values_sum($form_id, $input_id) { global $wpdb; $query = apply_filters('gwlimitbysum_query', array( 'select' => 'SELECT sum(value)', 'from' => "FROM {$wpdb->prefix}rg_lead_detail ld", 'where' => $wpdb->prepare("WHERE ld.form_id = %d AND CAST(ld.field_number as unsigned) = %d", $form_id, $input_id) )); $sql = implode(' ', $query); return $wpdb->get_var($sql); } public static function limit_by_approved_only($query) { global $wpdb; $query['from'] .= " INNER JOIN {$wpdb->prefix}rg_lead l ON l.id = ld.lead_id"; $query['where'] .= ' AND l.payment_status = 'Approved''; return $query; } }
new GWLimitBySum(array( 'form_id' => 113, 'field_id' => 13.3, 'limit' => 8, 'limit_message' => 'Sorry, there are no more tickets!', 'validation_message' => 'You ordered %1$s tickets. There are only %2$s tickets left.', 'approved_payments_only' => false, 'hide_form' => false ));
How do I install this snippet?
Easy peasy. Just copy and paste the code above into your theme's functions.php file.
Do I need to modify this snippet to work with my form?
You don’t have to modify the snippet itself. Just the parameters with which you initialize it.
new GWLimitBySum(array( 'form_id' => 113, 'field_id' => 13.3, 'limit' => 8, 'limit_message' => 'Sorry, there are no more tickets!', 'validation_message' => 'You ordered %1$s tickets. There are only %2$s tickets left.', 'approved_payments_only' => false, 'hide_form' => false
Parameters
$form_id
the ID of the form you are working with.$field_id
the ID of your product or quantity field. If using a Single Product field, you’ll need to specify the quantity input ID which will always be{field ID}.3
(ie if the field ID is12
, the quantity input ID will be12.3
). If using a separate Quantity field, simply specify the field ID.$limit
the number of this item you have available.$limit_message
the message which should be displayed to users when the product limit has been reached. You can get fancy with this and add HTML as well. Be sure to escape any double quotes with a backslash. Here’s a more advanced example:$sum_limit_message = '<div style="border: 1px solid #e6db55; background-color: #FFFFE0; padding: 10px;">Sorry, this show is sold out.</div>';Better Inventory: Limit Message
$validation_message
the validation message which should be displayed on the field if the limit has not been reached, but the user’s requested quantity would exceed the product limit.Better Inventory: Limit Validation Message
$approved_payments_only
true/false
indicate whether all submissions for this field should be counted against the limit or only submissions with an approved payment. You’ll want to be careful here when using PayPal Standard due to the delay between the form submission and the payment being approved. It could lead to users exceeding the limit.$hide_form
by default this snippet will only hide the field when the limit has been reached. If you would rather hide the entire form, set this totrue
.