it-swarm-id.com

Dapatkan semua pengguna dengan peran tertentu menggunakan EntityFieldQuery

Saya pikir ini adalah tugas yang mudah, namun sepertinya tidak ada metode Drupal untuk ini. Saya datang sejauh mengetahui bahwa saya harus menggunakan EntityFieldQuery untuk ini - karena API mengatakan kondisi untuk user_load_multiple() sudah usang.

Jadi saya mencoba ini:

  $query = new EntityFieldQuery;
  $query
    ->entityCondition('entity_type', 'user')
    ->propertyCondition('rid',array(1,2,3);

  $result = $query->execute();

Namun saya mendapatkan ini:

PDOException: SQLSTATE [42S22]: Kolom tidak ditemukan: 1054 Kolom tidak dikenal 'users.rid' di 'di mana klausa': SELECT users.uid AS entity_id,: entity_type AS entity_type, NULL AS revision_id,: bundel AS bundel DARI {pengguna} pengguna WHERE (users.rid =: db_condition_placeholder_0); Array ([: db_condition_placeholder_0] => 3 [: entity_type] => pengguna [: bundle] => pengguna) di EntityFieldQuery-> execute ()

Jadi pikiran pertama saya adalah, bahwa saya harus bergabung dengan users_roles- Tabel dan sebagainya, tapi itu akan menyebabkan duplikat.

Adakah yang punya ide bagaimana melakukannya?

35
Nils Riedemann

Sejujurnya, saya tidak tahu bagaimana mencapai ini. Contoh bagus tentang cara menggunakan EntityFieldQuery sulit ditemukan. Karena belum ada yang menjawab pertanyaan ini dan saya juga tertarik dengan solusi, saya akan mencoba membantu Anda. Dijelaskan di bawah ini adalah tebakan terbaik saya.

Satu hal yang perlu diingat: peran disimpan dalam tabel yang berbeda dari pengguna. Mereka ditambahkan menggunakan serController :: attachLoad .

Tampaknya ada tiga kondisi berbeda yang bisa Anda gunakan dengan EntityFieldQuery:

  1. entityCondition (Kondisi spesifik entitas: 'entity_type', 'bundle', 'revision_id' atau 'entitas_id')
  2. fieldCondition (Ketentuan pada bidang yang dikelola oleh API Bidang)
  3. propertyCondition (Ketentuan tentang properti entitas)

Opsi paling logis (jika ada) adalah menggunakan propertiCondition, tetapi karena peran ditambahkan ke pengguna di serController :: attachLoad Saya tidak berpikir EntityFieldQuery memiliki akses ke sana. Saya pikir EntityFieldQuery hanya menggunakan skema yang ditentukan dalam hook_schema ().

Ini membuat saya percaya bahwa apa yang Anda coba capai tidak mungkin. Solusinya adalah untuk mendapatkan semua cairan dengan permintaan normal:

Saya tidak memiliki akses ke Drupal sekarang, jadi kode di bawah ini mungkin tidak aktif. Saya yakin seseorang akan mengedit kesalahan.

// Use $query for readability
$query = 'SELECT DISTINCT(ur.uid) 
  FROM {users_roles} AS ur
  WHERE ur.rid IN (:rids)';
$result = db_query($query, array(':rids' => array(1,2,3)));

$uids = $result->fetchCol();

$users = user_load_multiple($uids);

Jika mungkin untuk mencapai apa yang Anda inginkan dengan EntityFieldQuery, saya akan tercerahkan.

32
Bart

Seharusnya melakukan trik

  $query = new EntityFieldQuery;
  $query
    ->entityCondition('entity_type', 'user')
    ->addTag('role_filter');
  $results = $query->execute();

/**
* Implement hook_query_TAG_alter
* 
* @param QueryAlterableInterface $query
*/
function MY_MODULE_query_role_filter_alter(QueryAlterableInterface $query) {
  $query->leftJoin('users_roles', 'r', 'users.uid = r.uid');  
  $and = db_and()
            ->condition('r.rid', MY_ROLE_INT, '=');
  $query
    ->condition($and);
}
19
alf

Sebenarnya ada cara untuk melakukan ini. Dalam hatinya, EntityFieldQuery (EFQ) hanyalah sebuah query database yang dapat diubah dengan query alter hooks.

Contoh yang paling sederhana:

function mymodule_get_users_by_rolename($rolename){
  $query = new EntityFieldQuery;
  $query->entityCondition('entity_type', 'user');
  $query->addTag('rolequery');
  $query->addMetaData('rolename', $rolename);

  return $query->execute();
}

function mymodule_query_rolequery_alter(QueryAlterableInterface $query) {
  $rolename = $query->getMetaData('rolename');

  $role_subquery = db_select("role", "role");
  $role_subquery->condition('role.name', $rolename, '=');
  $role_subquery->join('users_roles', "users_to_include", "role.rid = users_to_include.rid");
  $role_subquery->fields('users_to_include', array('uid' => 'uid'));
  $role_subquery->where('users_to_include.uid = users.uid');
  $query->exists($role_subquery);
}

Namun ada beberapa peringatan kecil dengan ini yang akan memerlukan beberapa pengkodean lagi. Misalnya dalam menangani satu-satunya kondisi yang ada di EFQ menjadi fieldCondition, basis pengguna tidak akan ada, jadi ketika Anda menjemput pengguna berdasarkan peran dan satu kondisi lapangan, Anda juga perlu memastikan bahwa tabel pengguna bergabung dan jika tidak, bergabung secara manual, yang merupakan sedikit proses yang membosankan.

Tetapi untuk kebutuhan Anda, ini akan membantu. Menyadari Anda dapat secara manual mengubah kueri EFQ membuka peluang besar dunia untuk membuat kueri yang sangat kuat sambil tetap menjaga antarmuka tetap bersih dan Drupal.

Beri tahu saya jika Anda memiliki pertanyaan atau masalah.

Sunting: Saya sebenarnya menemukan cara yang lebih banyak melakukan hal ini dan mengubah kode saya.

16
$user_list = array();
$roles = array('role_1', 'role_2');
$query = db_select('users_roles', 'ur');
$query->join('users', 'u', 'u.uid = ur.uid');
$query->join('role', 'r', 'r.rid = ur.rid');
$query->fields('u',array('uid'));
$query->fields('u',array('mail'));
$query->fields('u',array('name'));

$query->condition('r.name', $roles, 'IN');
$result = $query->execute();

if($result){
    foreach($result as $row ) {
        $uid = $row->uid;
        $user_list[$uid]['mail'] = $row->mail;
        $user_list[$uid]['name'] = $row->name;
        $user_list[$uid]['uid'] = $uid;
    }
}

return $user_list;
6
Dhanesh Haridas

/**
 * Get users by specific role
 */
function mymodule_get_users_by_role() {
    $role = user_role_load_by_name('rolename');
    $uids = db_select('users_roles', 'ur')
        ->fields('ur', array('uid'))
        ->condition('ur.rid', $role->rid, '=')
        ->execute()
        ->fetchCol();
    $users = user_load_multiple($uids);
}
5
ibit

Anda masih dapat menggunakan EntityFieldQuery () setelah Anda mendapatkan id pengguna untuk peran Anda, jika Anda mau, misalnya karena Anda ingin pengguna fieldCondition () atau metode lain.

Menggunakan array $ uids dalam contoh di atas:

$role = user_role_load_by_name('my_role_name');
$result = db_select('users_roles', 'ur')
->fields('ur', array('uid'))
->condition('rid', $role->rid)
->execute();

foreach($result as $record) {
  $uids[] = $record->uid;
}

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'user')
->entityCondition('entity_id', $uids, 'IN')
->execute();

