Contact Form 7 – 为两个字段自定义验证

huangapple go评论73阅读模式
英文:

Contact Form 7 - Custom Validation for Two Fields

问题

我想为电子邮件和电话字段添加自定义验证。我有两个字段,电子邮件和电话。最初,这两个字段应该是必填的,如果用户填写了其中一个字段并提交表单,表单应该被提交。

我已经添加了以下代码,但它不起作用。

add_filter('wpcf7_validate', 'custom_cf7_validation', 20, 2);

function custom_cf7_validation($result, $tags)
{
    // 获取两个字段的值
    $field1_value = isset($_POST['your-email']) ? sanitize_email_field($_POST['your-email']) : '';
    $field2_value = isset($_POST['your-phone']) ? sanitize_text_field($_POST['your-phone']) : '';

    // 如果任何一个字段有值,则使另一个字段不是必填的
    if (!empty($field1_value) || !empty($field2_value)) {
        $field1 = $tags[0];
        $field2 = $tags[1];

        $field1->set_properties(array('required' => false));
        $field2->set_properties(array('required' => false));
    }

    return $result;
}

以上代码显示以下错误:

POST https://example.com/wp-json/contact-form-7/v1/contact-forms/524/feedback 500
Response {type: 'basic', url: 'https://example.com/wp-json/contact-form-7/v1/contact-forms/524/feedback', redirected: false, status: 500, ok: false, …}
英文:

I want to add custom validation for Email and tel fields. I'm having two fields Email and Phone, Initially two fields should be mandatory, if the user filled any one of the field and submits the form it should be submitted.

I've added this code but it is now working.

add_filter('wpcf7_validate', 'custom_cf7_validation', 20, 2);

function custom_cf7_validation($result, $tags)
{
    // Get the values of the two fields
    $field1_value = isset($_POST['your-email']) ? sanitize_email_field($_POST['your-email']) : '';
    $field2_value = isset($_POST['your-phone']) ? sanitize_text_field($_POST['your-phone']) : '';

    // If either field has a value, make the other field not required
    if (!empty($field1_value) || !empty($field2_value)) {
        $field1 = $tags[0];
        $field2 = $tags[1];

        $field1->set_properties(array('required' => false));
        $field2->set_properties(array('required' => false));
    }

    return $result;
}

Above code showing the below error:

POST https://example.com/wp-json/contact-form-7/v1/contact-forms/524/feedback 500
Response {type: 'basic', url: 'https://example.com/wp-json/contact-form-7/v1/contact-forms/524/feedback', redirected: false, status: 500, ok: false, …}

答案1

得分: 0

CF7中有一些部分丢失,所以这里是应该有效的代码:

add_filter('wpcf7_posted_data', 'custom_cf7_validation');
function custom_cf7_validation($posted_data)
{
    $email_value = isset($posted_data['your-email']) ? sanitize_email($posted_data['your-email']) : '';
    $phone_value = isset($posted_data['your-phone']) ? sanitize_text_field($posted_data['your-phone']) : '';

    // 如果电子邮件或电话有值,则将另一个从所需验证中删除
    if (!empty($email_value) || !empty($phone_value)) {
        if (!empty($email_value)) {
            unset($posted_data['your-phone']);
        } else {
            unset($posted_data['your-email']);
        }
    }

    return $posted_data;
}

只需确保将 'your-email''your-phone' 替换为CF7表单中您的电子邮件和电话字段的正确名称。

英文:

There were some parts missing from CF7, so here is a code that should work:

add_filter('wpcf7_posted_data', 'custom_cf7_validation');
function custom_cf7_validation($posted_data)
{
    $email_value = isset($posted_data['your-email']) ? sanitize_email($posted_data['your-email']) : '';
    $phone_value = isset($posted_data['your-phone']) ? sanitize_text_field($posted_data['your-phone']) : '';

    // If either email or phone has a value, remove the other from the required validation
    if (!empty($email_value) || !empty($phone_value)) {
        if (!empty($email_value)) {
            unset($posted_data['your-phone']);
        } else {
            unset($posted_data['your-email']);
        }
    }

    return $posted_data;
}

Just make sure to replace 'your-email' and 'your-phone' with the correct names of your email and phone fields in the CF7 form.

答案2

得分: 0

这实际上在CF7中实现起来相当复杂,因为该插件并不设计用于复杂的验证。

您的方法失败的原因是wpcf7_validate在CF7验证提交并填充了$result对象的错误消息之后触发。

因此,您需要重新构建$result对象并返回它。有一个插件可以自动为您执行此操作,CF7的Smart Grid-layout扩展允许您基于其他提交来验证字段,因此使用启用该插件的最简单方法是使用以下挂钩:

add_filter('cf7sg_validate_submission','validate_field_submission',10,3);
function validate_field_submission($validation_errors, $submission, $cf7_key){
  /* $submission是一个数组,包含每个提交字段的<field-name>=>$value对。
   如果值无效,请在$validation_errors数组中返回<field-name>=> <error message string>对。提交过程将被取消,并要求用户在重新提交之前纠正字段。
   $cf7_key是用于识别您的表单的唯一表单键,$cf7_id是其post_id。
  */
  if('my-form'==$cf7_key ){
    //$validation_errors是一个字段名=>错误消息的数组。
    //这些包括CF7插件中针对必填字段/特殊字段格式的简单验证。
    
    if(!empty($submission['your-email']) || !empty($submission['your-phone'])){
      $validation_errors['your-email']='';
      $validation_errors['your-phone']=''; //简单清除CF7插件记录的任何错误消息。
    }
  }
  return $validation_errors;
}

