Skip Navigation

[Resolved] Dynamically Link Guest Users to CRED Forms Where Parent Posts are Pre-Selected

This support ticket is created 7 years, 1 month ago. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

Tagged: 

This topic contains 13 replies, has 2 voices.

Last updated by Christian Cox 7 years ago.

Assisted by: Christian Cox.

Author
Posts
#581923

My site currently has two user roles (Ship Owner and Reseller) and 6 CPTs (Vessel, Voyage, Ticket, Variation, Booking and Passenger). Ship Owners can Admin all of their own content, Resellers can only Create and Edit their own Bookings and Passengers.

Currently, after placing a Booking, a Reseller will be prompted to create Child 'Passenger' posts through a CRED Form that is associated with the Parent booking by default.

What I'd like is the ability for a Reseller to share a unique link to the Passenger CRED form that a Guest User could then complete. This form would need to automatically be assigned to the parent booking without the Guest user needing to choose a Parent.

One other way around this could be to have a page where Guest User searches for a Booking Post and verifies a few other details of that booking before being given a form to create the child post against it.

If any of the above is possible, could you advise on what might be the best approach?

#582122

Hi, if I recall correctly we discussed a few different ways to approach this. What if you:
- Create a custom Page called "Passenger Signup" or something similar where your Passenger CRED form will live.
- Set up a single Booking post Content Template or Template Layout. Insert a Create Child Post link using the CRED button.
- In the popup, select the Passenger Signup page as the destination page and insert some text like "Right click to copy distributable link address" for the link text
- Choose "Set the parent according to the currently displayed content" and insert the form in your template.
- Now on the front-end Booking page, your Reseller can right click to copy the link to send to potential Passengers.

This approach isn't highly secure, meaning that it might be possible to guess another parent Booking ID and use the form to sign up as a Passenger for another Booking by manipulating the URL parameters. The alternative here is to generate unique strings that cannot easily be guessed, and apply that string to a Booking post using a repeating custom field. I can't recall if you preferred one option over the other, so please let me know which you would like to pursue.

#582148

We would have to go for the more secure option, am I right in saying that would be the same process as the first, with the addition of generating unique strings?

#582162

Similar, but you won't use the Create Child Post link directly. Instead you will construct your own link using a unique string.
- When the Booking post is created, use the cred_save_data hook to save a unique string in a custom field on that Booking post. A GUID can be generated using this code sample: hidden link
- When you display the Booking post to your Reseller, you will construct a text link containing the unique string as a URL parameter, and display it on the screen. The link should point to the page that includes your edit form. This can be copied and distributed to any potential Passengers. It will look something like this:

<em><u>hidden link</u></em>

- Create your child Passenger CRED form. In the parent field, use the wpv-post-id shortcode to define the parent post. This will work because we will place the CRED form in a View of Bookings, so wpv-post-id will refer to the current Booking in the loop. Hide the field with CSS so that it's not visible to Passengers:

<div class="form-group" style="display:none;">
  <label>Booking</label>
  [cred_field field='_wpcf_belongs_booking_id' value='[wpv-post-id]' select_text='--- not set ---' class='form-control' output='bootstrap']
</div>

- On the passenger-form page, include a View of all Bookings filtered by the unique string custom field, provided by the URL attribute "ref". This means that only one Booking should be shown in the results - the one that has the matching unique ID. If someone tries to fake an ID, no matching Booking will be found and the form will not be shown. In the Loop Output of this View, insert your CRED form using a shortcode, something like this:

<wpv-loop>
    Booking: [wpv-post-title]<br />
    [cred_form form='new-child' form_name='New Child']
</wpv-loop>

- When the CRED form is submitted, the child post will be automatically associated with the parent post.

#582169

Okay, most of the above should be no problem but I'm getting caught up on saving the GUID

The part I'm sure of is where to place the $guid value in add_post_meta in order to get it to fill the field.

I have the following...

function getGUID(){
    if (function_exists('com_create_guid')){
        return com_create_guid();
    }else{
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = chr(123)// "{"
            .substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,20,12)
            .chr(125);// "}"
        return $uuid;
    }
}


