Gravity Forms Notification to Google Spreadsheet

The idea that data can flow to different places for different purposes is one of the key concepts I want people to believe in. Different technologies and different interfaces have different affordances depending on what you’re trying to do.

In this case, we’ve built some online training for students. As part of that training they need to sign off indicating they read various rules and safety advice. We’re using Gravity Forms to collect that information. We’re going to set a special notification email that’s easier to parse in addition to the regular email that gets sent out (that one is oriented towards student confirmation and alerting the individual faculty).

Gravity Forms Notification

We’re just going to put the student email and faculty email in the subject line with a space between them. I did some fancier stuff early but went back to this when I realized what we were doing just wasn’t complex enough to justify extra drama. I set the from name to Health Hub Logger so it’d be easier to write the filter in GMail.

Notifications in Gravity Forms are pretty straight forward but you can find out more on their site.

Screenshot of the Gravity Forms notification interface indicating that the students and faculty email are in the subject line of the email via variables.

GMail Filter

Screenshot of gmail filter interface showing that I want these emails marked as read and labeled as "HealthHub".
I then setup a filter in GMail so that I could be confident that the Google Script could find these emails and that I would not really see them. I search for anything from the Health Hub Logger name and make it as read and label it with the “HealthHub” tag.

Google Script

Now comes the Google Script. I open a spreadsheet. Go to Tools>Script Editor and put in the following. After that, I set the trigger in the Google Script editor interface to run every 15 minutes.

function healthHubLogger() {
  
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheets()[0];
  
 var today = new Date();
 var dd = today.getDate()-1;
 var mm = today.getMonth()+1; //January is 0 DO NOT FORGET THIS
 var yyyy = today.getFullYear();
 var yesterday = yyyy + '/' + mm + '/' + dd;
  
  var query = "after:" + yesterday  + " label:HealthHub";// not necessary to restrict date really but I figure it's faster -- note the HealthHub label
  
  var threads = GmailApp.search(query);
  
  var allSubjects = sheet.getRange("C:C" + sheet.getLastRow()).getValues();
  var flatSubjects = allSubjects.map(function(row) {return row[0]});
  
  for (var i = 0; i < threads.length; i++) {
    var messages = threads[i].getMessages();
    //Logger.log(messages);    
    for (var m = 0; m < messages.length; m++) {
       var healthLog = [];
     
      var from = messages[m].getFrom();
      var to = messages[m].getTo();
      var time = messages[m].getDate();
      var subject = messages[m].getSubject();
      var student = subjectSplitter(subject,0);
      var faculty = subjectSplitter(subject,1);
      var mId = messages[m].getId();
      
      var mYear = time.getFullYear();
      var mMonth = time.getMonth()+1;
      var mDay = time.getDate();
      var messageDate = mYear + '/' + mMonth + '/' + mDay;
      if(flatSubjects.indexOf(subject) < 0 ) { 
        healthLog.push(from);
        healthLog.push(time);
        healthLog.push(subject);
        healthLog.push(student);
        healthLog.push(faculty);
        healthLog.push('https://mail.google.com/mail/u/0/#inbox/'+mId);
        sheet.appendRow(healthLog);      
     }
    }

  }          

}


//split subject line
function subjectSplitter(subject,num){
  var emails = subject.split(" ");
  return emails[num];
}

Now all that I need to do is share the spreadsheet with the program administrators and they have an easy way to see what’s what without having to go into WordPress or get any additional accounts.

Gravity Forms to Graph Interaction

I’ve long wanted to build more interactive digital content after being inspired by Brett Victor’s explorable explanations. I’m now finally coming to the place where my ability to build things is starting to match my desire to create them.

This particular piece of interactive content was inspired by the NYT’s You Draw It Obama article. We did a direct imitation with carbon sequestration a while ago but I liked the broader concept of guessing at something and then being presented with data. In this case we’re trying to get people to think a little harder about the good things they got out of life just by being born.

Screenshot of the submission pattern for the confronting your privilege form. Buttons from -10 to 10 are horizontally across the top and a grid of yes/no questions are below.

Form Tweaking

