web-dev-qa-db-ja.com

エンティティ参照は、異なるフィールドを持つユーザー名を自動入力します

エンティティ参照モジュールを使用して、ユーザーを特定のコンテンツタイプに関連付けています。オートコンプリートウィジェット(タグスタイル)を使用しています。デフォルトでは、ユーザーのオートコンプリート時にユーザー名を使用します。ただし、検索対象のフィールドを変更したい。 nameフィールドの代わりに使用したいフィールドfield_complete_nameがあります。

私の質問は、エンティティ参照モジュールがこれを実行できるかどうかです。もしそうなら、どうすればいいですか?

2
Lester Peabody

上記のコメントでCliveによって言及されたソリューションを使用するか、entityreference_selection用の独自のCToolsプラグインを構築できます。これには試行錯誤が必要ですが、オートコンプリート機能の背後にあるクエリとロジックをさらに適切に制御できます。

1
Mikey P

私はマイキーの提案を取り入れて、ctoolsプラグインを作成しました。これが私が思いついたものです:

プラグインを格納するためにカスタムモジュールを使用していますが、技術的にはプラグインをエンティティ参照モジュール自体に配置できます。このメソッドはモジュールコードを置き換えないので、これは問題ありません(更新が中断されます)。

カスタムモジュールを作成すると仮定すると、このフックを.moduleファイルに配置する必要があります。

/* 
 * Implements hook_ctools_plugin_directory
 */
function custom_module_ctools_plugin_directory($module, $plugin) {
  if ($module == 'entityreference') {
    return 'plugins/' . $plugin;
  }
}

次に、モジュールのctoolsプラグインディレクトリ内にあるファイルを作成します:.../modules/custom_module/plugins/selection/realname.inc

ファイルは好きなように呼び出すことができますが、ファイルパスは重要です。 (上記のように).../modules/entityreference/plugins/selection/でファイルを作成することもできます。

Realname.incの内容:

<?php

$plugin = array(
  'title' => t('Use realname'),
  'class' => 'EntityReferenceSelectRealname',
  'weight' => 10,
);

次に、このファイルと同じディレクトリに別のファイルを作成します。このファイルは、上記で提供されたクラスの名前を.class.phpとして使用しているため、このクラスではEntityReferenceSelectRealname.class.phpになります。

EntityReferenceSelectRealname.class.phpの内容:

<?php

class EntityReferenceSelectRealname extends EntityReference_SelectionHandler_Generic {

  /**
   * Implements EntityReferenceHandler::getInstance().
   */
  public static function getInstance($field, $instance = NULL, $entity_type = NULL, $entity = NULL) {
    $target_entity_type = $field['settings']['target_type'];

    // Check if the entity type does exist and has a base table.
    $entity_info = entity_get_info($target_entity_type);
    if (empty($entity_info['base table'])) {
      return EntityReference_SelectionHandler_Broken::getInstance($field, $instance);
    }

    if (class_exists($class_name = 'EntityReferenceSelectRealname_' . $target_entity_type)) {
      return new $class_name($field, $instance, $entity_type, $entity);
    }
    else {
      return new EntityReferenceSelectRealname($field, $instance, $entity_type, $entity);
    }
  }
}

/**
 * Override for the User type.
 *
 * This only exists to workaround core bugs.
 */
class EntityReferenceSelectRealname_user extends EntityReferenceSelectRealname {
  public function buildEntityFieldQuery($match = NULL, $match_operator = 'CONTAINS') {
    $query = parent::buildEntityFieldQuery($match, $match_operator);

    // The user entity doesn't have a label column.
    if (isset($match)) {
      //This line uses the regular username:
      //$query->propertyCondition('name', $match, $match_operator);

      //This was added to use the "realname" field instead of the regular username:
      //CHANGE THIS:
      $query->fieldCondition('field_er_realname', 'value', $match, $match_operator);
    }

    // Adding the 'user_access' tag is sadly insufficient for users: core
    // requires us to also know about the concept of 'blocked' and
    // 'active'.
    if (!user_access('administer users')) {
      $query->propertyCondition('status', 1);
    }
    return $query;
  }

  //Not sure if this is necessary, but I'll add it in to be safe.
  public function entityFieldQueryAlter(SelectQueryInterface $query) {
    if (user_access('administer users')) {
      // In addition, if the user is administrator, we need to make sure to
      // match the anonymous user, that doesn't actually have a name in the
      // database.
      $conditions = &$query->conditions();
      foreach ($conditions as $key => $condition) {
        if ($key !== '#conjunction' && is_string($condition['field']) && $condition['field'] === 'users.name') {
          // Remove the condition.
          unset($conditions[$key]);

          // Re-add the condition and a condition on uid = 0 so that we end up
          // with a query in the form:
          //    WHERE (name LIKE :name) OR (:anonymous_name LIKE :name AND uid = 0)
          $or = db_or();
          $or->condition($condition['field'], $condition['value'], $condition['operator']);
          // Sadly, the Database layer doesn't allow us to build a condition
          // in the form ':placeholder = :placeholder2', because the 'field'
          // part of a condition is always escaped.
          // As a (cheap) workaround, we separately build a condition with no
          // field, and concatenate the field and the condition separately.
          $value_part = db_and();
          $value_part->condition('anonymous_name', $condition['value'], $condition['operator']);
          $value_part->compile(Database::getConnection(), $query);
          $or->condition(db_and()
            ->where(str_replace('anonymous_name', ':anonymous_name', (string) $value_part), $value_part->arguments() + array(':anonymous_name' => format_username(user_load(0))))
            ->condition('users.uid', 0)
          );
          $query->condition($or);
        }
      }
    }
  }
}

入力して、field_er_realnameをフィールドの名前に変更します。あなたの場合、これはfield_complete_nameです。ところで、私は 計算フィールドモジュール を使用して、提供された姓名に基づいて「realname」フィールドを生成しました。

7
Andrew

これを行う最も簡単な方法は、エンティティ選択モードのビューを提供することです。このコメントの簡単な指示に従うことができます:

https://drupal.stackexchange.com/a/39076/10176

0
Елин Й.