You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现Contact Form7表单分组评分重复值校验及错误提示

How to Validate Unique Rankings per Cluster in Contact Form7

Hey there! Let's walk through how to fix this validation issue step by step—since you're new to PHP and Contact Form7 (CF7), I'll keep things clear and explain each part.

First, Understand the Problem with Your Current Code

Your duplicate-check logic using array_unique() is actually on the right track! The main issues are:

  • You're using a $cluster1 variable that doesn't exist yet—you haven't collected the form values into this array.
  • Contact Form7 has its own hooks to handle validation, so we can't just run this code directly in functions.php without tying it to CF7's submission process.
  • We also need to handle cases where a user doesn't select an option (the default "--" value) before checking for duplicates.

Step 1: Use CF7's Validation Hook

CF7 provides the wpcf7_validate hook that lets us add custom validation rules before the form is submitted. We'll use this hook to run our checks.

Step 2: Collect Values for a Cluster

Since we can't access the frontend class attribute directly in PHP, we'll use the field name pattern to group values. For your first cluster, all fields start with one- (one-01, one-02, etc.). We'll loop through the submitted form data and collect these values into an array.

Step 3: Add Validation Logic

Once we have the cluster array, we'll:

  1. Check if any option is still set to the default "--" (empty/unchosen value).
  2. Check if there are duplicate rankings using array_unique().
  3. If either issue exists, we'll add an error message to the form.

Full Working Code

Add this to your child theme's functions.php file:

add_filter('wpcf7_validate', 'cf7_cluster_unique_ranking_validation', 10, 2);
function cf7_cluster_unique_ranking_validation($result, $tag) {
    // Get all submitted form data using CF7's official method
    $submission = WPCF7_Submission::get_instance();
    if (!$submission) return $result;
    $posted_data = $submission->get_posted_data();

    // --------------------------
    // Validate First Cluster (one-01 to one-04)
    // --------------------------
    $cluster1 = [];
    // Loop through fields starting with "one-" to collect values
    foreach ($posted_data as $field_name => $value) {
        if (str_starts_with($field_name, 'one-')) {
            // Check if user left an option unselected
            if ($value === '--') {
                $result->invalidate($tag, 'Please select a ranking for all options in the first cluster.');
                return $result;
            }
            $cluster1[] = $value;
        }
    }

    // Check for duplicate rankings in the cluster
    if (count(array_unique($cluster1)) !== count($cluster1)) {
        $result->invalidate($tag, 'You must use each score (1-4) only once per cluster.');
        return $result;
    }

    // --------------------------
    // Add More Clusters Here (e.g., cluster2 with fields starting with "two-")
    // --------------------------
    // $cluster2 = [];
    // foreach ($posted_data as $field_name => $value) {
    //     if (str_starts_with($field_name, 'two-')) {
    //         if ($value === '--') {
    //             $result->invalidate($tag, 'Please select a ranking for all options in the second cluster.');
    //             return $result;
    //         }
    //         $cluster2[] = $value;
    //     }
    // }
    // if (count(array_unique($cluster2)) !== count($cluster2)) {
    //     $result->invalidate($tag, 'You must use each score (1-4) only once per cluster.');
    //     return $result;
    // }

    return $result;
}

Key Explanations for Beginners

  • Hook into CF7: The add_filter('wpcf7_validate', ...) line tells WordPress to run our validation function when CF7 checks the form.
  • Get Submitted Data: WPCF7_Submission::get_instance() is the official CF7 way to access form data (avoid using $_POST directly—it's less reliable with CF7's internal handling).
  • Collect Cluster Values: We loop through all posted fields and grab those starting with one- (adjust this prefix if your other clusters use different names, like two-).
  • Check for Empty Selections: If any field is still set to "--", we show an error asking the user to fill all options.
  • Check for Duplicates: array_unique() removes duplicate values—if the length of the unique array is shorter than the original, that means there are duplicates in the rankings.

Important Notes

  • Make sure your CF7 select fields keep the -- as the first option (like your original code: [select* one-01 first_as_label class:cluster1 "--" "1" "2" "3" "4"]). This ensures we can detect unselected options.
  • If you add more clusters (like cluster2, cluster3), just copy the cluster validation block and change the field prefix (from one- to two-, etc.).
  • Always test the form after adding this code to make sure errors show up correctly when duplicates or empty selections are present.

内容的提问来源于stack exchange,提问作者timhuk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 12:42:26