First I wanted to tweak the gravity form layout. Given our first question was a placement on a scale of -10 to 10, that content needed to be arranged horizontally. This is Gravity Forms and the radio button input type. So I copied the HTML into a codepen to play with it. This is the result.

See the Pen
gform layout
by Tom (@twwoodward)
on CodePen.

Results Display

Another pattern I find myself repeating is roughing out the data display portion in Codepen. I can then figure out how I need Gravity Forms/WordPress to pass the data live but it’s easier to build out the experience a bit without worrying about getting live data. Isolate your variables and gradually add complexity.

In the codepen below you can see that scores are set manually for the demo. The function goes through each score and gets the div with the same ID. It also increments the data-count +1 each time it cycles through. That allows me to set an inline CSS style for border-top to be the data-count * 8.5 (or whatever looks good). Once we have enough entries we can tone this down but prest-o change-o a bar chart using nothing but thick borders.

let scores = ['pos-1', 'pos-1', 'pos-3','neg-2','pos-1', 'pos-1', 'pos-3','neg-2', 'neg-10','neg-10','neg-10','neg-10','neg-10','neg-10','neg-10','neg-10','pos-7']

countThem(scores)
function countThem(scores){
  scores.forEach(function(score){
    let bubble = document.getElementById(score);
    console.log(bubble)
    let count = parseInt(bubble.getAttribute('data-count'),10);
    count = count+1;
    bubble.setAttribute('data-count', count);
    bubble.setAttribute('style', 'border-top:' + (count*8.5) + 'px solid #00b3be;');
  })
}
<div class="bubble-holder" id="bubble-zone">
    <div class="bubble" id="neg-10" data-count="0">-10</div>
    <div class="bubble" id="neg-9" data-count="0">-9</div>
    <div class="bubble" id="neg-8" data-count="0">-8</div>
    <div class="bubble" id="neg-7" data-count="0">-7</div>
    <div class="bubble" id="neg-6" data-count="1">-6</div>
    <div class="bubble" id="neg-5" data-count="0">-5</div>
    <div class="bubble" id="neg-4" data-count="0">-4</div>
    <div class="bubble" id="neg-3" data-count="2">-3</div>
    <div class="bubble" id="neg-2" data-count="1">-2</div>
    <div class="bubble" id="neg-1" data-count="11">-1</div>
    <div class="bubble" id="zero-0" data-count="1">0</div>
    <div class="bubble" id="pos-1" data-count="3">1</div>
    <div class="bubble" id="pos-2" data-count="0">2</div>
    <div class="bubble" id="pos-3" data-count="3">3</div>
    <div class="bubble" id="pos-4" data-count="0">4</div>
    <div class="bubble" id="pos-5" data-count="5" >5</div>
    <div class="bubble" id="pos-6" data-count="0">6</div>
    <div class="bubble" id="pos-7" data-count="0">7</div>
    <div class="bubble" id="pos-8" data-count="0">8</div>
    <div class="bubble" id="pos-9" data-count="0">9</div>
    <div class="bubble" id="pos-10" data-count="0">10</div>
  </div>

See the Pen
bubblish chart exploration
by Tom (@twwoodward)
on CodePen.

WordPress/Gravity Forms Land

Now to get the live data and integrate it all. This function gets the Gravity Form entries and creates the data structure we need to pass on to the javascript.


function gform_stepper($entry, $form){
   $search_criteria = array(
    'status'        => 'active',    
);

  $sorting         = array();
  $paging          = array( 'offset' => 0, 'page_size' => 100 );//getting most recent 100 right now
  $total_count     = 0;

  $entries = GFAPI::get_entries(4, $search_criteria, $sorting, $paging, $total_count );
  $html = '';
  $total_scores = [];
  $total_guesses = [];
    foreach ($entries as $entry) {
      if (intval($entry['gsurvey_score'])>0){
        $pre = 'pos-';//add pos if greater than 0
      }
      if (intval($entry['gsurvey_score'])<0){
        $pre = 'neg';//add neg if less than 0
      } 
      if (intval($entry['gsurvey_score']) === 0) {
        $pre = 'zero-';
      }
      array_push($total_scores,$pre . $entry['gsurvey_score']);
      $guess = array_push($total_guesses, $entry[3]);
    }    
      $gform_scores = array(          
           'scores' => $total_scores,
       );
     wp_localize_script('main-course', 'gformScores', $gform_scores); //sends data to script as variable     
}

