Not sure this is the right place for this question but:

I'd like to validate a person's id number (not in drupal database) typed into a text field, against a list of valid numbers (a prebuilt array/text list, one id per line) — is this possible?

Thanks!!

CommentFileSizeAuthor
#16 1.png17.01 KBmar111
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

svendecabooter’s picture

Yeah that shouldn't be too hard with a custom module that implements the proper hooks that are supplied by the webform_validation module.
Below is some (untested) code that should get you started if you put it in a module called 'idvalidation'.

/**
 * Implementation of hook_webform_validation_validators().
 */
function idvalidation_webform_validation_validators() {
  return array(
    'validate_id' => array(
      'name' => "Validate ID",
      'component_types' => array(
        'textfield',
      ),
    )
  );
}

/**
 * Implementation of hook_webform_validation_validate().
 */
function idvalidation_webform_validation_validate($validator_name, $items, $components, $rule) {
  if ($items) {
    switch ($validator_name) {
      case 'validate_id':
        $valid_ids = array(1, 2, 3); // get this from database source instead
        foreach ($items as $key => $val) {
          if ($val && (!in_array($val, $valid_ids))) {
            $errors[$key] = t('%item is not a valid ID', array('%item' => $components[$key]['name']));
          }
        }
        return $errors;
        break;
    }
  }
}

svendecabooter’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

beckyjohnson’s picture

Status: Closed (fixed) » Active

I have a question about this line:

$valid_ids = array(1, 2, 3); // get this from database source instead How do you get this from a database source? Can you query a content type that the value is stored in? If anyone is still reading this, I would really like to see an example of how to grab this data from another database.

Thanks for any comments. I am trying to use webform validate to validate against a bunch of serial numbers formatted as such: 1234-1234-1234-1234.

Rebecca

svendecabooter’s picture

Status: Active » Closed (fixed)

Hi,

Basically it heavily depends on your use case, so there's not one definite solution as to how to get the values you want to validate against. Given 100 sites it will probably be a different approach a 100 times... It also will vary a lot based on whether you are using Drupal 6 or 7.

I would suggest you look into the Database API that is provided by Drupal:
- http://api.drupal.org/api/drupal/includes--database.inc/group/database/6 for Drupal 6
- http://api.drupal.org/api/drupal/includes--database--database.inc/group/... for Drupal 7

If you'd like to get the data from a content type (i.e. node) that contains the values, you should familiarise yourself with the node API (e.g. the node_load function)

Hope that gets you on your way...
If you need more specific support to query the data, i suggest you open a new topic in the drupal.org forums or stop by on IRC #drupal-support, as there will be more people there to support you. Since your issues are most likely not specifically related to the webform_validation but to Drupal APIs in general, you might get more luck at these places getting help for your specific use case.

Good luck!
Sven

beckyjohnson’s picture

If I import the numbers into their own content type, could I find the numbers by querying that content type in my code? I got this idea from reading book on drupal module building....

svendecabooter’s picture

Should be possible, depending on your coding skillset & set up structure. If you take the example above, you can write any PHP code to check for validation, and return the $errors array if a problem occurred.

TechNikh’s picture

+1 bookmarking..

stupiddingo’s picture

Here's two separate strategies based on @svendecabooter's example above to accomplish authorization code lookup that someone might find useful. These add custom errors as well.

1.) Validate against a user-entered (form author) list of validation codes
NOTE: This will allow one code to be used multiple times.

webform_validationauthcode.module

/**
* Implementation of hook_webform_validation_validators().
*/
function webform_validationauthcode_webform_validation_validators() {
  return array(
    'authcode' => array(
      'name' => "Authorization code",
      'component_types' => array(
        'textfield',
        'textarea',
        'email',
        'select',
      ),
      'custom_error' => TRUE,
      'custom_data' => array(
        'label' => t('Authorization code'),
        'description' => t('Specify legal authorization codes, separated by commas. Make sure to escape reserved regex characters with an escape (\) character.')
      ),
      'description' => t("Validates that user-entered authorization code is one value from a list of the specified codes"),
    ),
  );
}

/**
* Implementation of hook_webform_validation_validate().
*/
function webform_validationauthcode_webform_validation_validate($validator_name, $items, $components, $rule) {
  if ($items) {
    switch ($validator_name) {
      case 'authcode':
          $authcode = explode(',', $rule['data']);
          $authcode = array_map('trim', $authcode);
          foreach ($items as $key => $val) {
            if ($val && (!in_array(trim($val), $authcode))) {
			  $errors[$key] = t('%item ', array('%item' => $components[$key]['name'])) ._webform_validation_i18n_error_message($rule);
            }
        }
		return $errors;
        break;
    }
  }
}

2.) Validate against a provided web service URL
webform_validationservice.module

/**
* Implementation of hook_webform_validation_validators().
*/
function webform_validationservice_webform_validation_validators() {
  return array(
    'web_service' => array(
      'name' => "Web Service",
      'component_types' => array(
        'textfield',
        'textarea',
        'email',
      ),
      'custom_error' => TRUE,
      'custom_data' => array(
        'label' => t('Web Service to use for validation'),
        'description' => t('Enter the full URI of the web service to be used. Use <strong>%</strong> (percent sign) in place of the variable to be passed from user input.<br/><strong>Examples: &quot;myservice.php?q=%&quot;, &quot;http://example.com/myservice/%.html&quot;, &quot;http://127.0.0.1/myservice?id=%&cachebuster=1234&quot;</strong><br/><br/><em>Selected service must return valid JSON from a GET request, {"response":"true"} or {"response":"false"}. Form input will be URL encoded. External or internal web services may be used. It is up to the service author to decide how validation occurs (complex logic, uniqueness rules, reuse, and authentication).</em>')
      ),
      'description' => t("Validates that user-entered value is either valid (true) or invalid (false) when tested against a simple webservice GET request"),
    ),
  );
}

/**
* Implementation of hook_webform_validation_validate().
*/
function webform_validationservice_webform_validation_validate($validator_name, $items, $components, $rule) {
  if ($items) {
    switch ($validator_name) {
      case 'web_service':	
		foreach ($items as $key => $val) {
		if ($val) {
				$webservice_url = $rule['data'];  
				$url_var = strpos($webservice_url, '%');
				$url_prefix = substr($webservice_url,0,$url_var);
				$url_suffix = substr($webservice_url, $url_var + 1, strlen($webservice_url) - $url_var + 1);
				$url = $url_prefix .drupal_urlencode($val) .$url_suffix; 
				$json = drupal_http_request($url);
				$jsonresponse = json_decode($json->data,true);
				if (!$jsonresponse) {
					$errors[$key] = t('Authorization service is currently unavailable', array('%item' => $components[$key]['name']));
					watchdog('webform', $errors[$key], array(), WATCHDOG_ERROR);
					return $errors;
					break;
				}
				// If response is false then return error
				if ($jsonresponse["response"] == "false") {
					$errors[$key] = t('%item ', array('%item' => $components[$key]['name'])) ._webform_validation_i18n_error_message($rule);
				}
			}
        }
        return $errors;
        break;
    }
  }
}

Both will need .info files requiring webform and webform_validation.

Definitely must be better ways to accomplish this, but these two modules are stupid simple and work. Hope this helps someone, and I welcome improvements (new to Drupal and PHP).

beckyjohnson’s picture

Thank you for this work! It's really great to study. I ended up having a coworker help me make a module that added a table to my database and stored numbers I uploaded in CSV files and then , when the user entered a number, it got checked against that table.

Rebecca

mari3.14’s picture

@beckyjohnson, I was wondering whether you would mind sharing your custom module please. I am trying to do something very similar but the examples mentioned above are not enough for me to figure it out.

Ta.

Post_History’s picture

Version: 6.x-1.2 » 7.x-1.1
Status: Closed (fixed) » Active

hello im trying the above mentioned methods and still cannot seem to be able see the rule as an option for webforms. am i missing a step not described here ?

Post_History’s picture

Status: Active » Fixed

never mind specific values is enough for me i just had to change the length of the data that could be stored from 255 to 4000 !

dkre’s picture

I've been struggling for about a day with implementing a database query for validation, this is based off svendecabooter's code above. (Huge thanks).

Hope this is helpful to someone.

<?php
/**
 * Implementation of hook_webform_validation_validators().
 */
function webform_codevalidator_webform_validation_validators() {
  return array(
    'validate_id' => array(
      'name' => "Code Validator",
      'component_types' => array(
        'textfield',
      ),
	  'description' => t('Unique Code Validator'),
    )
  );
}

/**
 * Implementation of hook_webform_validation_validate().
 */
function webform_codevalidator_webform_validation_validate($validator_name, $items, $components, $rule) {
  if ($items) {
    switch ($validator_name) {
      case 'validate_id':
	  foreach ($items as $key => $val) {
		if ($val != '') {
        if (!db_query("SELECT COUNT(*) FROM {node} WHERE title = :title", array(':title' => $val))->fetchField()) {
            $errors[$key] = t('%item is not a valid ID', array('%item' => $components[$key]['name']));
          }
        }
        return $errors;
        break;
    }
  }
 } 
}

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

mar111’s picture

Title: How do I validate a number against a list of valid numbers? » Can validate a Spanish bank account number?
FileSize
17.01 KB

Can validate a Spanish bank account number? php code for this validation would be the next but I'm having to apply it to hook.

function ccc_valido($ccc)
{

//$ccc sería el 20770338793100254321
$valido = true;

///////////////////////////////////////////////////
// Dígito de control de la entidad y sucursal:
//Se multiplica cada dígito por su factor de peso
///////////////////////////////////////////////////
$suma = 0;
$suma += $ccc[0] * 4;
$suma += $ccc[1] * 8;
$suma += $ccc[2] * 5;
$suma += $ccc[3] * 10;
$suma += $ccc[4] * 9;
$suma += $ccc[5] * 7;
$suma += $ccc[6] * 3;
$suma += $ccc[7] * 6;

$division = floor($suma/11);
$resto = $suma - ($division * 11);
$primer_digito_control = 11 - $resto;
if($primer_digito_control == 11)
$primer_digito_control = 0;

if($primer_digito_control == 10)
$primer_digito_control = 1;

if($primer_digito_control != $ccc[8])
$valido = false;

///////////////////////////////////////////////////
// Dígito de control de la cuenta:
///////////////////////////////////////////////////
$suma = 0;
$suma += $ccc[10] * 1;
$suma += $ccc[11] * 2;
$suma += $ccc[12] * 4;
$suma += $ccc[13] * 8;
$suma += $ccc[14] * 5;
$suma += $ccc[15] * 10;
$suma += $ccc[16] * 9;
$suma += $ccc[17] * 7;
$suma += $ccc[18] * 3;
$suma += $ccc[19] * 6;

$division = floor($suma/11);
$resto = $suma-($division * 11);
$segundo_digito_control = 11- $resto;

if($segundo_digito_control == 11)
$segundo_digito_control = 0;
if($segundo_digito_control == 10)
$segundo_digito_control = 1;

if($segundo_digito_control != $ccc[9])
$valido = false;

return $valido;

}

mar111’s picture

Title: Can validate a Spanish bank account number? » How do I validate a number against a list of valid numbers?
mclinn’s picture

This was a big help to me, thank you for posting!

I've been tempted to use the "dangerous, do not use!" PHP validator module but decided to play it safe. Rather than doing my form from scratch, using custom validations like this may save me a lot of time.

I did have trouble with the fetchfield() part of the code; rather than spend time investigating I just used the $val in my query, like this:

function mcltesting_webform_validation_validate($validator_name, $items, $components, $rule) {
  if ($items) {
    switch ($validator_name) {
      case 'validate_id':
	  foreach ($items as $key => $val) {
		if ($val != '') {   
           
        $r = db_query("SELECT * FROM {testtable} WHERE uid = %d", $val) ;

        $found = false;
        while ($row = db_fetch_object($r)) {
        	  $found = true;
        	}

        	if (!$found)  {
            $errors[$key] = t('%item is not a valid ID', array('%item' => $components[$key]['name']));
          }
        }
        return $errors;
        break;
    }
  }
 } 
}

Also just used a "while" loop rather than fight with various ways to determine if the query had a result. Just validating one field here, so far it's working great!

Thanks again.

tmbridge’s picture

Hi,

I'm facing a similar predicament in that I cannot see my new rule in the list of validation rules. However, expanding the acceptable value of Specific Value(s) from 255 to 4000 would also work for me but I cannot find this setting anywhere?

Can you please direct me as to where to go to change this setting?

Thanks,
Tim