web-dev-qa-db-ja.com

Drupal 7のユーザーフィールドを更新する

Drupal 7ユーザーのカスタムフィールドをいくつか作成しました。これを外部ユーザーテーブルからインポートしました。

現在、カスタムモジュールを使用してこれらのカスタムフィールドの入力を自動化しようとしていますが、コードが機能していません。次のコードは私が取り組んできたものです:

<?php

function get_sage_fields($username) {

  // Get the extra fields for Sage users
  $sage_fields = db_query('SELECT OFFICE_ID, TRADE_STATUS, DESIGNATION,
    FIRST_NAME, LAST_NAME, PHONE_NUMBER, MAILING_ADDRESS, ACCOUNT_PREFIX,
    ALLOW_TO_TRADE FROM USER WHERE USER_ID = $username');
  return $sage_fields;
}

function sage_fields_user() {

  // Grab all usernames from the users table
  $usernames = db_query('SELECT name FROM users')->fetchCol();

  // Load the users
  $users = user_load_multiple($usernames);

  // Loop through and edit each user
  foreach($users as $user) {

    // Load the extra data
    $extra_data = get_sage_fields($user->name);

    // Update user fields
    $user->field_office_id[$user->language][0]['value'] = $extra_data['office_id'];
    $user->field_trade_status[$user->language][0]['value'] = $extra_data['trade_status'];
    $user->field_designation[$user->language][0]['value'] = $extra_data['designation'];
    $user->field_first_name[$user->language][0]['value'] = $extra_data['first_name'];
    $user->field_last_name[$user->language][0]['value'] = $extra_data['last_name'];
    $user->field_phone_number[$user->language][0]['value'] = $extra_data['phone_number'];
    $user->field_mailing_address[$user->language][0]['value'] = $extra_data['mailing_address'];
    $user->field_allow_to_trade[$user->language][0]['value'] = $extra_data['allow_to_trade'];

    // Save the user object
    user_save($user);
  }
}

Admin/modulesでカスタムモジュールを有効にして、.infoファイルに次のように含めました:

files[] = sage_fields.module

ただし、field_revision_[FIELD_NAME]私のD7データベースでは、これらのフィールドにデータが入力されていません。

誰かが私がどこが間違っているのか指摘してくれませんか?

1
chlong

とても簡単。貼り付けて

$user_fields = user_load($user->uid);    
$user_fields->field_points['und'][0]['value'] = $points;
user_save($user_fields);
5
Krunal Hingu

いくつかあります...

まず、db_query()(_$username_)に渡す引数は文字列であるため、クエリ内で引用符で囲む必要があります。データベースレイヤーでは、実際にはパラメーターを渡すことができます。これは(SQLインジェクションから保護するため)より安全であり、これについて心配する必要がないことを意味します。

_$args = array(':username' => $username);
$query = db_query('SELECT OFFICE_ID, TRADE_STATUS, DESIGNATION,
          FIRST_NAME, LAST_NAME, PHONE_NUMBER, MAILING_ADDRESS, ACCOUNT_PREFIX,
          ALLOW_TO_TRADE FROM USER WHERE USER_ID = :username', $args);
_

2つ目は、実際にdb_query()の結果を、呼び出し元の関数で使用できるものに変換する必要があることです。あなたのケースでは、クエリから単一のオブジェクトが必要なので、fetchObject()メソッドを使用します。

_return $query->fetchObject();
_

get_sage_fields()関数を上記のコードのように変更すると、少し運が良くなるでしょう:)

[〜#〜]編集[〜#〜]

明確にするために、完成したコードは次のようになります。

_function sage_fields_menu() {
  $items['user-data-import'] = array(
    'title' => 'User Data Import',
    'access arguments' => array('access administration pages'), // Or whatever permission you want to use
    'page callback' => 'sage_fields_import_user_data',
    'type' => MENU_CALLBACK
  );

  return $items;
}

function get_sage_fields($username) {
  // Get the extra fields for Sage users
  $args = array(':username' => $username);
  $sage_fields = db_query('SELECT OFFICE_ID, TRADE_STATUS, DESIGNATION,
    FIRST_NAME, LAST_NAME, PHONE_NUMBER, MAILING_ADDRESS, ACCOUNT_PREFIX,
    ALLOW_TO_TRADE FROM USER WHERE USER_ID = :username', $args);
  return $sage_fields->fetchObject();
}

// Don't call this function sage_fields_user as that will be an implementation
// of hook_user() and will cause you problems.
function sage_fields_import_user_data() {
  // Set 

  // Grab all user ids from the users table
  // You need the ids to load the user objects in user_load_multiple
  $uids = db_query('SELECT uid FROM users')->fetchCol();

  // Load the users
  $users = user_load_multiple($uids);

  // Loop through and edit each user
  foreach($users as $user) {

    // Load the extra data
    $extra_data = get_sage_fields($user->name);

    // Update user fields
    $user->field_office_id[$user->language][0]['value'] = $extra_data['office_id'];
    $user->field_trade_status[$user->language][0]['value'] = $extra_data['trade_status'];
    $user->field_designation[$user->language][0]['value'] = $extra_data['designation'];
    $user->field_first_name[$user->language][0]['value'] = $extra_data['first_name'];
    $user->field_last_name[$user->language][0]['value'] = $extra_data['last_name'];
    $user->field_phone_number[$user->language][0]['value'] = $extra_data['phone_number'];
    $user->field_mailing_address[$user->language][0]['value'] = $extra_data['mailing_address'];
    $user->field_allow_to_trade[$user->language][0]['value'] = $extra_data['allow_to_trade'];

    // Save the user object
    user_save($user);
  }

  return 'Done';
}
_

Drupalのキャッシュをクリアした後にメニューフックを追加しました。 http://mysite.com/user-data-import に移動するだけで、プロセスが開始されます。上記のコードは、_sage_fields_と呼ばれるモジュールに基づいています。別の名前が付けられている場合は、hook_menu()関数で変更する必要があります。

他の質問で述べたように、8500以上のユーザーに対してこれを一度に実行すると、サーバーがタイムアウトする可能性があります。おそらくこのインポートをバッチで実行したいと思うでしょう。

1
Clive