Save user profile on Drupal

Tested on:

  • Drupal 5.x

After you have created some user fields through Profile module provided by core, you can have the need to save value into the user object. Here a quick howto to do this.

On user creation:

/** create user profile ($new_user will be an user object) */
$new_user_array = array (
  'name' => "funnyusername",
  'pass' => "MyVerySecurePassword",
  'mail' => "info@example.gom",
  'status' => 1, # status: active
);
$new_user = user_save(NULL, $new_user_array, $category = 'account');
/** assign values to profile fields */
$new_user_edit =  array(
'profile_surname' => "Yumemiya",
'profile_name' => "Arika",
);
/** create and save profile fields */
profile_save_profile($new_user_edit, $new_user, "Character ID");

Where “Character ID” is the category name for profile_surname e profile_name.

To load current user instead creating new one, you have to use

global $user;

instead a previously declared user object $new_user.

See also:

Update:

  • Using this method during a cronjob (using hook_cron) I experienced an error: profile values are passed, but not written, but only if cronjob is launched automatically, and not forced by Report screen (as admin). After some days, I discovered that it’s a permission issue.
    Problem:
    Add a “cronbot” user with some privileges over user (“administer user”) to allow writing even on hidden Profile field.
    Solution:
    On a dedicated server, with a dedicated IP, you can automatically login by IP (by IP Login module for 5.x and 6.x) the cronjob using the server IP or loopback address (127.0.0.1) depending on server configuration (I use the first in production, the latter on local testing).

    1. Add an ip_login Profile field (single line text field, hidden field)
    2. Enable IP Login module
    3. Assign ip_login field to IP login by IP Login configuration screen
    4. Create a new role named “cronbots”, with “administer users” permission.
    5. Create a new user named “cronbot”, with “cronbots” role assigned
    6. Change the “IP login” field for “cronbot” to your server IP (127.0.0.1 or your static IP address as listed on ifconfig on *nix servers)

    On the next automatic cron run (not force it), you’ll see the “cronbot” user logging in. On Drupal logs, the cronjob execution pass from “Anonymous” to “cronbot”, and profile fields are rightly written.
    The other way:
    Just write profile field via db_query. (You don’t want to do a weird thing like that, right? 😉 )

Advertisements

Customize exposed filter on Drupal View

Tested on:

  • Drupal 5.x
  • Views 1.6

When you have to filter a view by a content type, you have to use Exposed filters. Since default list is somewhat ugly (a select with some elements and CTRL to be pressed) we transform it in simple checkboxes.

Copy and paste this code into your template.php:

# I use imagecache because on my site is active
# and doesn't use hook_form_alter
/** Display checkboxes instead select for exposed views filters */
function imagecache_form_alter($form_id, &$form) {
  if($form_id == 'views_filters' && arg(0) == 'change_to_your_view_path_before_slash') {
    if(!empty($form)) {
      foreach ($form as $id => $field) {
        if ($form[$id]['#type'] == 'select' && $form[$id]['#multiple'] == 'multiple') {
          # from select to checkboxes
          $form[$id]['#type'] = 'checkboxes';
	  foreach($form[$id]['#options'] as $key=>&$content) {
            # hide from list all content types that aren't mycontenttype or mycontenttype2
            if($key!='mycontenttype' && $key!='mycontenttype2'){
		unset($form[$id]['#options'][$key]);
	    }
	  }
        }
      }
    }
  }
}

To hide operators dropdown, you have to check “lock operators” on views page.

See also:

Tertiary links / 2: tree workaround

On Tertiary links on Drupal I described a simple approach to display the “tertiary” menu (childrens of secondary menus) on Drupal 5.x. This is an useful but sometimes limiting approach, since the secondary menu disappears when tertiary menu is displayed.

This is an alternative workaround made using a customized menu_tree function:

template.php:

function custom_menu_tree_secondary($pid = 1) {
  $menu = menu_get_menu();
  $output = '';

  if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) {
    foreach ($menu['visible'][$pid]['children'] as $mid) {
      $type = isset($menu['visible'][$mid]['type'])
? $menu['visible'][$mid]['type'] : NULL;
      $children = isset($menu['visible'][$mid]['children'])
? $menu['visible'][$mid]['children'] : NULL;
      # display only the children menu of the current menu
      if(menu_in_active_trail($mid)) {
      	$output .= theme('menu_tree', $mid);
      }
    }
  }
  return $output;
}

page.tpl.php (in place of standard $secondary block):

<div id="secondary">
<?php if ($secondary_links): ?>
<?php echo tools_menu_tree_secondary(variable_get('menu_primary_menu', 0));?>
<?php endif; ?>
</div>

Tested on:

  • Drupal 5.x
  • Zen subtheme