--- webform_validation.validators.inc	2011-03-27 11:39:31.000000000 -0700
+++ webform_validation.validators.inc.new.oneofseveral_extended	2011-06-23 10:01:20.000000000 -0700
@@ -150,6 +150,18 @@ function webform_validation_webform_vali
       'min_components' => 2,
       'description' => t('Forces the user to specify / select at least one of several selected webform components'),
     ),
+    'oneofseveral_expanded' => array( // Additional validator
+      'name' => "Require at least one of several fields - Expanded",
+      'component_types' => array(
+        'textfield',
+        'textarea',
+        'email',
+        'select',
+        'file',
+      ),
+      'min_components' => 2,
+      'description' => t('Same functionality as oneoftwo or oneofseveral, except this checks file fields as well and adds a custom error message when only two fields are selected.'),
+    ),
     'select_min' => array(
       'name' => "Minimum number of selections required",
       'component_types' => array(
@@ -407,6 +419,37 @@ function webform_validation_webform_vali
           return array($keys[0] => t('You have to specify at least one of these items:') . theme('item_list', $names));
         }
         break;
+      case "oneofseveral_expanded":
+        // $components should have at least 2 items - no need to check due to params in rule
+        $keys = array_keys($items);
+        $entryN = array();
+        foreach($keys as $jj=>$kk) {
+            if ($components[$kk]['type'] == 'file') { // Is it a file field?
+                $loc_form_key = $components[$kk]['form_key'];
+                if ($_FILES['files']['size'][$loc_form_key] > 0) { // ensure that the file exists by file byte size > 0
+                    $entryN[$jj] = $_FILES['files']['name'][$loc_form_key]; // sets with the file name
+                }
+                else { 
+                    $entryN[$jj] = ''; // empty
+                }
+            }
+            else { // non-file fields
+                $entryN[$jj] = _webform_validation_flatten_array($items[$kk]);
+            }
+        }
+        if (count(array_filter($entryN)) < 1) { // Are all the elements empty?
+            $names = array();
+            foreach ($keys as $value) {
+                $names[] = $components[$value]['name'];
+            }
+            if (count($keys) == 2) { // custom error msg for only two items
+                return array($keys[0] => t('You have to specify %item1 or %item2 (or both)', array('%item1' => $components[$keys[0]]['name'], '%item2' => $components[$keys[1]]['name'])));
+            }
+            else { // default error msg for three or more items
+                return array($keys[0] => t('You have to specify at least one of these items:') . theme('item_list', $names));
+            }
+        }
+        break;
       case "select_min":
         $min_selections = $rule['data'];
         foreach ($items as $key => $val) {
