ユーザの選択フィールド(entity_autocomplete利用)で、アカウント名以外の検索を行う方法

  •  
 
ナカちゃん に投稿

タグ

やりたいこと

フォーム要素として、以下のように記載した場合


$form['member'] = [
    '#type' => 'entity_autocomplete',
    '#target_type' => 'user',
];

実際に表示されるentity_autocompleteフィールドでは、ユーザアカウント名によって検索が行われる。

一般的なユーザ検索&選択

これをアカウント名以外のユーザフィールドに入力した値でマッチできるように変更したい。
(たとえば、独自に「ニックネーム(field_nickname)」のようなフィールドを作っていて、ここに入力した内容で引っ掛けたい場合など)
 

 

解決方法

以下の修正を行い、独自の検索処理を追加&利用することで解決できました。

1.独自検索処理の追加

UserSelectionクラスを拡張した、独自の(検索用)クラスを作成し、function buildEntityQueryにてquery(検索結果ではない)を返します。

  • your_module/src/Plugin/EntityReferenceSelection/UserByFieldNicknameSelection.php

namespace Drupal\your_module\Plugin\EntityReferenceSelection;
 
use Drupal\user\Plugin\EntityReferenceSelection\UserSelection;
 
/**
 * @EntityReferenceSelection(
 *   id = "your_module_selection:user_by_field_nickname",
 *   label = @Translation("User by field_nickname selection"),
 *   entity_types = {"user"},
 *   group = "your_module_selection",
 *   weight = 0
 * )
 */
class UserByFieldNameSelection extends UserSelection {
 
  /**
   * {@inheritdoc}
   */
  protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
    
    //入力した文字に対して、ユーザ名またはニックネームに部分一致するユーザを検索するquery
    //Anonymousまたは非アクティブユーザは除外する。
    $query = \Drupal::entityQuery('user')
      ->condition('status', 1)
      ->condition('uid', 0, '<>');
 
    $group = $query->orConditionGroup()
      ->condition('field_nickname', $match, $match_operator)
      ->condition('name', $match, $match_operator);
    $query->condition($group);
 
    return $query;
  } 
}

2.フォーム要素の修正

フィールドの定義を変更します。


$form['member'] = [
  '#type' => 'entity_autocomplete',
  '#target_type' => 'user',
  '#selection_handler' => 'your_module_selection',
]

 

 

結果

「ニックネーム」フィールドの入力内容(または従来どおりアカウント名)に対してマッチできるようになります。

修正後イメージ

修正後イメージ2

その他補足説明

@EntityReferenceSelectionの記載項目について

資料が少ないためソースコードや動きからの類推ですが、まとめておきます。
この情報を利用して、検索処理の呼び出しなどを行ってくれるようです。

  • id
    • この検索処理を特定するための一意な名称
    • "<group名>:<id名>"または"<id名>"というように記載する。
  •  label
    • ラベル(人が読んで理解できる名前をつける?)
  • entity_types
    • 検索対象としたい entity typeを指定する(らしい)
  •  group
    • この検索処理が含まれるグループ(任意の名前でOK)
    • "default"が予め用意されており、コアで提供される検索処理はこのグループに属する(ようです)。
  •  weight
    ※後述

 

#selection_handlerについて

以下の指定方法があります。

  • group名だけ
    • #selection_handler => "<group名>"
    • この場合、前述のgroupの中でもweightが一番大きい検索処理が呼ばれ、他は利用されない(という動きをしていた)
  • group名+ID
    • #selection_handler => "<group名>:<ID名>"
    • weight値に関係なく、指定した検索処理が呼ばれる。
    •  前述のidを"<group名>:<ID名>" と記述しておかないと呼び出せません(エラーも出ません)

 

#selection_handlerが指定されない場合は、#selection_handler => "default"と記述したことと同じとみなされます。
この場合はUserSelectionクラスの検索処理がデフォルトとして利用されるようです。

 

そのほか

@EntityReferenceSelectionの記載内容として、

group = "default",
weight = 2, ※1より大きい値であればよさそう

としておくと、#selection_handler が未指定のユーザの選択フィールド(entity_autocomplete)は、
独自の検索処理を優先して呼び出すようになります。
(デフォルト検索処理を上書き?出来るようなイメージです)

 

 

 

[参考]

コメントを追加

プレーンテキスト

  • HTMLタグは利用できません。
  • 行と段落は自動的に折り返されます。
  • ウェブページのアドレスとメールアドレスは自動的にリンクに変換されます。
CAPTCHA
この質問はあなたが人間の訪問者であるかどうかをテストし、自動化されたスパム送信を防ぐためのものです。