pull out data from database and display in Gravity form - php

I am using gravity forms plugin, and I'm trying to display the categories as a drop down list in the form I have already created.
If required, please here's a link to my website
I've been on this for too long, and no way out. Kindly help me out.
add_filter( 'gform_pre_render_1', 'populate_categories' );
add_filter( 'gform_pre_validation_1', 'populate_categories' );
add_filter( 'gform_pre_submission_filter_1', 'populate_categories' );
add_filter( 'gform_admin_pre_render_1', 'populate_categories' );
function populate_categories( $form ) {
foreach ( $form['fields'] as &$field ) {
if ( $field->id != 1 ) {
continue;
}
// you can add additional parameters here to alter the posts that are retrieved
// more info: [http://codex.wordpress.org/Template_Tags/get_posts](http://codex.wordpress.org/Template_Tags/get_posts)
$categories = get_categories ;
$choices = array();
foreach ( $categories as $categories ) {
$choices[] = array( 'text' => $categories->name, 'value' => $categories->name );
}
// update 'Select a Post' to whatever you'd like the instructive option to be
$field->placeholder = 'Category';
$field->choices = $choices;
}
return $form;
}

You can dynamically generate drop downs for gravity forms using the syntax provided below in this link. You have to take control over the functions.php file of the theme to retrieve your output as per your requirement.
Here is the clear documentation provided and you can create in a simple manner using this methods. There are two methods available refer to it.
https://www.gravityhelp.com/documentation/article/dynamically-populating-drop-down-fields/
If you face any problem with creation let me know we shall solve it.

Related

Woocommerce - Include custom user meta in order 'filter by registered customer' Ajax search

I am trying to include a users custom meta named 'sageaccountnumber' within the 'filter by registered customer' section of the WooCommerce orders list as shown below:
I already have the custom meta field named 'sageaccountnumber' working with the following PHP code:
add_action( 'personal_options_update', 'sab_save_sageaccount_user_profile_fields' );
add_action( 'edit_user_profile_update', 'sab_save_sageaccount_user_profile_fields' );
function sab_save_sageaccount_user_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) {
return false;
}
update_user_meta( $user_id, 'sageaccountnumber', $_POST['sageaccountnumber'] );
}
When searching for a registered customer I would like to include the user meta 'sageaccountnumber' within the search and display matching results.
I understand this uses AJAX within the file class-wc-ajax.php. This is the function in question: https://wp-kama.com/plugin/woocommerce/function/WC_AJAX::json_search_customers
I do not know alot about AJAX and I have not been able to find a way to include a custom user meta value in this search. I have not found anyone else doing this.
Any guidance or suggestions would be much appreciated? Thank you.
After getting lost with trying to understand the class-wc-ajax.php file, I completely missed a more obvious and simple solution. Here is the code I am using which works perfectly. I hope this helps others looking for similar solution.
This filter-hook allows you to add an additional meta_query to the existing search parameters. This will also allow your custom user meta to display in AJAX searches from the Orders & Subscriptions pages.
If you have a custom meta field setup for your users, simply change 'sageaccountnumber' to the name of your meta and it will be included in the AJAX search results.
add_filter ('woocommerce_customer_search_customers', 'sab_sageaccount_order_subscription_search', 10, 4);
function sab_sageaccount_order_subscription_search ($filter, $term, $limit, $type){
if ($type == 'meta_query'){ $filter['meta_query'][] = array('key' => 'sageaccountnumber', 'value' => $term, 'compare' => 'LIKE');
}
return $filter;
}
If you need to include the custom meta field in the normal users search, you can use the following code, again changing 'sageaccountnumber' to your custom meta name.
add_action( 'pre_user_query', 'sab_sageaccount_user_search' );
function sab_sageaccount_user_search( $query ) {
global $wpdb;
global $pagenow;
if (is_admin() && 'users.php' == $pagenow) {
if( empty($_REQUEST['s']) ){return;}
$query->query_fields = 'DISTINCT '.$query->query_fields;
$query->query_from .= ' LEFT JOIN '.$wpdb->usermeta.' ON '.$wpdb->usermeta.'.user_id = '.$wpdb->users.'.ID';
$query->query_where = "WHERE 1=1 AND (user_login LIKE '%".$_REQUEST['s']."%' OR ID = '".$_REQUEST['s']."' OR (meta_value LIKE '%".$_REQUEST['s']."%' AND meta_key = 'sageaccountnumber'))";
}
return $query;
}

