英文:
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( 'cf7sg_validate_submission','validate_field_submission',10,3);
function validate_field_submission($validation_errors, $submission, $cf7_key){
/* $submission an array of <field-name>=>$value pairs one for each submitted field.
if a value is not valid, return a <field-name>=><error message string> 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('my-form'==$cf7_key ){
//$validation_errors is an array of field-names=>error messages.
//these include the simple validation exposed in the CF7 plugin for required fields/special field formats.
if(!empty($submission['your-email']) || !empty($submission['your-phone']){
$validation_errors['your-email']='';
$validation_errors['your-phone']=''; //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('wpcf7_validate', 'custom_cf7_validation', 20, 2);
function custom_cf7_validation($result, $tags){
//step 1 retain any invalidations from other fields,
$invalids = $result->get_invalid_fields();
//step 2 build a new validation object
if(class_exists('WPCF7_Validation')){ //make sure it exists.
$result = new WPCF7_Validation();
}else{
return $result;
}
//step 3 custom validation
$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
$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;
}
//rebuild the validaiton object.
if(!empty($err_msg)) $result->invalidate($tag, $err_msg);
}
return $result;
}
NOTE: haven't tested the above code, but it gives you the basic idea of that is required.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论