1

My client has a "resource" blog with articles and PDFs that are available for download.

They would like for their users to enter in an email address before being allowed to download the PDFs (I know). The form would save the entry into the database and email an admin the information for a possible follow-up (I know..). They would also like for the user's data to be saved for that session so they don't have to fill out the form over-and-over if they choose to download other articles. They do not want the user to have to login or register.

I have this working outside of ExpressionEngine2 and Freeform, using $_SESSION variables to check if the form was submitted and saving the $_POST data into the $_SESSION array for auto-populating the form fields on subsequent article pages. The user just has to hit Submit again on the form, which is fine.

However, when implementing in EE 2.7.3 using FreeForm Pro 4.1.3, using the default form action, the POST and SESSION arrays are empty after submission. If I substitute the Freeform form:action it works as expected, but of course the form results aren't stored in the database or emailed to the admin.

They love the Freeform interface and ability to see and export previous entries. Also, I need to do the form submission check server-side, so a user can't just view the source and download the PDF without filling out the form.

Is there another way to accomplish this? I am a hook novice. Any help or insight is most appreciated.

Here's my current code on the blog listing template:

<?php session_start(); ?>
<!DOCTYPE html>
<head>
...
<body>
...
{exp:channel:entries channel="blog"}
        <h1>{title}</h1>

        <?php // SET VAR FOR FORM SUBMIT
            $submit = ee()->input->get_post('submit', TRUE); ?>

        <?php // IF FORM NOT FILLED OUT
            if ( empty($submit) ) { ?>

            <a class="download-prompt" title="Download Attachment" href="#"><strong>Download Attachment:</strong> {exp:channel:entries channel="blog"}{title}{/exp:channel:entries}</a>

            <!-- Hidden Contact Form - Shown on '.download-prompt' Click -->
            <div class="contact-form">
                {exp:freeform:form
                    form_id="16"
                    required="email"
                }
                <div class="line">
                    <label>Email <span class="required_item">*</span></label>
                    <input type="text" name="email" id="freeform_email" placeholder="Email" value="<?php if (!empty($_SESSION['email'])) { echo $_SESSION['email']; } ?>">
                </div>
                <div class="line">
                    <input type="submit" name="submit" value="Submit">
                </div>
                {/exp:freeform:form}
            </div><!-- /.contact-form -->


        <?php // ELSE IF FORM IS FILLED OUT
        } else if ( !empty($submit) ) { ?>

            <?php // Save each POST value in SESSION
            foreach ( $_POST as $key => $value ) {
                ${$key} = $value;
                $_SESSION[$key] = $value;
            }
            ?>

            <p>Thank you message.</p>

            <!-- Hidden iFrame to Auto Download Attachment -->
            <script type="text/javascript">
            $(document).ready(function() {
                $('<iframe src="/resources/download.php?file_source={blog_attachment}"></iframe>').appendTo('body').hide();
            });
            </script>


        <?php // ELSE SOMETHING BROKE
        } else { ?>
            <h3>Something went wrong. Please try again.</h3>
            <p><a href="{page_url}">Try again.</a></p>
        <?php } ?>

        {/exp:channel:entries}

3 Answers 3

1

I seem to recall freeform processes the form before returning you to the return page, loosing post data. You can specify %%entry_id%% in the return param and use that to do a look up of the entry and set a cookie or some such.

I've done something similar but used stash to store session vars. Its not perfect but achieves a similar outcome.

1
  • Thank you for your answer. This approach met all of my client's needs. I'll post my results for others below. +1
    – josh
    Jan 20, 2014 at 21:21
0

Have you considered Protected Links? (I haven't tried it myself so can't speak to its quality, but it appears to do what you're aiming for).

0

Based on the direction from @stuartmcd69 here's what I came up with...

First, I had to split this out into two templates and add the Stash module (which is awesome) and the Freebie module (because I'm also using Structure for page management).

The Stash variables take place of the $_SESSION variables from my first attempt. Freebie allows me to ignore anything after '/download' in the URL so Freeform can use the %%entry_id%% and channel:entries can grab the correct attachment based on {url_title}.

If you have difficulty retrieving the Freeform Entries, make sure you check the status... that took me a bit to figure out from the docs (e.g. status="pending|open").

Blog Listing Template:

{exp:freeform:form 
    form_id="16" 
    required="first_name|email" 
    return="/{segment_1}/download/{segment_2}/%%entry_id%%"
}
<div class="line">
    <label>First Name <span class="required_item">*</span></label>
    <input type="text" name="first_name" id="freeform_first_name" placeholder="First Name" value="{exp:stash:get name='first_name'}">
</div>
<div class="line">
    <label>Email <span class="required_item">*</span></label>
    <input type="text" name="email" id="freeform_email" value="{exp:stash:get name='email'}">
</div>
<div class="line">
    <input type="submit" name="submit" value="Submit">
</div>
{/exp:freeform:form}

Download Template:

<!-- Save Entry to Stash Vars -->
{exp:freeform:entries 
    form_id="16" 
    dynamic="no" 
    status="pending|open" 
    entry_id="{freebie_4}" limit="1"
}
    {exp:stash:set 
        type="variable" 
        dynamic="yes" 
        save="yes" 
        match="#^[a-zA-Z0-9\@\.,\s\-]+$#" 
        scope="user"
    }
        {stash:first_name}{freeform:field:first_name}{/stash:first_name}
        {stash:email}{freeform:field:email}{/stash:email}
    {/exp:stash:set}

    {if freeform:no_results}
        <p>There was an error. Please try again.</p>
    {/if}
{/exp:freeform:entries}

<!-- Hidden iFrame to Auto Download Attachment -->
{exp:channel:entries channel="blog" dynamic="no" url_title="{freebie_3}" limit="1"}
<script type="text/javascript">
    $(document).ready(function() {
        $('<iframe src="/resources/download.php?file_source={blog_attachment}"></iframe>').appendTo('body').hide();
    });
</script>
{/exp:channel:entries}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.