Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict access to pages based on cookies/form submissions #162

Open
wants to merge 6 commits into
base: staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions wp-content/themes/cjet/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,139 @@ function load_dashicons_front_end() {

}
add_action( 'wp_enqueue_scripts', 'load_dashicons_front_end' );

/**
* Set a user cookie to grant access to specific pages when a specific form
* is submitted through Gravity Forms.
*
* @param Obj $entry The form entry that was just submitted
* @param Obj $form The current form
*/
function set_cookie_on_form_submission( $entry, $form ) {

// uncomment to review the entry
// echo "<pre>".print_r($entry,true)."</pre>"; die;

// loop through $form fields to find field with access_ID as its label
foreach( $form['fields'] as $field ) {

if( 'access_ID' == $field->label ) {

$access_ID_field_ID = $field->id;

}

}

// if an access_ID field is found, use its value for $from_page and set the cookie
if( $access_ID_field_ID ) {

$from_page = $entry[$access_ID_field_ID];

// make sure $from_page is a valid post id before setting the cookie
if( is_string( $from_page ) && get_post_status( $from_page ) ) {

// set the cookie
setcookie( 'unrestrict_'.$from_page, 1, strtotime( '+365 days' ), COOKIEPATH, COOKIE_DOMAIN, false, false);

// redirect so we dont land on gravity forms "thank you" page
wp_redirect( get_permalink( $from_page ) );

}

}

}
add_action( 'gform_after_submission', 'set_cookie_on_form_submission', 10, 2 );

/**
* Grant access to pages that should be restricted
* based on if a cookie is set that matches the specific post ID
*
* If cookie is not set, try and find a form with a name identical to the current page
* and display it if found.
*
* @param Str $content The entire post content
*
* @return Str $content The entire post content
*/
function restrict_access_to_pages_by_cookie( $content ) {

global $post;

// see if current post/page is supposed to be restricted
$restrict_access = get_post_meta( $post->ID, 'cjet-content-restrict-access' )[0];

// go ahead andd display if not supposed to be restricted
if( ! $restrict_access || $restrict_access === 0 || is_user_logged_in() ) {

return $content;

}

// check if user has submitted this pages form, if not, show only form
if( ! isset( $_COOKIE['unrestrict_'.get_the_ID()] ) ) {

// but wait, what if this is a child page?
// we need to see if a cookie has been set to grant access to the parent page
// first, grab the top-level parent of this page
if( $post->post_parent ) {

$ancestors = get_post_ancestors( $post->ID );
$root = count( $ancestors ) - 1;
$parent = $ancestors[$root];

} else {

$parent = $post->ID;

}
Comment on lines +189 to +202
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than checking the immediate parent, should we check instead whether the cookie's ID is in the array of ancestors?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could do that. In your opinion, what would make that more beneficial than this way?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The possibility of a metered page having a grandchild or great-grandchild page. They're already using great-grandchild pages: https://learn.inn.org/startup-introduction/chapter-1-where-to-start-in-nonprofit-news/creating-a-business-model/idea-generation/


// if an actual parent was found (parent id doesn't match current post id),
// let's see if a cookie for it (parent) exists
if( $parent != $post->ID ) {

// if a cookie is found, let's display the content
if( isset( $_COOKIE['unrestrict_'.$parent] ) ) {

return $content;

// else if no cookie is found, let's redirect the user to the top-level parent
// so they can fill out the form
} else {

wp_redirect( get_permalink( $parent ) );

}

}

// make sure the GF methods exist before we try using them
// that way we don't see any scary 500 errors
if( method_exists( 'RGFormsModel', 'get_form_id' ) && method_exists( 'RGForms', 'get_form' ) ) {

// try and find a form that matches the current post title
benlk marked this conversation as resolved.
Show resolved Hide resolved
$form = RGFormsModel::get_form_id( $post->post_title );

// if a form is found with a matching name, show it to the user
if( $form ) {

$form = RGForms::get_form( $form );
return '<h4>'.__( 'The content on this '.$post->post_type.' is restricted. Please fill out the form below to gain access.', 'cjet' ).'</h4>'.$form;

}

}

return '<h4>'.__( 'The content on this '.$post->post_type.' is restricted.', 'cjet' ).'</h4>';

} else {

// user has submitted this pages form in the last 365 days
// show content
return $content;

}

}
add_action( 'the_content', 'restrict_access_to_pages_by_cookie' );
52 changes: 51 additions & 1 deletion wp-content/themes/cjet/inc/metaboxes.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,54 @@ function cjet_content_date_metabox() {

}

largo_register_meta_input( 'cjet_content_date' );
largo_register_meta_input( 'cjet_content_date' );

/**
* Adds metabox to allow pages/posts to be hidden behind cookies
*/
largo_add_meta_box(
'cjet_content_restrict_access_metabox',
__('Restrict Access', 'cjet'),
'cjet_content_restrict_access_metabox',
array( 'page', 'post' )
);

function cjet_content_restrict_access_metabox() {

global $post;

$values = get_post_custom( $post->ID );
$checked = isset($values["cjet-content-restrict-access"][0]) ? 'checked="checked" ' : '';
wp_nonce_field( 'largo_meta_box_nonce', 'meta_box_nonce' );
?>

<p>Should this <?php echo get_post_type( $post->ID ); ?> be hidden behind a cookie?</p>
<input type="checkbox" name="cjet-content-restrict-access" <?php echo $checked; ?>/>
<?php

}

/**
* Largo metabox API doesn't yet support checkboxes as an input type
* so we need a special function to save this checkbox field for restricting content (for now)
*
* @param int $post_ID The ID of the post we're saving to
*
* @return int $post_ID The ID of the post we're saving to
*/
function save_content_restriction_checkbox( $post_ID = 0 ) {

$post_ID = (int) $post_ID;
$post_type = get_post_type( $post_ID );
$post_status = get_post_status( $post_ID );

if ( $post_type && isset( $_POST['cjet-content-restrict-access'] ) && $_POST['cjet-content-restrict-access'] == 'on' ) {
update_post_meta( $post_ID, 'cjet-content-restrict-access', 'false' );
} else {
delete_post_meta( $post_ID, 'cjet-content-restrict-access' );
}

return $post_ID;

}
add_action( 'save_post', 'save_content_restriction_checkbox' );