这是简单的解决方案。

现在,如果您想采用困难的方式,这是您需要做的:

add_filter('wpcf7_validate', 'custom_cf7_validation', 20, 2);

function custom_cf7_validation($result, $tags){
  //步骤1 保留其他字段的任何无效化,
  $invalids = $result->get_invalid_fields();
  //步骤2 构建一个新的验证对象
  if(class_exists('WPCF7_Validation')){ //确保它存在。
    $result = new WPCF7_Validation();
  }else{
    return $result;
  }
  //步骤3 自定义验证
  $field1_value = isset($_POST['your-email']) ? sanitize_email_field($_POST['your-email']) : '';
  $field2_value = isset($_POST['your-phone']) ? sanitize_text_field($_POST['your-phone']) : '';

  // 如果其中一个字段有值,则将另一个字段设为非必填
  $is_valid = false;
  if (!empty($field1_value) || !empty($field2_value)) $is_valid=true;
  foreach($tags as $tag){
    $err_msg = '';
    if(isset($invalids[$tag['name']])) $err_msg = $invalids[$tag['name']]['reason'];
    switch($tag['name']){
      case  'your-email':
      case  'your-phone':
        $err_msg = $is_valid ? '': $err_msg ;
        break;
    }
    //重新构建验证对象。
    if(!empty($err_msg)) $result->invalidate($tag, $err_msg);
  }
  return $result;
}

注意:尚未测试上述代码,但它为您提供了所需的基本思路。

英文:

This is actually quite complex to achieve in CF7 because the plugin isn't designed for complex validation.

The reason why your approach fails is that the wpcf7_validate fires after CF7 has validated the submission and filled in the $result object with the error msgs.

Therefore, you need to rebuilt the $result object and return that instead. There is a plugin that will do this automatically for you, the Smart Grid-layout extension for CF7 allows you to validate fields based on other submissions, so the simplest way to achieve this with that plugin enabled is using the following hook,

add_filter( &#39;cf7sg_validate_submission&#39;,&#39;validate_field_submission&#39;,10,3);
function validate_field_submission($validation_errors, $submission, $cf7_key){
  /* $submission an array of &lt;field-name&gt;=&gt;$value pairs one for each submitted field.
   if a value is not valid, return a &lt;field-name&gt;=&gt;&lt;error message string&gt; pair in the $validation_errors array. The sbumission process will be cancelled and teh user required to correct the field before re-submitting.
  $cf7_key unique form key to identify your form, $cf7_id is its post_id.
  */
  if(&#39;my-form&#39;==$cf7_key ){
    //$validation_errors is an array of field-names=&gt;error messages.
    //these include the simple validation exposed in the CF7 plugin for required fields/special field formats.
    
    if(!empty($submission[&#39;your-email&#39;]) || !empty($submission[&#39;your-phone&#39;]){
      $validation_errors[&#39;your-email&#39;]=&#39;&#39;;
      $validation_errors[&#39;your-phone&#39;]=&#39;&#39;; //simply clear any error msg logged by the CF7 plugin.
    }
  }
  return $validation_errors;
}

This is the simple solution.

Now, if you want to do it the hard way, this is what you need to do:

add_filter(&#39;wpcf7_validate&#39;, &#39;custom_cf7_validation&#39;, 20, 2);

function custom_cf7_validation($result, $tags){
  //step 1 retain any invalidations from other fields,
  $invalids = $result-&gt;get_invalid_fields();
  //step 2 build a new validation object
  if(class_exists(&#39;WPCF7_Validation&#39;)){ //make sure it exists.
    $result = new WPCF7_Validation();
  }else{
    return $result;
  }
  //step 3 custom validation
  $field1_value = isset($_POST[&#39;your-email&#39;]) ? sanitize_email_field($_POST[&#39;your-email&#39;]) : &#39;&#39;;
  $field2_value = isset($_POST[&#39;your-phone&#39;]) ? sanitize_text_field($_POST[&#39;your-phone&#39;]) : &#39;&#39;;

  // If either field has a value, make the other field not required
  $is_valid = false;
  if (!empty($field1_value) || !empty($field2_value)) $is_valid=true;
  foreach($tags as $tag){
    $err_msg = &#39;&#39;;
    if(isset($invalids[$tag[&#39;name&#39;]]) $err_msg = $invalids[$tag[&#39;name&#39;]][&#39;reason&#39;];
    switch($tag[&#39;name&#39;]){
      case  &#39;your-email&#39;:
      case  &#39;your-phone&#39;:
        $err_msg = $is_valid ? &#39;&#39;: $err_msg ;
        break;
    }
    //rebuild the validaiton object.
    if(!empty($err_msg)) $result-&gt;invalidate($tag, $err_msg);
  }
  return $result;
}

NOTE: haven't tested the above code, but it gives you the basic idea of that is required.

huangapple
  • 本文由 发表于 2023年6月5日 19:16:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76405886.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定