WP ACF auto create shortcodes from multiple fields - php

GOAL
I currently have an acf field group with some fields for generic data like phonenumber, email, etc. (all simple text fields).
My goal is to have one function that will loop over all the fields and create a shortcode based on their respective name/label.
EDIT: PROGRESS
I think I am getting closer, simplified the whole thing and I believe I am on the right path..
I attached the field group to a post and if I log them like so:
$testing = get_field_objects(22);
do_action( 'php_console_log', $testing );
I get all the names, values etc. With the help of another snippet I found the shortcodes seem to be at least dynamic since they all stop showing just that there is no value somehow so it all stays blank.
This is the function now:
$hlfields = get_field_objects( 22 );
foreach ( $hlfields as ['name' => $name, 'value' => $value] ) {
${"{$name}_fn"} = function() {
$field = get_field($name, 22);
return $field;
};
add_shortcode($name, ${"{$name}_fn"});
}
Original attempt, not working and over complicated:
I currently have an acf field group with some fields for generic data like phonenumber, email, etc. (all simple text fields).
To be able to insert them all easily using a shortcode, I create one for each field like so:
function adresse_shortcode( $adresse ) {
$adresse = get_field( "adresse", 'option' );
return $adresse;
}
add_shortcode('adresse', 'adresse_shortcode');
While this works fine, I feel like I am repeating myself unnecessarily and also I need to add a function whenever I add a new field.
My goal is to have one function that will loop over all the fields and create a shortcode based on their respective name/label.
I found this snippet to get all fields of a field group by ID:
function get_specifications_fields() {
global $post;
$specifications_group_id = 13; // Post ID of the specifications field group.
$specifications_fields = array();
$fields = acf_get_fields( $specifications_group_id );
foreach ( $fields as $field ) {
$field_value = get_field( $field['name'] );
if ( $field_value && !empty( $field_value ) ) {
$specifications_fields[$field['name']] = $field;
$specifications_fields[$field['name']]['value'] = $field_value;
}
}
return $specifications_fields;
}
But I can't figure out how to create the shortcodes now, I have been trying everything I could think of along these lines:
function adresse_shortcode( $value ) {
$specifications_fields = get_specifications_fields();
foreach ( $specifications_fields as $name => $field ) {
$value = $field['value'];
$label = $field['label'];
$name = $field['name'];
return $name;
}
add_shortcode($value, 'adresse_shortcode');
}
I am not well versed in PHP so I am sure it's all sorts of wrong but I have been trying to figure it out for hours and was hoping someone might be able point me in the right direction.

Here's an example using anonymous functions that should do the trick
$hlfields = get_field_objects( 22 );
foreach ( $hlfields as ['name' => $name, 'value' => $value] ) {
$cb = function() use ($name) {
$field = get_field($name, 22);
return $field;
};
add_shortcode( $name, $cb );
}
Here's the sources i referred to while answering: Dynamic function name in php, Dynamic shortcodes and functions in WordPress, PHP: Variable functions

Related

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).

Gravity Forms: Dynamically populate field label or placeholder

I want to populate an input field with data from the current user.
At the moment I populate the fields value parameter but I want to keep the input empty.
Therefore it would be great if I could populate the label or the placeholder parameter of the input field.
I couldn't find anything in the docs.
Here's my current code:
add_filter('gform_field_value_username', create_function("", '$value = populate_usermeta(\'nickname\'); return $value;' ));
I believe this should work out-of-the-box with Gravity Forms:
With some help from the Gravity Forms support and some own testing, I came up with a solution:
function populate_usermeta($meta_key){
global $current_user;
return $current_user->__get($meta_key);
}
add_filter( 'gform_pre_render', 'populate_text' );
//Note: when changing choice values, we also need to use the gform_pre_validation so that the new values are available when validating the field.
add_filter( 'gform_pre_validation', 'populate_text' );
//Note: this will allow for the labels to be used during the submission process in case values are enabled
add_filter( 'gform_pre_submission_filter', 'populate_text' );
function populate_text( $form ) {
$items = array();
$fields = $form['fields'];
foreach( $form['fields'] as &$field ) {
if ( $field->type != 'text' || strpos( $field->cssClass, 'populate-placeholder' ) === false ) {
continue;
}
$field->placeholder = populate_usermeta($field->inputName);
}
return $form;
}

Get Specific Custom Field from Custom Post type by key

