When we re-did our DLINQ site, I set up a custom reservation system mixing Events Calendar Pro and Gravity Forms. One piece was sending out confirmation emails that include a URL that would enable people who registered to cancel their reservations. It was just a URL in the email with a URL parameter that acts as a code to confirm reservation deletion. So it’d look something like this.
https://multisitetwo.local/event/strange-tools-creative-applications-of-ai/?delete=jBkR9RK6wKBdMxSkY0RW
A number of our reservations were being canceled but people indicated they weren’t doing it. It appears that our email filtering/security service was scanning email URLs for security and that was resulting in the URLs being visited . . . and the reservations being canceled. I did not anticipate this.
So what I needed to was do two things. I changed the function from deleting the Gravity Forms submission to just altering the field where we register attendance to “canceled.”1 You can see that PHP function change below. It’s using the Gravity Forms API pattern.
//new option is non-destructive and just sets a value of 'Canceled' for the right field by ID GFAPI::update_entry_field($entry_id, 8,'Canceled'); //old result was a removal of the entry entirely GFAPI::delete_entry( $entry_id );
So now that we’re being a little more gentle with our reservation cancelation process, I also want to make sure a human is hitting this URL and doing something to confirm they want to cancel the reservation. To do that we’ll use a bit of javascript to set a new second URL parameter.
function deleteByHumanHand() {
if (window.location) {
const newUrl = new URL(window.location.href);//get the URL
const params = new URLSearchParams(newUrl.search);
let confirmed = false;//default confirmed to false just in case
if (params.has('delete') && !params.has('confirmed')) {//if we've got delete in the URL but NO confirmed
confirmed = confirm("Are you sure you want to delete your reservation?");//throw up a prompt
}
if (confirmed) {//if a person clicks yes on the prompt . . .
params.set("confirmed", "yes");//set confirmed to = yes
newUrl.search = params.toString();
window.location.replace(newUrl);//set the new URL
alert('Thank you for confirming the deletion.');//push a confirmation message - this may be unnecessary
}
}
}
As part of the larger PHP function that does the actual work, we’re now going to check for two URL parameters (confirmed and delete).
function dlinq_check_to_delete(){
$gf_workshop_registration_id = get_field('workshop_registration_form', 'option');
if( 'tribe_events' == get_post_type()){//is it an event?
if(isset($_GET["delete"]) && isset($_GET["confirmed"])){ //does it have two URL parameters set - delete and confirmed?
$passcode = $_GET["delete"];
$humanOk = $_GET['confirmed'];
$search_criteria = array(
'status' => 'active',
'field_filters' => array(
'mode' => 'any',
array(
'key' => '11',//field that contains our secret code
'value' => $passcode //find an entry with the right code value
)
)
);
$entry = GFAPI::get_entries($gf_workshop_registration_id, $search_criteria);
if(sizeof($entry)>0 && $humanOk != NULL){
$entry_id = $entry[0]['id'];
GFAPI::update_entry_field($entry_id, 8,'Canceled');//update the form entry
echo "<div class='notification delete-alert'>You have removed your reservation. Thank you.</div>";//echo out a confirmation message
}
}
}
}
1 I kind of knew this was a bad idea when I did it but I was fighting not to be a digital hoarder. I even wrote in the original comments that this might be a bad move.