let scores = gformScores.scores;//THIS IS THE VARIABLE PASSED via localize
countThem(scores)
function countThem(scores){

  scores.forEach(function(score){
    let bubble = document.getElementById(score);
    console.log(bubble)
    let count = parseInt(bubble.getAttribute('data-count'),10);
    count = count+1;
    bubble.setAttribute('data-count', count);
    bubble.setAttribute('style', 'border-top:' + (Math.ceil(count*3.5)) + 'px solid rgba(0, 179, 190,1);');
  })
}

The result is a form that you can submit and get results like you see below. Just the beginning of things but a step in the right direction I think.

After form submission the data is graphed and displayed. Boxes show your guess vs your actual score and combined scores of previous participants.

Gravity Forms to Graph Interaction

I’ve long wanted to build more interactive digital content after being inspired by Brett Victor’s explorable explanations. I’m now finally coming to the place where my ability to build things is starting to match my desire to create them.

This particular piece of interactive content was inspired by the NYT’s You Draw It Obama article. We did a direct imitation with carbon sequestration a while ago but I liked the broader concept of guessing at something and then being presented with data. In this case we’re trying to get people to think a little harder about the good things they got out of life just by being born.

Screenshot of the submission pattern for the confronting your privilege form. Buttons from -10 to 10 are horizontally across the top and a grid of yes/no questions are below.

Form Tweaking

First I wanted to tweak the gravity form layout. Given our first question was a placement on a scale of -10 to 10, that content needed to be arranged horizontally. This is Gravity Forms and the radio button input type. So I copied the HTML into a codepen to play with it. This is the result.

See the Pen
gform layout
by Tom (@twwoodward)
on CodePen.

Results Display

Another pattern I find myself repeating is roughing out the data display portion in Codepen. I can then figure out how I need Gravity Forms/WordPress to pass the data live but it’s easier to build out the experience a bit without worrying about getting live data. Isolate your variables and gradually add complexity.

In the codepen below you can see that scores are set manually for the demo. The function goes through each score and gets the div with the same ID. It also increments the data-count +1 each time it cycles through. That allows me to set an inline CSS style for border-top to be the data-count * 8.5 (or whatever looks good). Once we have enough entries we can tone this down but prest-o change-o a bar chart using nothing but thick borders.

let scores = ['pos-1', 'pos-1', 'pos-3','neg-2','pos-1', 'pos-1', 'pos-3','neg-2', 'neg-10','neg-10','neg-10','neg-10','neg-10','neg-10','neg-10','neg-10','pos-7']

countThem(scores)
function countThem(scores){
  scores.forEach(function(score){
    let bubble = document.getElementById(score);
    console.log(bubble)
    let count = parseInt(bubble.getAttribute('data-count'),10);
    count = count+1;
    bubble.setAttribute('data-count', count);
    bubble.setAttribute('style', 'border-top:' + (count*8.5) + 'px solid #00b3be;');
  })
}
<div class="bubble-holder" id="bubble-zone">
    <div class="bubble" id="neg-10" data-count="0">-10</div>
    <div class="bubble" id="neg-9" data-count="0">-9</div>
    <div class="bubble" id="neg-8" data-count="0">-8</div>
    <div class="bubble" id="neg-7" data-count="0">-7</div>
    <div class="bubble" id="neg-6" data-count="1">-6</div>
    <div class="bubble" id="neg-5" data-count="0">-5</div>
    <div class="bubble" id="neg-4" data-count="0">-4</div>
    <div class="bubble" id="neg-3" data-count="2">-3</div>
    <div class="bubble" id="neg-2" data-count="1">-2</div>
    <div class="bubble" id="neg-1" data-count="11">-1</div>
    <div class="bubble" id="zero-0" data-count="1">0</div>
    <div class="bubble" id="pos-1" data-count="3">1</div>
    <div class="bubble" id="pos-2" data-count="0">2</div>
    <div class="bubble" id="pos-3" data-count="3">3</div>
    <div class="bubble" id="pos-4" data-count="0">4</div>
    <div class="bubble" id="pos-5" data-count="5" >5</div>
    <div class="bubble" id="pos-6" data-count="0">6</div>
    <div class="bubble" id="pos-7" data-count="0">7</div>
    <div class="bubble" id="pos-8" data-count="0">8</div>
    <div class="bubble" id="pos-9" data-count="0">9</div>
    <div class="bubble" id="pos-10" data-count="0">10</div>
  </div>

