Good day!
I’m using Contact Form 7 and its wpcf7_before_send_mail action to interact with an API before sending the email. If the API returns an error, I want to be able to grab that error, display it as an error and prevent the form from being submitted.
I can’t seem to find what I’m looking for anywhere online. The best I can do is use the mail_sent_ok message string and display the error within it (which is obviously not the solution).
Basically, the ultimate solution would be to force the form submission to fail.
Anyone else in the same boat?
I'm not sure if it was possible at the time you asked your question but the wpcf7_before_send_mail hook has an abort flag that your just have to set to avoid mail to be sent.
for instance in pseudo PHP
add_action('wpcf7_before_send_mail', 'your_function', 10, 3);
function your_function($form, &$abort, $object){
$error = 1;
if($error != 0) {
$abort = true;
$object->set_response("An error happened");
}
}
Based on Louise-Philippe's answer, I solved with this code, since $object parameter happends to be always null:
add_action('wpcf7_before_send_mail', 'your_function', 10, 3);
function your_function($form, &$abort, $object){
$error = 1;
if($error != 0) {
$abort = true;
$msgs = $form->prop('messages');
$msgs['mail_sent_ng'] = "An error happened"; //<- your custom error message
$form->set_properties(array('messages' => $msgs));
}
}
Note: it's not mail_sent_ok but mail_sent_ng so you can have red border as predefined error messages.
you can do a custom validation with this filter :
add_filter("wpcf7_validate", function ($result, $tags) {
$valid = FALSE; // here you can do your API call to calculate the validation
if (!$valid) {
$result->offsetSet(
"reason"
, ["your-name" => "error message for this field"]
);
}
return $result;
}, 10, 2);
your-name must be the name of a existing field of this form.
Related
I am trying to customise the success message of the Contact Form 7 plugin in WordPress.
I understand that it could be done using javascript, but I don't have this option. That's because I've created a custom coupon code on form submission, by using this - add_action('wpcf7_mail_sent', 'dbo_generate_coupon');.
I need to display that coupon to the user after the form is sent.
I don't want to use an alert. I need to alter the standard "Thank you for your message. It has been sent." response.
I am confident I can retrieve the cookie ok, but the first ( simple? ) step is getting control of the success message. Here I'm out of my depth.
I've tried code like
return apply_filters('wpcf7_messages','dbo_update_form_messages',10,1);
and
add_action('wpcf7_before_send_mail', 'action_wpcf7_mail_sent', 10, 1);
add_action('wpcf7_mail_sent', 'action_wpcf7_mail_sent', 10, 1);
Clearly I need help.
Thanks in advance.
With a little more digging, I found the answer on Stack Overflow
I updated the code from lukeseager under the heading Send the email to a dynamic recipient
This is my working startpoint;
function wpcf7_before_send_mail_function( $contact_form, $abort, $submission ) {
$dynamic_email = ''; // get your email address...
$properties = $contact_form->get_properties();
$properties['messages']['mail_sent_ok'] = 'custom message';
$contact_form->set_properties($properties);
return $contact_form;
}
add_filter( 'wpcf7_before_send_mail', 'wpcf7_before_send_mail_function', 10, 3 );
I am trying to write a wordpress filter that would change the post status to trash if it contains explicit words, but I can't manage to get it to work. Could you please help me?
This is what I got so far:
add_filter('wp_insert_post_data', 'delete_invalid_posts', '99');
function delete_invalid_posts($data) {
$false_titles = array("*****", "******");
if (in_array($data['post_title'], $false_titles) {
// If post data is invalid then
$data['post_status'] = 'trash';
}
return $data;
}
If you want to search the title for Explicit Words, you may use this code:
add_filter('wp_insert_post_data', 'delete_invalid_posts', 99);
function delete_invalid_posts($data) {
$false_titles = array("*****", "******");
$title_arr = explode(' ', $data['post_title']);
$found = array_intersect($false_titles, $title_arr);
if (!empty($found)) {
$data['post_status'] = 'trash';
}
return $data;
}
I've not tested the code, So try it and if you have any question don't hesitate to ask.
I might be wrong, but I think you are missing a closing parentheses here...?
Are you getting an error message?
if (in_array($data['post_title'], $false_titles) // <--- HERE should be a ")"
Like I said, I could be mistaken or there may be other issues...
I have borrowed this code from stackoverflow in attempt to find a solution. I need to create a new post from submitted data on a form. I was using the filter:
add_filter( 'wpcf7_posted_data', 'save_new_booked_event_data' );
but found that it fired after every submit and not AFTER validation. So I moved on to this code:
add_action('wpcf7_before_send_mail','contactform7_before_send_mail',1);function
contactform7_before_send_mail( $contact_form ) {
if ( !isset($contact_form->posted_data) && class_exists('WPCF7_Submission') ) {
$submission = WPCF7_Submission::get_instance();
if ( $submission ) {
$formData = $submission->get_posted_data();
$formField = $formData['_wpcf7'];
update_post_meta(199, 'first_name', $formField);
}
} else {
// We can't retrieve the form data
return $contact_form;
}
return $contact_form;
}
Five hours later: the get_posted_data method is always NULL. I ve tried approaching it from different angles including turning off ajax and posting the form. I've checked and dumped every object to make sure that it works but it always turns up NULL. What am I missing here? Please anyone?
Thank you!
Educated guess:
The get_posted_data method relies on setup_posted_data firing, first, and that occurs when the constructor for the WPCF7_Submission class is invoked.
Perhaps there are multiple contact forms and your contactform7_before_send_mail function is hooked to one of them that hasn't been submitted, and therefore, the data are null.
That being the case, you could override and force population of posted data for your form if you pass an instance of WPCF7_ContactForm to the WPCF7_Submission::get_instance(); call.
Something like:
$form = new WPCF7_ContactForm($id_of_your_form);
$submission = WPCF7_Submission::get_instance($form);
By the way! Your snippet appears to be from this wordpress plugin. (Form to Post) In case you want a more configurable solution, or to browse the context it lives in.
I have been experimenting all day and researching the whole web, and I cant seem to get this action to work. Basically I'm trying to trigger a Woo Email when a custom order action is selected. In this case, its a gift receipt.
Please Note: When I turn on debugging, I get a headers already sent notice, none when its off.
Here is the code which I had tried:
function gift_receipt_add_order_meta_box_action($actions)
{
global $theorder;
$actions['send_gift_receipt'] = __('Send Gift Receipt', 'enyc');
return $actions;
}
add_action('woocommerce_order_actions', 'gift_receipt_add_order_meta_box_action');
function gift_receipt_wc_process_order_meta_box_action()
{
$mailer = WC()->mailer();
$mails = $mailer->get_emails();
if (!empty($mails))
{
foreach ($mails as $mail)
{
if ($mail->id == 'wc_gift_order_email')
{
$mail->trigger($order->id);
}
}
}
}
add_action('woocommerce_order_action_send_gift_receipt', 'gift_receipt_wc_process_order_meta_box_action');
Thanks.
function gift_receipt_wc_process_order_meta_box_action()
is missing $order
function gift_receipt_wc_process_order_meta_box_action($order)
might this be the issue?
So I figured it out after some more coffee. The problem was 2 fold:
1) I did not pass the order ($order) info to the function gift_receipt_wc_process_order_meta_box_action()
2) the id (name) of the email was actually 'wc_gift_order' instead of 'wc_gift_order_email'
Thanks for the help!
I am in the process of trying to get our custom code out of core.
In this function I capture the old session ID to update a project the user may have been working on while not logged in.
function user_authenticate_finalize(&$edit) {
global $user;
watchdog('user', 'Session opened for %name.', array('%name' => $user->name));
// Update the user table timestamp noting user has logged in.
// This is also used to invalidate one-time login links.
$user->login = time();
db_query("UPDATE {users} SET login = %d WHERE uid = %d", $user->login, $user->uid);
$old_session_id = session_id(); //THIS LINE NEEDS TO BE MOVED
// Regenerate the session ID to prevent against session fixation attacks.
sess_regenerate();
tf_user_new_session_id($user, $old_session_id); //THIS LINE NEEDS TO BE MOVED
user_module_invoke('login', $edit, $user);
}
The lines right before and right after sess_regenerate();
As far as I can tell, you would have to write your own login process to accomplish this cleanly in D6. I'd probably do a hook_form_alter() and replace the submit handler on the login form with my own.
function tf_user_user($op, &$edit, &$account, $category = NULL)
{
$current_session = session_id();
if ('login' == $op)
{
setcookie('session_id_anonymous', $current_session, time() + 86400);
}
if ('load' == $op)
{
if (isset($_COOKIE['session_id_anonymous']) && $_COOKIE['session_id_anonymous'] != $current_session)
{
tf_user_new_session_id($account->uid, $_COOKIE['session_id_anonymous'], $current_session);
setcookie('session_id_anonymous', $current_session, time() - 3600);
}
}
//more code
}