So I've been developing a module, which automatically-assigns roles based on taxonomy terms in user profiles. I can do that fine - but I wanted to add a settings page to the module that allows you to choose which vocabularies to assign roles for.

In the _settings hook, there is this code:


$vocabularies = array();
foreach (module_invoke('taxonomy', 'get_vocabularies') as $vocabulary) {
  $vocabularies[$vocabulary->vid] = $vocabulary->name;
}
$form['autorole_vocab_select'] = array('#type' => 'checkboxes', 
																				     '#title' => t('Vocabularies to auto-generate roles for'),
																					 '#default_value' => variable_get('autorole_vocab_select', 1),
																					 '#options' => $vocabularies,
																					 '#description' => t('Which vocabularies to auto-generate roles for'));
}

If I understand correctly, variable_get['autorole_vocab_select'] should contain the values that were selected in the settings page (and the database table variables reflects this correctly as well).

in the function that assigns the roles, this code is present:

 $allowed = variable_get('autorole_vocab_select', 'none');
 
 foreach($allowed as $vocab) {
 	$terms[] = module_invoke('taxonomy','taxonomy_get_tree', $vocab->vid);
 	}

It then checks that the field type the function got passed is a vocabulary, and checks that the name of it is in $terms - which should contain the vocab terms under the vocabularies that were selected, however if any vocabulary terms were selected, it acts as if all of them were selected. If none are selected it works as would be expected. Since the variable in the database table "variables" is correct, I assume that the problem must be in the $allowed = variable_get('autorole_vocab_select', 'none');call.

Any suggestions as to what I am doing wrong?

Comments

amnon’s picture

$allowed = variable_get('autorole_vocab_select', 'none');

This variable should be an array (since multiple checkboxes can be checked...).

Don't know if it's the only bug, but it's a good start.

kaens’s picture

Do you mean that $allowed should be an array? Because it is....otherwise foreach would spit me an error right? To be sure that it was, I declared it as an array before doing the call to variable get, and the problem is still exactly the same.

kaens’s picture

Man this is driving me nuts. Here's my logic, tell me if it's wrong:

 $form['autorole_settings'] = array('#type' => 'checkboxes', 
																					 '#title' => t('Vocabularies to auto-generate roles for'),
																					 '#default_value' => variable_get('autorole_settings', 0),
																					 '#options' => $vocabularies,
																					 '#description' => t('Which vocabularies to auto-generate roles for'))

Is in the _settings hook. This means that when someone goes and changes this, it gets stored in the variabe database table. It is. It is stored as serialized data in the form a3;{i:3;i:3;i:2;i:0;i:1;i:0;}, which means that it is an array with three elements - then the key => value pairs, which are all integers.

I get this vaiable with a call to variable_get('autorole_settings', 0), which should return the serialized data.
I then unserialize the data which (for the serialized data above,) should give me an array like so:

$unserialized = array(3 => 3, 2 => 0, 1 => 0);

Now, I should be able to iterate over that array with foreach.

 foreach($unserialized as $vocab => $option) {
 	//if an options value is zero, it is not selected
         if($option != 0) {
 		$terms[] = module_invoke('taxonomy','taxonomy_get_tree', $vocab);
 	}
 }

Since the options in the form were generated by a call to taxonomy_get_vocabularies, $vocab in the foreach call should correspond to the vocabularie's vid. - so I can populate the variable $terms with the term data through the call to taxonomy_get_tree. Now I should have a list of terms that are contained within the vocabularies that were selected to be used.

The part that assigns the roles is called by profile.module in the profile_save_profile function. My module checks to see if it's a vocabulary (which I'll be moving that into profile, probably....but anyhow), and then checks to make sure that the field title - which is the name of the term, is a member of terms with

if($field->type == 'vocabulary' && in_array($field->title, $terms))

Now, I can not for the life of me figure out why it is that if I select one vocabulary, it assigns roles for all vocabularies. The data in the variable table is correct, and as far as I can tell, the logic is as well. Maybe I need to run it through a debugger and trace it....any suggestions? On what's going on, or a good tracer, or anything?