See the Pen
bubblish chart exploration
by Tom (@twwoodward)
on CodePen.

WordPress/Gravity Forms Land

Now to get the live data and integrate it all. This function gets the Gravity Form entries and creates the data structure we need to pass on to the javascript.


function gform_stepper($entry, $form){
   $search_criteria = array(
    'status'        => 'active',    
);

  $sorting         = array();
  $paging          = array( 'offset' => 0, 'page_size' => 100 );//getting most recent 100 right now
  $total_count     = 0;

  $entries = GFAPI::get_entries(4, $search_criteria, $sorting, $paging, $total_count );
  $html = '';
  $total_scores = [];
  $total_guesses = [];
    foreach ($entries as $entry) {
      if (intval($entry['gsurvey_score'])>0){
        $pre = 'pos-';//add pos if greater than 0
      }
      if (intval($entry['gsurvey_score'])<0){
        $pre = 'neg';//add neg if less than 0
      } 
      if (intval($entry['gsurvey_score']) === 0) {
        $pre = 'zero-';
      }
      array_push($total_scores,$pre . $entry['gsurvey_score']);
      $guess = array_push($total_guesses, $entry[3]);
    }    
      $gform_scores = array(          
           'scores' => $total_scores,
       );
     wp_localize_script('main-course', 'gformScores', $gform_scores); //sends data to script as variable     
}

let scores = gformScores.scores;//THIS IS THE VARIABLE PASSED via localize
countThem(scores)
function countThem(scores){

  scores.forEach(function(score){
    let bubble = document.getElementById(score);
    console.log(bubble)
    let count = parseInt(bubble.getAttribute('data-count'),10);
    count = count+1;
    bubble.setAttribute('data-count', count);
    bubble.setAttribute('style', 'border-top:' + (Math.ceil(count*3.5)) + 'px solid rgba(0, 179, 190,1);');
  })
}

The result is a form that you can submit and get results like you see below. Just the beginning of things but a step in the right direction I think.

After form submission the data is graphed and displayed. Boxes show your guess vs your actual score and combined scores of previous participants.

Tag Cloud from Gravity Form Entries WP Plugin

A tag cloud of filler text.

Based on a conversation I had on Tuesday there appeared to be a need to generate a tag cloud1 from Gravity Forms responses. I didn’t see any immediate solutions after browsing for plugins. Granted, I could have jerry rigged something by creating posts and doing something weird where I added the words as tags . . . but I’m trying to do things in a more sustainable way lately and I figured this wouldn’t be too tough.

I’m going to try to do a decent job of moving through the development process in stages. If you just want to mess with the plugin, it’s on GitHub.

Find a Decent Tag Cloud Library

I looked around and found wordcloud2.js. It seemed perfect. It has some real flexibility and the hard work has been done for me. I played around with a demo in CodePen. This lets me work out any kinks I might have in the js/html/css side of things before adding any WordPress and PHP complexities. If I don’t force patterns like this, I’ll add enough complexity that figuring out which thing I’m not understanding is much harder. It might take some extra time but it saves me quite a bit more in the long run.

Building the Plugin Foundation

enqueue the main scripts

Following my mantra of slowly adding complexity, first I added the scripts. They’re all nicely enqueued the way WordPress likes. They’re just the css and js that wordcloud2.js needs to work. After verifying these loading correctly, I can move on to phase two.

