• magician11

    (@magician11)


    Hi,

    Where would I begin by customising a form submission that first emails the person who submitted the form a link to check to confirm their email address.

    I.e. “click here to confirm your email address”

    I’m using Contact Form 7. I’m happy to code something.. but not sure where to start in generating and confirming that link?

    cheers,
    A

Viewing 15 replies - 16 through 30 (of 30 total)
  • Swayze

    (@shelbyswayze)

    Thanks to both of you for a good lesson.

    Thread Starter magician11

    (@magician11)

    Hi guys,

    It’s been a few months and people are starting to use it which is great.

    2 bugs I’m wondering you could shed some light on..

    1) There must be some update in Contact Form 7? As when the verification link gets clicked, this line is getting called twice. Which means that the original email gets sent out, and then an error is sent out saying the saved form data cannot be found (as that data is deleted once the email address is verified and the form contents is sent out).
    2) Someone pointed out that attachments are not saved/sent through with this verification process. I think that’s because the uploaded file is deleted at some point from wp-content/uploads/wpcf7_uploads/ ?

    Tips or a direction to work on it would be great.

    Moderator bcworkz

    (@bcworkz)

    Honestly, I never felt ‘template_redirect’ was the best hook for accepting verification. It seemed to be working, so I did not raise any objection. I don’t think CF7 has changed anything to cause double calls. It could be something in core template loading has changed.

    I advocate finding a better hook of course, but If you’re feeling attached to ‘template_redirect’ something can be arranged to stop the error event. You could create a special error handler to trap this specific event. It could be removed once the code has safely executed.

    Or you could throw an exception if you can somehow identify the second call. This kind of ties into another concern I have about deleting the transient immediately. More on that later, but if a flag were added to the transient that is no longer deleted when the mail is sent, you could identify a second call and abort the process.

    It appears to me that the verification link, after sending the email on, ends up loading the site home page? No message about “Thanks for verifying, your message has been sent on to whomever”? There’s all sorts of ways to pickup on the verification key and load a different page or insert a message under the header of the main page.

    It could also be part of a different process to handle the sent verification key. I propose sending the verification link to wp-admin/admin-post.php along with an ‘action’ parameter in addition to the verification key. For example, if you sent ‘action=wpcf7ev’ as an URL parameter, you would add your ‘check_for_verifier’ function to the actions ‘admin_post_nopriv_wpcf7ev’ and ‘admin_post_wpcf7ev’. If you’re familiar with WP AJAX methods, this should look very familiar, it’s the same concept without javascript. It may appear to only work for POST requests, but GET will work just as well. In addition, your function could easily output a simple page confirming the original message has been sent on before possibly redirecting else where.

    Now, about deleting the transient. Email delivery can be less than reliable. Even if wp_mail() succeeds, the message may not reach the intended recipient for any number of reasons. Immediately deleting the message data could mean the message cannot be recreated in case of delivery failure. What if you left the transient to expire on it’s own? It then becomes a sort of trash bin. You could add a function for users to manually extract the message (if it has not deleted itself yet) in case the original message bounced or otherwise failed to be delivered.

    About attachments. When files are uploaded, they go into a temporary folder. Normally, to permanently save the file on the server, it must be copied from the temporary location to its intended location. After it is moved, it is customary to delete the temporary file, but I believe the server will eventually clear it out of the folder on its own automatically.

    I suspect CF7 never copies the file. It provides the temporary path to wp_mail() and it gets copied into the mail message directly from the temporary location. If users are a little slow to verify, the temporary folder gets cleaned out so the file reference stored in the transient is no longer valid. This is all speculation on my part. You should investigate further in order to best plan an appropriate solution.

    If I’m right, what you probably need to do is create a longer term temporary storage and copy attached files into there and update the attachment fields in the CF7 data accordingly. Once in a while, run a scheduled task to delete files that are older than a certain time frame, perhaps similar to the transient expiration time frame.

    I’m glad people are finding your plugin useful, and that I had some small part in it. Once the bugs are ironed out, it will be a great tool for those that need it. Nice work!

    Thread Starter magician11

    (@magician11)

    Thank you bcworkz for your detailed response.

    You have played a significant part in this plugin’s development! Would you like me to add you as a contributor? I would be more than happy to add you.

    On double calls
    —————
    I am definitely not attached to ‘template_redirect’ and more than happy to cleaner/more efficient solutions. It sounds like your preferred idea is “sending the verification link to wp-admin/admin-post.php along with an ‘action’ parameter in addition to the verification key”. I am loosely familiar with AJAX but not so much WP AJAX. I think I know enough to add the flag idea you mentioned but might need help with your idea.

    Yes, I agree leaving the transient to expire itself later (currently set to 4 hours). Things happen, and a buffer of time will allow the form contents to be extracted later if need be.

    Agree too that a message should be displayed once the link is clicked. Does your method above of creating a link to the wp-admin page support this too? I like the idea of “insert a message under the header of the main page.”

    For attachments
    —————

    For the uploads.. this is what part of the CF7 object looks like after a form submission

    ` [posted_data] => Array
    (
    [_wpcf7] => 35
    [_wpcf7_version] => 3.6
    [_wpcf7_locale] => en_US
    [_wpcf7_unit_tag] => wpcf7-f35-p29-o1
    [_wpnonce] => 2c06b3f0f3
    [your-name] => BoB
    [your-email] => [email protected]
    [your-subject] => mouses
    [your-message] => asdfasd
    [_wpcf7_is_ajax_call] => 1
    [attachment] => blacktocat.png
    )

    [uploaded_files] => Array
    (
    [attachment] => /home2/xxx/public_html/development/testing/wp-content/uploads/wpcf7_uploads/blacktocat.png
    )`

    So it looks like it gets uploaded to a CF7 folder.. but the file must get deleted almost immediately.. because I don’t see any files in that folder ever. Even immediately after a form submission. So yes, I could create a copy of that file from the code and store it somewhere. Is there a way to save a file as a transient type object? Otherwise copying it then clearing it later using this function I guess.

    Thanks for your input and help!

    Moderator bcworkz

    (@bcworkz)

    Me a contributor? It wouldn’t have occurred to me that I am that involved, but I think I often grossly underestimate the value of ideas. Since you are offering, it would be awesome to get some kudos. Thanks!

    The under the header idea was just that, an idea. Now that the practicalities of actually doing it are considered, it may not be that simple. Different themes handle this area differently, and some users have a certain home page template, others use the default post listing. A lot of variables, some of which we can’t know precisely ??

    I’m going to change concept to the message on an interstitial page that redirects to the main page after a time delay for the sake of discussion. We can figure out the under the header thing if it’s really important, or do something else. The main thing is to process the key and send the email. Yes, I do think going through admin-post.php is the best approach, especially for a plugin.

    There really isn’t much more to it than what I mentioned in my previous post. Unfortunately, I don’t know of any good documentation of this feature. I actually just recently learned of it. It was mentioned in passing. I learned more about it just by looking at the source code, there’s not that much to it. It loads the WP environment and routes the request to a callback function based on the ‘action’ parameter.

    The process may be less obvious if you are not familiar with WP AJAX. I hate to suggest looking at WP AJAX just because it’s similar. WP AJAX is actually much more complicated than admin-post. I also would hate to write up a whole tutorial for you since you could certainly figure out most of it on your own. I’ll have to go with try and figure it out, ask me about anything that you can’t figure out. You can send a message with this process. It’s almost required, since the user did follow a link to get here, they are expecting something as a response.

    As mentioned previously, ‘check_for_verifier’ becomes the callback for the actions you add that work with admin-post.php. In addition, the function will need to send a response back to the browser. Nothing at this point has been sent by WP, so you could simply send a location header and redirect elsewhere. For now, I’m suggesting a interstitial page is sent. You could send your own head section, or call get_header().

    Then send the body content with the message sent (or verification failed) content. After a time delay, use wp_redirect() to load the main page. You probably don’t want to redirect if the verification failed, rather provide instructions on what to do next. (What would they do?? Retry later? Probably depends on why the failure.)

    As for deleting attachment files, there is no file based version of transients AFAIK. I suppose you could store the file as an actual transient, but I think storing potentially large file data in the DB would be a bad idea. Besides the wp_schedule_event() function, about the only other thing you could do is setup a CRON TAB directly on the server, which is really the same thing, but way beyond the scope of a plugin. wp_schedule_event() it is!

    Sorry to leave you on your own with admin-post.php, I just don’t know what to tell you. I guess I’m always guided by the need to answer questions. Without questions, I’m at a loss for what to write :/

    Alright. So I am not a coder of any sorts, but after a form has been verified, I receive the form submitted. But then I also receive this message:

    Subject: Could not find verification key

    Someone clicked on a verification link for a form submission and the
    corresponding key and transient CF7 object could not be found.

    I tried reading all of this, but I was very confused. I code websites, but I don’t code plugins :/

    Moderator bcworkz

    (@bcworkz)

    @izamarvirafuentes – Yes, this is the exact problem we are working on. The verification process is hooked to a less than optimal hook, causing double (or more?) verification requests with one single click. The redundant requests erroneously think there is an error and send the message you received. Please be assured the form was submitted.

    magician11 is working on an updated version using a better hook. Please be patient, the update will be available soon.

    Thread Starter magician11

    (@magician11)

    Thanks for pointing that out @izamarvirafuentes. Yes, we’re aware of that bug and working on that now.

    Thank you @bcworkz for your detailed response.. pretty much pseudocode ?? I’ll start work on it now.

    Thread Starter magician11

    (@magician11)

    Ok, getting there. Code updated to use a different hook and display a message. (code) (demo)

    I’ve been looking at redirecting after a delay, not sure yet how best to set the delay. (option 1) (stackoverflow discussion) I’ve been getting errors on attempting to modify the header..

    Any feedback on the code is appreciated. e.g. more efficient ways to do something.

    Still todo: handle attachments.

    Moderator bcworkz

    (@bcworkz)

    What you have so far looks great, can’t find a thing wrong with it ??

    I’m glad you figured out admin-post.php. It’s quite simple really, but hard to explain.

    You can’t send headers as a redirect if using an interstitial page. That will only work if you do not output anything before sending headers. You could use a meta refresh tag, though I understand it is now considered bad practice. I don’t know the reasoning though.

    What I had in mind was sleep() followed by wp_redirect(). From stackoverflow, sleep() could suppress page output, which defeats the purpose of the delay. I wonder if there is some way to force the output before sleeping, such as flush(). Failing that, you should be able to first ob_start() and then ob_flush() I should think.

    Attachments could be interesting. It might be worth seeing if CF7 behavior can be modified cleanly to delay or prevent deleting attachments. I would hate to have to copy attachments to a different location and fear simply moving will cause CF7 to choke when the file it needs to delete is not there.

    FYI, I’ll have sporadic Internet access for about a week, so any responses from me may take a few days. I’m not ignoring you ??

    Hello guys! Thanks for updating me on this issue. Is it safe for me to update now?

    Thread Starter magician11

    (@magician11)

    Hello @izamarvirafuentes

    I’ve just updated it. I’m not sure how long WordPress takes before the update is available.. but yeah, I’ve fixed that issue you had.

    Thread Starter magician11

    (@magician11)

    Hi bcworkz,

    I’ve been busy with other things, but back on board to further this plugin. My todos.

    I need some help with it.

    I sent a post on the CF7 forum asking how they process attachments. That was two weeks ago and no response. I’m getting an email or two asking for attachment support, so I’d like to work it out. Are you interested in helping me out with it?

    Also some people would like to be able to edit the verification message in the Dashboard. I haven’t done that before either, so a pointer on where to start would be great ??

    Thanks!

    Moderator bcworkz

    (@bcworkz)

    Hi there!

    I can take a look at CF7 and try to suss out how attachments are handled. It could take a short while, I’ll report back one way or the other. I’m not that familiar with file uploads, but I suppose I know enough to figure out something. Storing random files on someone’s server makes me rather nervous. It’s one thing to upload then delete seconds later. Upload and store is another thing entirely. It’s of course not a problem if done properly, but I’m not sure I know what that is. This will require some careful consideration.

    The easiest way to let people alter the verification message is to apply a filter. This would of course entail some modest coding for users to implement. The user friendly way would mean establishing a settings page. You can use the Settings API do handle this. The advantage is mainly the entered values are semi-automatically handled for you.

    Frankly, for starting a new admin page using the API, I think it’s more cumbersome than it’s worth. It works better for slipping in custom fields to existing pages. Which might be an option if this is the only field. But I imagine there’s a few other things that users might like control over.

    Whether you create a conventional page or use the API, you then need to insert the page into the Administration Menus structure. There is certainly a learning curve with this stuff. It’s mostly straight forward, but there are a few things that are less than clear, expect to make a few wrong turns. Much like admin-post.php, once you establish a functional framework, the rest is easy. If all else fails, you know where to find me ??

    The current trend in WP core development is to remove little used options, or at least hide them, to strive for a simpler, less confusing user experience. So don’t provide a bunch of options just because it’s conceivable someone might like to alter a setting. Provide options that people actually need to have control over.

    That’s for the settings page. For the inner workings, I think it’s a good idea to provide filter and action hooks so that advanced users are easily able to customize the functioning to their liking. Still, there is no reason to filter everything, but the threshold of potential usefulness is lower for filters than for admin settings.

    Another thing you should probably add to the to-do list is to allow for translation into other languages. This will require some consideration of how text is output since one cannot translate variables. This is also an issue with the settings, so the two needs have the same restriction.

    Moderator bcworkz

    (@bcworkz)

    OK, here’s the summary of attachment handling. It’s pretty much as we thought. Uploads are moved from the PHP temp folder to a CF7 temp folder that defaults to uploads/wpcf7_uploads/ but can be overridden by defining WPCF7_UPLOADS_TMP_DIR. The files are deleted from this folder as soon as the email is sent. In case any are missed, there is also a routine that runs on normal non-admin GET requests that deletes any files older than 60 seconds.

    Fortunately, the same hook you are already using is a good opportunity to move the files to another folder for longer term storage. CF7 ignores errors from the unlink call, so the lack of files to delete will not cause any issues. I have some security issues I’d like to discuss. (no faults in CF7, files cannot exist longer than 60 secs.) Still I’d rather not make them public. Please email me, I use gmail with the same user name, except the final z needs to be an s in this case. The files attached are listed in the mail object properties $uploaded_files and $posted_data. These should be updated with the new paths, but only in a copy that will be saved for email verification. The original object must remain unchanged otherwise CF7 will delete the moved files!

    Once the verification is received, the attachments should just work because the paths were corrected. There will need to be some routine similar to the one used by CF7 to clean out old files, except the max age should be the same as the transient time instead of 60 secs.

Viewing 15 replies - 16 through 30 (of 30 total)
  • The topic ‘confirm email address’ is closed to new replies.