Фильтровать ModelAdmin по соотношению many_many
Я управляю классом DataObject с помощью ModelAdmin. Тренер имеет отношение много-много к моему другому языку "класс".
В моем классе 'trainer' я манипулирую функцией 'searchableFields', чтобы отобразить ListboxField в области фильтров.
public function searchableFields() {
$languagesField = ListboxField::create(
'Languages',
'Sprachen',
Language::get()->map()->toArray()
)->setMultiple(true);
return array (
'Languages' => array (
'filter' => 'ExactMatchFilter',
'title' => 'Sprachen',
'field' => $languagesField
)
);
}
Это работает, как ожидалось, и показывает мне нужный ListboxField. Проблема в том, что после выбора 1 или 2 или любого другого языка и отправки формы я получаю
[Warning] trim() ожидает, что параметр 1 будет строкой, задан массив
Можно ли здесь фильтровать с отношением many_many? И если да, то как? Было бы здорово, если бы кто-то мог указать мне правильное направление.
Обновить:
Полное сообщение об ошибке: http://www.sspaste.com/paste/show/56589337eea35
Класс тренера: http://www.sspaste.com/paste/show/56589441428d0
2 ответа
Вы должны определить эту логику в параметре $searchable_fields вместо searchableFields(), который фактически создает доступные для поиска поля и логику.
PHP, скорее всего, выдаст ошибку, если вы будете делать причудливые формы в самом массиве, поэтому перенесите это поле формы в отдельный метод в том же DataObject и просто вызовите его.
Смотрите мой пример, я надеюсь, что это поможет.
/* Define this DataObjects searchable Fields */
private static $searchable_fields = array(
'Languages' => array (
'filter' => 'ExactMatchFilter',
'title' => 'Sprachen',
'field' => self::languagesField()
)
);
/* Return the searchable field for Languages */
public function languagesField() {
return ListboxField::create(
'Languages',
'Sprachen',
Language::get()->map()->toArray()
)->setMultiple(true);
}
Да, это возможно. Вам просто нужно переопределить два метода - один в объекте данных Trainer и один в TrainerModelAdmin. Первый сделает поле, второй - фильтрацию.
Объект данных тренера:
public function scaffoldSearchFields($_params = null)
{
$fields = parent::scaffoldSearchFields($_params);
// get values from query, if set
$query = Controller::curr()->request->getVar('q');
$value = !empty($query['Languages']) && !empty($query['Languages']) ? $query['Languages'] : array();
// create a field with options and values
$lang = ListboxField::create("Languages", "Sprachen", Language::get()->map()->toArray(), $value, null, true);
// push it to field list
$fields->push($lang);
return $fields;
}
Тренер модель админ
public function getList()
{
$list = parent::getList();
// check if managed model is right and is query set
$query = $this->request->getVar('q');
if ($this->modelClass === "Trainer" && !empty($query['Languages']) && !empty($query['Languages']))
{
// cast all values to integer, just to be sure
$ids = array();
foreach ($query['Languages'] as $lang)
{
$ids[] = (int)$lang;
}
// make a condition for query
$langs = join(",", $ids);
// run the query and take only trainer IDs
$trainers = DB::query("SELECT * FROM Trainer_Languages WHERE LanguageID IN ({$langs})")->column("TrainerID");
// filter query on those IDs and return it
return $list->filter("ID", $trainers);
}
return $list;
}