add_action('wp_enqueue_scripts', 'gqcloud_load_scripts');
function gqcloud_load_scripts() {                              
    wp_enqueue_script('gravity-cloud-main-js', plugin_dir_url( __FILE__) . 'js/gravity-cloud-main.js',array(), '1.0', false); 
    wp_enqueue_style( 'gravity-cloud-main-css', plugin_dir_url( __FILE__) . 'css/gravity-cloud-main.css');  
}

At this point I need two additional pieces to make sure all is working as expected. I need an HTML element with an ID and I need a little javascript that loads some data and targets that ID for the cloud creation.

I can make the HTML directly in the post easily enough and I know it works on based on my codepen testing.

<div id="demo" style="width: 1170px; height: 760px; position: relative;"></div>

There are a couple different ways I could add the javascript for the test but I opted to do it via content filter. That’s also why I’m initially loading the wordcloud2.js in the header rather than the footer. Load order matters and I’m loading this little script pretty randomly so I want to make sure the main script is there first. You’ll note in the script below I’m not trying to load any data from Gravity Forms yet, I’m just making sure all this stuff works how I expect it to.

//TEMPooooooorary
function my_the_content_filter($content) {
  $script = "<script>
let list = [['bar', 56], ['buzz', 72], ['spanish', 21], ['green', 11]];
var attempt = WordCloud(document.getElementById('demo'), { list: list } );
</script>";
  return $content . $script;
}
add_filter( 'the_content', 'my_the_content_filter' );

Seeing this work, I now know that any issues I have are going to be things I’ve done.

enqueue the little script

Now we’ll just take that little script and enqueue it properly. That’s just a matter of adding an additional line. Now we’re enqueueing two scripts and one css file. Once I make sure it all still works, I can move on to figuring out how to get the data.

add_action('wp_enqueue_scripts', 'gqcloud_load_scripts');

function gqcloud_load_scripts() {                              
    wp_enqueue_script('gravity-cloud-main-js', plugin_dir_url( __FILE__) . 'js/gravity-cloud-main.js',array(), '1.0', true); 
    wp_enqueue_style( 'gravity-cloud-main-css', plugin_dir_url( __FILE__) . 'css/gravity-cloud-main.css');  
    wp_enqueue_script('gravity-cloud-indiv-js', plugin_dir_url( __FILE__) . 'js/gravity-cloud-indiv.js',array('gravity-cloud-main-js'),'1.0', true); 
}

Getting the Data

Once again, I tried to keep one thing in motion at a time. First we want to get the data. Retrieving data from Gravity Forms is pretty easy if you’re familiar with the WordPress query loop. I started off by hard coding the form ID and the desired field ID. Once I made sure it was returning what I wanted I added the form ID and field ID options into the shortcode. I ended up with the function below that gets the data.

function get_gform_words($form_id, $fields){
	$search_criteria = array(
    'status'        => 'active',
);

  $sorting         = array();
  $paging          = array( 'offset' => 0, 'page_size' => 200);
  $total_count     = 0;

  $entries = GFAPI::get_entries($form_id, $search_criteria, $sorting, $paging, $total_count );
  $raw = "";
  $tag_data = [];
  $fields_array = explode(',',$fields);
  foreach ($entries as $key => $value) {	 
     foreach ($fields_array as $field_id) {
       $raw .= $value[$field_id];
     }
    
     //$common_removed = remove_common_words($raw); // this will be where I do the removal of common words
  	 $no_punctuation = preg_replace("/(?![=$%-])\p{P}/u", "",$raw); //removes punctuation
  	 $bits = preg_split('/\s+/', $no_punctuation);
     foreach ($bits as $key => $bit) {
      if(multiKeyExists($tag_data, $bit)) {
        $i = $tag_data[$bit] = $tag_data[$bit]+1;
      } else {
        $tag_data[$bit] = 1;
      }
     }   
  }
     //print("<pre>".print_r($tag_data,true)."</pre>");
     return $tag_data;
}

As a minor tip, if you’re trying to figure out PHP variables var_dump is fine but you’ll have a much better time using the bit of code below. It makes reading the arrays etc. much, much easier.

