• Resolved geertvanderheide

    (@geertvanderheide)


    I’m trying to use the ‘wpcf7_before_send_mail’ filter to dynamically change the recipient of a CF7 contact form. The recipient e-mail address should come from a custom field, specifically one from the Advanced Custom Fields (ACF) plugin. If the custom field is not filled, then the regular recipient address (from the CF7 form) should be used. I feel like the code I have is pretty close, but it’s not working: It always still sends to the regular recipient. And since I’m using AJAX for the CF7 form (as is the default), I’m having trouble debugging.

    Below is my code. Can anyone give me any pointers as to what may be going wrong?

    // Set the recipient of the question form to the e-mail address of the connected person
    function set_question_form_recipient(&$WPCF7_ContactForm) {
      // Check if it's the right form
      if (102 == $WPCF7_ContactForm->id()) :
        //Get current form and submission instance
        $wpcf7      = WPCF7_ContactForm::get_current();
        $submission = WPCF7_Submission::get_instance();
    
        if ($submission) :
          // Get submission data
          $data = $submission->get_posted_data();
    
          // nothing's here... do nothing...
          if (empty($data)) { return; }
          
          // Get the post ID from the unit_tag
          $unit_tag = $submission->get_meta( 'unit_tag' );  
          $explode_unit_tag = explode("-", $unit_tag);  
          $post_id = str_replace("p", "", $explode_unit_tag[2]);
    
          // Get the connected persons
          $connected_persons = get_field('connected_persons', $post_id);
    
          if ($connected_persons) :
            // Get the e-mail address
            $person_id    = $connected_persons[0]->ID;
            $person_email = get_field("person_email", $person_id);
    
            if ($person_email) :
              // Set the recipient
              $mail = $wpcf7->prop('mail');
              $mail['recipient'] = $person_email;
              $wpcf7->set_properties(array( "mail" => $mail ));
            endif;
          endif;
          
          // return current cf7 instance
          return $wpcf7;
        endif;
      endif;
    }
    add_filter('wpcf7_before_send_mail', 'set_question_form_recipient');
