diff --git a/experimental/gfjs-early-init-scripts.php b/experimental/gfjs-early-init-scripts.php
index 469da1458..6b80d51b4 100644
--- a/experimental/gfjs-early-init-scripts.php
+++ b/experimental/gfjs-early-init-scripts.php
@@ -1,30 +1,6 @@
$script ) {
- if ( strpos( $slug, 'gf_custom_js' ) === 0 ) {
- $filtered = array( $slug => $script ) + $filtered;
- } else {
- $filtered[ $slug ] = $script;
- }
- }
-
- GFFormDisplay::$init_scripts[ $form['id'] ] = $filtered;
-
-}, 100 /* right after GF Custom JS */ );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gfjs-early-init-scripts.php
+ */
\ No newline at end of file
diff --git a/experimental/gfsa-auto-allow-administrator-access.php b/experimental/gfsa-auto-allow-administrator-access.php
index 1fa8e4e12..005f5e54e 100644
--- a/experimental/gfsa-auto-allow-administrator-access.php
+++ b/experimental/gfsa-auto-allow-administrator-access.php
@@ -1,8 +1,6 @@
_args = wp_parse_args( $args, array(
- 'form_id' => false,
- ) );
-
- add_action( 'init', array( $this, 'add_hooks' ), 16 ); // Wait for all add-ons
- }
-
- public function add_hooks() {
- if ( ! function_exists( 'gp_disable_entry_creation' ) ) {
- return;
- }
-
- add_filter( 'gpdec_should_delete_entry_' . $this->_args['form_id'], '__return_false' );
- add_action( 'gfpdf_post_generate_and_save_pdf_notification', array( $this, 'post_generate_and_save' ), 50, 4 );
- add_action( 'shutdown', array( $this, 'shutdown' ) );
- }
-
- public function post_generate_and_save( $form, $entry, $settings, $notifications ) {
- if ( $form['id'] != $this->_args['form_id'] ) {
- return;
- }
-
- $this->deletion_queue[] = $entry;
- }
-
- public function shutdown() {
- if ( empty( $this->deletion_queue ) ) {
- return;
- }
-
- foreach ( $this->deletion_queue as $entry ) {
- gp_disable_entry_creation()->delete_form_entry( $entry );
- }
- }
-}
-
-/*
- * Basic Usage
- *
- * Uncomment the lines below (remove the preceding // on each line) and adjust the form ID accordingly.
- * You may also duplicate the class instantiation if this is required for more than one form.
- */
-
-//new GPDEC_GFPDF_Delayed_Deletion( array(
-// 'form_id' => 3,
-//) );
diff --git a/experimental/gpdtc-calculated-input-value.php b/experimental/gpdtc-calculated-input-value.php
index 8d653c6a0..12639b107 100644
--- a/experimental/gpdtc-calculated-input-value.php
+++ b/experimental/gpdtc-calculated-input-value.php
@@ -1,6 +1,6 @@
choices;
-
- foreach ( $choices as &$choice ) {
- if ( $source_field->enablePrice ) {
- $price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) );
- $choice['value'] .= '|' . $price;
- }
- }
-
- return array(
- 'type' => 'select',
- 'choices' => $choices,
- );
-}, 10, 5 );
-
-add_filter( "gform_pre_process_{$gpias_form_id}", function( $form ) {
- global $gpias_list_field_id, $gpias_product_field_id;
-
- $list_field = GFAPI::get_field( $form, $gpias_list_field_id );
- $booths = $list_field->get_value_submission( array() );
-
- foreach ( $form['fields'] as $field ) {
-
- if ( $field->id != $gpias_product_field_id ) {
- continue;
- }
-
- while ( ! empty( $booths ) ) {
-
- $booth = array_shift( $booths );
- $_POST[ "input_{$field->id}" ] = $booth;
-
- $_fields = $form['fields'];
- $form['fields'] = array( $field );
-
- $result = gp_inventory_type_choices()->validation( array(
- 'is_valid' => true,
- 'form' => $form,
- ) );
-
- $form['fields'] = $_fields;
-
- if ( $result['is_valid'] ) {
- $field->failed_validation = false;
- return $form;
- }
- }
-
- if ( empty( $booths ) ) {
- $list_field->failed_validation = true;
- $list_field->validation_message = 'None of your selected booths are available.';
- }
- }
-
- return $form;
-} );
diff --git a/experimental/gpi-copy-exhausted-inventory-to-another-field.js b/experimental/gpi-copy-exhausted-inventory-to-another-field.js
index 063e11917..0da78c3fb 100644
--- a/experimental/gpi-copy-exhausted-inventory-to-another-field.js
+++ b/experimental/gpi-copy-exhausted-inventory-to-another-field.js
@@ -1,17 +1,5 @@
/**
- * Gravity Perks // Inventory // Copy Exhausted Choices to Another Field
- * https://gravitywiz.com/documentation/gravity-forms-inventory/
- *
- * Instructions:
- *
- * 1. Install this snippet with our free Custom JavaScript plugin.
- * https://gravitywiz.com/gravity-forms-code-chest/
- * 2. Configure the snippet per the inline instructions.
- */
-// Update "1" to the ID of your Inventory-enabled field.
-var $disabled = $( '#input_GFFORMID_1 option:disabled' );
-
-// Update "2" to the ID of the field to which exhausted choices should be copied.
-$( '#input_GFFORMID_2' ).html( $disabled.clone().prop( 'disabled', false ) );
-
-$disabled.remove();
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-inventory/gpi-copy-exhausted-inventory-to-another-field.js
+ */
\ No newline at end of file
diff --git a/experimental/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php b/experimental/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php
index 8f8a17acf..0084f276d 100644
--- a/experimental/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php
+++ b/experimental/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php
@@ -1,34 +1,6 @@
prepare( 'AND meta_value != %s', rgpost( 'partial_entry_id' ) );
- }
- $query['where'] .= "
- AND e.id IN (
- SELECT entry_id FROM {$wpdb->prefix}gf_entry_meta
- WHERE meta_key = 'gpnf_entry_parent'
- AND meta_value NOT IN(
- SELECT entry_id FROM {$wpdb->prefix}gf_entry_meta WHERE meta_key = 'partial_entry_id' $meta_value_clause
- )
- )";
- }
- return $query;
-}, 10, 2 );
diff --git a/experimental/gpi-packaged-products.php b/experimental/gpi-packaged-products.php
index f5c29ef5f..057cefff2 100644
--- a/experimental/gpi-packaged-products.php
+++ b/experimental/gpi-packaged-products.php
@@ -1,146 +1,6 @@
_args = wp_parse_args( $args, array(
- 'form_id' => null,
- 'package_field_id' => null,
- 'field_ids_in_package' => array(),
- ) );
-
- $this->form_id = $this->_args['form_id'];
- $this->package_field = GFAPI::get_field( $this->form_id, $this->_args['package_field_id'] );
- $this->field_ids_in_package = $this->_args['field_ids_in_package'];
-
- add_action( 'init', array( $this, 'init' ) );
- }
-
- public function init() {
- add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
- $this,
- 'package_field_claimed_inventory',
- ), 10, 2 );
-
- add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
- $this,
- 'add_claimed_package_inventory_to_individual_products',
- ), 10, 2 );
-
- add_filter( 'gpi_requested_quantity_' . $this->form_id, array(
- $this,
- 'add_requested_packages_to_individual_products',
- ), 10, 2 );
- }
-
- /**
- * Add claimed inventory of packaged items to packages if their inventory is below packages.
- */
- public function package_field_claimed_inventory( $package_claimed_inventory, $field ) {
- if ( $field->id !== $this->package_field->id ) {
- return $package_claimed_inventory;
- }
-
- remove_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
- $this,
- 'add_claimed_package_inventory_to_individual_products',
- ) );
-
- $inventory_limit = gp_inventory_type_advanced()->get_stock_quantity( $this->package_field );
- $package_available_inventory = $inventory_limit - $package_claimed_inventory;
- $packaged_item_available_amounts = array();
-
- foreach ( $this->field_ids_in_package as $field_id_in_package ) {
- $field_in_package = GFAPI::get_field( $this->form_id, $field_id_in_package );
- $packaged_item_available_amount = gp_inventory_type_advanced()->get_available_stock( $field_in_package ) - $package_claimed_inventory;
- $packaged_item_available_amounts[] = $packaged_item_available_amount;
- }
-
- $lowest_package_item_available_amount = min( $packaged_item_available_amounts );
-
- if ( $lowest_package_item_available_amount < $package_available_inventory ) {
- $difference = $package_available_inventory - $lowest_package_item_available_amount;
- $package_claimed_inventory = $package_claimed_inventory + $difference;
- }
-
- add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
- $this,
- 'add_claimed_package_inventory_to_individual_products',
- ), 10, 2 );
-
- return $package_claimed_inventory;
- }
-
- /**
- * Add claimed inventory of packages to packaged items.
- */
- public function add_claimed_package_inventory_to_individual_products( $claimed_inventory, $field ) {
- if ( ! in_array( $field->id, $this->field_ids_in_package ) ) {
- return $claimed_inventory;
- }
-
- remove_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
- $this,
- 'package_field_claimed_inventory',
- ) );
-
- $claimed_packages_inventory = gp_inventory_type_advanced()->get_claimed_inventory( $this->package_field );
-
- add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
- $this,
- 'package_field_claimed_inventory',
- ), 10, 2 );
-
- return (int) $claimed_inventory + (int) $claimed_packages_inventory;
- }
-
- /**
- * Add requested quantity of packages to packaged items.
- */
- public function add_requested_packages_to_individual_products( $requested_quantity, $field ) {
- if ( ! in_array( $field->id, $this->field_ids_in_package ) ) {
- return $requested_quantity;
- }
-
- $requested_packages_qty = rgpost( 'input_' . $this->package_field->id . '_3' );
-
- return (int) $requested_quantity + (int) $requested_packages_qty;
- }
-
-}
-
-/**
- * Configuration
- */
-new GP_Inventory_Packaged_Products( array(
- 'form_id' => 2,
- 'package_field_id' => 4,
- 'field_ids_in_package' => array( 1, 2 ),
-) );
diff --git a/experimental/gpnf-comma-delimited-email-list.php b/experimental/gpnf-comma-delimited-email-list.php
index 994c59a35..bee63d68d 100644
--- a/experimental/gpnf-comma-delimited-email-list.php
+++ b/experimental/gpnf-comma-delimited-email-list.php
@@ -1,23 +1,6 @@
choices ) || ! in_array( $field->id, $fields_to_use_values ) || $field->formId !== $child_form_id ) {
- return $field_value;
- }
-
- return $raw_field_value;
-}, 10, 6 );
diff --git a/experimental/gpnf-gv-duplicate-child-entries.php b/experimental/gpnf-gv-duplicate-child-entries.php
index 415c8a65e..e627abeac 100644
--- a/experimental/gpnf-gv-duplicate-child-entries.php
+++ b/experimental/gpnf-gv-duplicate-child-entries.php
@@ -1,6 +1,6 @@
id ) ) ) ) {
- $value['label'] = 'β';
- }
- return $value;
-}, 10, 4 );
diff --git a/experimental/gpnf-parent-form-field-values-in-child-form-filters.php b/experimental/gpnf-parent-form-field-values-in-child-form-filters.php
index f2b4fe0c4..f1f9b5368 100644
--- a/experimental/gpnf-parent-form-field-values-in-child-form-filters.php
+++ b/experimental/gpnf-parent-form-field-values-in-child-form-filters.php
@@ -1,29 +1,6 @@
get_value_default();
-
- return $entry;
-}, 10, 3 );
diff --git a/experimental/gpnf-sortable-entries.php b/experimental/gpnf-sortable-entries.php
index b7af81ce7..6bebe08d1 100644
--- a/experimental/gpnf-sortable-entries.php
+++ b/experimental/gpnf-sortable-entries.php
@@ -1,380 +1,6 @@
_args = wp_parse_args( $args, array(
- 'form_id' => false,
- 'field_id' => false,
- ) );
-
- // do version check in the init to make sure if GF is going to be loaded, it is already loaded
- add_action( 'init', array( $this, 'init' ) );
-
- }
-
- /**
- * @return void
- */
- public function init() {
-
- // time for hooks
- add_filter( 'gform_pre_render', array( $this, 'load_form_script' ), 10, 2 );
- add_action( 'gform_register_init_scripts', array( $this, 'add_init_script' ), 10, 2 );
- add_filter( 'gpnf_should_use_static_value', array( $this, 'use_static_value' ), 10, 3 );
- add_action( 'wp_ajax_gpnf_update_entry_order', array( $this, 'update_entry_order' ) );
- add_action( 'wp_ajax_no_priv_gpnf_update_entry_order', array( $this, 'update_entry_order' ) );
- add_filter( 'gpnf_init_script_args', array( $this, 'add_init_script_args' ), 10, 3 );
-
- }
-
- /**
- * Filter the init script to sort the entries based on what's set in the cookie.
- *
- * @param array $args {
- *
- * @var int $formId The current form ID.
- * @var int $fieldId The field ID of the Nested Form field.
- * @var int $nestedFormId The form ID of the nested form.
- * @var string $modalTitle The title to be displayed in the modal header.
- * @var string $editModalTitle The title to be displayed in the modal header when editing an existing entry.
- * @var array $displayFields The fields which will be displayed in the Nested Forms entries view.
- * @var array $entries An array of modified entries, including only their display values.
- * @var string $ajaxUrl The URL to which AJAX requests will be posted.
- * @var int $modalWidth The default width of the modal; defaults to 700.
- * @var mixed $modalHeight The default height of the modal; defaults to 'auto' which will automatically size the modal based on its contents.
- * @var string $modalClass The class that will be attached to the modal for styling.
- * @var string $modalHeaderColor A HEX color that will be set as the default background color of the modal header.
- * @var bool $hasConditionalLogic Indicate whether the current form has conditional logic enabled.
- * @var bool $hasConditionalLogic Indicate whether the current form has conditional logic enabled.
- * @var bool $enableFocusTrap Whether the nested form should use a focus trap when open to prevent tabbing outside the nested form.
- *
- * }
- * @param GF_Field $field The current Nested Form field.
- * @param array $form The current form.
- */
- public function add_init_script_args( $args, $field, $form ) {
- if ( ! $this->is_applicable_form( $form ) || ! $this->is_applicable_field( $field->id ) ) {
- return $args;
- }
-
- $session = new GPNF_Session( $form['id'] );
- $cookie_name = $session->get_cookie_name();
-
- $cookie_raw = rgar( $_COOKIE, $cookie_name );
-
- if ( ! $cookie_raw ) {
- return $args;
- }
-
- $cookie = json_decode( stripslashes( $_COOKIE[ $cookie_name ] ), true );
- $cookie_entries = rgars( $cookie, 'nested_entries/' . $field->id );
-
- if ( empty( $cookie_entries ) ) {
- return $args;
- }
-
- // Sort $args['entries'] which contains Gravity Forms entries arrays. They contain an 'id' key.
- // $cookie_entries contains the entry IDs in the order they should be displayed.
- $sorted_entries = array();
-
- foreach ( $cookie_entries as $entry_id ) {
- foreach ( $args['entries'] as $entry ) {
- if ( $entry['id'] == $entry_id ) {
- $sorted_entries[] = $entry;
- break;
- }
- }
- }
-
- $args['entries'] = $sorted_entries;
-
- return $args;
- }
-
- /**
- * Handles updating the entry order in the GPNF session after a sort event.
- *
- * @return void
- */
- public function update_entry_order() {
- check_ajax_referer( 'gpnf_refresh_markup', 'nonce' );
-
- $form_id = rgpost( 'formId' );
- $field_id = rgpost( 'fieldId' );
- $entry_ids = rgpost( 'entryIds' );
-
- $session = new GPNF_Session( $form_id );
- $cookie_name = $session->get_cookie_name();
-
- // Most of GPNF_Session is private so we need to modify the cookie directly.
- $cookie = json_decode( stripslashes( $_COOKIE[ $cookie_name ] ), true );
-
- // If 'nested_entries' is not set for the field, just die.
- if ( ! isset( $cookie['nested_entries'][ $field_id ] ) ) {
- die();
- }
-
- // Update the nested_entries array with the new order.
- $cookie['nested_entries'][ $field_id ] = $entry_ids;
-
- // Update the cookie.
- setcookie( $cookie_name, json_encode( $cookie ), 0, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
-
- die();
- }
-
- /**
- * Use static values if sorting is enabled, otherwise a GF_Query will be used to get the child entries and
- * the sorting will not be applied.
- *
- * @param bool $should_use_static_value Should the field's value be static?
- * @param \GP_Field_Nested_Form $field The current Nested Form field.
- * @param array $entry The current entry.
- */
- public function use_static_value( $should_use_static_value, $field, $entry ) {
- if ( ! $this->is_applicable_form( $field->formId ) || ! $this->is_applicable_field( $field->id ) ) {
- return $should_use_static_value;
- }
-
- return true;
- }
-
- /**
- * @param array $form
- * @param bool $is_ajax_enabled
- *
- * @return array
- */
- public function load_form_script( $form, $is_ajax_enabled ) {
- if ( $this->is_applicable_form( $form ) && ! has_action( 'wp_footer', array( $this, 'output_script' ) ) ) {
- add_action( 'wp_footer', array( $this, 'output_script' ) );
- add_action( 'gform_preview_footer', array( $this, 'output_script' ) );
- }
-
- return $form;
- }
-
- /**
- * @return void
- */
- public function output_script() {
- ?>
-
-
-
- is_applicable_form( $form ) ) {
- return;
- }
-
- $args = array(
- 'formId' => $this->_args['form_id'],
- 'fieldId' => $this->_args['field_id'],
- );
-
- // Enqueue jQuery UI Sortable
- wp_enqueue_script( 'jquery-ui-sortable' );
-
- $script = 'new ' . __CLASS__ . '( ' . json_encode( $args ) . ' );';
- $slug = implode( '_', array( strtolower( __CLASS__ ), $this->_args['form_id'], $this->_args['field_id'] ) );
-
- GFFormDisplay::add_init_script( $form['id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script );
-
- }
-
- /**
- * @param array $form
- *
- * @return bool
- */
- public function is_applicable_form( $form ) {
-
- $form_id = isset( $form['id'] ) ? $form['id'] : $form;
-
- return empty( $this->_args['form_id'] ) || (int) $form_id == (int) $this->_args['form_id'];
- }
-
- /**
- * Check if the field is applicable for the current instance.
- *
- * @param int $field_id
- *
- * @return bool
- */
- public function is_applicable_field( $field_id ) {
- $field_ids = isset( $this->_args['field_id'] ) ? $this->_args['field_id'] : array();
-
- if ( empty( $field_ids ) ) {
- return true;
- }
-
- if ( ! is_array( $field_ids ) ) {
- $field_ids = array( $field_ids );
- }
-
- if ( in_array( $field_id, $field_ids, false ) ) {
- return true;
- }
-
- return false;
- }
-
-}
-
-# Configuration
-
-// Enable sorting for all Nested Form fields on all forms.
-new GPNF_Sortable_Entries();
-
-// Enable sorting for Nested Form field with ID 1 on form with ID 8.
-//new GPNF_Sortable_Entries( array(
-// 'form_id' => 8,
-// 'field_id' => 1,
-//) );
-
-// Enable sorting for all Nested Form fields on form with ID 8.
-//new GPNF_Sortable_Entries( array(
-// 'form_id' => 8,
-//) );
-
diff --git a/experimental/gppa-acf-populate-multiple-items-from-repeater-row.php b/experimental/gppa-acf-populate-multiple-items-from-repeater-row.php
index a1a809ec3..6cc3b79ce 100644
--- a/experimental/gppa-acf-populate-multiple-items-from-repeater-row.php
+++ b/experimental/gppa-acf-populate-multiple-items-from-repeater-row.php
@@ -1,19 +1,6 @@
{
- if (
- !$(elem)
- .parent()
- .hasClass('gfield-image-choice-wrapper-inner')
- ) {
- return;
- }
- $(elem).trigger('change.gppa');
- }
-);
\ No newline at end of file
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-click-image-choice-image-wrapper.js
+ */
\ No newline at end of file
diff --git a/experimental/gppa-conditional-logic-when-no-results.js b/experimental/gppa-conditional-logic-when-no-results.js
index 56a67e9aa..e2cc5938a 100644
--- a/experimental/gppa-conditional-logic-when-no-results.js
+++ b/experimental/gppa-conditional-logic-when-no-results.js
@@ -1,17 +1,5 @@
/**
- * Gravity Perks // Populate Anything // Conditional Logic using a field that populates with no result
- * https://gravitywiz.com/documentation/gravity-forms-populate-anything/
- *
- * 1. Install this snippet with our free Custom JavaScript plugin.
- * https://gravitywiz.com/gravity-forms-code-chest/
- */
-
-gform.addAction('gform_post_conditional_logic_field_action', function (formId, action, targetId, defaultValues, isInit) {
- // replace 26 with the field ID of the field that gets dynamically populated with No Results
- var targetValue = $( '#input_GFFORMID_26 :selected' ).val();
- if ( targetValue === 'Check' ) {
- // replace 27 with the field ID of the field that needs to be displayed with conditional logic
- $( '#field_GFFORMID_27' ).show();
- }
-});
-
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-conditional-logic-when-no-results.js
+ */
\ No newline at end of file
diff --git a/experimental/gppa-conditionally-exclude-filter-by-field-value.php b/experimental/gppa-conditionally-exclude-filter-by-field-value.php
index fc3d060a9..aa0faec8a 100644
--- a/experimental/gppa-conditionally-exclude-filter-by-field-value.php
+++ b/experimental/gppa-conditionally-exclude-filter-by-field-value.php
@@ -1,22 +1,6 @@
formId == 123 && $args['field']->id == 4 ) {
- foreach ( $query['where'] as &$where_group ) {
- foreach ( $where_group as &$where ) {
- // Update "Unsure" to the field value you wish to exempt a filter.
- if ( strpos( $where, 'Unsure' ) !== false ) {
- $where = null;
- unset( $where );
- }
- }
- $where_group = array_filter( $where_group );
- }
- $query['where'] = array_filter( $query['where'] );
- }
- return $query;
-}, 10, 2 );
diff --git a/experimental/gppa-enable-choice-values-for-gravity-view.php b/experimental/gppa-enable-choice-values-for-gravity-view.php
index 3b6525de8..9910640b1 100644
--- a/experimental/gppa-enable-choice-values-for-gravity-view.php
+++ b/experimental/gppa-enable-choice-values-for-gravity-view.php
@@ -1,26 +1,6 @@
post_type !== 'gravityview' ) {
- return $form;
- }
-
- foreach ( $form['fields'] as &$field ) {
- if ( $field->{'gppa-choices-enabled'} ) {
- $field->enableChoiceValue = true;
- }
- }
-
- return $form;
-} );
diff --git a/experimental/gppa-faceted-filters.php b/experimental/gppa-faceted-filters.php
index a731b104b..6aae0727e 100644
--- a/experimental/gppa-faceted-filters.php
+++ b/experimental/gppa-faceted-filters.php
@@ -1,39 +1,6 @@
id !== 5 || $field->formId !== 2 ) {
- return $query_builder_args;
- }
-
- if ( rgblank( $filter_value ) ) {
- array_pop( $query_builder_args['where'][ $filter_group_index ] );
- }
-
- return $query_builder_args;
-}, 10, 2 );
-
-// Disable requiring field filter values to not be empty for form ID 2
-add_filter( 'gppa_has_empty_field_filter_value_2', '__return_false' );
diff --git a/experimental/gppa-filter-entries-by-time-field.php b/experimental/gppa-filter-entries-by-time-field.php
index 1d47d4aa9..c1694e483 100644
--- a/experimental/gppa-filter-entries-by-time-field.php
+++ b/experimental/gppa-filter-entries-by-time-field.php
@@ -1,35 +1,6 @@
$time_field_id, wp_timezone() );
- if ( $choice_time > current_datetime() ) {
- $new_choices[] = $choice;
- }
- }
-
- if ( empty( $new_choices ) ) {
- $new_choices[] = array(
- 'text' => 'No items available.',
- 'value' => '',
- 'isSelected' => false,
- );
- }
-
- return $new_choices;
-}, 10, 3 );
diff --git a/experimental/gppa-firefox-select-fixer.js b/experimental/gppa-firefox-select-fixer.js
index 4067e5e70..310a49642 100644
--- a/experimental/gppa-firefox-select-fixer.js
+++ b/experimental/gppa-firefox-select-fixer.js
@@ -1,22 +1,5 @@
/**
- * Gravity Wiz // Populate Anything // Firefox Select Fixer
- * https://gravitywiz.com/
- *
- * Firefox will auto-fill fields (including select fields) with the selected option upon
- * refresh. This can be problematic with Populate Anything if fields or Live Merge Tags rely
- * upon the value of the select as Firefox does not trigger any events. To work around this, we
- * compare the values between the select field and the option with the selected attribute. If they
- * differ, we trigger a forceReload event which is an event Populate Anything listens for.
- *
- * Installation:
- * 1. Install and Activate https://gravitywiz.com/gravity-forms-code-chest/
- * 2. Navigate to Form Settings > Custom JavaScript and add this snippet.
- */
-jQuery('#gform_GFFORMID').find('select').each(function() {
- var $el = $(this);
- var $selOption = $el.find('option[selected="selected"]');
-
- if ($selOption.val() !== $el.val()) {
- $el.trigger('forceReload');
- }
-});
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-firefox-select-fixer.js
+ */
\ No newline at end of file
diff --git a/experimental/gppa-google-sheets-filter-by-date.php b/experimental/gppa-google-sheets-filter-by-date.php
index aaf623465..a2073688e 100644
--- a/experimental/gppa-google-sheets-filter-by-date.php
+++ b/experimental/gppa-google-sheets-filter-by-date.php
@@ -1,13 +1,6 @@
array( 4, 5, 6 ),
- );
-
- if ( ! function_exists( 'gravityview' ) || ! gravityview()->request->is_view() ) {
- return $display_value;
- }
-
- if ( ! is_callable( 'gp_populate_anything' ) ) {
- return $display_value;
- }
-
- remove_filter( 'gform_entry_field_value', array( gp_populate_anything(), 'entry_field_value' ), 20 );
-
- if ( ! in_array( $field->id, rgar( $targets, $field->formId, array() ) ) ) {
- $display_value = gp_populate_anything()->get_submitted_choice_label( $display_value, $field, $entry['id'] );
- }
-
- return $display_value;
-}, 19, 4 );
diff --git a/experimental/gppa-hydrate-choices-on-entry-list.php b/experimental/gppa-hydrate-choices-on-entry-list.php
index d95ecec27..3856265e0 100644
--- a/experimental/gppa-hydrate-choices-on-entry-list.php
+++ b/experimental/gppa-hydrate-choices-on-entry-list.php
@@ -1,27 +1,6 @@
hydrate_form( $form, array() );
- add_filter( 'gform_form_post_get_meta', 'gppa_hydrate_form_entry_details' );
-
- return $form;
-}
-add_filter( 'gform_form_post_get_meta', 'gppa_hydrate_form_entry_details' );
diff --git a/experimental/gppa-lmt-numbers-only-modifier.php b/experimental/gppa-lmt-numbers-only-modifier.php
index 6f7253b82..78b9ec72a 100644
--- a/experimental/gppa-lmt-numbers-only-modifier.php
+++ b/experimental/gppa-lmt-numbers-only-modifier.php
@@ -1,11 +1,6 @@
%s', $url, basename( $url ) );
- }
- return implode( ' ', $links );
-}, 10, 5 );
diff --git a/experimental/gppa-object-type-acf-options-page.php b/experimental/gppa-object-type-acf-options-page.php
index eae3eb72c..507342d21 100644
--- a/experimental/gppa-object-type-acf-options-page.php
+++ b/experimental/gppa-object-type-acf-options-page.php
@@ -1,77 +1,6 @@
'options-page',
- 'label' => esc_html__( 'Options Page', 'gp-populate-anything' ),
- 'callable' => array( $this, 'get_options_pages' ),
- );
- }
-
- public function get_options_pages() {
- return wp_list_pluck( acf_get_options_pages(), 'page_title', 'menu_slug' );
- }
-
- public function get_properties( $options_page = null ) {
- $field_groups = acf_get_field_groups(array(
- 'options_page' => $options_page,
- ));
-
- $properties = array();
-
- foreach ( $field_groups as $field_group ) {
- $fields = acf_get_fields( $field_group );
-
- foreach ( $fields as $field ) {
- $properties[ $field['name'] ] = array(
- 'value' => $field['name'],
- 'label' => $field['label'],
- 'callable' => '__return_false',
- 'orderby' => false,
- );
- }
- }
-
- return $properties;
- }
-
- public function get_object_id( $object, $primary_property_value = null ) {
- return null;
- }
-
- public function query( $args ) {
- /**
- * @var $primary_property_value string
- * @var $field_values array
- * @var $filter_groups array
- * @var $ordering array
- * @var $field GF_Field
- */
- // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
- extract( $args );
-
- $all_fields = (object) get_fields( 'option' );
-
- return array( $all_fields );
- }
-}
-
-add_action('init', function() {
- gp_populate_anything()->register_object_type( 'acf-options-page', 'GPPA_Object_Type_ACF_Options_Page' );
-});
diff --git a/experimental/gppa-object-type-json-api-with-query-params.php b/experimental/gppa-object-type-json-api-with-query-params.php
index b7b0fbe82..dbc2347e0 100644
--- a/experimental/gppa-object-type-json-api-with-query-params.php
+++ b/experimental/gppa-object-type-json-api-with-query-params.php
@@ -1,145 +1,6 @@
array(
- 'label' => esc_html__( 'Query Properties', 'gp-populate-anything' ),
- ),
- 'result_properties' => array(
- 'label' => esc_html__( 'Result Properties', 'gp-populate-anything' ),
- ),
- );
- }
-
- public function get_properties( $_ = null ) {
-
- $properties = array();
-
- /* Examples */
- $json_props = array(
- 'name',
- 'email',
- 'company',
- );
-
- foreach ( $json_props as $json_prop ) {
- $properties[ $json_prop ] = array(
- 'group' => 'result_properties',
- 'label' => $json_prop,
- 'value' => $json_prop,
- 'orderby' => false,
- 'callable' => '__return_empty_array',
- 'operators' => null,
- );
- }
-
- /* Query Properties */
- $properties['query_sales_rep'] = array(
- 'group' => 'query_properties',
- 'label' => 'Sales Rep',
- 'value' => 'sales_rep',
- 'orderby' => false,
- 'callable' => '__return_empty_array',
- 'operators' => array(
- 'is',
- ),
- );
-
- return $properties;
-
- }
-
- public function fetch( $sales_rep ) {
-
- if ( ! $sales_rep ) {
- return array();
- }
-
- $cache_key = 'sample_json_json_' . $sales_rep;
-
- if ( $data = get_transient( $cache_key ) ) {
- return $data;
- }
-
- $url = add_query_arg( array(
- 'salesRep' => $sales_rep,
- ), 'https://samplejson.com' );
-
- $results = wp_remote_get( $url );
-
- $api_response = json_decode( wp_remote_retrieve_body( $results ), true );
- set_transient( $cache_key, $api_response, DAY_IN_SECONDS );
-
- return $api_response;
-
- }
-
- public function process_filter_default( $search, $args ) {
- /**
- * @var $filter_value
- * @var $filter
- * @var $filter_group
- * @var $filter_group_index
- * @var $primary_property_value
- * @var $property
- * @var $property_id
- */
- extract( $args );
-
- $search[ $property_id ] = $filter_value;
-
- return $search;
- }
-
- public function query( $args ) {
- $search_params = $this->process_filter_groups( $args );
- $query_results = $this->fetch( rgar( $search_params, 'sales_rep' ) );
-
- return $query_results;
-
- }
-
- public function get_object_prop_value( $object, $prop ) {
- if ( ! isset ( $object[ $prop ] ) ) {
- return null;
- }
-
- return $object[ $prop ];
- }
-
-}
-
-add_action( 'init', function () {
- gp_populate_anything()->register_object_type( 'sample_json_api', 'GPPA_Object_Type_Sample_JSON_API' );
-} );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-object-type-json-api-with-query-params.php
+ */
\ No newline at end of file
diff --git a/experimental/gppa-object-type-json-api.php b/experimental/gppa-object-type-json-api.php
index 1780af3ef..f4f7aa1fe 100644
--- a/experimental/gppa-object-type-json-api.php
+++ b/experimental/gppa-object-type-json-api.php
@@ -1,201 +1,6 @@
id, array( $this, 'add_filter_hooks' ) );
- }
-
- public function add_filter_hooks() {
- add_filter( 'gppa_object_type_' . $this->id . '_filter', array( $this, 'process_filter_default' ), 10, 4 );
- }
-
- public function get_object_id( $object, $primary_property_value = null ) {
- return $object['iata'];
- }
-
- public function get_label() {
- return esc_html__( 'JSON API', 'gp-populate-anything' );
- }
-
- public function get_groups() {
- return array(
- 'columns' => array(
- 'label' => esc_html__( 'Columns', 'gp-populate-anything' ),
- ),
- );
- }
-
- public function get_properties( $_ = null ) {
-
- $properties = array();
-
- $json_props = array(
- 'iata' => 'IATA Code',
- 'lon' => 'Longitude',
- 'iso' => 'ISO Code',
- 'status' => 'Status',
- 'name' => 'Airport Name',
- 'continent' => 'Continent (Abbr)',
- 'type' => 'Type',
- 'lat' => 'Latitude',
- 'size' => 'Size',
- );
-
- foreach ( $json_props as $json_prop => $label ) {
- $properties[ $json_prop ] = array(
- 'group' => 'columns',
- 'label' => $label,
- 'value' => $json_prop,
- 'orderby' => false,
- 'callable' => '__return_empty_array',
- 'operators' => array(
- 'is',
- 'isnot',
- 'contains',
- ),
- );
- }
-
- return $properties;
-
- }
-
- public function fetch() {
-
- $cache_key = 'airports_json';
-
- if ( $data = get_transient( $cache_key ) ) {
- return $data;
- }
-
- $url = esc_url_raw( 'https://raw.githubusercontent.com/jbrooksuk/JSON-Airports/master/airports.json' );
- $results = wp_remote_get( $url );
-
- $api_response = json_decode( wp_remote_retrieve_body( $results ), true );
-
- set_transient( $cache_key, $api_response );
-
- return $api_response;
-
- }
-
- public function process_filter_default( $search, $args ) {
-
- /**
- * @var $filter_value
- * @var $filter
- * @var $filter_group
- * @var $filter_group_index
- * @var $primary_property_value
- * @var $property
- * @var $property_id
- */
- extract( $args );
-
- $search[ $filter_group_index ][] = array(
- 'property' => $property_id,
- 'operator' => $filter['operator'],
- 'value' => $filter_value,
- );
-
- return $search;
-
- }
-
- public function perform_search( $var, $search ) {
-
- switch ( $search['operator'] ) {
- case 'is':
- return ( $var[ $search['property'] ] == $search['value'] );
-
- case 'isnot':
- return ( $var[ $search['property'] ] != $search['value'] );
-
- case 'contains':
- return ( stripos( $var[ $search['property'] ], $search['value'] ) !== false );
-
- default:
- throw new Error( 'Invalid operator provided.' );
- }
-
- }
-
- /**
- * Each search group is an OR
- *
- * If everything matches in one group, we can immediately bail out as we have a positive match.
- *
- * @param $var
- * @param $search_params
- *
- * @return bool
- */
- public function search( $var, $search_params ) {
- foreach ( $search_params as $search_group ) {
- // For GPPA 2.0+, search_group may also read the numeric "limit" value, so skip for non-array values.
- if ( ! is_array( $search_group ) ) {
- continue;
- }
-
- $matches_group = true;
-
- foreach ( $search_group as $search ) {
- $matches_group = $this->perform_search( $var, $search );
-
- if ( ! $matches_group ) {
- break;
- }
- }
-
- if ( $matches_group ) {
- return true;
- }
- }
-
- return false;
- }
-
- public function query( $args ) {
-
- $search_params = $this->process_filter_groups( $args );
- $results = $this->fetch();
-
- if ( ! empty( $search_params ) ) {
- $results = array_filter( $results, function ( $var ) use ( $search_params ) {
- return $this->search( $var, $search_params );
- } );
- }
-
- $query_limit = gp_populate_anything()->get_query_limit( $this, $args['field'] );
- $query_results = array_slice( $results, 0, $query_limit );
-
- return $query_results;
-
- }
-
- public function get_object_prop_value( $object, $prop ) {
-
- if ( ! isset( $object[ $prop ] ) ) {
- return null;
- }
-
- return $object[ $prop ];
-
- }
-
-}
-
-add_action('init', function() {
- gp_populate_anything()->register_object_type( 'json-api', 'GPPA_Object_Type_JSON_API' );
-});
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-object-type-json-api.php
+ */
\ No newline at end of file
diff --git a/experimental/gppa-page-modifier.php b/experimental/gppa-page-modifier.php
index 203dc31e0..b903ef3f6 100644
--- a/experimental/gppa-page-modifier.php
+++ b/experimental/gppa-page-modifier.php
@@ -1,148 +1,6 @@
_args = wp_parse_args( $args, array() );
-
- // do version check in the init to make sure if GF is going to be loaded, it is already loaded
- add_action( 'init', array( $this, 'init' ) );
-
- }
-
- public function init() {
-
- add_filter( 'gform_pre_render', array( $this, 'load_form_script' ), 10, 2 );
- add_filter( 'gform_register_init_scripts', array( $this, 'add_init_script' ), 10, 2 );
-
- add_filter( 'gform_pre_replace_merge_tags', array( $this, 'handle_page_modifier' ), 10, 7 );
-
- }
-
- public function handle_page_modifier( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format ) {
-
- preg_match_all( '/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $text, $matches, PREG_SET_ORDER );
- if ( empty( $matches ) ) {
- return $text;
- }
-
- foreach ( $matches as $match ) {
- $modifiers = $this->parse_modifiers( rgar( $match, 4 ) );
- if ( ! rgar( $modifiers, 'page' ) ) {
- continue;
- }
- if ( rgpost( 'page-number' ) && rgpost( 'page-number' ) < $modifiers['page'] ) {
- $text = str_replace( $match[0], '', $text );
- }
- }
-
- return $text;
- }
-
- public function load_form_script( $form, $is_ajax_enabled ) {
-
- if ( ! has_action( 'wp_footer', array( $this, 'output_script' ) ) ) {
- add_action( 'wp_footer', array( $this, 'output_script' ) );
- add_action( 'gform_preview_footer', array( $this, 'output_script' ) );
- }
-
- return $form;
- }
-
- public function output_script() {
- ?>
-
-
-
- rgar( $meta, 'coupon_code' ),
- 'value' => $object['id'],
- );
- }
-
- return $choices;
-}, 10, 3 );
-
-// Update "123" to your form ID.
-add_action( 'gform_after_submission_123', function() {
- if ( is_callable( 'gf_coupons' ) ) {
- // Update "4" to the ID of your coupon-populated field.
- gf_coupons()->delete_feed( (int) rgpost( 'input_4' ) );
- }
-} );
diff --git a/experimental/gppa-populate-date-in-fields-format.php b/experimental/gppa-populate-date-in-fields-format.php
index 6033735dd..2cba52b14 100644
--- a/experimental/gppa-populate-date-in-fields-format.php
+++ b/experimental/gppa-populate-date-in-fields-format.php
@@ -1,23 +1,6 @@
get_input_type() === 'date' && $field->dateType === 'datepicker' ) {
- list( $format, $separator ) = array_pad( explode( '_', $field->dateFormat ), 2, 'slash' );
-
- $separators = array(
- 'slash' => '/',
- 'dash' => '-',
- 'dot' => '.',
- );
-
- $format = str_replace( 'y', 'Y', $format );
- $format = implode( $separators[ $separator ], str_split( $format ) );
-
- // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
- $value = date( $format, strtotime( $value ) );
- }
- return $value;
-}, 10, 2 );
diff --git a/experimental/gppa-remove-filter-groups-with-missing-values.php b/experimental/gppa-remove-filter-groups-with-missing-values.php
index 9948cc8f3..b7b6f1626 100644
--- a/experimental/gppa-remove-filter-groups-with-missing-values.php
+++ b/experimental/gppa-remove-filter-groups-with-missing-values.php
@@ -1,29 +1,6 @@
id !== 4 || $field->formId !== 123 ) {
- return $query_builder_args;
- }
-
- if ( ! $filter_value ) {
- unset( $query_builder_args['where'][ $filter_group_index ] );
- }
-
- return $query_builder_args;
-}, 11, 2 );
diff --git a/experimental/gppa-select-all-checkboxes.js b/experimental/gppa-select-all-checkboxes.js
index 80c2ec337..c00813486 100644
--- a/experimental/gppa-select-all-checkboxes.js
+++ b/experimental/gppa-select-all-checkboxes.js
@@ -1,26 +1,5 @@
/**
- * Gravity Perks // GP Populate Anything // Automatically Check Checkboxes
- * http://gravitywiz.com/documentation/gravity-forms-populate-anything
- *
- * Instructions:
- * 1. Install our free Custom Javascript for Gravity Forms plugin.
- * Download the plugin here: https://gravitywiz.com/gravity-forms-code-chest/
- * 2. Copy and paste the snippet into the editor of the Custom Javascript for Gravity Forms plugin.
- *. 3. This snippet is meant to be a starting point. You will need to update the selectors accordingly
- */
-
-// Select all choices for field ID 1 on initial load
-jQuery('#button_1_select_all').each(function() {
- gformToggleCheckboxes(this);
-});
-
-// Select all choices for field ID 2 whenever its choices are repopulated dynamically
-jQuery(document).on('gppa_updated_batch_fields', function(event, formId, fieldIds) {
- if (formId != GFFORMID) {
- return;
- }
-
- jQuery('#button_2_select_all').each(function() {
- gformToggleCheckboxes(this);
- });
-})
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-select-all-checkboxes.js
+ */
\ No newline at end of file
diff --git a/experimental/gppa-simply-schedule-appointments-refresh-lmts.js b/experimental/gppa-simply-schedule-appointments-refresh-lmts.js
index 99adbd1ab..7fb561970 100644
--- a/experimental/gppa-simply-schedule-appointments-refresh-lmts.js
+++ b/experimental/gppa-simply-schedule-appointments-refresh-lmts.js
@@ -1,29 +1,5 @@
/**
- * --- STOP! ---
- *
- * This snippet is deprecated and no longer required if you are using the latest version of Simply Schedule Appointments.
- */
-/**
- * Gravity Perks // GP Populate Anything // Refresh Live Merge Tags pointing to Simply Schedule Appointments field
- * https://gravitywiz.com/documentation/gravity-forms-populate-anything
- *
- * By default, if using a Simply Schedule Appointments field and you select an appointment time, any Live Merge Tags
- * referencing the SSA field will not automatically update due to SSA not firing a change event on the hidden input.
- *
- * This snippet works around the issue by utilizing a MutationObserver that watches the hidden input's value attribute.
- *
- * Instructions:
- *
- * 1. Install this snippet with our free Custom JavaScript plugin.
- * https://gravitywiz.com/gravity-forms-code-chest/
- */
-var observer = new MutationObserver( function ( mutationList ) {
- mutationList.forEach( function () {
- window.gppaForms[GFFORMID].bulkBatchedAjax( [] );
- } );
-} );
-
-observer.observe( document.querySelector( '.ssa_appointment_form_field_appointment_id' ), {
- attributeFilter: ['value'],
- attributeOldValue: true
-} );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-populate-anything/gppa-simply-schedule-appointments-refresh-lmts.js
+ */
\ No newline at end of file
diff --git a/experimental/gppa-wc-country-to-gf-address-field.php b/experimental/gppa-wc-country-to-gf-address-field.php
index 063f8c9d8..6b01d5ca1 100644
--- a/experimental/gppa-wc-country-to-gf-address-field.php
+++ b/experimental/gppa-wc-country-to-gf-address-field.php
@@ -1,13 +1,6 @@
get_default_countries();
- $template_value = rgar( $countries, $template_value, $template_value );
- }
- return $template_value;
-}, 10, 8 );
diff --git a/experimental/gppa-woo-commerce-lmt.php b/experimental/gppa-woo-commerce-lmt.php
index e5bbdccc9..484196be5 100644
--- a/experimental/gppa-woo-commerce-lmt.php
+++ b/experimental/gppa-woo-commerce-lmt.php
@@ -1,28 +1,6 @@
cart->get_cart() as $cart_item_key => $cart_item ) {
- add_filter( 'gform_pre_render', function( $form ) use ( $cart_item ) {
- $gravity_form_data = $cart_item['_gravity_form_data'];
- $form_meta = RGFormsModel::get_form_meta( $gravity_form_data['id'] );
- foreach ( $form_meta['fields'] as $field_index => $field ) {
- if ( ! $field['choices'] ) {
- continue;
- }
-
- foreach ( $field['choices'] as $choice_index => $choice ) {
- $choice['text'] = gp_populate_anything()->live_merge_tags->replace_live_merge_tags( $choice['text'], $form_meta, $cart_item['_gravity_form_lead'] );
-
- $form_meta['fields'][ $field_index ]->choices[ $choice_index ] = $choice;
- }
- }
- return $form;
- });
- }
-});
diff --git a/experimental/gprf-reload-globally.js b/experimental/gprf-reload-globally.js
index 891c734cf..8987ec8aa 100644
--- a/experimental/gprf-reload-globally.js
+++ b/experimental/gprf-reload-globally.js
@@ -1,8 +1,5 @@
/**
- * By default, GPRF scopes it's replacement to a static container. If the user is including multiple instances of the same form
- * on the same page (which GF does not support by default), all instances of the form will be submitted but only the submitted
- * instance will be reloaded. Use this snippet to reload all forms of the same ID.
- */
-gform.addFilter( 'gprf_replacing_elem', function( $replacingElem, formId ) {
- return jQuery( '#gform_confirmation_wrapper_' + formId + ', .gform_confirmation_message_' + formId + ', #gform_wrapper_' + formId );
-} );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-reload-form/gprf-reload-globally.js
+ */
\ No newline at end of file
diff --git a/experimental/gpuid-belgium-cipher.php b/experimental/gpuid-belgium-cipher.php
index 05e89ee1e..f1ba56b75 100644
--- a/experimental/gpuid-belgium-cipher.php
+++ b/experimental/gpuid-belgium-cipher.php
@@ -1,41 +1,6 @@
inputName, $key ) === false ) {
- continue;
- }
-
- $source_field_id = (int) str_replace( $key . '_', '', $field->inputName );
- if ( ! $source_field_id ) {
- continue;
- }
-
- $value = (int) rgar( $entry, $source_field_id );
- $mod97 = $value % 97;
- $last_two = str_pad( $mod97 ? $mod97 : '97', 2, '0', STR_PAD_LEFT );
- $combined = $value . $last_two;
- $code = '+++' . substr( $combined, 0, 3 ) . '/' . substr( $combined, 3, 4 ) . '/' . substr( $combined, 7, 5 ) . '+++';
-
- $entry[ $field->id ] = $code;
- GFAPI::update_entry_field( $entry['id'], $field->id, $code );
- }
-
- return $entry;
-}, 9, 2 );
diff --git a/experimental/gpuid-clear-index.php b/experimental/gpuid-clear-index.php
index 7645f404e..110989411 100644
--- a/experimental/gpuid-clear-index.php
+++ b/experimental/gpuid-clear-index.php
@@ -1,54 +1,6 @@
prefix}gpui_sequence";
- $index_results = $wpdb->get_results( "SHOW INDEX FROM `{$wpdb->prefix}gpui_sequence`;" );
- $indexes = array();
- foreach ( $index_results as $index_result ) {
- $indexes[ $index_result->Key_name ] = true;
- }
- $indexes = array_keys( $indexes );
- // Clear all indexes
- foreach ( $indexes as $index ) {
- // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
- $wpdb->query( "DROP INDEX `{$index}` ON `{$wpdb->prefix}gpui_sequence`;" );
- }
- // All done, redirect
- wp_redirect( '/wp-admin/plugins.php?plugin_status=recently_activated&guid_clear_indexes_success=true' );
- exit();
-} );
-
-add_action( 'admin_notices', function ( $messages ) {
- if ( rgget( 'guid_clear_indexes_error_active' ) ) :
- ?>
-
-
Please disable GP Unique ID before attempting to clear the indexes.
-
-
-
-
GP Unique ID table indexes were cleared. Please de-activate this snippet and enable GPUID again.
-
-
-
-
GP Unique ID Clear Indexes snippet is active. If you have already cleared the indexes please remove it.
- Otherwise you can start clearing indexes here.
-
- lines_limit ) {
- var extraLine = lines.pop();
- lines[ lines.length - 1 ] += extraLine;
- }
- $( this ).val( lines.join( '\n' ) );
-} );
+/**
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gp-word-count/gpwc-limit-line-breaks.js
+ */
\ No newline at end of file
diff --git a/experimental/gspc-remove-wc-product-from-entry-order-summary.php b/experimental/gspc-remove-wc-product-from-entry-order-summary.php
index 2bf009619..afd1afbe3 100644
--- a/experimental/gspc-remove-wc-product-from-entry-order-summary.php
+++ b/experimental/gspc-remove-wc-product-from-entry-order-summary.php
@@ -1,11 +1,6 @@
wc_product_form_display, 'inject_base_price_product_field_gppa_ajax' ) );
- remove_filter( 'gform_product_info', array( gs_product_configurator()->wc_product_form_display, 'inject_base_price_into_product_info' ) );
- }
-}, 16 );
diff --git a/experimental/gspc-set-subscription-length-by-field-value.php b/experimental/gspc-set-subscription-length-by-field-value.php
index af437ddca..1acdd7559 100644
--- a/experimental/gspc-set-subscription-length-by-field-value.php
+++ b/experimental/gspc-set-subscription-length-by-field-value.php
@@ -1,43 +1,6 @@
4,
- // Repeat that process for as many form/field pairs as you'd like.
- 124 => 5,
- );
-
- $subscription_items = $subscription->get_items();
-
- foreach ( $subscription_items as $subscription_item ) {
-
- $gspc_order_item = new GS_Product_Configurator\WC_Order_Item( $subscription_item );
- $entries = $gspc_order_item->get_entries();
- if ( empty( $entries ) ) {
- continue;
- }
-
- $form_id = rgars( $entries, '0/form_id' );
- $sub_length_field_id = rgar( $form_field_map, $form_id );
- if ( ! $sub_length_field_id ) {
- continue;
- }
-
- $sub_length = rgars( $entries, "0/{$sub_length_field_id}" );
-
- // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
- $sub_end_date = date( 'Y-m-d H:i:s', strtotime( "+{$sub_length} months" ) );
-
- $subscription->update_dates( array( 'end' => $sub_end_date ) );
-
- return;
-
- }
-
-} );
diff --git a/experimental/gw-add-attachments-by-field.php b/experimental/gw-add-attachments-by-field.php
index 98c03c066..e855005df 100644
--- a/experimental/gw-add-attachments-by-field.php
+++ b/experimental/gw-add-attachments-by-field.php
@@ -1,54 +1,6 @@
id );
-
- if ( empty( $url ) ) {
- return $notification;
- }
-
- if ( $field->multipleFiles ) {
- $uploaded_files = json_decode( stripslashes( $url ), true );
- foreach ( $uploaded_files as $uploaded_file ) {
- $attachment = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $uploaded_file );
- $notification['attachments'][] = $attachment;
- }
- } else {
- $attachment = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $url );
- $notification['attachments'][] = $attachment;
- }
-
- return $notification;
-}
diff --git a/experimental/gw-add-custom-footer-button.php b/experimental/gw-add-custom-footer-button.php
index 1b7d8aa9c..db8dacec6 100644
--- a/experimental/gw-add-custom-footer-button.php
+++ b/experimental/gw-add-custom-footer-button.php
@@ -1,9 +1,6 @@
'button' ), 'My Custom Button', 'gform_previous_button', 'My Custom Button', false );
-}, 10, 2 );
diff --git a/experimental/gw-auto-prepend-https.js b/experimental/gw-auto-prepend-https.js
index 8840191c1..5341bc2b6 100644
--- a/experimental/gw-auto-prepend-https.js
+++ b/experimental/gw-auto-prepend-https.js
@@ -1,20 +1,5 @@
/**
- * Gravity Wiz // Gravity Forms // Auto-prepend HTTPS to URLs
- * https://gravitywiz.com/
- *
- * Auto-prepend "https://" to URLs in Website fields.
- */
-// Update "1" to your field ID.
-$( '#input_GFFORMID_1' )
- .on( 'focus', function() {
- if ( $( this ).val() === '' ) {
- $( this ).val( 'https://' );
- }
- } )
- .on( 'keyup', function() {
- if ( $( this ).val() === 'https:/' ) {
- $( this ).val( 'https://' );
- } else if ( $( this ).val().indexOf( 'https://' ) !== 0 ) {
- $( this ).val( 'https://' + $( this ).val() );
- }
- } );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-auto-prepend-https.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-capture-file-extension.php b/experimental/gw-capture-file-extension.php
index f942ae615..fe1565e84 100644
--- a/experimental/gw-capture-file-extension.php
+++ b/experimental/gw-capture-file-extension.php
@@ -1,26 +1,6 @@
Custom JavaScript and add this snippet.
- */
-var uploadFieldId = 4;
-var targetFieldId = 5;
-var template = '{filename}';
-
-var $uploadField = $( '#input_GFFORMID_{0}'.gformFormat( uploadFieldId ) );
-var $targetField = $( '#input_GFFORMID_{0}'.gformFormat( targetFieldId ) );
-
-$uploadField.on( 'change', function() {
- var filename = $( this ).val().split("\\").pop();
- $targetField.val( template.replace( '{filename}', filename ) ).change();
-} );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-capture-filename.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-capture-list-field-column-as-comma-delimited-list.php b/experimental/gw-capture-list-field-column-as-comma-delimited-list.php
index bf1b1a45a..367090b2e 100644
--- a/experimental/gw-capture-list-field-column-as-comma-delimited-list.php
+++ b/experimental/gw-capture-list-field-column-as-comma-delimited-list.php
@@ -1,30 +1,6 @@
create_list_array( $_POST[ "input_{$list_field_id}" ] );
- $values = array();
-
- if ( is_array( $rows[0] ) ) {
- foreach ( $rows as $row ) {
- $row = array_values( $row );
- $values[] = $row[ $column_number - 1 ];
- }
- } else {
- foreach ( $rows as $row ) {
- $values[] = $row;
- }
- }
-
- $_POST[ "input_{$target_field_id}" ] = implode( ',', $values );
-
-} );
diff --git a/experimental/gw-checkbox-to-list-field.js b/experimental/gw-checkbox-to-list-field.js
index c191fd813..00ed52ec1 100644
--- a/experimental/gw-checkbox-to-list-field.js
+++ b/experimental/gw-checkbox-to-list-field.js
@@ -1,54 +1,5 @@
/**
- * Gravity Wiz // Gravity Forms // Checkbox to List Field
- * https://gravitywiz.com/
- *
- * When a Checkbox is clicked, add a new row to a List field with the checkbox value as the value in the first column
- * of the newly added row.
- */
-// Update "1" to your Checkbox field ID.
-var $checkboxField = $( '#field_GFFORMID_1' );
-
-// // Update "2" to your List field ID.
-var $listField = $( '#field_GFFORMID_2' );
-
-$checkboxField.find( 'input' ).on( 'click', function() {
- if ( $( this ).is( ':checked' ) ) {
- addRow( $listField, $( this ).val() );
- } else {
- removeRow( $listField, $( this ).val() );
- }
-} );
-
-function removeRow( $listField, value ) {
- var rowCount = $listField.find( '.gfield_list_group' ).length;
- if ( rowCount === 1 ) {
- $listField.find( 'input' ).val( '' );
- } else {
- $listField
- .find( '.gfield_list_group_item:first-child' )
- .find( 'input' )
- .each( function() {
- if ( $( this ).val() === value ) {
- $( this )
- .parents( '.gfield_list_group' )
- .find( '.delete_list_item' )
- .click();
- }
- } );
- }
-}
-
-function addRow( $listField, value ) {
- var rowCount = $listField.find( '.gfield_list_group' ).length;
- var $singleRowNoValue = rowCount && $listField.find( 'input' ).first().val() === '';
- if ( ! $singleRowNoValue ) {
- $listField
- .find( '.gfield_list_group:last-child' )
- .find( '.add_list_item' )
- .click();
- }
- $listField
- .find( '.gfield_list_group:last-child' )
- .find( '.gfield_list_group_item:first-child input' )
- .val( value );
-}
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-checkbox-to-list-field.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-count-sundays.js b/experimental/gw-count-sundays.js
index b6d7ab481..c366d2e31 100644
--- a/experimental/gw-count-sundays.js
+++ b/experimental/gw-count-sundays.js
@@ -1,59 +1,5 @@
/**
- * Gravity Wiz // Gravity Forms // Count Number of Sundays Between Two Dates
- * https://gravitywiz.com/path/to/article/
- *
- * Use this snippet to count the number of Sundays between a start and end date, including those dates themselves.
- *
- * Note: This is a JavaScript snippet and there is no server-side validation to ensure that the calculated value
- * has not been tampered with prior to submission.
- *
- * Instructions:
- *
- * 1. Install this snippet with our free Custom JavaScript plugin.
- * https://gravitywiz.com/gravity-forms-code-chest/
- *
- * 2. Update the required field IDs to match your own by following the inline instructions.
- */
-// Update "1" with the ID of your start Date field.
-const startDateField = document.getElementById('input_GFFORMID_1');
-
-// Update "2" with the ID of your end Date field.
-const endDateField = document.getElementById('input_GFFORMID_2');
-
-// Update "3" with the ID of your Sunday count field.
-const countField = document.getElementById('input_GFFORMID_3');
-
-function calculateSundays() {
- const startDate = new Date(startDateField.value);
- const endDate = new Date(endDateField.value);
- let sundays = 0;
-
- // Loop through the dates and count Sundays
- while (startDate <= endDate) {
- if (startDate.getDay() === 0) { // Sunday is represented by 0 in JavaScript's getDay() function
- sundays++;
- }
- startDate.setDate(startDate.getDate() + 1); // Move to the next day
- }
-
- return sundays;
-}
-function updateSundayCount() {
- countField.value = calculateSundays();
-}
-
-// Update Sunday count each time a date is manually entered.
-startDateField.addEventListener('change', updateSundayCount);
-endDateField.addEventListener('change', updateSundayCount);
-
-// Update Sunday count each time a date is selected via the Datepicker.
-gform.addFilter( 'gform_datepicker_options_pre_init', function( optionsObj, formId, fieldId ) {
- var origOnSelect = optionsObj.onSelect;
- optionsObj.onSelect = function( value, dpObject ) {
- if ( origOnSelect ) {
- origOnSelect();
- }
- updateSundayCount()
- }
- return optionsObj;
-} );
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-count-sundays.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-crazy-snippet.php b/experimental/gw-crazy-snippet.php
index 427b73b74..0cb5dcb87 100644
--- a/experimental/gw-crazy-snippet.php
+++ b/experimental/gw-crazy-snippet.php
@@ -1,4 +1,6 @@
array(
- array(
- 'key' => 'created_by',
- 'value' => $deleted_user_id,
- ),
- ),
- );
-
- $paging = array(
- 'offset' => 0,
- 'page_size' => 300,
- );
-
- $entries = GFAPI::get_entries( 0, $search, null, $paging );
-
- foreach ( $entries as $entry ) {
- if ( $reassigned_user_id ) {
- GFAPI::update_entry_property( $entry['id'], 'created_by', $reassigned_user_id );
- } else {
- GFAPI::delete_entry( $entry['id'] );
- }
- }
-
-}, 10, 2 );
diff --git a/experimental/gw-field-ids-in-editor-labels.php b/experimental/gw-field-ids-in-editor-labels.php
index 11a3bde7b..ffb60b1a0 100644
--- a/experimental/gw-field-ids-in-editor-labels.php
+++ b/experimental/gw-field-ids-in-editor-labels.php
@@ -1,39 +1,6 @@
- .gw-inline-field-id {
- background-color: #ecedf8;
- border: 1px solid #d5d7e9;
- border-radius: 40px;
- font-size: 0.6875rem;
- font-weight: 600;
- padding: 0.1125rem 0.4625rem;
- margin-bottom: 0.5rem;
- display: inline-block;
- vertical-align: middle;
- }
- ';
- $_gw_inline_field_id_style = true;
- }
-
- $search = '<\/label>|<\/legend>';
- $replace = sprintf( '\0 ID: %d', $field->id );
- $content = preg_replace( "/$search/", $replace, $content, 1 );
-
- return $content;
-}, 10, 2 );
diff --git a/experimental/gw-force-greater-end-time.js b/experimental/gw-force-greater-end-time.js
index f64877d9d..24037ca58 100644
--- a/experimental/gw-force-greater-end-time.js
+++ b/experimental/gw-force-greater-end-time.js
@@ -1,114 +1,5 @@
/**
- * Gravity Wiz // Gravity Forms // Force Greater End Time.
- * https://gravitywiz.com/
- *
- * Force the user to enter an end time greater than the start time.
- *
- * Instructions:
- *
- * 1. Install this snippet with our free Custom JavaScript plugin.
- * https://gravitywiz.com/gravity-forms-code-chest/
- * 2. Configure based on the inline instructions.
- */
-
-// Update "3" to the Start Date Field ID.
-var startDateId = 1;
-// Update "4" to the End Date Field ID.
-var endDateId = 3;
-// Update "5" to the Start Time Field ID.
-var startTimeFieldId = 4;
-// Update "6" to the End Date Field ID.
-var endTimeFieldId = 5;
-
-var selectors = [
- '#input_'+ GFFORMID + '_' + startDateId,
- '#input_'+ GFFORMID + '_' + endDateId,
- '#field_' + GFFORMID + '_' + startTimeFieldId,
- '#field_' + GFFORMID + '_' + endTimeFieldId
-];
-
-$( selectors.join( ', ' ) ).change( function(){
- evaluateTimes();
-} );
-
-function evaluateTimes() {
-
- var startTimestamp = getTimestamp( startDateId, startTimeFieldId );
- var endTimestamp = getTimestamp( endDateId, endTimeFieldId );
-
- if ( ! startTimestamp || ! endTimestamp ) {
- return false;
- }
-
- var difference = endTimestamp - startTimestamp;
- if ( difference <= 60 * 60 * 1000 ) {
- setEndTime( startTimestamp );
- }
-
-}
-
-function getTimestamp ( dateFieldId, timeFieldId ){
-
- var inputs = $( '#field_' + GFFORMID + '_' + timeFieldId ).find('input, select' );
- var hour = inputs.eq( 0 ).val();
- var min = inputs.eq( 1 ).val();
- var ampm = inputs.eq( 2 ).val();
- // @todo This only supports datepickers.
- var datetime = new Date( $( '#input_'+ GFFORMID + '_' + dateFieldId ).val() );
-
- if ( inputs.eq( 0 ).val() =='' || inputs.eq( 1 ).val() == '' ){
- return false
- }
-
- if ( inputs.eq( 2 ).length ) {
- if ( ampm.toLowerCase() === 'pm' ) {
- datetime.setHours( parseInt( hour ) + ( hour === '12' ? 0 : 12 ) );
- }else if ( ampm.toLowerCase() === 'am') {
- datetime.setHours( parseInt( hour ) - ( hour === '12' ? 12 : 0 ) );
- }
- else{
- datetime.setHours( parseInt( hour ) );
- }
- } else {
- datetime.setHours( parseInt( hour ) );
- }
-
- datetime.setMinutes( min );
-
- return datetime.getTime();
-}
-
-function setEndTime ( startTimestamp ) {
-
- var endDateTime = new Date( startTimestamp );
- var endInputs = $( '#field_' + GFFORMID + '_' + endTimeFieldId ).find( 'input, select' );
-
- var hours = isNaN( endDateTime.getHours() ) ? '' : endDateTime.getHours() + 1,
- minutes = isNaN( endDateTime.getMinutes() ) ? '' : endDateTime.getMinutes(),
- hasAMPM = endInputs.length === 3,
- isPM = false;
-
- if ( hasAMPM ) {
- if ( hours === 0 ) {
- hours = 12;
- } else if ( hours > 12 ) {
- hours -= 12;
- isPM = true;
- } else if ( hours == 12 ) {
- // for 12 PM, the PM display should update
- isPM = true;
- }
-
- }
-
- endInputs.eq( 0 ).val( ( '0' + hours ).slice( -2 ) );
- endInputs.eq( 1 ).val( ( '0' + minutes ).slice( -2 ) );
-
- if ( hasAMPM ) {
- if ( isPM ) {
- endInputs.eq( 2 ).find( 'option:last' ).prop( 'selected', true );
- } else {
- endInputs.eq( 2 ).find( 'option:first' ).prop( 'selected', true );
- }
- }
-}
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-force-greater-end-time.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-force-numeric-keyboard-on-mobile.php b/experimental/gw-force-numeric-keyboard-on-mobile.php
index 7fdaab0c6..45edc022f 100644
--- a/experimental/gw-force-numeric-keyboard-on-mobile.php
+++ b/experimental/gw-force-numeric-keyboard-on-mobile.php
@@ -1,18 +1,6 @@
get_input_type() === 'number' ) {
- $content = preg_replace( '/type=\'(number|text)\'/', 'type=\'tel\'', $content );
- }
- return $content;
-}, 10, 2 );
diff --git a/experimental/gw-gfapc-map-multiple-fields-to-taxonomy.php b/experimental/gw-gfapc-map-multiple-fields-to-taxonomy.php
index 24fbf3b23..6ee0ca9a0 100644
--- a/experimental/gw-gfapc-map-multiple-fields-to-taxonomy.php
+++ b/experimental/gw-gfapc-map-multiple-fields-to-taxonomy.php
@@ -1,29 +1,6 @@
_args = wp_parse_args( $args, array(
- 'custom_fields' => array(),
- ) );
-
- // do version check in the init to make sure if GF is going to be loaded, it is already loaded
- add_action( 'init', array( $this, 'init' ) );
-
- }
-
- public function init() {
-
- add_action( 'gform_post_data', array( $this, 'stash_post_custom_fields_data' ) );
- add_action( 'gform_after_create_post', array( $this, 'populate_custom_fields' ) );
-
- }
-
- public function stash_post_custom_fields_data( $post_data ) {
- $this->post_custom_fields = $post_data['post_custom_fields'];
- }
-
- public function populate_custom_fields( $post_id ) {
-
- foreach ( $this->_args['custom_fields'] as $custom_field ) {
- delete_post_meta( $post_id, $custom_field );
- $value = json_decode( rgar( $this->post_custom_fields, $custom_field ) );
- update_post_meta( $post_id, $custom_field, $value );
- }
-
- }
-
-}
-
-# Configuration
-
-new GW_GF_To_WP_Job_Manager( array(
- 'custom_fields' => array( '_job_core_skills' ),
-) );
diff --git a/experimental/gw-live-field-values-post-submission.php b/experimental/gw-live-field-values-post-submission.php
index 7a41cdfc4..5b7913b66 100644
--- a/experimental/gw-live-field-values-post-submission.php
+++ b/experimental/gw-live-field-values-post-submission.php
@@ -1,36 +1,6 @@
format( 'Y' ) - (int) $date_created->format( 'Y' ) + $years_of_exp;
- $values[ $entry['id'] ] = $calc_years_of_exp;
-
- $processing = false;
-
- return $calc_years_of_exp;
-}, 10, 2 );
diff --git a/experimental/gw-minimum-file-count.php b/experimental/gw-minimum-file-count.php
index 1ddcbeb09..f28a96947 100644
--- a/experimental/gw-minimum-file-count.php
+++ b/experimental/gw-minimum-file-count.php
@@ -1,43 +1,6 @@
id !== $field_id_to_validate ) {
- continue;
- }
-
- if ( empty( GFFormsModel::$uploaded_files[ $form['id'] ] ) ) {
- continue;
- }
-
- $input_name = 'input_' . $field->id;
- $uploaded_files = GFFormsModel::$uploaded_files[ $form['id'] ][ $input_name ];
-
- if ( count( $uploaded_files ) < $minimum_number_of_files ) {
- $field['failed_validation'] = true;
- $field['validation_message'] = $validation_message;
- $result['is_valid'] = false;
- }
- }
-
- $result['form'] = $form;
-
- return $result;
-} );
diff --git a/experimental/gw-prevent-duplicate-drop-down-selections.js b/experimental/gw-prevent-duplicate-drop-down-selections.js
index 1c4b9cbdf..1fb904674 100644
--- a/experimental/gw-prevent-duplicate-drop-down-selections.js
+++ b/experimental/gw-prevent-duplicate-drop-down-selections.js
@@ -1,5 +1,5 @@
/**
- * This snippet has evolved! π¦
- * Find the new version of this snippet here:
- * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-prevent-duplicate-selections.js
- */
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-prevent-duplicate-drop-down-selections.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-prevent-non-numeric-chars.js b/experimental/gw-prevent-non-numeric-chars.js
index 4bed0a30a..494b5c7ea 100644
--- a/experimental/gw-prevent-non-numeric-chars.js
+++ b/experimental/gw-prevent-non-numeric-chars.js
@@ -1,21 +1,5 @@
/**
- * Gravity Wiz // Gravity Forms // Prevent Non-numeric Characters in Input
- * https://gravitywiz.com/
- *
- * Based on solution provided here: https://stackoverflow.com/a/15729184/227711
- *
- * Instructions:
- *
- * 1. Install this snippet with our free Custom JavaScript plugin.
- * https://gravitywiz.com/gravity-forms-code-chest/
- * 2. Configure snippet for your form based on inline instructions.
- */
-// Update "1" to your field ID.
-document.getElementById( 'input_GFFORMID_1' ).onkeypress = function( e ) {
- e = e || window.event;
- var charCode = ( typeof e.which == 'undefined' ) ? e.keyCode : e.which;
- var charStr = String.fromCharCode( charCode );
- if ( ! /\d/.test( charStr ) ) {
- return false;
- }
-};
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-prevent-non-numeric-chars.js
+ */
\ No newline at end of file
diff --git a/experimental/gw-preview-mode-tweaks.php b/experimental/gw-preview-mode-tweaks.php
index c7e0f65dd..9519eeca4 100644
--- a/experimental/gw-preview-mode-tweaks.php
+++ b/experimental/gw-preview-mode-tweaks.php
@@ -1,53 +1,6 @@
-
- type !== 'address' ) {
- return $result;
- }
-
- $street = trim( rgar( $value, $field->id . '.1' ) );
-
- // Look for a standalone number at the beginning or end of the Address Line 1 value
- if ( ! preg_match( '/^\d+\s+/', $street ) && ! preg_match( '/\s+\d+$/', $street ) ) {
- $result['is_valid'] = false;
- $result['message'] = empty( $field->errorMessage ) ? 'Please provide an address with a house number.' : $field->errorMessage;
-
- $field->set_input_validation_state( 1, false );
- }
-
- return $result;
-}, 10, 4 );
diff --git a/experimental/gw-rich-text-html-fields.php b/experimental/gw-rich-text-html-fields.php
index 7d5d0b563..6fe38bf49 100644
--- a/experimental/gw-rich-text-html-fields.php
+++ b/experimental/gw-rich-text-html-fields.php
@@ -1,76 +1,6 @@
-
-
-
-
-
-
-
- id . '.6' );
- if ( $country == $country_to_check ) {
- if ( $result['is_valid'] ) {
- $zip_value = rgar( $value, $field->id . '.5' );
- if ( ! preg_match( $regex_pattern, strtoupper( $zip_value ) ) ) {
- $result['is_valid'] = false;
- $result['message'] = 'Please enter a valid UK postcode.';
- }
- }
- }
- return $result;
-}
diff --git a/experimental/gw-value-counter.js b/experimental/gw-value-counter.js
index 9a18de034..d8e97397b 100644
--- a/experimental/gw-value-counter.js
+++ b/experimental/gw-value-counter.js
@@ -1,25 +1,5 @@
/**
- * Gravity Wiz // Gravity Forms // Value Counter
- * https://gravitywiz.com/
- *
- * Count the number of times a given value has been selected in a group of fields and populate that number into a Number field.
- * This snippet is designed to target a Number field and count selected values in Checkbox and Radio Button fields.
- *
- * This snippet works best with our free [GF Custom Javascript](https://gravitywiz.com/gravity-forms-code-chest/) plugin.
- */
-// Replace the "1", "2" and "3" with field IDs of fields that should have their selected values counted. If you are using the
-var $radios = jQuery( '#field_GFFORMID_1, #field_GFFORMID_2, #field_GFFORMID_3' );
-// Replace "4" with the ID of the Number field in which the count should be populated.
-var $target = jQuery( '#field_GFFORMID_4' );
-// Replace "a" with the value you wish to count if selected.
-var countValue = 'a';
-
-function gwRecountValues() {
- $target.find( 'input' ).val( $radios.find( 'input:checked[value="' + countValue + '"]' ).length );
-}
-
-$radios.on( 'change', function() {
- gwRecountValues();
-} );
-
-gwRecountValues();
+ * We're no longer using the experimental folder for experimental snippets. π§
+ * You can now find the snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-value-counter.js
+ */
\ No newline at end of file
diff --git a/gp-date-time-calculator/gpdtc-calculated-input-value.php b/gp-date-time-calculator/gpdtc-calculated-input-value.php
new file mode 100644
index 000000000..6ccb28e2a
--- /dev/null
+++ b/gp-date-time-calculator/gpdtc-calculated-input-value.php
@@ -0,0 +1,8 @@
+_args = wp_parse_args( $args, array(
+ 'form_id' => false,
+ ) );
+
+ add_action( 'init', array( $this, 'add_hooks' ), 16 ); // Wait for all add-ons
+ }
+
+ public function add_hooks() {
+ if ( ! function_exists( 'gp_disable_entry_creation' ) ) {
+ return;
+ }
+
+ add_filter( 'gpdec_should_delete_entry_' . $this->_args['form_id'], '__return_false' );
+ add_action( 'gfpdf_post_generate_and_save_pdf_notification', array( $this, 'post_generate_and_save' ), 50, 4 );
+ add_action( 'shutdown', array( $this, 'shutdown' ) );
+ }
+
+ public function post_generate_and_save( $form, $entry, $settings, $notifications ) {
+ if ( $form['id'] != $this->_args['form_id'] ) {
+ return;
+ }
+
+ $this->deletion_queue[] = $entry;
+ }
+
+ public function shutdown() {
+ if ( empty( $this->deletion_queue ) ) {
+ return;
+ }
+
+ foreach ( $this->deletion_queue as $entry ) {
+ gp_disable_entry_creation()->delete_form_entry( $entry );
+ }
+ }
+}
+
+/*
+ * Basic Usage
+ *
+ * Uncomment the lines below (remove the preceding // on each line) and adjust the form ID accordingly.
+ * You may also duplicate the class instantiation if this is required for more than one form.
+ */
+
+//new GPDEC_GFPDF_Delayed_Deletion( array(
+// 'form_id' => 3,
+//) );
diff --git a/gp-inventory/gpi-auto-selections.php b/gp-inventory/gpi-auto-selections.php
new file mode 100644
index 000000000..b3c0ef12a
--- /dev/null
+++ b/gp-inventory/gpi-auto-selections.php
@@ -0,0 +1,73 @@
+choices;
+
+ foreach ( $choices as &$choice ) {
+ if ( $source_field->enablePrice ) {
+ $price = rgempty( 'price', $choice ) ? 0 : GFCommon::to_number( rgar( $choice, 'price' ) );
+ $choice['value'] .= '|' . $price;
+ }
+ }
+
+ return array(
+ 'type' => 'select',
+ 'choices' => $choices,
+ );
+}, 10, 5 );
+
+add_filter( "gform_pre_process_{$gpias_form_id}", function( $form ) {
+ global $gpias_list_field_id, $gpias_product_field_id;
+
+ $list_field = GFAPI::get_field( $form, $gpias_list_field_id );
+ $booths = $list_field->get_value_submission( array() );
+
+ foreach ( $form['fields'] as $field ) {
+
+ if ( $field->id != $gpias_product_field_id ) {
+ continue;
+ }
+
+ while ( ! empty( $booths ) ) {
+
+ $booth = array_shift( $booths );
+ $_POST[ "input_{$field->id}" ] = $booth;
+
+ $_fields = $form['fields'];
+ $form['fields'] = array( $field );
+
+ $result = gp_inventory_type_choices()->validation( array(
+ 'is_valid' => true,
+ 'form' => $form,
+ ) );
+
+ $form['fields'] = $_fields;
+
+ if ( $result['is_valid'] ) {
+ $field->failed_validation = false;
+ return $form;
+ }
+ }
+
+ if ( empty( $booths ) ) {
+ $list_field->failed_validation = true;
+ $list_field->validation_message = 'None of your selected booths are available.';
+ }
+ }
+
+ return $form;
+} );
diff --git a/gp-inventory/gpi-copy-exhausted-inventory-to-another-field.js b/gp-inventory/gpi-copy-exhausted-inventory-to-another-field.js
new file mode 100644
index 000000000..c5febca33
--- /dev/null
+++ b/gp-inventory/gpi-copy-exhausted-inventory-to-another-field.js
@@ -0,0 +1,19 @@
+/**
+ * Gravity Perks // Inventory // Copy Exhausted Choices to Another Field
+ * https://gravitywiz.com/documentation/gravity-forms-inventory/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Instructions:
+ *
+ * 1. Install this snippet with our free Custom JavaScript plugin.
+ * https://gravitywiz.com/gravity-forms-code-chest/
+ * 2. Configure the snippet per the inline instructions.
+ */
+// Update "1" to the ID of your Inventory-enabled field.
+var $disabled = $( '#input_GFFORMID_1 option:disabled' );
+
+// Update "2" to the ID of the field to which exhausted choices should be copied.
+$( '#input_GFFORMID_2' ).html( $disabled.clone().prop( 'disabled', false ) );
+
+$disabled.remove();
diff --git a/gp-inventory/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php b/gp-inventory/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php
new file mode 100644
index 000000000..5fb89fe46
--- /dev/null
+++ b/gp-inventory/gpi-gpnf-exclude-child-entries-when-attached-to-a-partial-entry.php
@@ -0,0 +1,36 @@
+prepare( 'AND meta_value != %s', rgpost( 'partial_entry_id' ) );
+ }
+ $query['where'] .= "
+ AND e.id IN (
+ SELECT entry_id FROM {$wpdb->prefix}gf_entry_meta
+ WHERE meta_key = 'gpnf_entry_parent'
+ AND meta_value NOT IN(
+ SELECT entry_id FROM {$wpdb->prefix}gf_entry_meta WHERE meta_key = 'partial_entry_id' $meta_value_clause
+ )
+ )";
+ }
+ return $query;
+}, 10, 2 );
diff --git a/gp-inventory/gpi-packaged-products.php b/gp-inventory/gpi-packaged-products.php
new file mode 100644
index 000000000..9c793fac4
--- /dev/null
+++ b/gp-inventory/gpi-packaged-products.php
@@ -0,0 +1,148 @@
+_args = wp_parse_args( $args, array(
+ 'form_id' => null,
+ 'package_field_id' => null,
+ 'field_ids_in_package' => array(),
+ ) );
+
+ $this->form_id = $this->_args['form_id'];
+ $this->package_field = GFAPI::get_field( $this->form_id, $this->_args['package_field_id'] );
+ $this->field_ids_in_package = $this->_args['field_ids_in_package'];
+
+ add_action( 'init', array( $this, 'init' ) );
+ }
+
+ public function init() {
+ add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
+ $this,
+ 'package_field_claimed_inventory',
+ ), 10, 2 );
+
+ add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
+ $this,
+ 'add_claimed_package_inventory_to_individual_products',
+ ), 10, 2 );
+
+ add_filter( 'gpi_requested_quantity_' . $this->form_id, array(
+ $this,
+ 'add_requested_packages_to_individual_products',
+ ), 10, 2 );
+ }
+
+ /**
+ * Add claimed inventory of packaged items to packages if their inventory is below packages.
+ */
+ public function package_field_claimed_inventory( $package_claimed_inventory, $field ) {
+ if ( $field->id !== $this->package_field->id ) {
+ return $package_claimed_inventory;
+ }
+
+ remove_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
+ $this,
+ 'add_claimed_package_inventory_to_individual_products',
+ ) );
+
+ $inventory_limit = gp_inventory_type_advanced()->get_stock_quantity( $this->package_field );
+ $package_available_inventory = $inventory_limit - $package_claimed_inventory;
+ $packaged_item_available_amounts = array();
+
+ foreach ( $this->field_ids_in_package as $field_id_in_package ) {
+ $field_in_package = GFAPI::get_field( $this->form_id, $field_id_in_package );
+ $packaged_item_available_amount = gp_inventory_type_advanced()->get_available_stock( $field_in_package ) - $package_claimed_inventory;
+ $packaged_item_available_amounts[] = $packaged_item_available_amount;
+ }
+
+ $lowest_package_item_available_amount = min( $packaged_item_available_amounts );
+
+ if ( $lowest_package_item_available_amount < $package_available_inventory ) {
+ $difference = $package_available_inventory - $lowest_package_item_available_amount;
+ $package_claimed_inventory = $package_claimed_inventory + $difference;
+ }
+
+ add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
+ $this,
+ 'add_claimed_package_inventory_to_individual_products',
+ ), 10, 2 );
+
+ return $package_claimed_inventory;
+ }
+
+ /**
+ * Add claimed inventory of packages to packaged items.
+ */
+ public function add_claimed_package_inventory_to_individual_products( $claimed_inventory, $field ) {
+ if ( ! in_array( $field->id, $this->field_ids_in_package ) ) {
+ return $claimed_inventory;
+ }
+
+ remove_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
+ $this,
+ 'package_field_claimed_inventory',
+ ) );
+
+ $claimed_packages_inventory = gp_inventory_type_advanced()->get_claimed_inventory( $this->package_field );
+
+ add_filter( 'gpi_claimed_inventory_' . $this->form_id, array(
+ $this,
+ 'package_field_claimed_inventory',
+ ), 10, 2 );
+
+ return (int) $claimed_inventory + (int) $claimed_packages_inventory;
+ }
+
+ /**
+ * Add requested quantity of packages to packaged items.
+ */
+ public function add_requested_packages_to_individual_products( $requested_quantity, $field ) {
+ if ( ! in_array( $field->id, $this->field_ids_in_package ) ) {
+ return $requested_quantity;
+ }
+
+ $requested_packages_qty = rgpost( 'input_' . $this->package_field->id . '_3' );
+
+ return (int) $requested_quantity + (int) $requested_packages_qty;
+ }
+
+}
+
+/**
+ * Configuration
+ */
+new GP_Inventory_Packaged_Products( array(
+ 'form_id' => 2,
+ 'package_field_id' => 4,
+ 'field_ids_in_package' => array( 1, 2 ),
+) );
diff --git a/experimental/gplc-multiselect.js b/gp-limit-choices/gplc-multiselect.js
similarity index 86%
rename from experimental/gplc-multiselect.js
rename to gp-limit-choices/gplc-multiselect.js
index 6c799f237..089b5c090 100644
--- a/experimental/gplc-multiselect.js
+++ b/gp-limit-choices/gplc-multiselect.js
@@ -1,4 +1,6 @@
/**
* This snippet has graduated from the experimental folder π
* You can now find the snippet here: https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-limit-multiselect.js
+ *
+ * Experimental Snippet π§ͺ
*/
diff --git a/gp-nested-forms/gpnf-comma-delimited-email-list.php b/gp-nested-forms/gpnf-comma-delimited-email-list.php
new file mode 100644
index 000000000..4a04aef06
--- /dev/null
+++ b/gp-nested-forms/gpnf-comma-delimited-email-list.php
@@ -0,0 +1,25 @@
+choices ) || ! in_array( $field->id, $fields_to_use_values ) || $field->formId !== $child_form_id ) {
+ return $field_value;
+ }
+
+ return $raw_field_value;
+}, 10, 6 );
diff --git a/gp-nested-forms/gpnf-gv-duplicate-child-entries.php b/gp-nested-forms/gpnf-gv-duplicate-child-entries.php
new file mode 100644
index 000000000..1d4697de4
--- /dev/null
+++ b/gp-nested-forms/gpnf-gv-duplicate-child-entries.php
@@ -0,0 +1,8 @@
+id ) ) ) ) {
+ $value['label'] = 'β';
+ }
+ return $value;
+}, 10, 4 );
diff --git a/gp-nested-forms/gpnf-parent-form-field-values-in-child-form-filters.php b/gp-nested-forms/gpnf-parent-form-field-values-in-child-form-filters.php
new file mode 100644
index 000000000..fb2c364b3
--- /dev/null
+++ b/gp-nested-forms/gpnf-parent-form-field-values-in-child-form-filters.php
@@ -0,0 +1,31 @@
+get_value_default();
+
+ return $entry;
+}, 10, 3 );
diff --git a/gp-nested-forms/gpnf-sortable-entries.php b/gp-nested-forms/gpnf-sortable-entries.php
new file mode 100644
index 000000000..f1026b303
--- /dev/null
+++ b/gp-nested-forms/gpnf-sortable-entries.php
@@ -0,0 +1,382 @@
+_args = wp_parse_args( $args, array(
+ 'form_id' => false,
+ 'field_id' => false,
+ ) );
+
+ // do version check in the init to make sure if GF is going to be loaded, it is already loaded
+ add_action( 'init', array( $this, 'init' ) );
+
+ }
+
+ /**
+ * @return void
+ */
+ public function init() {
+
+ // time for hooks
+ add_filter( 'gform_pre_render', array( $this, 'load_form_script' ), 10, 2 );
+ add_action( 'gform_register_init_scripts', array( $this, 'add_init_script' ), 10, 2 );
+ add_filter( 'gpnf_should_use_static_value', array( $this, 'use_static_value' ), 10, 3 );
+ add_action( 'wp_ajax_gpnf_update_entry_order', array( $this, 'update_entry_order' ) );
+ add_action( 'wp_ajax_no_priv_gpnf_update_entry_order', array( $this, 'update_entry_order' ) );
+ add_filter( 'gpnf_init_script_args', array( $this, 'add_init_script_args' ), 10, 3 );
+
+ }
+
+ /**
+ * Filter the init script to sort the entries based on what's set in the cookie.
+ *
+ * @param array $args {
+ *
+ * @var int $formId The current form ID.
+ * @var int $fieldId The field ID of the Nested Form field.
+ * @var int $nestedFormId The form ID of the nested form.
+ * @var string $modalTitle The title to be displayed in the modal header.
+ * @var string $editModalTitle The title to be displayed in the modal header when editing an existing entry.
+ * @var array $displayFields The fields which will be displayed in the Nested Forms entries view.
+ * @var array $entries An array of modified entries, including only their display values.
+ * @var string $ajaxUrl The URL to which AJAX requests will be posted.
+ * @var int $modalWidth The default width of the modal; defaults to 700.
+ * @var mixed $modalHeight The default height of the modal; defaults to 'auto' which will automatically size the modal based on its contents.
+ * @var string $modalClass The class that will be attached to the modal for styling.
+ * @var string $modalHeaderColor A HEX color that will be set as the default background color of the modal header.
+ * @var bool $hasConditionalLogic Indicate whether the current form has conditional logic enabled.
+ * @var bool $hasConditionalLogic Indicate whether the current form has conditional logic enabled.
+ * @var bool $enableFocusTrap Whether the nested form should use a focus trap when open to prevent tabbing outside the nested form.
+ *
+ * }
+ * @param GF_Field $field The current Nested Form field.
+ * @param array $form The current form.
+ */
+ public function add_init_script_args( $args, $field, $form ) {
+ if ( ! $this->is_applicable_form( $form ) || ! $this->is_applicable_field( $field->id ) ) {
+ return $args;
+ }
+
+ $session = new GPNF_Session( $form['id'] );
+ $cookie_name = $session->get_cookie_name();
+
+ $cookie_raw = rgar( $_COOKIE, $cookie_name );
+
+ if ( ! $cookie_raw ) {
+ return $args;
+ }
+
+ $cookie = json_decode( stripslashes( $_COOKIE[ $cookie_name ] ), true );
+ $cookie_entries = rgars( $cookie, 'nested_entries/' . $field->id );
+
+ if ( empty( $cookie_entries ) ) {
+ return $args;
+ }
+
+ // Sort $args['entries'] which contains Gravity Forms entries arrays. They contain an 'id' key.
+ // $cookie_entries contains the entry IDs in the order they should be displayed.
+ $sorted_entries = array();
+
+ foreach ( $cookie_entries as $entry_id ) {
+ foreach ( $args['entries'] as $entry ) {
+ if ( $entry['id'] == $entry_id ) {
+ $sorted_entries[] = $entry;
+ break;
+ }
+ }
+ }
+
+ $args['entries'] = $sorted_entries;
+
+ return $args;
+ }
+
+ /**
+ * Handles updating the entry order in the GPNF session after a sort event.
+ *
+ * @return void
+ */
+ public function update_entry_order() {
+ check_ajax_referer( 'gpnf_refresh_markup', 'nonce' );
+
+ $form_id = rgpost( 'formId' );
+ $field_id = rgpost( 'fieldId' );
+ $entry_ids = rgpost( 'entryIds' );
+
+ $session = new GPNF_Session( $form_id );
+ $cookie_name = $session->get_cookie_name();
+
+ // Most of GPNF_Session is private so we need to modify the cookie directly.
+ $cookie = json_decode( stripslashes( $_COOKIE[ $cookie_name ] ), true );
+
+ // If 'nested_entries' is not set for the field, just die.
+ if ( ! isset( $cookie['nested_entries'][ $field_id ] ) ) {
+ die();
+ }
+
+ // Update the nested_entries array with the new order.
+ $cookie['nested_entries'][ $field_id ] = $entry_ids;
+
+ // Update the cookie.
+ setcookie( $cookie_name, json_encode( $cookie ), 0, COOKIEPATH, COOKIE_DOMAIN, is_ssl() );
+
+ die();
+ }
+
+ /**
+ * Use static values if sorting is enabled, otherwise a GF_Query will be used to get the child entries and
+ * the sorting will not be applied.
+ *
+ * @param bool $should_use_static_value Should the field's value be static?
+ * @param \GP_Field_Nested_Form $field The current Nested Form field.
+ * @param array $entry The current entry.
+ */
+ public function use_static_value( $should_use_static_value, $field, $entry ) {
+ if ( ! $this->is_applicable_form( $field->formId ) || ! $this->is_applicable_field( $field->id ) ) {
+ return $should_use_static_value;
+ }
+
+ return true;
+ }
+
+ /**
+ * @param array $form
+ * @param bool $is_ajax_enabled
+ *
+ * @return array
+ */
+ public function load_form_script( $form, $is_ajax_enabled ) {
+ if ( $this->is_applicable_form( $form ) && ! has_action( 'wp_footer', array( $this, 'output_script' ) ) ) {
+ add_action( 'wp_footer', array( $this, 'output_script' ) );
+ add_action( 'gform_preview_footer', array( $this, 'output_script' ) );
+ }
+
+ return $form;
+ }
+
+ /**
+ * @return void
+ */
+ public function output_script() {
+ ?>
+
+
+
+ is_applicable_form( $form ) ) {
+ return;
+ }
+
+ $args = array(
+ 'formId' => $this->_args['form_id'],
+ 'fieldId' => $this->_args['field_id'],
+ );
+
+ // Enqueue jQuery UI Sortable
+ wp_enqueue_script( 'jquery-ui-sortable' );
+
+ $script = 'new ' . __CLASS__ . '( ' . json_encode( $args ) . ' );';
+ $slug = implode( '_', array( strtolower( __CLASS__ ), $this->_args['form_id'], $this->_args['field_id'] ) );
+
+ GFFormDisplay::add_init_script( $form['id'], $slug, GFFormDisplay::ON_PAGE_RENDER, $script );
+
+ }
+
+ /**
+ * @param array $form
+ *
+ * @return bool
+ */
+ public function is_applicable_form( $form ) {
+
+ $form_id = isset( $form['id'] ) ? $form['id'] : $form;
+
+ return empty( $this->_args['form_id'] ) || (int) $form_id == (int) $this->_args['form_id'];
+ }
+
+ /**
+ * Check if the field is applicable for the current instance.
+ *
+ * @param int $field_id
+ *
+ * @return bool
+ */
+ public function is_applicable_field( $field_id ) {
+ $field_ids = isset( $this->_args['field_id'] ) ? $this->_args['field_id'] : array();
+
+ if ( empty( $field_ids ) ) {
+ return true;
+ }
+
+ if ( ! is_array( $field_ids ) ) {
+ $field_ids = array( $field_ids );
+ }
+
+ if ( in_array( $field_id, $field_ids, false ) ) {
+ return true;
+ }
+
+ return false;
+ }
+
+}
+
+# Configuration
+
+// Enable sorting for all Nested Form fields on all forms.
+new GPNF_Sortable_Entries();
+
+// Enable sorting for Nested Form field with ID 1 on form with ID 8.
+//new GPNF_Sortable_Entries( array(
+// 'form_id' => 8,
+// 'field_id' => 1,
+//) );
+
+// Enable sorting for all Nested Form fields on form with ID 8.
+//new GPNF_Sortable_Entries( array(
+// 'form_id' => 8,
+//) );
+
diff --git a/gp-populate-anything/gppa-acf-populate-multiple-items-from-repeater-row.php b/gp-populate-anything/gppa-acf-populate-multiple-items-from-repeater-row.php
new file mode 100644
index 000000000..231f9fb5f
--- /dev/null
+++ b/gp-populate-anything/gppa-acf-populate-multiple-items-from-repeater-row.php
@@ -0,0 +1,21 @@
+ {
+ if (
+ !$(elem)
+ .parent()
+ .hasClass('gfield-image-choice-wrapper-inner')
+ ) {
+ return;
+ }
+ $(elem).trigger('change.gppa');
+ }
+);
\ No newline at end of file
diff --git a/gp-populate-anything/gppa-conditional-logic-when-no-results.js b/gp-populate-anything/gppa-conditional-logic-when-no-results.js
new file mode 100644
index 000000000..95c09f6d8
--- /dev/null
+++ b/gp-populate-anything/gppa-conditional-logic-when-no-results.js
@@ -0,0 +1,19 @@
+/**
+ * Gravity Perks // Populate Anything // Conditional Logic using a field that populates with no result
+ * https://gravitywiz.com/documentation/gravity-forms-populate-anything/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * 1. Install this snippet with our free Custom JavaScript plugin.
+ * https://gravitywiz.com/gravity-forms-code-chest/
+ */
+
+gform.addAction('gform_post_conditional_logic_field_action', function (formId, action, targetId, defaultValues, isInit) {
+ // replace 26 with the field ID of the field that gets dynamically populated with No Results
+ var targetValue = $( '#input_GFFORMID_26 :selected' ).val();
+ if ( targetValue === 'Check' ) {
+ // replace 27 with the field ID of the field that needs to be displayed with conditional logic
+ $( '#field_GFFORMID_27' ).show();
+ }
+});
+
diff --git a/gp-populate-anything/gppa-conditionally-exclude-filter-by-field-value.php b/gp-populate-anything/gppa-conditionally-exclude-filter-by-field-value.php
new file mode 100644
index 000000000..5f7b7fbae
--- /dev/null
+++ b/gp-populate-anything/gppa-conditionally-exclude-filter-by-field-value.php
@@ -0,0 +1,24 @@
+formId == 123 && $args['field']->id == 4 ) {
+ foreach ( $query['where'] as &$where_group ) {
+ foreach ( $where_group as &$where ) {
+ // Update "Unsure" to the field value you wish to exempt a filter.
+ if ( strpos( $where, 'Unsure' ) !== false ) {
+ $where = null;
+ unset( $where );
+ }
+ }
+ $where_group = array_filter( $where_group );
+ }
+ $query['where'] = array_filter( $query['where'] );
+ }
+ return $query;
+}, 10, 2 );
diff --git a/gp-populate-anything/gppa-enable-choice-values-for-gravity-view.php b/gp-populate-anything/gppa-enable-choice-values-for-gravity-view.php
new file mode 100644
index 000000000..289951364
--- /dev/null
+++ b/gp-populate-anything/gppa-enable-choice-values-for-gravity-view.php
@@ -0,0 +1,28 @@
+post_type !== 'gravityview' ) {
+ return $form;
+ }
+
+ foreach ( $form['fields'] as &$field ) {
+ if ( $field->{'gppa-choices-enabled'} ) {
+ $field->enableChoiceValue = true;
+ }
+ }
+
+ return $form;
+} );
diff --git a/gp-populate-anything/gppa-faceted-filters.php b/gp-populate-anything/gppa-faceted-filters.php
new file mode 100644
index 000000000..008562c4e
--- /dev/null
+++ b/gp-populate-anything/gppa-faceted-filters.php
@@ -0,0 +1,41 @@
+id !== 5 || $field->formId !== 2 ) {
+ return $query_builder_args;
+ }
+
+ if ( rgblank( $filter_value ) ) {
+ array_pop( $query_builder_args['where'][ $filter_group_index ] );
+ }
+
+ return $query_builder_args;
+}, 10, 2 );
+
+// Disable requiring field filter values to not be empty for form ID 2
+add_filter( 'gppa_has_empty_field_filter_value_2', '__return_false' );
diff --git a/gp-populate-anything/gppa-filter-entries-by-time-field.php b/gp-populate-anything/gppa-filter-entries-by-time-field.php
new file mode 100644
index 000000000..e557f8382
--- /dev/null
+++ b/gp-populate-anything/gppa-filter-entries-by-time-field.php
@@ -0,0 +1,37 @@
+$time_field_id, wp_timezone() );
+ if ( $choice_time > current_datetime() ) {
+ $new_choices[] = $choice;
+ }
+ }
+
+ if ( empty( $new_choices ) ) {
+ $new_choices[] = array(
+ 'text' => 'No items available.',
+ 'value' => '',
+ 'isSelected' => false,
+ );
+ }
+
+ return $new_choices;
+}, 10, 3 );
diff --git a/gp-populate-anything/gppa-firefox-select-fixer.js b/gp-populate-anything/gppa-firefox-select-fixer.js
new file mode 100644
index 000000000..07992c3d0
--- /dev/null
+++ b/gp-populate-anything/gppa-firefox-select-fixer.js
@@ -0,0 +1,24 @@
+/**
+ * Gravity Wiz // Populate Anything // Firefox Select Fixer
+ * https://gravitywiz.com/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Firefox will auto-fill fields (including select fields) with the selected option upon
+ * refresh. This can be problematic with Populate Anything if fields or Live Merge Tags rely
+ * upon the value of the select as Firefox does not trigger any events. To work around this, we
+ * compare the values between the select field and the option with the selected attribute. If they
+ * differ, we trigger a forceReload event which is an event Populate Anything listens for.
+ *
+ * Installation:
+ * 1. Install and Activate https://gravitywiz.com/gravity-forms-code-chest/
+ * 2. Navigate to Form Settings > Custom JavaScript and add this snippet.
+ */
+jQuery('#gform_GFFORMID').find('select').each(function() {
+ var $el = $(this);
+ var $selOption = $el.find('option[selected="selected"]');
+
+ if ($selOption.val() !== $el.val()) {
+ $el.trigger('forceReload');
+ }
+});
diff --git a/gp-populate-anything/gppa-google-sheets-filter-by-date.php b/gp-populate-anything/gppa-google-sheets-filter-by-date.php
new file mode 100644
index 000000000..336c4d06e
--- /dev/null
+++ b/gp-populate-anything/gppa-google-sheets-filter-by-date.php
@@ -0,0 +1,15 @@
+ array( 4, 5, 6 ),
+ );
+
+ if ( ! function_exists( 'gravityview' ) || ! gravityview()->request->is_view() ) {
+ return $display_value;
+ }
+
+ if ( ! is_callable( 'gp_populate_anything' ) ) {
+ return $display_value;
+ }
+
+ remove_filter( 'gform_entry_field_value', array( gp_populate_anything(), 'entry_field_value' ), 20 );
+
+ if ( ! in_array( $field->id, rgar( $targets, $field->formId, array() ) ) ) {
+ $display_value = gp_populate_anything()->get_submitted_choice_label( $display_value, $field, $entry['id'] );
+ }
+
+ return $display_value;
+}, 19, 4 );
diff --git a/gp-populate-anything/gppa-hydrate-choices-on-entry-list.php b/gp-populate-anything/gppa-hydrate-choices-on-entry-list.php
new file mode 100644
index 000000000..919f4cd87
--- /dev/null
+++ b/gp-populate-anything/gppa-hydrate-choices-on-entry-list.php
@@ -0,0 +1,29 @@
+hydrate_form( $form, array() );
+ add_filter( 'gform_form_post_get_meta', 'gppa_hydrate_form_entry_details' );
+
+ return $form;
+}
+add_filter( 'gform_form_post_get_meta', 'gppa_hydrate_form_entry_details' );
diff --git a/gp-populate-anything/gppa-lmt-numbers-only-modifier.php b/gp-populate-anything/gppa-lmt-numbers-only-modifier.php
new file mode 100644
index 000000000..35df1a555
--- /dev/null
+++ b/gp-populate-anything/gppa-lmt-numbers-only-modifier.php
@@ -0,0 +1,13 @@
+%s', $url, basename( $url ) );
+ }
+ return implode( ' ', $links );
+}, 10, 5 );
diff --git a/gp-populate-anything/gppa-object-type-acf-options-page.php b/gp-populate-anything/gppa-object-type-acf-options-page.php
new file mode 100644
index 000000000..3134b0940
--- /dev/null
+++ b/gp-populate-anything/gppa-object-type-acf-options-page.php
@@ -0,0 +1,79 @@
+ 'options-page',
+ 'label' => esc_html__( 'Options Page', 'gp-populate-anything' ),
+ 'callable' => array( $this, 'get_options_pages' ),
+ );
+ }
+
+ public function get_options_pages() {
+ return wp_list_pluck( acf_get_options_pages(), 'page_title', 'menu_slug' );
+ }
+
+ public function get_properties( $options_page = null ) {
+ $field_groups = acf_get_field_groups(array(
+ 'options_page' => $options_page,
+ ));
+
+ $properties = array();
+
+ foreach ( $field_groups as $field_group ) {
+ $fields = acf_get_fields( $field_group );
+
+ foreach ( $fields as $field ) {
+ $properties[ $field['name'] ] = array(
+ 'value' => $field['name'],
+ 'label' => $field['label'],
+ 'callable' => '__return_false',
+ 'orderby' => false,
+ );
+ }
+ }
+
+ return $properties;
+ }
+
+ public function get_object_id( $object, $primary_property_value = null ) {
+ return null;
+ }
+
+ public function query( $args ) {
+ /**
+ * @var $primary_property_value string
+ * @var $field_values array
+ * @var $filter_groups array
+ * @var $ordering array
+ * @var $field GF_Field
+ */
+ // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
+ extract( $args );
+
+ $all_fields = (object) get_fields( 'option' );
+
+ return array( $all_fields );
+ }
+}
+
+add_action('init', function() {
+ gp_populate_anything()->register_object_type( 'acf-options-page', 'GPPA_Object_Type_ACF_Options_Page' );
+});
diff --git a/gp-populate-anything/gppa-object-type-json-api-with-query-params.php b/gp-populate-anything/gppa-object-type-json-api-with-query-params.php
new file mode 100644
index 000000000..de6792f71
--- /dev/null
+++ b/gp-populate-anything/gppa-object-type-json-api-with-query-params.php
@@ -0,0 +1,147 @@
+ array(
+ 'label' => esc_html__( 'Query Properties', 'gp-populate-anything' ),
+ ),
+ 'result_properties' => array(
+ 'label' => esc_html__( 'Result Properties', 'gp-populate-anything' ),
+ ),
+ );
+ }
+
+ public function get_properties( $_ = null ) {
+
+ $properties = array();
+
+ /* Examples */
+ $json_props = array(
+ 'name',
+ 'email',
+ 'company',
+ );
+
+ foreach ( $json_props as $json_prop ) {
+ $properties[ $json_prop ] = array(
+ 'group' => 'result_properties',
+ 'label' => $json_prop,
+ 'value' => $json_prop,
+ 'orderby' => false,
+ 'callable' => '__return_empty_array',
+ 'operators' => null,
+ );
+ }
+
+ /* Query Properties */
+ $properties['query_sales_rep'] = array(
+ 'group' => 'query_properties',
+ 'label' => 'Sales Rep',
+ 'value' => 'sales_rep',
+ 'orderby' => false,
+ 'callable' => '__return_empty_array',
+ 'operators' => array(
+ 'is',
+ ),
+ );
+
+ return $properties;
+
+ }
+
+ public function fetch( $sales_rep ) {
+
+ if ( ! $sales_rep ) {
+ return array();
+ }
+
+ $cache_key = 'sample_json_json_' . $sales_rep;
+
+ if ( $data = get_transient( $cache_key ) ) {
+ return $data;
+ }
+
+ $url = add_query_arg( array(
+ 'salesRep' => $sales_rep,
+ ), 'https://samplejson.com' );
+
+ $results = wp_remote_get( $url );
+
+ $api_response = json_decode( wp_remote_retrieve_body( $results ), true );
+ set_transient( $cache_key, $api_response, DAY_IN_SECONDS );
+
+ return $api_response;
+
+ }
+
+ public function process_filter_default( $search, $args ) {
+ /**
+ * @var $filter_value
+ * @var $filter
+ * @var $filter_group
+ * @var $filter_group_index
+ * @var $primary_property_value
+ * @var $property
+ * @var $property_id
+ */
+ extract( $args );
+
+ $search[ $property_id ] = $filter_value;
+
+ return $search;
+ }
+
+ public function query( $args ) {
+ $search_params = $this->process_filter_groups( $args );
+ $query_results = $this->fetch( rgar( $search_params, 'sales_rep' ) );
+
+ return $query_results;
+
+ }
+
+ public function get_object_prop_value( $object, $prop ) {
+ if ( ! isset ( $object[ $prop ] ) ) {
+ return null;
+ }
+
+ return $object[ $prop ];
+ }
+
+}
+
+add_action( 'init', function () {
+ gp_populate_anything()->register_object_type( 'sample_json_api', 'GPPA_Object_Type_Sample_JSON_API' );
+} );
diff --git a/gp-populate-anything/gppa-object-type-json-api.php b/gp-populate-anything/gppa-object-type-json-api.php
new file mode 100644
index 000000000..8e6f30558
--- /dev/null
+++ b/gp-populate-anything/gppa-object-type-json-api.php
@@ -0,0 +1,203 @@
+id, array( $this, 'add_filter_hooks' ) );
+ }
+
+ public function add_filter_hooks() {
+ add_filter( 'gppa_object_type_' . $this->id . '_filter', array( $this, 'process_filter_default' ), 10, 4 );
+ }
+
+ public function get_object_id( $object, $primary_property_value = null ) {
+ return $object['iata'];
+ }
+
+ public function get_label() {
+ return esc_html__( 'JSON API', 'gp-populate-anything' );
+ }
+
+ public function get_groups() {
+ return array(
+ 'columns' => array(
+ 'label' => esc_html__( 'Columns', 'gp-populate-anything' ),
+ ),
+ );
+ }
+
+ public function get_properties( $_ = null ) {
+
+ $properties = array();
+
+ $json_props = array(
+ 'iata' => 'IATA Code',
+ 'lon' => 'Longitude',
+ 'iso' => 'ISO Code',
+ 'status' => 'Status',
+ 'name' => 'Airport Name',
+ 'continent' => 'Continent (Abbr)',
+ 'type' => 'Type',
+ 'lat' => 'Latitude',
+ 'size' => 'Size',
+ );
+
+ foreach ( $json_props as $json_prop => $label ) {
+ $properties[ $json_prop ] = array(
+ 'group' => 'columns',
+ 'label' => $label,
+ 'value' => $json_prop,
+ 'orderby' => false,
+ 'callable' => '__return_empty_array',
+ 'operators' => array(
+ 'is',
+ 'isnot',
+ 'contains',
+ ),
+ );
+ }
+
+ return $properties;
+
+ }
+
+ public function fetch() {
+
+ $cache_key = 'airports_json';
+
+ if ( $data = get_transient( $cache_key ) ) {
+ return $data;
+ }
+
+ $url = esc_url_raw( 'https://raw.githubusercontent.com/jbrooksuk/JSON-Airports/master/airports.json' );
+ $results = wp_remote_get( $url );
+
+ $api_response = json_decode( wp_remote_retrieve_body( $results ), true );
+
+ set_transient( $cache_key, $api_response );
+
+ return $api_response;
+
+ }
+
+ public function process_filter_default( $search, $args ) {
+
+ /**
+ * @var $filter_value
+ * @var $filter
+ * @var $filter_group
+ * @var $filter_group_index
+ * @var $primary_property_value
+ * @var $property
+ * @var $property_id
+ */
+ extract( $args );
+
+ $search[ $filter_group_index ][] = array(
+ 'property' => $property_id,
+ 'operator' => $filter['operator'],
+ 'value' => $filter_value,
+ );
+
+ return $search;
+
+ }
+
+ public function perform_search( $var, $search ) {
+
+ switch ( $search['operator'] ) {
+ case 'is':
+ return ( $var[ $search['property'] ] == $search['value'] );
+
+ case 'isnot':
+ return ( $var[ $search['property'] ] != $search['value'] );
+
+ case 'contains':
+ return ( stripos( $var[ $search['property'] ], $search['value'] ) !== false );
+
+ default:
+ throw new Error( 'Invalid operator provided.' );
+ }
+
+ }
+
+ /**
+ * Each search group is an OR
+ *
+ * If everything matches in one group, we can immediately bail out as we have a positive match.
+ *
+ * @param $var
+ * @param $search_params
+ *
+ * @return bool
+ */
+ public function search( $var, $search_params ) {
+ foreach ( $search_params as $search_group ) {
+ // For GPPA 2.0+, search_group may also read the numeric "limit" value, so skip for non-array values.
+ if ( ! is_array( $search_group ) ) {
+ continue;
+ }
+
+ $matches_group = true;
+
+ foreach ( $search_group as $search ) {
+ $matches_group = $this->perform_search( $var, $search );
+
+ if ( ! $matches_group ) {
+ break;
+ }
+ }
+
+ if ( $matches_group ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function query( $args ) {
+
+ $search_params = $this->process_filter_groups( $args );
+ $results = $this->fetch();
+
+ if ( ! empty( $search_params ) ) {
+ $results = array_filter( $results, function ( $var ) use ( $search_params ) {
+ return $this->search( $var, $search_params );
+ } );
+ }
+
+ $query_limit = gp_populate_anything()->get_query_limit( $this, $args['field'] );
+ $query_results = array_slice( $results, 0, $query_limit );
+
+ return $query_results;
+
+ }
+
+ public function get_object_prop_value( $object, $prop ) {
+
+ if ( ! isset( $object[ $prop ] ) ) {
+ return null;
+ }
+
+ return $object[ $prop ];
+
+ }
+
+}
+
+add_action('init', function() {
+ gp_populate_anything()->register_object_type( 'json-api', 'GPPA_Object_Type_JSON_API' );
+});
diff --git a/gp-populate-anything/gppa-page-modifier.php b/gp-populate-anything/gppa-page-modifier.php
new file mode 100644
index 000000000..586e67a76
--- /dev/null
+++ b/gp-populate-anything/gppa-page-modifier.php
@@ -0,0 +1,150 @@
+_args = wp_parse_args( $args, array() );
+
+ // do version check in the init to make sure if GF is going to be loaded, it is already loaded
+ add_action( 'init', array( $this, 'init' ) );
+
+ }
+
+ public function init() {
+
+ add_filter( 'gform_pre_render', array( $this, 'load_form_script' ), 10, 2 );
+ add_filter( 'gform_register_init_scripts', array( $this, 'add_init_script' ), 10, 2 );
+
+ add_filter( 'gform_pre_replace_merge_tags', array( $this, 'handle_page_modifier' ), 10, 7 );
+
+ }
+
+ public function handle_page_modifier( $text, $form, $entry, $url_encode, $esc_html, $nl2br, $format ) {
+
+ preg_match_all( '/{[^{]*?:(\d+(\.\d+)?)(:(.*?))?}/mi', $text, $matches, PREG_SET_ORDER );
+ if ( empty( $matches ) ) {
+ return $text;
+ }
+
+ foreach ( $matches as $match ) {
+ $modifiers = $this->parse_modifiers( rgar( $match, 4 ) );
+ if ( ! rgar( $modifiers, 'page' ) ) {
+ continue;
+ }
+ if ( rgpost( 'page-number' ) && rgpost( 'page-number' ) < $modifiers['page'] ) {
+ $text = str_replace( $match[0], '', $text );
+ }
+ }
+
+ return $text;
+ }
+
+ public function load_form_script( $form, $is_ajax_enabled ) {
+
+ if ( ! has_action( 'wp_footer', array( $this, 'output_script' ) ) ) {
+ add_action( 'wp_footer', array( $this, 'output_script' ) );
+ add_action( 'gform_preview_footer', array( $this, 'output_script' ) );
+ }
+
+ return $form;
+ }
+
+ public function output_script() {
+ ?>
+
+
+
+ rgar( $meta, 'coupon_code' ),
+ 'value' => $object['id'],
+ );
+ }
+
+ return $choices;
+}, 10, 3 );
+
+// Update "123" to your form ID.
+add_action( 'gform_after_submission_123', function() {
+ if ( is_callable( 'gf_coupons' ) ) {
+ // Update "4" to the ID of your coupon-populated field.
+ gf_coupons()->delete_feed( (int) rgpost( 'input_4' ) );
+ }
+} );
diff --git a/gp-populate-anything/gppa-populate-date-in-fields-format.php b/gp-populate-anything/gppa-populate-date-in-fields-format.php
new file mode 100644
index 000000000..551b228ea
--- /dev/null
+++ b/gp-populate-anything/gppa-populate-date-in-fields-format.php
@@ -0,0 +1,25 @@
+get_input_type() === 'date' && $field->dateType === 'datepicker' ) {
+ list( $format, $separator ) = array_pad( explode( '_', $field->dateFormat ), 2, 'slash' );
+
+ $separators = array(
+ 'slash' => '/',
+ 'dash' => '-',
+ 'dot' => '.',
+ );
+
+ $format = str_replace( 'y', 'Y', $format );
+ $format = implode( $separators[ $separator ], str_split( $format ) );
+
+ // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
+ $value = date( $format, strtotime( $value ) );
+ }
+ return $value;
+}, 10, 2 );
diff --git a/gp-populate-anything/gppa-remove-filter-groups-with-missing-values.php b/gp-populate-anything/gppa-remove-filter-groups-with-missing-values.php
new file mode 100644
index 000000000..afd9a17f5
--- /dev/null
+++ b/gp-populate-anything/gppa-remove-filter-groups-with-missing-values.php
@@ -0,0 +1,31 @@
+id !== 4 || $field->formId !== 123 ) {
+ return $query_builder_args;
+ }
+
+ if ( ! $filter_value ) {
+ unset( $query_builder_args['where'][ $filter_group_index ] );
+ }
+
+ return $query_builder_args;
+}, 11, 2 );
diff --git a/gp-populate-anything/gppa-select-all-checkboxes.js b/gp-populate-anything/gppa-select-all-checkboxes.js
new file mode 100644
index 000000000..700fbc8e8
--- /dev/null
+++ b/gp-populate-anything/gppa-select-all-checkboxes.js
@@ -0,0 +1,28 @@
+/**
+ * Gravity Perks // GP Populate Anything // Automatically Check Checkboxes
+ * http://gravitywiz.com/documentation/gravity-forms-populate-anything
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Instructions:
+ * 1. Install our free Custom Javascript for Gravity Forms plugin.
+ * Download the plugin here: https://gravitywiz.com/gravity-forms-code-chest/
+ * 2. Copy and paste the snippet into the editor of the Custom Javascript for Gravity Forms plugin.
+ *. 3. This snippet is meant to be a starting point. You will need to update the selectors accordingly
+ */
+
+// Select all choices for field ID 1 on initial load
+jQuery('#button_1_select_all').each(function() {
+ gformToggleCheckboxes(this);
+});
+
+// Select all choices for field ID 2 whenever its choices are repopulated dynamically
+jQuery(document).on('gppa_updated_batch_fields', function(event, formId, fieldIds) {
+ if (formId != GFFORMID) {
+ return;
+ }
+
+ jQuery('#button_2_select_all').each(function() {
+ gformToggleCheckboxes(this);
+ });
+})
diff --git a/gp-populate-anything/gppa-simply-schedule-appointments-refresh-lmts.js b/gp-populate-anything/gppa-simply-schedule-appointments-refresh-lmts.js
new file mode 100644
index 000000000..99adbd1ab
--- /dev/null
+++ b/gp-populate-anything/gppa-simply-schedule-appointments-refresh-lmts.js
@@ -0,0 +1,29 @@
+/**
+ * --- STOP! ---
+ *
+ * This snippet is deprecated and no longer required if you are using the latest version of Simply Schedule Appointments.
+ */
+/**
+ * Gravity Perks // GP Populate Anything // Refresh Live Merge Tags pointing to Simply Schedule Appointments field
+ * https://gravitywiz.com/documentation/gravity-forms-populate-anything
+ *
+ * By default, if using a Simply Schedule Appointments field and you select an appointment time, any Live Merge Tags
+ * referencing the SSA field will not automatically update due to SSA not firing a change event on the hidden input.
+ *
+ * This snippet works around the issue by utilizing a MutationObserver that watches the hidden input's value attribute.
+ *
+ * Instructions:
+ *
+ * 1. Install this snippet with our free Custom JavaScript plugin.
+ * https://gravitywiz.com/gravity-forms-code-chest/
+ */
+var observer = new MutationObserver( function ( mutationList ) {
+ mutationList.forEach( function () {
+ window.gppaForms[GFFORMID].bulkBatchedAjax( [] );
+ } );
+} );
+
+observer.observe( document.querySelector( '.ssa_appointment_form_field_appointment_id' ), {
+ attributeFilter: ['value'],
+ attributeOldValue: true
+} );
diff --git a/gp-populate-anything/gppa-wc-country-to-gf-address-field.php b/gp-populate-anything/gppa-wc-country-to-gf-address-field.php
new file mode 100644
index 000000000..870fa1284
--- /dev/null
+++ b/gp-populate-anything/gppa-wc-country-to-gf-address-field.php
@@ -0,0 +1,15 @@
+get_default_countries();
+ $template_value = rgar( $countries, $template_value, $template_value );
+ }
+ return $template_value;
+}, 10, 8 );
diff --git a/gp-populate-anything/gppa-woo-commerce-lmt.php b/gp-populate-anything/gppa-woo-commerce-lmt.php
new file mode 100644
index 000000000..6ae71a466
--- /dev/null
+++ b/gp-populate-anything/gppa-woo-commerce-lmt.php
@@ -0,0 +1,30 @@
+cart->get_cart() as $cart_item_key => $cart_item ) {
+ add_filter( 'gform_pre_render', function( $form ) use ( $cart_item ) {
+ $gravity_form_data = $cart_item['_gravity_form_data'];
+ $form_meta = RGFormsModel::get_form_meta( $gravity_form_data['id'] );
+ foreach ( $form_meta['fields'] as $field_index => $field ) {
+ if ( ! $field['choices'] ) {
+ continue;
+ }
+
+ foreach ( $field['choices'] as $choice_index => $choice ) {
+ $choice['text'] = gp_populate_anything()->live_merge_tags->replace_live_merge_tags( $choice['text'], $form_meta, $cart_item['_gravity_form_lead'] );
+
+ $form_meta['fields'][ $field_index ]->choices[ $choice_index ] = $choice;
+ }
+ }
+ return $form;
+ });
+ }
+});
diff --git a/gp-reload-form/gprf-reload-globally.js b/gp-reload-form/gprf-reload-globally.js
new file mode 100644
index 000000000..1ff947d6c
--- /dev/null
+++ b/gp-reload-form/gprf-reload-globally.js
@@ -0,0 +1,9 @@
+/**
+ * Experimental Snippet π§ͺ
+ * By default, GPRF scopes it's replacement to a static container. If the user is including multiple instances of the same form
+ * on the same page (which GF does not support by default), all instances of the form will be submitted but only the submitted
+ * instance will be reloaded. Use this snippet to reload all forms of the same ID.
+ */
+gform.addFilter( 'gprf_replacing_elem', function( $replacingElem, formId ) {
+ return jQuery( '#gform_confirmation_wrapper_' + formId + ', .gform_confirmation_message_' + formId + ', #gform_wrapper_' + formId );
+} );
diff --git a/gp-unique-id/gpuid-belgium-cipher.php b/gp-unique-id/gpuid-belgium-cipher.php
new file mode 100644
index 000000000..72d525f79
--- /dev/null
+++ b/gp-unique-id/gpuid-belgium-cipher.php
@@ -0,0 +1,43 @@
+inputName, $key ) === false ) {
+ continue;
+ }
+
+ $source_field_id = (int) str_replace( $key . '_', '', $field->inputName );
+ if ( ! $source_field_id ) {
+ continue;
+ }
+
+ $value = (int) rgar( $entry, $source_field_id );
+ $mod97 = $value % 97;
+ $last_two = str_pad( $mod97 ? $mod97 : '97', 2, '0', STR_PAD_LEFT );
+ $combined = $value . $last_two;
+ $code = '+++' . substr( $combined, 0, 3 ) . '/' . substr( $combined, 3, 4 ) . '/' . substr( $combined, 7, 5 ) . '+++';
+
+ $entry[ $field->id ] = $code;
+ GFAPI::update_entry_field( $entry['id'], $field->id, $code );
+ }
+
+ return $entry;
+}, 9, 2 );
diff --git a/gp-unique-id/gpuid-clear-index.php b/gp-unique-id/gpuid-clear-index.php
new file mode 100644
index 000000000..deaee7d3b
--- /dev/null
+++ b/gp-unique-id/gpuid-clear-index.php
@@ -0,0 +1,55 @@
+prefix}gpui_sequence";
+ $index_results = $wpdb->get_results( "SHOW INDEX FROM `{$wpdb->prefix}gpui_sequence`;" );
+ $indexes = array();
+ foreach ( $index_results as $index_result ) {
+ $indexes[ $index_result->Key_name ] = true;
+ }
+ $indexes = array_keys( $indexes );
+ // Clear all indexes
+ foreach ( $indexes as $index ) {
+ // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
+ $wpdb->query( "DROP INDEX `{$index}` ON `{$wpdb->prefix}gpui_sequence`;" );
+ }
+ // All done, redirect
+ wp_redirect( '/wp-admin/plugins.php?plugin_status=recently_activated&guid_clear_indexes_success=true' );
+ exit();
+} );
+
+add_action( 'admin_notices', function ( $messages ) {
+ if ( rgget( 'guid_clear_indexes_error_active' ) ) :
+ ?>
+
+
Please disable GP Unique ID before attempting to clear the indexes.
+
+
+
+
GP Unique ID table indexes were cleared. Please de-activate this snippet and enable GPUID again.
+
+
+
+
GP Unique ID Clear Indexes snippet is active. If you have already cleared the indexes please remove it.
+ Otherwise you can start clearing indexes here.
+
+ lines_limit ) {
+ var extraLine = lines.pop();
+ lines[ lines.length - 1 ] += extraLine;
+ }
+ $( this ).val( lines.join( '\n' ) );
+} );
diff --git a/gravity-forms/gfjs-early-init-scripts.php b/gravity-forms/gfjs-early-init-scripts.php
new file mode 100644
index 000000000..da977f220
--- /dev/null
+++ b/gravity-forms/gfjs-early-init-scripts.php
@@ -0,0 +1,32 @@
+ $script ) {
+ if ( strpos( $slug, 'gf_custom_js' ) === 0 ) {
+ $filtered = array( $slug => $script ) + $filtered;
+ } else {
+ $filtered[ $slug ] = $script;
+ }
+ }
+
+ GFFormDisplay::$init_scripts[ $form['id'] ] = $filtered;
+
+}, 100 /* right after GF Custom JS */ );
diff --git a/gravity-forms/gfsa-auto-allow-administrator-access.php b/gravity-forms/gfsa-auto-allow-administrator-access.php
new file mode 100644
index 000000000..a98a3801e
--- /dev/null
+++ b/gravity-forms/gfsa-auto-allow-administrator-access.php
@@ -0,0 +1,10 @@
+id );
+
+ if ( empty( $url ) ) {
+ return $notification;
+ }
+
+ if ( $field->multipleFiles ) {
+ $uploaded_files = json_decode( stripslashes( $url ), true );
+ foreach ( $uploaded_files as $uploaded_file ) {
+ $attachment = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $uploaded_file );
+ $notification['attachments'][] = $attachment;
+ }
+ } else {
+ $attachment = preg_replace( '|^(.*?)/gravity_forms/|', $upload_root, $url );
+ $notification['attachments'][] = $attachment;
+ }
+
+ return $notification;
+}
diff --git a/gravity-forms/gw-add-custom-footer-button.php b/gravity-forms/gw-add-custom-footer-button.php
new file mode 100644
index 000000000..7c2b33b08
--- /dev/null
+++ b/gravity-forms/gw-add-custom-footer-button.php
@@ -0,0 +1,11 @@
+ 'button' ), 'My Custom Button', 'gform_previous_button', 'My Custom Button', false );
+}, 10, 2 );
diff --git a/gravity-forms/gw-auto-prepend-https.js b/gravity-forms/gw-auto-prepend-https.js
new file mode 100644
index 000000000..801c4fe98
--- /dev/null
+++ b/gravity-forms/gw-auto-prepend-https.js
@@ -0,0 +1,22 @@
+/**
+ * Gravity Wiz // Gravity Forms // Auto-prepend HTTPS to URLs
+ * https://gravitywiz.com/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Auto-prepend "https://" to URLs in Website fields.
+ */
+// Update "1" to your field ID.
+$( '#input_GFFORMID_1' )
+ .on( 'focus', function() {
+ if ( $( this ).val() === '' ) {
+ $( this ).val( 'https://' );
+ }
+ } )
+ .on( 'keyup', function() {
+ if ( $( this ).val() === 'https:/' ) {
+ $( this ).val( 'https://' );
+ } else if ( $( this ).val().indexOf( 'https://' ) !== 0 ) {
+ $( this ).val( 'https://' + $( this ).val() );
+ }
+ } );
diff --git a/gravity-forms/gw-capture-file-extension.php b/gravity-forms/gw-capture-file-extension.php
new file mode 100644
index 000000000..b20594d4a
--- /dev/null
+++ b/gravity-forms/gw-capture-file-extension.php
@@ -0,0 +1,28 @@
+ Custom JavaScript and add this snippet.
+ */
+var uploadFieldId = 4;
+var targetFieldId = 5;
+var template = '{filename}';
+
+var $uploadField = $( '#input_GFFORMID_{0}'.gformFormat( uploadFieldId ) );
+var $targetField = $( '#input_GFFORMID_{0}'.gformFormat( targetFieldId ) );
+
+$uploadField.on( 'change', function() {
+ var filename = $( this ).val().split("\\").pop();
+ $targetField.val( template.replace( '{filename}', filename ) ).change();
+} );
diff --git a/gravity-forms/gw-capture-list-field-column-as-comma-delimited-list.php b/gravity-forms/gw-capture-list-field-column-as-comma-delimited-list.php
new file mode 100644
index 000000000..e5ea3cf6b
--- /dev/null
+++ b/gravity-forms/gw-capture-list-field-column-as-comma-delimited-list.php
@@ -0,0 +1,32 @@
+create_list_array( $_POST[ "input_{$list_field_id}" ] );
+ $values = array();
+
+ if ( is_array( $rows[0] ) ) {
+ foreach ( $rows as $row ) {
+ $row = array_values( $row );
+ $values[] = $row[ $column_number - 1 ];
+ }
+ } else {
+ foreach ( $rows as $row ) {
+ $values[] = $row;
+ }
+ }
+
+ $_POST[ "input_{$target_field_id}" ] = implode( ',', $values );
+
+} );
diff --git a/gravity-forms/gw-checkbox-to-list-field.js b/gravity-forms/gw-checkbox-to-list-field.js
new file mode 100644
index 000000000..b52b7533d
--- /dev/null
+++ b/gravity-forms/gw-checkbox-to-list-field.js
@@ -0,0 +1,56 @@
+/**
+ * Gravity Wiz // Gravity Forms // Checkbox to List Field
+ * https://gravitywiz.com/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * When a Checkbox is clicked, add a new row to a List field with the checkbox value as the value in the first column
+ * of the newly added row.
+ */
+// Update "1" to your Checkbox field ID.
+var $checkboxField = $( '#field_GFFORMID_1' );
+
+// // Update "2" to your List field ID.
+var $listField = $( '#field_GFFORMID_2' );
+
+$checkboxField.find( 'input' ).on( 'click', function() {
+ if ( $( this ).is( ':checked' ) ) {
+ addRow( $listField, $( this ).val() );
+ } else {
+ removeRow( $listField, $( this ).val() );
+ }
+} );
+
+function removeRow( $listField, value ) {
+ var rowCount = $listField.find( '.gfield_list_group' ).length;
+ if ( rowCount === 1 ) {
+ $listField.find( 'input' ).val( '' );
+ } else {
+ $listField
+ .find( '.gfield_list_group_item:first-child' )
+ .find( 'input' )
+ .each( function() {
+ if ( $( this ).val() === value ) {
+ $( this )
+ .parents( '.gfield_list_group' )
+ .find( '.delete_list_item' )
+ .click();
+ }
+ } );
+ }
+}
+
+function addRow( $listField, value ) {
+ var rowCount = $listField.find( '.gfield_list_group' ).length;
+ var $singleRowNoValue = rowCount && $listField.find( 'input' ).first().val() === '';
+ if ( ! $singleRowNoValue ) {
+ $listField
+ .find( '.gfield_list_group:last-child' )
+ .find( '.add_list_item' )
+ .click();
+ }
+ $listField
+ .find( '.gfield_list_group:last-child' )
+ .find( '.gfield_list_group_item:first-child input' )
+ .val( value );
+}
diff --git a/gravity-forms/gw-count-sundays.js b/gravity-forms/gw-count-sundays.js
new file mode 100644
index 000000000..3c087fa03
--- /dev/null
+++ b/gravity-forms/gw-count-sundays.js
@@ -0,0 +1,61 @@
+/**
+ * Gravity Wiz // Gravity Forms // Count Number of Sundays Between Two Dates
+ * https://gravitywiz.com/path/to/article/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Use this snippet to count the number of Sundays between a start and end date, including those dates themselves.
+ *
+ * Note: This is a JavaScript snippet and there is no server-side validation to ensure that the calculated value
+ * has not been tampered with prior to submission.
+ *
+ * Instructions:
+ *
+ * 1. Install this snippet with our free Custom JavaScript plugin.
+ * https://gravitywiz.com/gravity-forms-code-chest/
+ *
+ * 2. Update the required field IDs to match your own by following the inline instructions.
+ */
+// Update "1" with the ID of your start Date field.
+const startDateField = document.getElementById('input_GFFORMID_1');
+
+// Update "2" with the ID of your end Date field.
+const endDateField = document.getElementById('input_GFFORMID_2');
+
+// Update "3" with the ID of your Sunday count field.
+const countField = document.getElementById('input_GFFORMID_3');
+
+function calculateSundays() {
+ const startDate = new Date(startDateField.value);
+ const endDate = new Date(endDateField.value);
+ let sundays = 0;
+
+ // Loop through the dates and count Sundays
+ while (startDate <= endDate) {
+ if (startDate.getDay() === 0) { // Sunday is represented by 0 in JavaScript's getDay() function
+ sundays++;
+ }
+ startDate.setDate(startDate.getDate() + 1); // Move to the next day
+ }
+
+ return sundays;
+}
+function updateSundayCount() {
+ countField.value = calculateSundays();
+}
+
+// Update Sunday count each time a date is manually entered.
+startDateField.addEventListener('change', updateSundayCount);
+endDateField.addEventListener('change', updateSundayCount);
+
+// Update Sunday count each time a date is selected via the Datepicker.
+gform.addFilter( 'gform_datepicker_options_pre_init', function( optionsObj, formId, fieldId ) {
+ var origOnSelect = optionsObj.onSelect;
+ optionsObj.onSelect = function( value, dpObject ) {
+ if ( origOnSelect ) {
+ origOnSelect();
+ }
+ updateSundayCount()
+ }
+ return optionsObj;
+} );
diff --git a/gravity-forms/gw-crazy-snippet.php b/gravity-forms/gw-crazy-snippet.php
new file mode 100644
index 000000000..591c83b1d
--- /dev/null
+++ b/gravity-forms/gw-crazy-snippet.php
@@ -0,0 +1,7 @@
+ array(
+ array(
+ 'key' => 'created_by',
+ 'value' => $deleted_user_id,
+ ),
+ ),
+ );
+
+ $paging = array(
+ 'offset' => 0,
+ 'page_size' => 300,
+ );
+
+ $entries = GFAPI::get_entries( 0, $search, null, $paging );
+
+ foreach ( $entries as $entry ) {
+ if ( $reassigned_user_id ) {
+ GFAPI::update_entry_property( $entry['id'], 'created_by', $reassigned_user_id );
+ } else {
+ GFAPI::delete_entry( $entry['id'] );
+ }
+ }
+
+}, 10, 2 );
diff --git a/gravity-forms/gw-field-ids-in-editor-labels.php b/gravity-forms/gw-field-ids-in-editor-labels.php
new file mode 100644
index 000000000..302828aaa
--- /dev/null
+++ b/gravity-forms/gw-field-ids-in-editor-labels.php
@@ -0,0 +1,41 @@
+
+ .gw-inline-field-id {
+ background-color: #ecedf8;
+ border: 1px solid #d5d7e9;
+ border-radius: 40px;
+ font-size: 0.6875rem;
+ font-weight: 600;
+ padding: 0.1125rem 0.4625rem;
+ margin-bottom: 0.5rem;
+ display: inline-block;
+ vertical-align: middle;
+ }
+ ';
+ $_gw_inline_field_id_style = true;
+ }
+
+ $search = '<\/label>|<\/legend>';
+ $replace = sprintf( '\0 ID: %d', $field->id );
+ $content = preg_replace( "/$search/", $replace, $content, 1 );
+
+ return $content;
+}, 10, 2 );
diff --git a/gravity-forms/gw-force-greater-end-time.js b/gravity-forms/gw-force-greater-end-time.js
new file mode 100644
index 000000000..2b9a4d3e0
--- /dev/null
+++ b/gravity-forms/gw-force-greater-end-time.js
@@ -0,0 +1,116 @@
+/**
+ * Gravity Wiz // Gravity Forms // Force Greater End Time.
+ * https://gravitywiz.com/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Force the user to enter an end time greater than the start time.
+ *
+ * Instructions:
+ *
+ * 1. Install this snippet with our free Custom JavaScript plugin.
+ * https://gravitywiz.com/gravity-forms-code-chest/
+ * 2. Configure based on the inline instructions.
+ */
+
+// Update "3" to the Start Date Field ID.
+var startDateId = 1;
+// Update "4" to the End Date Field ID.
+var endDateId = 3;
+// Update "5" to the Start Time Field ID.
+var startTimeFieldId = 4;
+// Update "6" to the End Date Field ID.
+var endTimeFieldId = 5;
+
+var selectors = [
+ '#input_'+ GFFORMID + '_' + startDateId,
+ '#input_'+ GFFORMID + '_' + endDateId,
+ '#field_' + GFFORMID + '_' + startTimeFieldId,
+ '#field_' + GFFORMID + '_' + endTimeFieldId
+];
+
+$( selectors.join( ', ' ) ).change( function(){
+ evaluateTimes();
+} );
+
+function evaluateTimes() {
+
+ var startTimestamp = getTimestamp( startDateId, startTimeFieldId );
+ var endTimestamp = getTimestamp( endDateId, endTimeFieldId );
+
+ if ( ! startTimestamp || ! endTimestamp ) {
+ return false;
+ }
+
+ var difference = endTimestamp - startTimestamp;
+ if ( difference <= 60 * 60 * 1000 ) {
+ setEndTime( startTimestamp );
+ }
+
+}
+
+function getTimestamp ( dateFieldId, timeFieldId ){
+
+ var inputs = $( '#field_' + GFFORMID + '_' + timeFieldId ).find('input, select' );
+ var hour = inputs.eq( 0 ).val();
+ var min = inputs.eq( 1 ).val();
+ var ampm = inputs.eq( 2 ).val();
+ // @todo This only supports datepickers.
+ var datetime = new Date( $( '#input_'+ GFFORMID + '_' + dateFieldId ).val() );
+
+ if ( inputs.eq( 0 ).val() =='' || inputs.eq( 1 ).val() == '' ){
+ return false
+ }
+
+ if ( inputs.eq( 2 ).length ) {
+ if ( ampm.toLowerCase() === 'pm' ) {
+ datetime.setHours( parseInt( hour ) + ( hour === '12' ? 0 : 12 ) );
+ }else if ( ampm.toLowerCase() === 'am') {
+ datetime.setHours( parseInt( hour ) - ( hour === '12' ? 12 : 0 ) );
+ }
+ else{
+ datetime.setHours( parseInt( hour ) );
+ }
+ } else {
+ datetime.setHours( parseInt( hour ) );
+ }
+
+ datetime.setMinutes( min );
+
+ return datetime.getTime();
+}
+
+function setEndTime ( startTimestamp ) {
+
+ var endDateTime = new Date( startTimestamp );
+ var endInputs = $( '#field_' + GFFORMID + '_' + endTimeFieldId ).find( 'input, select' );
+
+ var hours = isNaN( endDateTime.getHours() ) ? '' : endDateTime.getHours() + 1,
+ minutes = isNaN( endDateTime.getMinutes() ) ? '' : endDateTime.getMinutes(),
+ hasAMPM = endInputs.length === 3,
+ isPM = false;
+
+ if ( hasAMPM ) {
+ if ( hours === 0 ) {
+ hours = 12;
+ } else if ( hours > 12 ) {
+ hours -= 12;
+ isPM = true;
+ } else if ( hours == 12 ) {
+ // for 12 PM, the PM display should update
+ isPM = true;
+ }
+
+ }
+
+ endInputs.eq( 0 ).val( ( '0' + hours ).slice( -2 ) );
+ endInputs.eq( 1 ).val( ( '0' + minutes ).slice( -2 ) );
+
+ if ( hasAMPM ) {
+ if ( isPM ) {
+ endInputs.eq( 2 ).find( 'option:last' ).prop( 'selected', true );
+ } else {
+ endInputs.eq( 2 ).find( 'option:first' ).prop( 'selected', true );
+ }
+ }
+}
diff --git a/gravity-forms/gw-force-numeric-keyboard-on-mobile.php b/gravity-forms/gw-force-numeric-keyboard-on-mobile.php
new file mode 100644
index 000000000..d4661ebaf
--- /dev/null
+++ b/gravity-forms/gw-force-numeric-keyboard-on-mobile.php
@@ -0,0 +1,20 @@
+get_input_type() === 'number' ) {
+ $content = preg_replace( '/type=\'(number|text)\'/', 'type=\'tel\'', $content );
+ }
+ return $content;
+}, 10, 2 );
diff --git a/gravity-forms/gw-gfapc-map-multiple-fields-to-taxonomy.php b/gravity-forms/gw-gfapc-map-multiple-fields-to-taxonomy.php
new file mode 100644
index 000000000..c151602e3
--- /dev/null
+++ b/gravity-forms/gw-gfapc-map-multiple-fields-to-taxonomy.php
@@ -0,0 +1,31 @@
+_args = wp_parse_args( $args, array(
+ 'custom_fields' => array(),
+ ) );
+
+ // do version check in the init to make sure if GF is going to be loaded, it is already loaded
+ add_action( 'init', array( $this, 'init' ) );
+
+ }
+
+ public function init() {
+
+ add_action( 'gform_post_data', array( $this, 'stash_post_custom_fields_data' ) );
+ add_action( 'gform_after_create_post', array( $this, 'populate_custom_fields' ) );
+
+ }
+
+ public function stash_post_custom_fields_data( $post_data ) {
+ $this->post_custom_fields = $post_data['post_custom_fields'];
+ }
+
+ public function populate_custom_fields( $post_id ) {
+
+ foreach ( $this->_args['custom_fields'] as $custom_field ) {
+ delete_post_meta( $post_id, $custom_field );
+ $value = json_decode( rgar( $this->post_custom_fields, $custom_field ) );
+ update_post_meta( $post_id, $custom_field, $value );
+ }
+
+ }
+
+}
+
+# Configuration
+
+new GW_GF_To_WP_Job_Manager( array(
+ 'custom_fields' => array( '_job_core_skills' ),
+) );
diff --git a/gravity-forms/gw-live-field-values-post-submission.php b/gravity-forms/gw-live-field-values-post-submission.php
new file mode 100644
index 000000000..ea4ee90ac
--- /dev/null
+++ b/gravity-forms/gw-live-field-values-post-submission.php
@@ -0,0 +1,38 @@
+format( 'Y' ) - (int) $date_created->format( 'Y' ) + $years_of_exp;
+ $values[ $entry['id'] ] = $calc_years_of_exp;
+
+ $processing = false;
+
+ return $calc_years_of_exp;
+}, 10, 2 );
diff --git a/gravity-forms/gw-minimum-file-count.php b/gravity-forms/gw-minimum-file-count.php
new file mode 100644
index 000000000..164fa22ea
--- /dev/null
+++ b/gravity-forms/gw-minimum-file-count.php
@@ -0,0 +1,45 @@
+id !== $field_id_to_validate ) {
+ continue;
+ }
+
+ if ( empty( GFFormsModel::$uploaded_files[ $form['id'] ] ) ) {
+ continue;
+ }
+
+ $input_name = 'input_' . $field->id;
+ $uploaded_files = GFFormsModel::$uploaded_files[ $form['id'] ][ $input_name ];
+
+ if ( count( $uploaded_files ) < $minimum_number_of_files ) {
+ $field['failed_validation'] = true;
+ $field['validation_message'] = $validation_message;
+ $result['is_valid'] = false;
+ }
+ }
+
+ $result['form'] = $form;
+
+ return $result;
+} );
diff --git a/gravity-forms/gw-prevent-duplicate-drop-down-selections.js b/gravity-forms/gw-prevent-duplicate-drop-down-selections.js
new file mode 100644
index 000000000..a675eb1ea
--- /dev/null
+++ b/gravity-forms/gw-prevent-duplicate-drop-down-selections.js
@@ -0,0 +1,7 @@
+/**
+ * This snippet has evolved! π¦
+ * Find the new version of this snippet here:
+ * https://github.com/gravitywiz/snippet-library/blob/master/gravity-forms/gw-prevent-duplicate-selections.js
+ *
+ * Experimental Snippet π§ͺ
+ */
diff --git a/gravity-forms/gw-prevent-non-numeric-chars.js b/gravity-forms/gw-prevent-non-numeric-chars.js
new file mode 100644
index 000000000..eefc9e61d
--- /dev/null
+++ b/gravity-forms/gw-prevent-non-numeric-chars.js
@@ -0,0 +1,23 @@
+/**
+ * Gravity Wiz // Gravity Forms // Prevent Non-numeric Characters in Input
+ * https://gravitywiz.com/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Based on solution provided here: https://stackoverflow.com/a/15729184/227711
+ *
+ * Instructions:
+ *
+ * 1. Install this snippet with our free Custom JavaScript plugin.
+ * https://gravitywiz.com/gravity-forms-code-chest/
+ * 2. Configure snippet for your form based on inline instructions.
+ */
+// Update "1" to your field ID.
+document.getElementById( 'input_GFFORMID_1' ).onkeypress = function( e ) {
+ e = e || window.event;
+ var charCode = ( typeof e.which == 'undefined' ) ? e.keyCode : e.which;
+ var charStr = String.fromCharCode( charCode );
+ if ( ! /\d/.test( charStr ) ) {
+ return false;
+ }
+};
diff --git a/gravity-forms/gw-preview-mode-tweaks.php b/gravity-forms/gw-preview-mode-tweaks.php
new file mode 100644
index 000000000..65c9049e5
--- /dev/null
+++ b/gravity-forms/gw-preview-mode-tweaks.php
@@ -0,0 +1,55 @@
+
+
+ type !== 'address' ) {
+ return $result;
+ }
+
+ $street = trim( rgar( $value, $field->id . '.1' ) );
+
+ // Look for a standalone number at the beginning or end of the Address Line 1 value
+ if ( ! preg_match( '/^\d+\s+/', $street ) && ! preg_match( '/\s+\d+$/', $street ) ) {
+ $result['is_valid'] = false;
+ $result['message'] = empty( $field->errorMessage ) ? 'Please provide an address with a house number.' : $field->errorMessage;
+
+ $field->set_input_validation_state( 1, false );
+ }
+
+ return $result;
+}, 10, 4 );
diff --git a/gravity-forms/gw-rich-text-html-fields.php b/gravity-forms/gw-rich-text-html-fields.php
new file mode 100644
index 000000000..0bbbe0671
--- /dev/null
+++ b/gravity-forms/gw-rich-text-html-fields.php
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+ id . '.6' );
+ if ( $country == $country_to_check ) {
+ if ( $result['is_valid'] ) {
+ $zip_value = rgar( $value, $field->id . '.5' );
+ if ( ! preg_match( $regex_pattern, strtoupper( $zip_value ) ) ) {
+ $result['is_valid'] = false;
+ $result['message'] = 'Please enter a valid UK postcode.';
+ }
+ }
+ }
+ return $result;
+}
diff --git a/gravity-forms/gw-value-counter.js b/gravity-forms/gw-value-counter.js
new file mode 100644
index 000000000..d1f0491d3
--- /dev/null
+++ b/gravity-forms/gw-value-counter.js
@@ -0,0 +1,27 @@
+/**
+ * Gravity Wiz // Gravity Forms // Value Counter
+ * https://gravitywiz.com/
+ *
+ * Experimental Snippet π§ͺ
+ *
+ * Count the number of times a given value has been selected in a group of fields and populate that number into a Number field.
+ * This snippet is designed to target a Number field and count selected values in Checkbox and Radio Button fields.
+ *
+ * This snippet works best with our free [GF Custom Javascript](https://gravitywiz.com/gravity-forms-code-chest/) plugin.
+ */
+// Replace the "1", "2" and "3" with field IDs of fields that should have their selected values counted. If you are using the
+var $radios = jQuery( '#field_GFFORMID_1, #field_GFFORMID_2, #field_GFFORMID_3' );
+// Replace "4" with the ID of the Number field in which the count should be populated.
+var $target = jQuery( '#field_GFFORMID_4' );
+// Replace "a" with the value you wish to count if selected.
+var countValue = 'a';
+
+function gwRecountValues() {
+ $target.find( 'input' ).val( $radios.find( 'input:checked[value="' + countValue + '"]' ).length );
+}
+
+$radios.on( 'change', function() {
+ gwRecountValues();
+} );
+
+gwRecountValues();
diff --git a/gs-product-configurator/gspc-remove-wc-product-from-entry-order-summary.php b/gs-product-configurator/gspc-remove-wc-product-from-entry-order-summary.php
new file mode 100644
index 000000000..07a077d30
--- /dev/null
+++ b/gs-product-configurator/gspc-remove-wc-product-from-entry-order-summary.php
@@ -0,0 +1,13 @@
+wc_product_form_display, 'inject_base_price_product_field_gppa_ajax' ) );
+ remove_filter( 'gform_product_info', array( gs_product_configurator()->wc_product_form_display, 'inject_base_price_into_product_info' ) );
+ }
+}, 16 );
diff --git a/gs-product-configurator/gspc-set-subscription-length-by-field-value.php b/gs-product-configurator/gspc-set-subscription-length-by-field-value.php
new file mode 100644
index 000000000..c2de05a6a
--- /dev/null
+++ b/gs-product-configurator/gspc-set-subscription-length-by-field-value.php
@@ -0,0 +1,45 @@
+ 4,
+ // Repeat that process for as many form/field pairs as you'd like.
+ 124 => 5,
+ );
+
+ $subscription_items = $subscription->get_items();
+
+ foreach ( $subscription_items as $subscription_item ) {
+
+ $gspc_order_item = new GS_Product_Configurator\WC_Order_Item( $subscription_item );
+ $entries = $gspc_order_item->get_entries();
+ if ( empty( $entries ) ) {
+ continue;
+ }
+
+ $form_id = rgars( $entries, '0/form_id' );
+ $sub_length_field_id = rgar( $form_field_map, $form_id );
+ if ( ! $sub_length_field_id ) {
+ continue;
+ }
+
+ $sub_length = rgars( $entries, "0/{$sub_length_field_id}" );
+
+ // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date
+ $sub_end_date = date( 'Y-m-d H:i:s', strtotime( "+{$sub_length} months" ) );
+
+ $subscription->update_dates( array( 'end' => $sub_end_date ) );
+
+ return;
+
+ }
+
+} );