print("<pre>".print_r($foo,true)."</pre>");

The Shortcode

The shortcode ends up with three variables right now. The first is the form ID, followed by the field IDs you want, and finally the size of the font you want. You can see that they default to 1, 1, and 1.6 respectively if you leave them blank.

The more interesting portion is wp_localize_script, which we’re using to pass the php variables into the javascript.

function gqcloud_make_the_list( $atts, $content = null ) {
    extract(shortcode_atts( array(
         'id' => '', //gform ID   
         'fields' => '',//field IDs separated by commas
         'size' => '', //this determines the size of the font    
    ), $atts));         
    if($id){      
    	$id = $id;   
    } else {
      $id = 1;
    } 
    if ($fields){
      $fields = $fields;
    }  else {
      $fields = 1;
    }
     if ($size){
      $size = $size;
     } else {
      $size = 1.6;
     }
    $entries = get_gform_words($id, $fields);   
   //return $entries;
    $cloud_data = array(          
           'source' => json_encode($entries),
           'size' => $size,
       );
    wp_localize_script('gravity-cloud-indiv-js', 'cloudData', $cloud_data); //sends data to script as variable
	  return '<div id="gc-cloud" style="100%; height: 50vw; position: relative;">foo</div>';//gives us the HTML
}
add_shortcode( 'gcloud', 'gqcloud_make_the_list' );

On the javascript side of things, we have this.

let list = cloudData.source;//the localized script variable from the php that gives the data
let weight = cloudData.size;//the localized script variable from the php that sets the font size
let a = JSON.parse(list);
let b = [];
for(var i in a){
b.push([i, a[i]]);
}

