Ubercart defines the following uc_price type in uc_store_element_info:

$types['uc_price'] = array(
  '#input' => TRUE,
  '#size' => 15,
  '#maxlength' => 15,
  '#autocomplete_path' => FALSE,
  '#process' => array('ajax_process_form'),
  '#element_validate' => array('uc_store_validate_number'),
  '#theme' => 'textfield',
  '#theme_wrappers' => array('form_element'),
  '#field_prefix' => $sign_flag ? '' : $currency_sign,
  '#field_suffix' => $sign_flag ? $currency_sign : '',
  '#allow_negative' => FALSE, 
  '#empty_zero' => TRUE,

Assume I want to allow negative prices by setting #allow_negative to TRUE. (Maybe this is a bad idea, but play along.) Maybe I will need to replace the #element_validate array with a custom function as well.

From reading the API documentation here: https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_element_info_alter/7.x it looks as if making a custom module and implementing hook_element_info_alter should let me do this. I made a module called customcode and implemented the following function:

function customcode_element_info_alter(&$type) {
  drupal_set_message('Altering uc_price');
  if (isset($type['uc_price'])) {
    $type['uc_price']['#allow_negative'] = TRUE;
} /* end hook_element_info_alter */

but this does not work. Maybe this does not work for obvious reasons but I am pretty confused, and web searching (on this site and elsewhere) is not clearing up my confusion. I could easily believe I am specifying the array element incorrectly, but without troubleshooting information it's difficult to figure out what is going on.

Here are some questions:

  • How do I see the value of the $type array? When troubleshooting other forms I have used print_var or dpm, but those do not do anything here. I do not understand at what point this code is executed and how to display output from it. The drupal_set_message displays nothing.
  • Is hook_element_info_alter the way I want to modify this element? If not, what approach should I take? I obviously do not want to hack the Ubercart module unless there is no other choice.
  • If so, is creating the function with the name I have chosen (customcode_element_info_alter) correct? When I use hook_form_alter I need to include the original form ID in the name. I do not understand how this hook knows enough to alter the data in uc_store_element_info.

Thanks for any help you can offer.

  • Okay, so customcode_element_info_alter looks like the right name, based upon a few other modules that implement this hook. The rest is still mysterious. Apr 30 '16 at 10:34
  • 1
    Don't rely on drupal_set_message() to know if your hook is invoked; rather, use watchdog().
    – apaderno
    Apr 30 '16 at 15:14

The underlying problem was caching. I thought I had cleared cache, but apparently not.

Here are answers to my questions:

As suggested above, use watchdog() to see the value of the $type array. Here is a (probably dangerous) snippet:

watchdog('customcode', 'uc_price after mod: <pre>'. 
print_r($type['uc_price'], TRUE) . '</pre>');

hook_element_info_alter is how I want to modify the element, and the function should replace hook with the name of the custom module.

It looks as if all hook_element_info_alter hooks are called after all type elements are defined somehow, but I am still fuzzy on this.

I am not certain when hook_element_info_alter is called, but it appears to be called early (there is no need to visit the form in question) and it appears to be cached for a long time.

My strategy of setting #allow_negative to TRUE was in fact the right approach, because the validation function uc_store_validate_number takes this into account. Otherwise I would have had to unset the validation function and replace it with a custom one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.