通过many_many关系过滤ModelAdmin

时间:2015-11-26 23:58:13

标签: silverstripe

我正在使用ModelAdmin管理DataObject类'培训师'。培训师与我的其他班级“语言”有许多关系。

在我的'培训师'课程中,我正在操纵'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或任何语言并提交表格后,我正在接收

  

[警告] trim()期望参数1为字符串,给定数组

这里是否可以使用many_many关系进行过滤?如果是这样,怎么样?如果有人能指出我正确的方向,那就太好了。

更新

完整错误消息:http://www.sspaste.com/paste/show/56589337eea35

培训师课程:http://www.sspaste.com/paste/show/56589441428d0

2 个答案:

答案 0 :(得分:0)

您需要在$ 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);
}

答案 1 :(得分:0)

是的,这是可能的。您只需要覆盖两个方法 - 一个在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;
}