When I added the field "Customer profile reference" that would allow users to fill out their payment information when they create an account in drupal. But commerce-user is always created with the role of "guest". That is, without reference to the drupal-user.

guest_users.png17.96 KBaa2007


aa2007’s picture

Status: Active » Closed (won't fix)

Solved the problem with the Rules.

rszrama’s picture

Title: No relationship Drupal-user and commerce-user. » Allow users to create default customer profiles on account creation
Project: Drupal Commerce » Commerce Addressbook
Version: 7.x-1.3 » 7.x-2.x-dev
Component: Customer » Code
Category: bug » feature
Status: Closed (won't fix) » Active

Yeah, unfortunately the customer profile manager widget doesn't work like you were expecting, but I'm glad you got it sorted out. The widget's primary purpose is to allow administrators to create and manage customer profiles from the order edit form, and it's through the Order module that we actually alter the widget to save a customer profile with the same uid as an order. The idea here is that the manager widget allows you to manage other profiles, not really create one and have it automatically associated to your account.

I think this issue would be better placed as a feature request to the Addressbook module (unless it already supports this). The module already has the concept of default customer profiles, and it could just be updated to facilitate their creation during the registration process.

colinsherry’s picture


How did you solve this problem using rules

aa2007’s picture


Events: After saving a new user account
Conditions: Data value is empty — Data selector: account:field-customer-profile-reference:uid
Actions: Set a data value — Selected data: account:field-customer-profile-reference:uid, Value — Data selector: account:uid

GiorgosK’s picture

would be nice to get this feature request going

emptyvoid’s picture

I ended up write a branch of the logintoboggin module and addressbook to include the field on the registration process.

The biggest challenge was instantiating the entity so I could modify and or save it.

function hook_user_insert(&$edit, $account, $category) {
    $x = 0;
    $profile = commerce_customer_profile_new('billing', 0);

// Assign profile properties
// userid
    $profile->uid = $account->uid;

    // if the address object exists
    if (property_exists($account, 'commerce_customer_address')) {

        $target_address = &$account->commerce_customer_address[LANGUAGE_NONE][0];
        $profile_address = &$profile->commerce_customer_address[LANGUAGE_NONE][0];

        // First Name
        if (array_key_exists('first_name', $target_address)) {
            $profile_address['first_name'] = $target_address['first_name'];
        // Last Name
        if (array_key_exists('last_name', $target_address)) {
            $profile_address['last_name'] = $target_address['last_name'];

        // Street Address
        if (array_key_exists('thoroughfare', $target_address)) {
            $profile_address['thoroughfare'] = commerce_ecometry_customer_sanatize_address($target_address['thoroughfare']);

        // City
        if (array_key_exists('locality', $target_address)) {
            $profile_address['locality'] = $target_address['locality'];

        // State
        if (array_key_exists('administrative_area', $target_address)) {
            $profile_address['administrative_area'] = $target_address['administrative_area'];

        // Zip
        if (array_key_exists('postal_code', $target_address)) {
            $profile_address['postal_code'] = $target_address['postal_code'];

        // Country
        if (array_key_exists('country', $target_address)) {
            $profile_address['country'] = $target_address['country'];

    // Daytime phone number
    if (property_exists($account, 'field_customer_daytime_phone')) {
        $profile->field_customer_daytime_phone = $account->field_customer_daytime_phone;

    // Nighttime phone number
    if (property_exists($account, 'field_customer_nighttime_phone')) {
        $profile->field_customer_nighttime_phone = $account->field_customer_nighttime_phone;

    // Save the profile.

    // set the billing profile as default.


Rendering the fields in the altered form was also fun to figure out.

function hook_form_user_register_form_alter(&$form, &$form_state, $form_id) {
    global $user;

    $form['customer_notice'] = array(
        '#type' => 'fieldset',
        '#title' => t(''),
        '#collapsible' => false,
        '#collapsed' => false,
        '#weight' => -15,
        '#attributes' => array('style' => array('width: 300px; float: right; margin-left: 20px;')),

    if (stripos(current_path(), 'checkout') !== FALSE) {
        $login_path = '/checkout/'.arg(1);
    } else {
        $login_path = '';

    // Ensure this include file is loaded when the form is rebuilt from the cache.
    $form_state['build_info']['files']['form'] = drupal_get_path('module', 'commerce_customer') . '/includes/commerce_customer_profile.forms.inc';

    $profile = commerce_customer_profile_new('billing', 0);

    // Ensure the owner name is accessible if the uid is set.
      if (!empty($profile->uid) && $owner = user_load($profile->uid)) {
        $profile->name = $owner->name;

      if (empty($profile->created)) {
        $profile->date = format_date(REQUEST_TIME, 'custom', 'Y-m-d H:i:s O');

    $form_state['customer_profile'] = $profile;

    field_attach_form('commerce_customer_profile', $profile, $form, $form_state);

    // add submission and validation
    // We add the form's #submit array to this button along with the actual submit
    // handler to preserve any submit handlers added by a form callback_wrapper.
      $submit = array();

      if (!empty($form['#submit'])) {
        $submit += $form['#submit'];

      $form['actions']['submit'] = array(
        '#type' => 'submit',
        '#value' => t('Create New Account'),
        '#submit' => array_merge($submit, array('hook_form_user_register_form_submit')),

      // We append the validate handler to #validate in case a form callback_wrapper
      // is used to add validate handlers earlier.
      $form['#validate'][] = 'hook_form_user_register_form_validate';

      $form['contact'] = array(
          '#type' => 'fieldset',
          '#title' => t('Contact Information'),
        '#collapsible' => false,
        '#collapsed' => false,
        '#weight' => 15,

      $form['contact']['field_customer_nighttime_phone'] = $form['field_customer_nighttime_phone'];
      $form['contact']['field_customer_daytime_phone'] = $form['field_customer_daytime_phone'];

      //$form['group_contact'] = $form['#fieldgroups']['group_contact'];

      $form_state['field']['field_customer_nighttime_phone'][LANGUAGE_NONE]['instance']['settings']['user_registration_form'] = TRUE;
      $form_state['field']['field_customer_daytime_phone'][LANGUAGE_NONE]['instance']['settings']['user_registration_form'] = TRUE;


Obviously where I use "hook_" it should be substituted with your custom module name.

kaido24’s picture

You can do it with rules but I didn't get the label for address_book address name. But I am sure if there's need for that it can be done. I guess you would need to write your own action then.
But this wasn't really my case right now. I used commerce_single_address module and this is how I got it cloned.

  1. New field: address field to my user account with the widget settings as I have in customer profile.
  2. After saving a new user account
  3. Action1: Create new Entity (type: Commerce Customer profile).
  4. Action2: Set a data value (type: my_new_entity:commerce-customer-address === account:field-address).

Here's my rules export for that.

{ "rules_clone_account_address_to_customer" : {
    "LABEL" : "Clone account address to customer",
    "PLUGIN" : "reaction rule",
    "REQUIRES" : [ "rules" ],
    "ON" : [ "user_insert" ],
    "DO" : [
      { "entity_create" : {
          "USING" : {
            "type" : "commerce_customer_profile",
            "param_type" : "billing",
            "param_user" : [ "account" ]
          "PROVIDE" : { "entity_created" : { "billing_data" : "Billing data" } }
      { "entity_create" : {
          "USING" : {
            "type" : "commerce_customer_profile",
            "param_type" : "shipping",
            "param_user" : [ "account" ]
          "PROVIDE" : { "entity_created" : { "shipping_data" : "Shipping data" } }
      { "data_set" : {
          "data" : [ "shipping-data:commerce-customer-address" ],
          "value" : [ "account:field-address" ]
      { "data_set" : {
          "data" : [ "shipping-data:commerce-customer-address" ],
          "value" : [ "shipping-data:commerce-customer-address" ]

And one extra helper from #6 if using the addressbook // set the billing profile as default.
commerce_addressbook_set_default_profile($profile); as action..

kaido24’s picture

PQ’s picture

Issue summary: View changes

If it helps, here's a quick snippet that adds the address entered at registration to the address book for both billing and shipping:

 * On user creation, copy the user's address fields to their address book.
function MODULE_user_insert(&$edit, $account, $category) {
  $profile_items = field_get_items('user', $account, 'field_address');
  $account_profile = commerce_customer_profile_load($profile_items[0]['profile_id']);

  foreach (array('billing', 'shipping') as $type) {
    $profile = commerce_customer_profile_new($type, $account->uid);
    $profile->commerce_customer_address = $account_profile->commerce_customer_address;


  • Change "MODULE" to your module name
  • This is based on the address field on the user entity being called "field_address", change to whatever your field is called
  • In this case field_address was a mandatory field and appears on the registration form, if that's not the case then you'd need to add some test to make sure "$profile_items[0]['profile_id']" exists before running "$profile->commerce_customer_address = $account_profile->commerce_customer_address;"
  • If you don't have shipping installed then remove the start and end of the foreach loop and replace "$type" with 'billing'
nfehren’s picture

#9 works perfectly for me.

Thank you very much for sharing this with us. This will save me a lot of time.