やりたいこと
フォーム要素として、以下のように記載した場合
$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',
]
結果
「ニックネーム」フィールドの入力内容(または従来どおりアカウント名)に対してマッチできるようになります。
その他補足説明
@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)は、
独自の検索処理を優先して呼び出すようになります。
(デフォルト検索処理を上書き?出来るようなイメージです)
[参考]
- 閲覧数 201
コメントを追加