Фильтровать 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;
}
Другие вопросы по тегам