Akan lebih baik jika EntityFieldQuery memiliki metode bergabung.

5
JUPITER

OK Ini sudah lama, tetapi Anda bisa melakukan sesuatu seperti ini:

$query = new EntityFieldQuery();
$query->entityCondition('entity_type', 'user')

$roles_subquery = db_select('users_roles', 'ur');
$roles_subquery->fields('ur', array('uid'));
$roles_subquery->condition('rid', $my_role_id);

$query->propertyCondition('uid', $roles_subquery, 'IN');
4
Fabio Epifani

Ini sedikit terlambat untuk permainan, tapi saya pikir itulah yang diminta OP. misalnya tidak sql, semua drupal. Semoga yang lain bermanfaat. Pencarian ini membawa saya ke sini dan inilah yang saya hasilkan.

    /**
     * Users with role
     *
     * @param $role mixed The name or rid of the role we're wanting users to have
     * @param $active_user boolean Only return active accounts?
     *
     * @return array An array of user objects with the role
     */
    function users_with_role($role, $active_user = TRUE) {
      $uids = array();
      $users = array();
      if (is_int($role)) {
        $my_rid = $role;
      }
      else {
        $role_obj = user_role_load_by_name($role);
      }
      $result = db_select('users_roles', 'ur')
        ->fields('ur')
        ->condition('ur.rid', $role_obj->rid, '=')
        ->execute();
      foreach ($result as $record) {
        $uids[] = $record->uid;
      };
      $query = new EntityFieldQuery();
      $query->entityCondition('entity_type', 'user')
        ->propertyCondition('uid', $uids, 'IN');
      if ($active_user) {
        $query->propertyCondition('status', 1);
      }
      $entities = $query->execute();
      if (!empty($entities)) {
        $users = entity_load('user', array_keys($entities['user']));
      }
      return $users;
    }
2
Gold

Ini memang topik yang lebih tua dan saya menemukan banyak pendekatan yang bagus.

Saya akan sedikit meningkatkan pada solusi yang disediakan oleh @alf, karena saya pikir satu permintaan dengan bergabung adalah pendekatan terbaik. Namun saya juga suka fungsi saya memiliki parameter dan tidak bergantung pada konstanta. Jadi begini:

function MY_MODULE_load_users_by_role($rid) {
  $query = new EntityFieldQuery;
  $query
    ->entityCondition('entity_type', 'user')
    ->addMetaData('account_role', user_role_load($rid))
    ->addTag('role_filter');
  $results = $query->execute();

  if (isset($results['user'])) {
    $uids = array_keys($results['user']);
    $users = entity_load('user', $uids);
  }
  else {
    $users = array();
  }

  return $users;
}

/**
 * Implement hook_query_TAG_alter
 *
 * @param QueryAlterableInterface $query
 */
function MY_MODULE_query_role_filter_alter(QueryAlterableInterface $query) {
  $rid = $query->alterMetaData['account_role']->rid;
  $query->leftJoin('users_roles', 'r', 'users.uid = r.uid');
  $and = db_and()
    ->condition('r.rid', $rid, '=');
  $query
    ->condition($and);
}
0
benelori