Viewing 6 replies - 1 through 6 (of 6 total)
  • Plugin Author Takayuki Miyoshi

    (@takayukister)

    Use wpcf7_mail_components filter if you want to change the mail recipient.

    Thread Starter geertvanderheide

    (@geertvanderheide)

    Thank you for your reply. Using the filter you mentioned, and the method for getting the post ID you gave here, I was able to get it working.

    One more question: Is there a way to get the form ID with this filter? I’d like to make sure this code runs only for one specific CF7 form. The function’s second and third parameter ($form and $object) are both NULL for me. Any ideas there?

    Here’s a code example for others looking to change the recipient using a custom field:

    function set_question_form_recipient($components, $form, $object) {
      // Get the post ID
      $post_id = wpcf7_special_mail_tag('', '_post_id');
      
      // Get the recipient e-mail address from an Advanced Custom Field
      $recipient_email = get_field( 'name_of_acf_field', $post_id );
    
      // If you use a regular (non-ACF) custom field, use:
      // $recipient_email = get_post_meta( $post_id, 'name_of_custom_field', true );
    
      if ($recipient_email) :
        // Set the recipient
        $components['recipient'] = $recipient_email;
      endif;
      
      // Return the modified array
      return $components;
    }
    add_filter('wpcf7_mail_components', 'set_question_form_recipient');
    Plugin Author Takayuki Miyoshi

    (@takayukister)

    add_filter('wpcf7_mail_components', 'set_question_form_recipient');

    Don’t forget the $accepted_args parameter.

    To get the form ID, do
    $form_id = $form->id();

    Thread Starter geertvanderheide

    (@geertvanderheide)

    That’s exactly what I was missing. Thank you very much for the support!

    The complete code example for anyone who finds this:

    function set_question_form_recipient($components, $form, $object) {
      if ($form->id() == 102) :
        // Get the ID of the post the form was sent from
        $post_id = wpcf7_special_mail_tag('', '_post_id');
      
        // Get the recipient e-mail address from an Advanced Custom Field
        $recipient_email = get_field( 'name_of_acf_field', $post_id );
    
        // If you use a regular (non-ACF) custom field, use:
        // $recipient_email = get_post_meta( $post_id, 'name_of_custom_field', true );
    
        if ($recipient_email) :
          // Set the recipient
          $components['recipient'] = $recipient_email;
        endif;
      endif;
      
      // Return the modified array (not sure if needed)
      return $components;
    }
    add_filter('wpcf7_mail_components', 'set_question_form_recipient', 10, 3);

    In this example, the ID of the CF7 form (102 in the example), and the field names, need to be replaced with the ones you’re using.

    Thanks Geert and Takayuki – much appreciated.

    Found this post very useful. I had a piece of code that, after upgrading my website to the latest wp/wpcf7 (was still using wp<4 and old wpcf7) wasn’t working anymore.

    This was the doce:

    function my_custom_emailing( $wpcf7 ) {
    	$myStr = array('plant1' => "email1",
    				   'plantN'	=> 'mailM');
    	if (( $wpcf7->id == XXX ) || ( $wpcf7->id == YYY )) {
    		$wpcf7->skip_mail = 1;
    	}
    	if ( $wpcf7->id == ZZZ ) {
    		wp_redirect( 'http://mysampleredirect' );
    		$wpcf7->skip_mail = 1;
    	}
    	if ( $wpcf7->id != MYSPECIAL ) {
    		return $wpcf7;
    	}
    	if ( $wpcf7->id == MYSPECIAL ) {
    		if ( $wpcf7->posted_data ) {
    			if($wpcf7->posted_data['Item'][0]==='Register') {
    				$wpcf7->skip_mail = 1;
    			}
    			if($wpcf7->posted_data['Item'][0]==='TVCC') {
    	$wpcf7->posted_data['email_to']=$myStr[$wpcf7->posted_data['plant']];
    				$wpcf7->posted_data['email_cc'] = 'my, custom, cc, comma, separated';
    			}
    	
    			if($wpcf7->posted_data['Item'][0]==='Maintenance') {
    				$wpcf7->posted_data['email_to'] = "custom_to@domain.com";
    				$wpcf7->posted_data['email_cc'] = "custom_cc@domain.com";
    			}
    		}
    		return $wpcf7;
    	 }
    }
    add_action( 'wpcf7_before_send_mail', 'my_custom_emailing');

    After reading this post, I changed my piece of code this way

    function my_custom_emailing( $wpcf7 ) {
    	if (( XXX==$wpcf7->id ) || ( YYY==$wpcf7->id )) {
    		$wpcf7->skip_mail = 1;
    	}
    	if ( ZZZ == $wpcf7->id ) {
    		wp_redirect( 'http://mysampleredirect' );
    		$wpcf7->skip_mail = 1;
    	}
    	if ( MYSPECIAL != $wpcf7->id ) {
    		return $wpcf7;
    	}
    	if ( MYSPECIAL == $wpcf7->id ) {
    		if ( $wpcf7->posted_data ) {
    			if($wpcf7->posted_data['Item'][0]==='Register') {
    				$wpcf7->skip_mail = 1;
    			}
    		}
    		return $wpcf7;
    	 }
    }
    add_action( 'wpcf7_before_send_mail', 'my_custom_emailing');
    
    function set_question_form_recipient($components, $form, $object) {
    
      if (XXX == $form->id()) {
    
    	$myStr = array('plant1' => "custom@domain.com",
    				   'plantX' => "sample@mail.net"
    				   );
    
    	$submission = WPCF7_Submission::get_instance();
        $posted_data = $submission->get_posted_data();
    
    	if($posted_data['Item'][0]==='TVCC') {
    	  $components['recipient'] = $myStr[$posted_data['plant']];
    	  $components['additional_headers'] = 'CC: my, custom, cc, comma, separated';
    	}
    	  
    	if($posted_data['Item'][0]==='Maintenance') {
    	  $components['recipient'] = 'customrecipient@sample.net';
    	  $components['additional_headers'] = 'CC: custom_cc@sample.net';
    	}
      }
      
      // Return the modified array (not sure if needed)
      return $components;
    }
    add_filter('wpcf7_mail_components', 'set_question_form_recipient', 10, 3);

    Well, to be honest at least it works, in the sense that emails are being sent once again when needed. But in a particular condition, when mail should be skipped, I receive the standard errr message complaining that there was an error while sending the email.
    This should be due to the recipient not being set up, but I do not need to send the email so no recipient…

    I believe that the error is due to the skip_email not working as expected.

    Anyone could point me to the right direction?

    Thanks

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘How to use post meta to set mail recipient dynamically?’ is closed to new replies.