How to dynamically populate Gravity Forms select (dropdown) menu items from Google Sheets data

I'm trying to dynamically populate the options available for selection in a dropdown menu using data from google sheets. The data is located on column A (A2:A4 at the moment, but this is subject to change) and will include the names of available employees.
So if:
A
1 name
2 jack
3 Bob
4 John
I need these 3 names to dynamically be available for selection in a dropdown menu within gravity forms. I also need the flexibility allowing there to be more or less names whenever an employees availability changes.
I've been trying to put something together using the gravity forms documentation, as well as taking bits and pieces from snippets I've found on github. This is what I have so far, but it is giving me a critical error:
$location_form_id = [FORM ID HERE];
add_filter( 'gform_pre_render_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_validation_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_filter_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_admin_pre_render_'.$location_form_id, 'populate_posts' );
function populate_posts($form){
foreach($form['fields'] as &$field){
if($field->id != [FIELD ID HERE] ) {
continue;
// Hook into Google Spreadsheets //
$url = 'http://spreadsheets.google.com/feeds/list/[SPREADSHEET ID HERE]/od6/public/values?alt=json';
$file = file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
$names = array();
foreach($rows as $row) {
$name = $row->{'gsx$name'}->{'$t'};
$names[] = $name;
}
foreach($names as $single_name){
$choices[] = array('text' => $single_name, 'value' => $single_name );
}
$field['choices'] = $choices;
}
return $form;
}
You need to use few filters given by gravity forms to achieve this. Only four filters are required.
gform_pre_render_
gform_pre_validation_
gform_pre_submission_filter_
gform_admin_pre_render_
You need to get the loop through all the fields of your form id XX and check whether the field you are selecting is an actual dropdown field means a select field.
To push all the new found in the sheets we can use array_push method and then loop through that array to get all the names that were stored.
You can also add a placeholder if you want to to your select field and lastly just the return the $form
In the below code just add your own $form_id, select $feild_id and $gSheet_form_ID .
Add this code your active theme functions.php file. (Code tested and works)
$location_form_id = '62';
add_filter( 'gform_pre_render_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_validation_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_filter_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_admin_pre_render_'.$location_form_id, 'populate_posts' );
function populate_posts( $form ) {
//the select feild id you want the names to load
$field_ID = '2';
//your g sheet ID
$gSheet_form_ID = 'your_public_google_sheet_id';
//get data
$url = 'https://spreadsheets.google.com/feeds/list/'.$gSheet_form_ID.'/public/values?alt=json';
$file = file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
//get all the same from sheet
$names = array(); //store names in this array
foreach($rows as $row) {
$name = $row->{'gsx$name'}->{'$t'};
array_push($names, $name); //push data
}
//Go through each form fields
foreach ( $form['fields'] as $field ) {
//check if field type is a select dropdown and id is 2
if ( $field->type == 'select' && $field->id == $field_ID) {
//add name and value to the option
foreach($names as $single_name){
$choices[] = array('text' => $single_name, 'value' => $single_name );
}
//Add a place holder
$field->placeholder = 'Select a Name';
//Add the new names to the form choices
$field->choices = $choices;
}
}
return $form; //return form
}
Working Select Field Preview
Thank you for this great example. Initially, it did not work for me until I realized that the 'name' is the heading (name) of the column and is hard-coded - I modified that. I was also missing the ability to browse between lists, so I added a variable for that.
Lastly, if your side is running on WordPress, I recommend using the 'Code Snippets' plugin instead of directly adding code into the functions.php - it is cleaner + will not stop working if your theme is modified/changed.
See below:
$location_form_id = '21';
add_filter( 'gform_pre_render_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_validation_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_pre_submission_filter_'.$location_form_id, 'populate_posts' );
add_filter( 'gform_admin_pre_render_'.$location_form_id, 'populate_posts' );
function populate_posts( $form ) {
//the select feild id you want the names to load
$field_ID = 'FIELD_ID_HERE';
//your g sheet ID
$gSheet_form_ID = 'SHEET_ID_HERE';
// which column to scan - what is the heading name
$column_name = 'COLUMN_HEADING_NAME_HERE';
$placeholder = 'YOUR_PLACEHOLDER_HERE';
$list_number = '1';
//get data
$url = 'https://spreadsheets.google.com/feeds/list/'.$gSheet_form_ID.'/'.$list_number.'/public/values?alt=json';
$file = file_get_contents($url);
$json = json_decode($file);
$rows = $json->{'feed'}->{'entry'};
//get all the same from sheet
$names = array(); //store names in this array
foreach($rows as $row) {
$name = $row->{'gsx$'.$column_name}->{'$t'};
array_push($names, $name); //push data
}
//Go through each form fields
foreach ( $form['fields'] as $field ) {
//check if field type is a select dropdown and id is correct
if ( $field->type == 'select' && $field->id == $field_ID) {
//add name and value to the option
foreach($names as $single_name){
$choices[] = array('text' => $single_name, 'value' => $single_name );
}
//Add a place holder
$field->$placeholder;
//Add the new names to the form choices
$field->choices = $choices;
// Print out the contents of the array (troubleshooting only)
//echo '<pre>'; print_r($choices); echo '</pre>';
}
}
return $form; //return form
}
What can still be improved?
The URL used for retrieving the data via Google Sheets API is using API v3, which will be deprecated on June 8th, 2021. If anyone has thoughts on how to improve the code for APIv4, then please let us know!
If you are checking for a cell that is in a column that is 'shorter' than another one, you will end up with empty values in the array. There should be a check against empty values in the code (should be pretty simple to add).

How can I store the values from a WPForm in WordPress to a MySQL database?

How can I store the values from a WPForm in WordPress to a MySQL database?When we use WPForms where I have to add PHP part to store data? Can we store form data to tables when we are using free version of WPForms without buying it?
If you are using WP Forms Lite you can't do this directly, either you'll need to upgrade to PRO version or build your own custom save actions.
If you decide to go with your own custom version, some details below on how to intersect form submission on WP Forms.
WPForms has some actions you can use to do you own custom actions after form submission:
wpforms_process_complete
do_action( 'wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id );
By using on your own template or plugin the wordpress hook add_action for any of the events described, you are able to get form data and do the handling you need.
Reference for wordpress add_action can be seen on the official documentation.
https://developer.wordpress.org/reference/functions/add_action/
Did a quick snippet that will help you get started:
add_action("wpforms_process_complete", 'function_save_custom_form_data');
function function_save_custom_form_data($params) {
foreach($params as $idx=>$item) {
$field_name = $item['name'];
$fiel_value = $item['value'];
// Do whatever you need
}
return true;
}
Please let me know if you need any further details.
WPForms store all form data in two tables within the native WordPress database. They are:
wp_wpforms_entries: In this table, the field values for entries are stored.
wp_wpforms_entry_meta: This table contains meta information about your entries such as IDs associated and the date that entries were submitted.
After publishing the form, make sure to add a form entry, so we can access the entry from your WordPress dashboard. Additionally, in your form builder, go to Settings » General and make sure that entry storing in WordPress is not disabled.
Create custom tables for example wpforms_entries and wpforms_entry_meta in your database to store form data. Use the provided action hook wpforms_process_complete to store the form entries.
add_action( 'wpforms_process_complete', 'process_entry', 5, 4 );
function process_entry( $form_fields, $entry, $form_data, $entry_id ) {
global $wpdb;
$form_id = $form_data['id'];
$entry_data = array(
'form_id' => $form_id,
'status' => 'publish',
'referer' => $_SERVER['HTTP_REFERER'],
'date_created' => current_time( 'mysql' )
);
// Insert into wpforms_entries custom table.
$success = $wpdb->insert( $wpdb->prefix . 'wpforms_entries', $entry_data );
$entry_id = $wpdb->insert_id;
// Create meta data.
if ( $entry_id ) {
foreach ( $form_fields as $field ) {
$field = apply_filters( 'wpforms_process_entry_field', $field, $form_data, $entry_id );
if ( isset( $field['value'] ) && '' !== $field['value'] ) {
$field_value = is_array( $field['value'] ) ? serialize( $field['value'] ) : $field['value'];
$entry_metadata = array(
'entry_id' => $entry_id,
'meta_key' => $field['name'],
'meta_value' => $field_value,
);
// Insert entry meta.
$wpdb->insert( $wpdb->prefix . 'wpforms_entrymeta', $entry_metadata );
}
}
}
}
Refrence: https://github.com/sanzeeb3/entries-for-wpforms/blob/master/includes/functions-wpfe-core.php#L59
Alternatively, the plugin itself is available: https://wordpress.org/plugins/entries-for-wpforms/
Free version of WPForms does not save the entry details captured in form. Therefore, you will need to write custom code to save the values in your custom DB table and then display them.
Below hook of WPForms can be used for saving data being entered in WPForms
/*hook to save entries coming from WPforms into database*/
add_action( 'wpforms_process_entry_save', array( $this, 'ank_wpforms_save_entries' ), 10, 4 );
public function ank_wpforms_save_entries( $fields, $entry, $form_id, $form_data ) {
//no need to sanitize data coming from WPForms as it is being sanitized in WPForms plugin before this hook using
//wpforms_process_validate_{$field_type} in class-process.php
$data = array();
$data['form_id'] = $form_id;
$data['entry_details'] = $fields;
//additional sanity checks are also performed while json encoding in "add" before adding in database
ank_wpforms_entry()->get_class_instance( 'entry-db' )->add( $data );
}
Alternatively , You can use this free plugin to save entries coming from WPForms into wordpress database and then display them in Wordpress Dashboard - https://wordpress.org/plugins/add-entries-functionality-to-wpforms/

Search WooCommerce orders admin for custom fields

Probably a very simple question but it leaves me clueless..
On the web if found the following code for searching a custom field on the order page. What If I wanted to scope another field?
add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_order_total' );
function woocommerce_shop_order_search_order_total( $search_fields ) {
$search_fields[] = 'woochimp_field';
return $search_fields;
}
Thanks
$search_fields[] Is an Array as it turns out. Every time you use $search_fields[] = 'woochimp_field'; you add to the array and makes you able to search more custom fields.
add_filter( 'woocommerce_shop_order_search_fields', 'woocommerce_shop_order_search_order_total' );
function woocommerce_shop_order_search_order_total( $search_fields ) {
$search_fields[] = 'woochimp_field';
$search_fields[] = 'woochimp_field_2'; //example
return $search_fields;
}

Link between Gravity Forms and Woocommerce APIs

I have a Woocommerce site, and I use Gravity Forms to further expand each order.
I am coding a management tool that consumes both APIs to make some statistics and other administration tools.
I can get a list of the Gravity Forms entries, and also a list of the orders. The problem I have is that I don't know how can I get the entry that is related to a particular order.
Is there a way to do this?
have you tried with the woocomerce history plugin or fetching the raw metadata out the item¿?
wc_get_order_item_meta($order_item_id, "_gravity_forms_history");
wc_get_order_item_meta($order_item_id, "_gravity_form_data");
keep in mind that this will require a new endpoint to be created is not put of the box.
The last time I worked with the WooCommerce Gravity Forms Product Addons (a year or so ago) it did not store the order ID in the entry (would have to happen after the entry is created and after the order is created), or the entry ID in the order. The latter probably makes more sense but both would require custom code.
Again, it's been some time since I worked with the add-on. I'd ping WC support and see if they any tips on implementing support for this.
This is where I found the link between WooCommerce and the gravity forms product addon:
In the database, find the order in the table your_table_prefix_posts, and grab its ID. I was filtering for the post_type "shop_order."
In the table your_table_prefix_woocommerce_order_items, find the ID just found and filter for "line_item" in the "order_item_type" column, and grab the "order_item_id."
Use that "order_item_id" to find the order's meta in the table your_table_prefix_woocommerce_order_itemmeta.
All of the order's gravity forms data is in there. It looks like there is no actual tie between what woo does and gravity, except that the form is filled out and it data is grabbed and stuck into your_table_prefix_woocommerce_order_itemmeta. I cannot find anything that ties a particular order to a particular gf entry, but you can get the data from Woo, and at least use that to search GF entries.
I was able to do this using Gravity Forms, Gravity Forms Product Addons, and Woocommerce using a three step process:
STEP 1: Get GF Entry ID/s as the entry is made and store it in a session. This happens before checkout is complete and sometimes before the user is logged in.
add_action( 'gform_after_submission', 'blb_get_lead_entry_id', 10, 2 );
function blb_get_lead_entry_id( $entry, $form ) {
$meta_value = $entry['id'];
//session array with all the entries because GF creates 2 entries each time for validation purposes apparently
if (!isset($_SESSION['entryclump'])) {
$_SESSION['entryclump'] = array();
}
$_SESSION['entryclump'][] = $meta_value;
//also an array with just the current entry which will end up be the later of the two entries added by GF
$_SESSION[ 'gf-entry-id' ] = $meta_value;
}
STEP 2: Include the entry you just gathered ($_SESSION[ 'gf-entry-id' ]) with the Cart Item Meta and then save it.
In this case, i am saving a field called "_gf_entry_ID" which will get added to the woocommerce_order_itemmeta table with the correct order_item_id and the later of the two GF entries as the meta_value.
//add cart item data
add_filter( 'woocommerce_add_cart_item_data', 'blb_add_gfentry_to_cart_data', 10, 3 );
function blb_add_gfentry_to_cart_data( $cartItemData, $productId, $variationId ) {
$entryid=$_SESSION[ 'gf-entry-id' ];
$cartItemData['GFentryID'] = $entryid;
return $cartItemData;
unset($_SESSION[ 'gf-entry-id' ]);
}
//add cart item data: session stuff
add_filter( 'woocommerce_get_cart_item_from_session', 'blb_cart_item_session', 10, 3 );
function blb_cart_item_session( $cartItemData, $cartItemSessionData, $cartItemKey ) {
if ( isset( $cartItemSessionData['GFentryID'] ) ) {
$cartItemData['GFentryID'] = $cartItemSessionData['GFentryID'];
}
return $cartItemData;
}
//save the data
add_action( 'woocommerce_add_order_item_meta', 'blb_save_gfentry', 10, 3 );
function blb_save_gfentry( $itemId, $values, $key ) {
if ( isset( $values['GFentryID'] ) ) {
wc_add_order_item_meta( $itemId, '_gf_entry_ID', $values['GFentryID'] );
}
}
STEP 3 (optional): Update the GF Form to reflect the correct created_by user ID. Now that checkout is complete and the user is logged in, we can do that.
function blb_woocommerce_thankyou( $order_id ) {
//Current User
$currentUserID = wp_get_current_user()->ID;
//GF Entry Array for Order
$order = new WC_Order( $order_id );
$items = $order->get_items();
$order_item_ids = array();
$gf_entry_ids = array();
foreach ( $items as $key=>$item ) {
$gf_entry_ids[] = $item['item_meta']['_gf_entry_ID'][0];
}
//First real quick clear all the entries in the entry clump (in case the user was already logged in)
//This is important because GF creates two forms for product add ons with Woocommerce and we only want one to show up in the list and edit plugin
$entryclump = $_SESSION[ 'entryclump' ];
foreach ( $entryclump as $entry ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => null), array('id' => $entry));
}
//Update wp_rg_lead
if (($currentUserID!=0) && (isset($_SESSION[ 'entryclump' ])) ) {
foreach ( $gf_entry_ids as $gf_entry_id ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => $currentUserID), array('id' => $gf_entry_id));
} //foreach
} //if
unset($_SESSION[ 'entryclump' ]);
};
add_action( 'woocommerce_thankyou', 'blb_woocommerce_thankyou', 10, 1 );

Categories