Skip to content

Instantly share code, notes, and snippets.

@spivurno
Created September 16, 2013 18:51
Show Gist options
  • Star 12 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save spivurno/6584835 to your computer and use it in GitHub Desktop.
Save spivurno/6584835 to your computer and use it in GitHub Desktop.
Gravity Forms Cookies // Saves the query string parameters from a users visit to a cookie and allows these values to be populated via Gravity Forms' Dynamic
<?php
/**
Plugin Name: Gravity Forms Cookies
Plugin URI: http://ounceoftalent.com/
Description: Saves the query string parameters from a users visit to a cookie and allows these values to be populated via Gravity Forms' Dynamic Population feature.
Version: 1.5
Author: David Smith
Author URI: http://ounceoftalent.com
License: GPL2
*/
class GFCookie {
public static $cookie_prefix = 'gfc_';
public static $session = false;
public static $fresh_cookies = array();
public static function init() {
//GFCookie::delete_cookies(); exit;
if(!is_admin()) {
add_action('parse_request', array('GFCookie', 'save_cookie'), 9);
add_action('gform_pre_render', array('GFCookie', 'load_cookie'));
}
add_shortcode('gf_cookied_link', array('GFCookie', 'cookied_link_shortcode'));
}
public static function save_cookie() {
// if cookies are not enabled, default to session use
// start the session regardless of $_GET being empty as session may have been previously populated
if(!self::cookies_enabled()) {
session_start();
}
// don't do anything with cookie if there is no data
if(!empty($_GET))
self::save_get_data();
self::save_server_data();
}
public static function load_cookie($form = null) {
$cookie = self::get_cookie_data(false);
foreach($cookie as $key => $value) {
// skip cookies that were not added by us
if(strpos($key, self::$cookie_prefix) === false)
continue;
// load cookie value into $_GET for population into Gravity Forms
$key = str_replace(self::$cookie_prefix, '', $key);
$_GET[$key] = $value;
}
// if gfc referrer is set, find {referer} merge tag and replace
if(self::get_cookie_data('HTTP_REFERER')) {
foreach($form['fields'] as &$field) {
if(strpos(rgar($field, 'defaultValue'), '{referer}') !== false)
$field['defaultValue'] = str_replace('{referer}', self::get_cookie_data('HTTP_REFERER'), $field['defaultValue']);
}
}
return $form;
}
public static function get_cookie_data($key = false) {
$session = isset($_SESSION) && is_array($_SESSION) ? $_SESSION : array();
$cookie = self::cookies_enabled() ? $_COOKIE : $session;
// cookies that have not yet been sent through the header are merged with existing cookies
$cookie = array_merge($cookie, self::$fresh_cookies);
if($key === false)
return $cookie;
$gfc_key = self::$cookie_prefix . $key;
return rgar($cookie, $gfc_key);
}
public static function save_get_data() {
$reserved_words = array('attachment_id', 'author', 'author_name', 'calendar', 'cat', 'category', 'category__and', 'category__in', 'category__not_in', 'category_name', 'comments_per_page', 'comments_popup', 'cpage', 'day', 'debug', 'error', 'exact', 'feed', 'hour', 'link_category', 'm', 'minute', 'monthnum', 'more', 'name', 'nav_menu', 'nopaging', 'offset', 'order', 'orderby', 'p', 'page', 'page_id', 'paged', 'pagename', 'pb', 'perm', 'post', 'post__in', 'post__not_in', 'post_format', 'post_mime_type', 'post_status', 'post_tag', 'post_type', 'posts', 'posts_per_archive_page', 'posts_per_page', 'preview', 'robots', 's', 'search', 'second', 'sentence', 'showposts', 'static', 'subpost', 'subpost_id', 'tag', 'tag__and', 'tag__in', 'tag__not_in', 'tag_id', 'tag_slug__and', 'tag_slug__in', 'taxonomy', 'tb', 'term', 'type', 'w', 'withcomments', 'withoutcomments', 'year', 'DBGSESSID');
foreach($_GET as $key => $value) {
if(!in_array($key, $reserved_words)) {
self::save_data($key, $value);
}
}
}
public static function save_server_data() {
$server_keys = array('HTTP_REFERER');
foreach($_SERVER as $key => $value) {
if(in_array($key, $server_keys))
self::save_data($key, $value);
}
}
public static function save_data($key, $value) {
$gfc_key = self::$cookie_prefix . $key;
if(self::cookies_enabled()) {
if(!rgar($_COOKIE, $gfc_key)) {
setcookie($gfc_key, $value, time() + 60*60*24*60, '/');
self::$fresh_cookies[$gfc_key] = $value;
}
} else {
if(!rgar($_SESSION, $gfc_key)) {
$_SESSION[$gfc_key] = $value;
self::$fresh_cookies[$gfc_key] = $value;
}
}
}
/**
* WP uses cookies by default so if $_COOKIES global is empty, cookies are likely not enabled
*
*/
public static function cookies_enabled() {
return !empty($_COOKIE);
}
public static function delete_cookies() {
foreach($_COOKIE as $key => $value) {
if(strpos($key, self::$cookie_prefix) !== false) {
self::delete_cookie($key);
}
}
}
public static function delete_cookie($key) {
setcookie($key, null, time() - 3600, '/');
}
public static function cookied_link_shortcode($atts) {
extract( shortcode_atts( array(
'url' => false
), $atts ) );
return !$url ? '' : gf_get_cookied_link($url);
}
}
GFCookie::init();
if(!function_exists('gf_get_cookied_link')) {
function gf_get_cookied_link($url) {
$cookies = GFCookie::get_cookie_data();
$gfc_cookies = array();
foreach($cookies as $key => $value) {
if(strpos($key, GFCookie::$cookie_prefix) !== false) {
$key = str_replace('gfc_', '', $key);
$gfc_cookies[$key] = str_replace(array('http://', 'https://'), '', $value);
}
}
return add_query_arg($gfc_cookies, $url);
}
}
@spivurno
Copy link
Author

spivurno commented May 4, 2021

@Cometeelcoco Fantastic!

@adonnan
Copy link

adonnan commented Apr 21, 2022

What type of cache exclusion do you recommend for implementing this on a wpengine hosted website? This seems to only work when you're logged during my testing.

@spivurno
Copy link
Author

@adonnan Does WP Engine support exempting any cookie with a prefix? If so, exempting any cookie with the "gfc_" prefix should do the trick.

@adonnan
Copy link

adonnan commented Apr 21, 2022

@spivurno That did the trick, thanks! I've been trying to figure that one out for a while.

@spivurno
Copy link
Author

Glad to help, @adonnan!

@taylor-onfido
Copy link

@maan1234, I'm seeing the same issue with first time visitors. Your solution of returning true from cookies_enabled seems to fix the issue. Would this change introduce any new potential issues with how this is currently implemented?

@spivurno, thanks for the great snippet!

@spivurno
Copy link
Author

@taylor-onfido My pleasure!

@amar8105alva
Copy link

Wow David, 10 years ago and still found useful your creations, like this one. One thing: how can implement a way to update the cookies created by query string when a new query string is created? I saw the part //GFCookie::delete_cookies(); exit; at beginning but how to use this function to clear the cokies created? Kind regards

@spivurno
Copy link
Author

@amar8105alva Glad you're still finding this useful!

You can call GFCookie::delete_cookies() anytime before content is being rendered to the screen to delete all cookies created by GFCookie. For example, you could do something like:

add_action( 'init', function() {
    GFCookie::delete_cookies();
}, 9 );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment