I've added a bunch of new user profiles under: administer -> users -> configure -> profiles

If I want to do some simple data validation on these new fields, what is the most logical place to put my PHP code?

thanks!

Comments

Aran Deltac’s picture

Well, the fields that are available and how they are validated is all in the profile.module file. If you want custom fields (and thus custom validation) then it'd probably be a good idea to put in a feature request on that module.

If you want to be really inventive you could come up with a scheme where someone can specify a custom regular expression for text fields that it would validate against. In any case - post your request as a feature request on the core drupal project since profile.module is a part of the core:

http://drupal.org/node/add/project_issue/drupal/feature

If you just want a quick fix you should probably just go in to profile.module and duplicate all the code for how it handles the URL field and modify the validation to fit whatever you want your field to be.

--
http://www.electroniclife.org/

moshe weitzman’s picture

you have a couple options:

- enhance profile.module so that it accepts custom validation routines. i would think that you could add a hook during validation so that a developer could write a function that does the validation.

- don't use profile.module for these fields. Implementing them yourself in hook_user(). Thats the hook that profile.module itself uses.

juanfe’s picture

Hello,

This is what I did to validate profile fields.

Case
I have a Country and State/Province dropdown in my user profile creation and edit list. Because of how I built the profile fields, the first item is <----> in the dropdown for country, and the State/Province country includes a couple of separators that break out the provinces for separate countries. This means that some of the options in the dropdown menus are there for information but should really not go in the database.

I wanted to validate the Country and State province field so that if a user selected one of those separators, the user would be prompted to choose a valid entry.

Implementation
I followed a three-step process:

  1. Create a custom module called sitehelper by defining two files, sitehelper.info and sitehelper.module, and placing them in /sites/all/modules/sitehelper/. The .info file is a standard drupal info file:
    ; $Id$
    name = Custom Helper Functions
    description = "A module to add custom form handling for my site."
    package = "Helpers"
    version = "$Name$"
    
  2. in sitehelper.module, define a function called sitehelper_form_alter, as follows:
    function sitehelper_form_alter($form_id, &$form) {
    //intercept user_register and user_edit forms and add validation function for country and state
      if ($form_id == 'user_register' || $form_id == 'user_edit') {
       $form['Company']['profile_country']['#validate'] = array('sitehelper_profile_country_validate' => array());
      
       $form['Company']['profile_state']['#validate'] = array('sitehelper_profile_state_validate' =>array());
      }
    }
    

    In this case, ['Company'] is the Category in which I put the Country and State fields -- you would use the text you entered in the 'Category' field when you created the profile field. ['profile_country'] and ['profile_state'] are the names of the field I'm validating -- you would enter whatever Drupal's Profile fields screen shows you under "Name" in /admin/user/profile . ['#validate'] is an element in the Form API that instructs drupal to call the function you specify in the assignment when validating the field -- in this case, I use two different functions, sitehelper_profile_country_validate and sitehelper_profile_state_validate to handle the country and the state cases.

  3. Define the validation functions in sitehelper.module, as follows:
    function sitehelper_profile_country_validate ($element) {
      if ($element['#value'] == "<---->") {
    	form_set_error('profile_country', t('Please select a country from the list.'));
      }
    }
    
    function sitehelper_profile_state_validate ($element) {
      if ($element['#value'] == "<--CHOOSE-->" ||
         $element['#value'] == "<--ARGENTINA-->" ||
         $element['#value'] == "<--BRASIL-->" ||
         $element['#value'] == "<--MEXICO-->" ||
         $element['#value'] == "<--PERU-->" ||
         $element['#value'] == "<--UNITED STATES-->") {
    	form_set_error('profile_state', t('Please select a state from the list.'));
      }
    }
    

    What I'm doing there is checking for the values I don't want (they're drop-downs, so anything else is Kosher as far as I'm concerned) and using form_set_error to tell drupal that the field specified as the first parameter is in error (so that it puts a red box around it) and the error message to display on the top. $element is what drupal passes to your validation function, which contains the specific form element you're validating.

  4. Activate the module in your admin screen and test it out.

Overall this was about 15 minutes worth of work, mostly in figuring out the form hierarchy.

Hope this helps.

juanfe

antonl1969’s picture

I think you are the one who cal help me.

I have been posting this for so long and I know you can answer. I want create to two roles eg contestant and member. Member gender can select on both male and female listbox but on contestant female only.

Is it possible to validate this during registration? Pls help. thanks

juanfe’s picture

Hello,

This is what I did to validate profile fields.

Case
I have a Country and State/Province dropdown in my user profile creation and edit list. Because of how I built the profile fields, the first item is <----> in the dropdown for country, and the State/Province country includes a couple of separators that break out the provinces for separate countries. This means that some of the options in the dropdown menus are there for information but should really not go in the database.

I wanted to validate the Country and State province field so that if a user selected one of those separators, the user would be prompted to choose a valid entry.

Implementation
I followed a three-step process:

  1. Create a custom module called sitehelper by defining two files, sitehelper.info and sitehelper.module, and placing them in /sites/all/modules/sitehelper/. The .info file is a standard drupal info file:
    ; $Id$
    name = Custom Helper Functions
    description = "A module to add custom form handling for my site."
    package = "Helpers"
    version = "$Name$"
    
  2. in sitehelper.module, define a function called sitehelper_form_alter, as follows:
    function sitehelper_form_alter($form_id, &$form) {
    //intercept user_register and user_edit forms and add validation function for country and state
      if ($form_id == 'user_register' || $form_id == 'user_edit') {
       $form['Company']['profile_country']['#validate'] = array('sitehelper_profile_country_validate' => array());
      
       $form['Company']['profile_state']['#validate'] = array('sitehelper_profile_state_validate' =>array());
      }
    }
    

    In this case, ['Company'] is the Category in which I put the Country and State fields -- you would use the text you entered in the 'Category' field when you created the profile field. ['profile_country'] and ['profile_state'] are the names of the field I'm validating -- you would enter whatever Drupal's Profile fields screen shows you under "Name" in /admin/user/profile . ['#validate'] is an element in the Form API that instructs drupal to call the function you specify in the assignment when validating the field -- in this case, I use two different functions, sitehelper_profile_country_validate and sitehelper_profile_state_validate to handle the country and the state cases.

  3. Define the validation functions in sitehelper.module, as follows:
    function sitehelper_profile_country_validate ($element) {
      if ($element['#value'] == "<---->") {
    	form_set_error('profile_country', t('Please select a country from the list.'));
      }
    }
    
    function sitehelper_profile_state_validate ($element) {
      if ($element['#value'] == "<--CHOOSE-->" ||
         $element['#value'] == "<--ARGENTINA-->" ||
         $element['#value'] == "<--BRASIL-->" ||
         $element['#value'] == "<--MEXICO-->" ||
         $element['#value'] == "<--PERU-->" ||
         $element['#value'] == "<--UNITED STATES-->") {
    	form_set_error('profile_state', t('Please select a state from the list.'));
      }
    }
    

    What I'm doing there is checking for the values I don't want (they're drop-downs, so anything else is Kosher as far as I'm concerned) and using form_set_error to tell drupal that the field specified as the first parameter is in error (so that it puts a red box around it) and the error message to display on the top. $element is what drupal passes to your validation function, which contains the specific form element you're validating.

  4. Activate the module in your admin screen and test it out.

Overall this was about 15 minutes worth of work, mostly in figuring out the form hierarchy.

Hope this helps.

juanfe

mortenson’s picture

juanfe: many thanks for this explanation!

And to add something for module developers newbies like me:

If you get his problem:

"This version is incompatible with the 6.1 version of Drupal core."

Just add this line somewhere in the modulename.info file, in this case in the sitehelper.info file

core = 6.x

http://drupal.org/node/229940

mortenson’s picture

I have been trying to make a much simple validation module in Drupal 6.1 to dont let visitors register if they havent accepted the terms and conditions of the page. For that, I created a checkbox using profile module called "profile_acepto" that when checked the user is accepting terms and conditions. After that I have followed juanfe explenation step by step, but its not working.

My sitehelper.module file looks like this:

function sitehelper_form_alter($form_id, &$form) {
//intercept user_register and user_edit forms and add validation function for the terms and conditions chekbox
if ($form_id == 'user_register' || $form_id == 'user_edit') {
$form['Personal Information']['profile_acepto']['#validate'] = array('sitehelper_profile_acepto_validate' => array());
}
}
function sitehelper_profile_acepto_validate ($element) {
if ($element['#value'] == '1') {
form_set_error('profile_acepto', t('Please accept Terms and Conditions'));
}
}

Still a visitor can register without cheking the terms and conditions checkbox.

I also get this errors when registering:

warning: Cannot modify header information - headers already sent by (output started at /home/nosfuimo/public_html/sites/all/modules/sitehelper/sitehelper.module:10) in /home/nosfuimo/public_html/includes/common.inc on line 141.

Any help is welcome

tlhong’s picture

Possible you have a new line after the closing php tag.

Alaska’s picture

Can someone post the code to make this work in 5.14?

Thanks

Dillibabucm’s picture

this is good procedure

vr_mex’s picture

I copied the code above and it does not work for Drupal 6.9, I would appreciate someone posting it for Drupal 6.9

The module loads ok and it is recognized in the modules section of Drupal 6.9 but it wont validate custom profile fields.

vr_mex’s picture

This code will work for Drupal 6.9

This is the sitehelper.info

; $Id$
name = Custom helper functions
description = A module to add custom registration form field validation.
package = Helpers
core = 6.x

This is the sitehelper.module

// $Id$
 function sitehelper_form_alter(&$form, $form_state, $form_id) {
//intercept user_register and user_edit forms and add validation function for edad
  if ($form_id == 'user_register' || $form_id == 'user_edit') {
   
   $form['Info Personal']['profile_edad']['#element_validate'] = array('sitehelper_profile_edad_validate');
  }
}


 function sitehelper_profile_edad_validate ($element) {
   if ($element['#value'] == "Selecciona uno") {
     form_set_error('profile_edad', t('Por favor selecciona tu edad.'));
   }
 }
 
Alaska’s picture

What are the mods to make this work for 5.14 in profile.module?

michaelfavia’s picture

There are no API breaks among 5.X versions And where this is concerned, only the name of the validation element in fapi changed that I remember (and the info file format) so the above would work by only chnaging that from #element_validate to #validate. -mf

Alaska’s picture

Thanks for the heads up. Will give you mods a try.

sycorax’s picture

its creating problems with 6.11, is there any change required?

sycorax’s picture

it gives me this warning, when i tested it online, and i needed to refresh my page to go to that page.

for example, if i login into my site using user name and password it doesnt open, it shows a blank white page, and after i refresh it goes to my home page.

it was working fine on my localhost. what could be the problem?

wwarning: Cannot modify header information - headers already sent by (output started at /home/content/a/s/s/mysite/html/modules/Form validation/sitehelper.module:2) in /home/content/a/s/s/mysite/html/includes/session.inc on line 97.

warning: session_regenerate_id() [function.session-regenerate-id]: Cannot regenerate session id - headers already sent in /home/content/a/s/s/mysite/html/includes/session.inc on line 100.

mysite= the name of my site.

sankatha’s picture

Cant you just implement hook_user() as follows :(. Works fine for me and think it is pretty easy

/**
 * DRUPAL 6
 * Override the hook_user in your module if you have one or create a one for your validation stuff
 */ 

function mymodulename_user($op, &$edit, &$account, $category = NULL) {
    if ($op == 'validate') {
         // Do the validations
         // example: validate an email address created via your profile module called profile_user_second_email
         
         if (preg_match('/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,7})+$/',  $account['profile_user_second_email']) == 0) {
             // Kick out a form error
             form_set_error('profile_user_second_email', t('Dude you should get your email right....'));
         } 
    }
}
scrowder’s picture

I am finding that Sankatha is right, hook_user() is a lot easier than the above example.

robin van emden’s picture

Sankatha is correct, but for a small adaptation. It shouldn't be $account['profile_user_second_email'] but $edit['profile_user_second_email'], since you are validating form values, not the account.
The former does work during registration, but will break when editing users (ie at user/1/edit), while the latter works in both cases.

/**
* DRUPAL 6
* Override the hook_user in your module if you have one or create a one for your validation stuff
*/

function mymodulename_user($op, &$edit, &$account, $category = NULL) {
    if ($op == 'validate') {
         // Do the validations
         // example: validate an email address created via your profile module called profile_user_second_email
        
         if (preg_match('/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,7})+$/',  $edit['profile_user_second_email']) == 0) {
             // Kick out a form error
             form_set_error('profile_user_second_email', t('Dude you should get your email right....'));
         }
    }
}
akalata’s picture

I'm finding that this validation posted by Robin also runs on the default account page -- where the users update their email address, change their password, and set timezone settings, among other things. If you find this happenening, add a conditional so that the validation only runs when the field is present; i.e.

if (isset($edit['profile_user_second_email'])) {
         if (preg_match('/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,7})+$/',  $edit['profile_user_second_email']) == 0) {
                      // Kick out a form error
                      form_set_error('profile_user_second_email', t('Dude you should get your email right....'));
                  }
}