var attempt = WordCloud(document.getElementById(‘gc-cloud’), {
list: b,
fontFamily: ‘Times, serif’,
rotateRatio: 0.5,
rotationSteps: 2,
backgroundColor: ‘#fff’,
drawOutOfBound: true,
gridSize: Math.round(16 * jQuery(‘#gc-cloud’).width() / 1024),
weightFactor: function (size) {
return Math.pow(size, weight) * jQuery(‘#gc-cloud’).width() / 1024;
},
minFontSize: 200,

});
[\javascript]

And that’s pretty much it. I’ve got to add an “ignore words” list but it’s functional and might be useful to someone else.


1 Welcome to 2008? While I mock many uses of the tag cloud there are some interesting applications in the right scenarios.

Gravity Forms to ACF Pattern

When you use Gravity Forms to make a post, you can provision ACF fields but what I found was that the data wasn’t showing up correctly until I manually went and updated the created post. I tried using the WordPress wp_update_post() function but found that didn’t do it.

I ended up taking a look at the post_meta in the database directly.1 That’s something that I find myself doing more and more. When you can look directly at evidence, do that. Don’t assume. So what I saw was this . . .
Screenshot of Sequel Pro showing the metadata associated with the post that Gravity Forms created.
You can see that the base custom fields are there. The data is visible.

Now I hit update and refreshed the database view and saw lots of new custom fields get generated. This data associates the human readable fields with the field keys that ACF creates. Note the underscores which prevent those fields from showing up in the backend of WP even if you have view custom fields selected.
New view showing all the new metadata fields that get generated.

I feel like this has something to do with acf/save_post but couldn’t figure out how to make that work. When my knowledge fails,2 I resort to force.

First, I turned on the ability to see the field keys in ACF. It’s easy to miss and easy to forget that this is a Screen Option in WP.
Showing the screen option at the top of the page that allows you to see the ACF field keys.

Once I could see that clearly, I felt typing in all that junk would take a while and be a place where I could make dumb errors. So I cut and pasted the data into a Google Sheet and used my old text manipulation tools to build the function that would build the text I needed.

="update_field("&$D$1&C2&$D$1&","&$D$1&D2&$D$1&",$post_id);"

That was cut/pasted into the plugin and hooked to the after submission hook that Gravity Forms has.

add_action( 'gform_after_submission_1', 'asphs_update_post_content', 10, 2 );

That triggers this function and everything now behaves.

function asphs_update_post_content( $entry, $form ) {
    //getting post
        $post_id = get_post( $entry['post_id'] );
        update_field("_personal_information_first_name","field_5b672aa250437",$post_id);
	update_field("_personal_information_last_name","field_5b672aa850438",$post_id);
	update_field("_personal_information_email","field_5b677443f6a3b",$post_id);
	update_field("_personal_information_phone_number","field_5b672ab050439",$post_id);
	update_field("_personal_information_university_affiliation","field_5b672ab75043a",$post_id);
	update_field("_personal_information_private","field_5b672afd156eb",$post_id);
	update_field("_personal_information_biography","field_5b672adeed779",$post_id);
	update_field("_personal_information_profile_picture","field_5b672c956690c",$post_id);
	update_field("_personal_information_expertise","field_5b9871dce76ec",$post_id);
	update_field("_personal_information","field_5b672a9150436",$post_id);
	update_field("_location_street_address","field_5b6727dba1a94",$post_id);
	update_field("_location_city","field_5b6727e5a1a95",$post_id);
	update_field("_location_state_province","field_5b9daddced8c0",$post_id);
	update_field("_location_zip_code","field_5b6727eba1a96",$post_id);
	update_field("_location_country","field_5b6727f5a1a97",$post_id);
	update_field("_location","field_5b6727c3a1a93",$post_id);
    $i = wp_update_post( $post_id );

}

1 I use Sequel Pro.

2 And many, many Google searches . . .

Auto Featured Image for Gravity Forms Posts by Response

This scenario is fairly specific, Gravity Forms to post and adding a specific featured image based on a form field but the ease of assigning a featured image via the media post ID is hand elsewhere and it’s always nice to document more ways to tweak Gravity Forms.

Step One

Upload your images to the WP Media Library. After uploading the images you want to use, go to the Media Library and change the view to list view. If you mouse over the edit button, you’ll see a URL appear in the bottom right of your browser window.
Shows clicking on list view in WordPress media file.

Setup Your Form

Take note of the entry ID of the form element that’s going to determine the featured image. It’s likely the same number you’d get if you counted the fields from top to bottom but if you made them and rearranged them it could be something else. If you mouse over the field in the form editor, you’ll see the form ID in blue.
Screenshot of gravity forms form ID on mouseover.

The Code

Now we’re just writing a bit of PHP to tie into the form. In this case I’m tying it just to form 5 with this action add_action( ‘gform_after_submission_5’, ‘altlab_timeline_featured_image’, 10, 2 );. Leaving off the _5 would apply it to all forms and changing the 5 to another number would target another form.

In this example I’m using field 3/question 3 to determine my featured image. It’s just a series of if statements to set our $img_id and then a final set_post_thumbnail to attach the image to the right post.

function altlab_timeline_featured_image($entry, $form){
	$timeline_type = rgar($entry, '3');
	if ($timeline_type  == 'First computer I owned' ){
		$img_id = 6895;
	}
	if ($timeline_type  == 'First time online'){
		$img_id = 6899;
	}
	if ($timeline_type  == 'First email'){
		$img_id = 6900;
	}
	if ($timeline_type  == 'First cell phone'){
		$img_id =  6898;
	}

	set_post_thumbnail( $entry['post_id'], $img_id );
}
add_action( 'gform_after_submission_5', 'altlab_timeline_featured_image', 10, 2 );

Backdating a Gravity Forms Created Post

This is something that’ll come in handy with forms creating timeline events. You can add a date field to the form and this will change the post date to match it. It might work the other way too, I didn’t try that.

Take note of the notes below as this is setup for the date being field one of the form and for the form having ID 5.

/*
*******
*******
*********************************TIMELINE STUFF****************************
*******
*******
*/
function special_timeline_update($entry, $form){
	$time = rgar($entry, '1');//assumes the gform date field is field 1 if not change it
	$post = get_post( $entry['post_id'] );
	$post->post_date = $time;
	$post->post_date_gmt = get_gmt_from_date( $time );
	wp_update_post($post);
}

add_action( 'gform_after_submission_5', 'special_timeline_update', 10, 2 );//set to run off form 5 if not change it