I have been searching for this and took days but didn't find the solution anywhere. I am using a code to get the specific custom field value by key number (see below code) but I want to get the value of a custom field by key name for example key name is "post-code".
Note: lead_custom_field is a custom field.
<?php
$custom_fields = get_post_custom($post_id);
$my_custom_field = $custom_fields['lead_custom_field'];
foreach ( $my_custom_field as $key => $value ) {
$a1 = unserialize( $value );
echo '<td>'. $a1[1]['value'] . '</td>';
}
?>
Please help, I am stuck in this for so long.
get_post_custom() returns all of the custom fields associated with a post.
You can use get_post_meta() which will return a single value by key.
The following will output the value of the your lead_custom_field custom field key.
var_dump( get_post_meta( $post_id, 'lead_custom_field', true ) );
It appears you are storing an multi-dimensional array inside lead_custom_field. You should consider restructuring your data to a more appropriate format like so:
array(
'post-code' => 12345,
'first-name' => 'John',
'last-name' => 'Doe
)
Which would allow you to simply do:
$data = get_post_meta( $post_id, 'lead_custom_field', true );
echo 'Post Code: '. $data['post-code'];
Without restructuring how you save that data, you'll need to keep using a loop of some kind since, based on our chat, you have:
A key named "key" with a value of "post-code"
A key named "value" with a value of "12345"
All inside an unnamed arrays. So you need to loop through somehow unless you fundamentally change how you store that data. Either in an array like I have above, or in separate custom fields.
One of my friend helped me in this he's a great php developer. Posting here as an answer if someone looking for this.
<?php
$post_id = get_the_ID();
$custom_fields = get_post_custom($post_id);
$my_custom_field = unserialize( $custom_fields['lead_custom_field'][0] );
$params = [];
foreach ($my_custom_field as $k) {
$params[ $k["key"] ] = $k["value"];
}
echo '<td>' . $params["post-code"] . '</td>';
?>

pull out data from database and display in Gravity form

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.

Gravity forms input values

I'm new in the php world and i'm trying to build something in wordpress by gravity forms.
Basicly for now I just playing around and try to create some codes I can use when I start building. My question is: I have a form 1 where I can enter a name e.g. Football,Baseball,Hockey and it get saved to my data base. Then I have another form with the id 2 where there is a drop down box, here i want those values(names) submitted in form 1 to be dynamically populated. I have been trying to create a code by finding pieces around some websites (you will properly discover I'm mixing everything together) and ended up with this:
add_filter("gform_pre_render", "test_task");
add_filter("gform_admin_pre_render", "test_task");
add_filter('gform_pre_submission_filter', 'test_task');
function test_task($entry, $form){
if($form["id"] != 2)
return $form;
$entry["1"];
$items = array();
$items[] = array("text" => "Choose Sport", "value" => "");
foreach($posts as $post)
$items[] = array("value" => $post->post_title, "text" => $post->post_title);
foreach($form["fields"] as &$field)
if($field["id"] == 2){
$field["choices"] = $items;
}
return $form;
}
Hope someone can show me how it should be done so I can learn to do it in the future.
Sincerely
Lars
I'm afraid the $entry object is not available to the gform_pre_render, gform_pre_submission_filter or gform_admin_pre_render hooks. Give the following a try.
add_filter( 'gform_pre_render', 'populate_sports_choices' );
add_filter( 'gform_pre_validation', 'populate_sports_choices' );
add_filter( 'gform_pre_submission_filter', 'populate_sports_choices' );
add_filter( 'gform_admin_pre_render', 'populate_sports_choices' );
function populate_sports_choices( $form ) {
// only run for form 2
if( $form['id'] != 2 )
return $form;
foreach ( $form['fields'] as &$field ) {
function populate_sports_choices( $form ) {
foreach ( $form['fields'] as &$field ) {
// only populate the field if it is a select and has the designated css class name
if ( $field['type'] != 'select' || strpos( $field['cssClass'], 'populate-sport' ) === false )
continue;
// get form 1 field 4 entry values
$sports = get_entry_field_values( 4, 1 );
// create the $choices array and set the placeholder choice
$choices = array( array( 'text' => 'Select a Sport', 'value' => '' ) );
// loop through each of the sports and add them to the $choices array
foreach ( $sports as $sport ) {
$choices[] = array( 'text' => $sport['value'], 'value' => $sport['value'] );
}
//replace the field choices with the contents of the $choices array
$field['choices'] = $choices;
}
return $form;
}
/**
* Allows you to retrieve an array of field values.
* Requires either the $field object or a field ID and a form ID.
*
* Example: $values = get_entry_field_values( 5, 113 );
*/
function get_entry_field_values( $field_id, $form_id ) {
global $wpdb;
if ( is_array( $field_id ) ) {
$field_id = rgget( 'id', $field_id );
}
$tablename = $wpdb->prefix . 'rg_lead_detail';
$sql = "SELECT value FROM $tablename WHERE form_id = %d AND CAST(field_number as unsigned) = %d";
return $wpdb->get_results( $wpdb->prepare( $sql, $form_id, $field_id ), ARRAY_A );
}
The above is based on examples from the following sources:
http://www.gravityhelp.com/documentation/page/Dynamically_Populating_Drop_Down_Fields
http://www.gravityhelp.com/forums/topic/drop-down-dynamic-population-from-single-line-text
I don't think you need to write any code at all. This is supported by Gravity Forms itself. In the form editor go to settings > confirmations, then choose redirect, enter the page form 2 is on and select Pass Field Data Via Query String then enter name={Name:1} or something similar depending on the name and id of the fields in Form 1. And then in Form 2, go to the field you want to populate and select advanced and dynamically prepopulate and enter what you typed to the left of the =, in this case name.

Categories