it-swarm.asia

احصل على جميع المستخدمين ذوي الأدوار المحددة باستخدام EntityFieldQuery

اعتقدت أن هذه كانت مهمة سهلة ، ولكن لا يبدو أن هناك طريقة دروبال لهذا. لقد وصلت إلى حد معرفة أن علي استخدام EntityFieldQuery لهذا - لأن واجهة برمجة التطبيقات (API) قالت أن شروط user_load_multiple() متوقفة.

لذا حاولت هذا:

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

  $result = $query->execute();

ومع ذلك حصلت على هذا:

PDOException: SQLSTATE [42S22]: لم يتم العثور على العمود: 1054 عمود غير معروف 'users.rid' في 'حيث جملة': SELECT users.uid AS الكيان_المعروف: الكيان_النوع AS الكيان_النوع ، NULL AS revision_id ،: الحزمة AS الحزمة من {المستخدمين} المستخدمين WHERE (users.rid =: db_condition_placeholder_0) ، الصفيف ([: db_condition_placeholder_0] => 3 [: الكيان_نوع] => المستخدم [: bundle] => المستخدم) في EntityFieldQuery-> تنفيذ ()

لذا فكرتي الأولى ، أنه كان علي الانضمام مع users_roles- الجدول وما إلى ذلك ، ولكن هذا سيؤدي إلى التكرارات.

هل لدى أي شخص فكرة عن كيفية القيام بذلك؟

35
Nils Riedemann

لنكون صادقين ، ليس لدي أي فكرة عن كيفية تحقيق ذلك. من الصعب العثور على أمثلة جيدة حول كيفية استخدام EntityFieldQuery. نظرًا لعدم إجابة أحد على هذا السؤال حتى الآن وأنا مهتم أيضًا بالحل ، سأحاول مساعدتك. الموضح أدناه هو أفضل تخميني.

شيء يجب تذكره: يتم تخزين الأدوار في جدول مختلف عن المستخدمين. يتم إضافتها باستخدام serController :: attachLoad .

يبدو أن هناك ثلاثة شروط مختلفة يمكنك استخدامها مع EntityFieldQuery:

  1. كيانكونديتيون (الشروط الخاصة بالكيان: "الكيان_نوع" ، "حزمة" ، "معرّف_مراجعة" أو "كيان_ معرف")
  2. fieldCondition (شروط الحقول التي تحتفظ بها واجهة برمجة التطبيقات الميدانية)
  3. propertyCondition (الشروط على خصائص الكيان)

الخيار الأكثر منطقية (إن وجد) هو استخدام خاصية propertyCondition ، ولكن عند إضافة الأدوار إلى المستخدم في serController :: attachLoad لا أعتقد أن EntityFieldQuery يمكنه الوصول إليها. أعتقد أن EntityFieldQuery يستخدم فقط المخطط المحدد في hook_schema ().

هذا يقودني إلى الاعتقاد بأن ما تحاول تحقيقه مستحيل. سيكون الحل البديل الحصول على جميع uids باستخدام استعلام عادي:

ليس لدي حق الوصول إلى Drupal الآن ، لذلك قد يكون الرمز أدناه معطلاً. أنا متأكد من أن شخصًا ما سيعدل الأخطاء.

// 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);

إذا كان من الممكن تحقيق ما تريده باستخدام EntityFieldQuery ، فسأكون مستنيرًا.

32
Bart

يجب أن تفعل الخدعة

  $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

في الواقع هناك طريقة للقيام بذلك. في جوهرها ، فإن EntityFieldQuery (EFQ) هو مجرد استعلام قاعدة بيانات يمكن تعديله باستخدام روابط تغيير الاستعلام.

أبسط مثال ممكن:

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);
}

ومع ذلك ، هناك عدد قليل من المحاذير الصغيرة مع هذا الأمر يتطلب المزيد من الترميز. على سبيل المثال في العناية بالشرط الوحيد الموجود في EFQ كونه fieldCondition ، لن يكون أساس قاعدة المستخدمين موجودًا ، لذلك عندما تجلب المستخدمين حسب الدور وحقل واحد ، تحتاج أيضًا إلى التأكد من يتم ضم جدول المستخدمين ، وإذا لم يكن كذلك ، فقم بالانضمام إليه يدويًا ، وهو ما يعد عملية مملة.

ولكن لحاجتك ، فإن هذا سيفي بالغرض. يؤدي إدراك أنه يمكنك تغيير استعلامات EFQ يدويًا إلى فتح عالم ضخم من الفرص لإنشاء استعلامات قوية جدًا مع الحفاظ على نظافة الواجهة ودروبال.

يُرجى إعلامنا إذا كانت لديك أي أسئلة أو مشكلات.

تحرير: لقد وجدت في الواقع طريقة أكثر فعالية للقيام بذلك وقمت بتغيير التعليمات البرمجية وفقًا لذلك.

16
Tommi Forsström
$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

لا يزال بإمكانك استخدام EntityFieldQuery () بمجرد الحصول على معرفات المستخدم لدورك ، إذا كنت ترغب في ذلك ، على سبيل المثال لأنك ترغب في حقل fieldCondition () المستخدم أو طريقة أخرى.

باستخدام المصفوفة $ uids في المثال أعلاه:

$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();

سيكون أجمل إذا كان لدى EntityFieldQuery طريقة ربط.

5
JUPITER

حسنًا ، هذا قديم ، ولكن يمكنك فعل شيء كهذا:

$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

هذا متأخر قليلاً على اللعبة ، لكن أعتقد أن هذا ما كان يطلبه OP. على سبيل المثال لا مزود ، كل دروبال. نأمل أن يجدها الآخرون مفيدة. قادني البحث عن هذا إلى هنا وهذا ما توصلت إليه.

    /**
     * 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

هذا بالفعل موضوع قديم وقد وجدت الكثير من الأساليب الجيدة.

سأحسن قليلاً على الحل المقدم منalf ، لأنني أعتقد أن أحد الاستعلامات مع الصلة هو أفضل نهج. ومع ذلك ، فأنا أحب أيضًا أن تحتوي وظائفي على معلمات ولا تعتمد على ثابت. وهنا يأتي:

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