add_action('cred_save_data', 'save_booking_guid_func',10,2);
function save_booking_guid_func($post_id, $form_data)
{
    // if a specific form
    if ($form_data['id']==248)
    {
	$GUID = getGUID();
        if (isset($_POST['booking_unique_id']))
        {
            // add it to saved post meta
            add_post_meta($post_id, '__booking_unique_id', $_POST[$GUID], true);
        }
    }
}
#582337

Okay, this may be bad practice (so do correct me if I should do it differently) but I've managed to get the GUID generated to the custom field by creating a shortcode with it and then making that shortcode the default field value in the CRED form.

For now at least this has allowed me to find the second issue, which is that the brackets { and } at either end of the GUID are preventing the process from working.

Basically the field value is currently generated as something like {C02344AB-D328-5A40-7C2B-49670D99E908}. Because the URL removes the {}, the Ref doesn't match the field value. If I go to the Booking post and manually remover the {}, the URL to the View with the form works successfully.

Now, I have tried removing the {} from the getGUID() code but with no luck, so I assume that com_create_guid already exists and they are created within that.

Having said that, I've tried adding the following with no luck...

function getGUID($trim = true){
    if (function_exists('com_create_guid')){
        if ($trim === true)
            return trim(com_create_guid(), '{}');
        else
            return com_create_guid();

and

return trim(com_create_guid(), '{}');
function getGUID(){
    if (function_exists('com_create_guid')){
        return com_create_guid();
    }else{
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = chr(123)// "{"
            .substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,20,12)
            .chr(125);// "}"
        return $uuid;
    }
}
add_shortcode( 'Booking_GUID', 'getGUID' );

// Code in New Booking Form
<div class="form-group" style="display:none;">
		<label>GUID</label>
		[cred_field field='booking_unique_id' post='booking' value='[Booking_GUID]' urlparam='' class='form-control' output='bootstrap']
	</div>

Can you suggest a way that might work in removing the {} from the GUID or the field value? Is there a way to remove with cred_save_data or cred_form_validate?

#582472

I was thinking something like this:

function getGUID(){
    if (function_exists('com_create_guid')){
        return com_create_guid();
    }else{
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = chr(123)// "{"
            .substr($charid, 0, 8).$hyphen
            .substr($charid, 8, 4).$hyphen
            .substr($charid,12, 4).$hyphen
            .substr($charid,16, 4).$hyphen
            .substr($charid,20,12)
            .chr(125);// "}"
        return $uuid;
    }
}

add_shortcode( 'toolset_guid', 'toolset_guid_func');
function toolset_guid_func($atts)
{
  $GUID = getGUID();
  return trim($GUID, "{}");
}

Then in your form:

[cred_field field='booking_unique_id' post='booking' value='[toolset_guid]' urlparam='' class='form-control' output='bootstrap']
#582501

Okay, that's done the trick.

Quick note on the above, apologies if Debug Info would have helped, I've only just figured out why that field was appearing in some instances and not others! (not included this time as problem was solved, but will if requested in future)

I have a couple of follow up questions...

1. For each booking the New Passenger form will have to be filled out as many times as the value in the booking field 'Number of Places Booked'.

I'm know I could show that numeric field value and also show a view calculating how many child post the booking has to construct a statement for the user. What I'm wandering is if the amount of times the form can be filled in can be limited by that field value with a message after the last entry to say the process is complete.

For example, if the value in the Booking field is 3, the CRED form will allow 3 Passenger posts to be created. after the third is created the form will no longer appear and a message will show to state completion.

Is the above possible? If you can think of a more user-friendly way please let me know this also!

2. This form data may include passport and medical information alongside other personal info. Could you give me some idea of how secure this data is when stored within our system? I ask as this may be a big sticking point when selling to our customers.

When the afore-mentioned form is filled in don't think we have to display the data to the user (though perhaps we could email it to them) so that may help. I will also set up a secure site certificate at some point but I don't really understand what impact that would have.

#582505

Another quick question here...

When the URL contains the correct GUID the process works - a single form appears on screen for the single found booking.
Example at...
hidden link

Adjusting the GUID brings up "No Items Found" as expected.

However, typing the original page URL hidden link or hidden link will display what I think is as any forms as there are bookings. Is there a way to stop this happening?

#582513

1. For each booking the New Passenger form will have to be filled out as many times as the value in the booking field 'Number of Places Booked'...What I'm wandering is if the amount of times the form can be filled in can be limited by that field value with a message after the last entry to say the process is complete.
It sounds like this could be accomplished with a conditional that checks the number in the booking field and compares it to something else - I assume the total number of Passengers that are already created for the current booking, correct?
So you could create a View of Passengers, filtered by post relationship, where the parent Booking ID is provided by a shortcode attribute. You will pass the current Booking ID into the View using the wpv-post-id shortcode.

<wpv-loop>
    Booking: [wpv-post-title]<br />
    [wpv-view name='your-view-of-passengers' booking='[wpv-post-id]']
</wpv-loop>

Inside that View, you can use the wpv-found-count shortcode to determine the total number of child Passengers already created. This will allow you to create a conditional inside the View of Passengers that compares the booking field from the Booking post, and the number of child passengers. This way you can show your form or show the message instead.
See "Accessing the arguments" here:
https://toolset.com/documentation/user-guides/passing-arguments-to-views/
See information about accessing fields from other posts using the ID attribute here:
https://toolset.com/documentation/user-guides/views-shortcodes/#wpv-post-field

2. This form data may include passport and medical information alongside other personal info. Could you give me some idea of how secure this data is when stored within our system? I ask as this may be a big sticking point when selling to our customers.
It is no more or less secure than any other custom field information or post information in your database. WordPress stores most information in plain text, or in serialized data structures of plain text. If anyone gained access to your database, all custom field data would be fully accessible, as well as all post data. Neither WordPress nor Toolset offer native support for encryption of custom fields. As far as I know, only User passwords are encrypted in the WP database.

#584967

Here's a quick message to keep the thread from closing - I'll test the above as soon as possible and get back to you.

#585344

Thanks, I'll stand by.

#586453

On Item 1

Okay, I appear to have the conditional display working now, though there's just one issue I've found, as follows...

If somebody decides to remove the GUID from the URL (i.e. going to hidden link as opposed to hidden link) they will be met with what appears to be an endless list of the same form over and over again. From what I can tell it displays once for every booking on the site.

Is there a way to prevent this from happening?

On Item 2

Understood - Is creating custom code for encryption of a small number of custom fields something your support would be able to assist me with, or point me in the right direction for? (If yes I'll open a new ticket)

#586477

If somebody decides to remove the GUID from the URL...they will be met with what appears to be an endless list of the same form over and over again
I see, in this case you can use conditional HTML to suppress the View unless the URL parameter exists and contains some value. I can't recall if I shared this shortcode with you:

add_shortcode( 'wpv-post-param', 'wpv_post_param_shortcode' );

function wpv_post_param_shortcode( $atts ) {
  if ( !empty( $atts['var'] ) ) {
    $var = (array)$_GET[$atts['var']];
    return esc_html( implode( ', ', $var ) );
  }
}

This shortcode lets you access URL parameters, and will give you the ability to test the "ref" URL parameter value in a conditional like so:

[wpv-conditional if="( '[wpv-post-param var='ref']' eq '' )" evaluate="false"]
  [wpv-view name='your-view-slug']
[/wpv-conditional]

Note that we're checking if the URL param "ref" is equal to a blank string, and we're using evaluate="false" to negate that. You may need to register the wpv-post-param shortcode in Toolset > Settings > Frontend Content > Functions inside Conditional Evaluations.

Is creating custom code for encryption of a small number of custom fields something your support would be able to assist me with?
We can't help with that, sorry. Our software is not designed to support encrypted data like this, so not only data storage but also data display, sorting and filtering, and administration would require major changes. My recommendation here is to avoid storing PII at all costs.