2015-11-26 3 views
0

Я управляю «тренером» класса DataObject с помощью ModelAdmin. Тренер имеет многое отношение к моему языку другого класса.Filter ModelAdmin by many_many Отношение

В моем классе «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    
    ) 
); 
} 

Это работает так, как ожидалось, и показывает мне необходимый список полей. Проблема в том, после выбора 1 или 2 или любой другой языки и отправки формы, я получаю

[Warning] trim() expects parameter 1 to be string, array given

возможно ли это здесь, чтобы фильтр с MANY_MANY отношения? И если да, то как? Было бы здорово, если бы кто-то мог указать мне в правильном направлении.

Update:

Полное сообщение об ошибке: http://www.sspaste.com/paste/show/56589337eea35

Trainer Класс: http://www.sspaste.com/paste/show/56589441428d0

ответ

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

спасибо за ваш ответ, вы когда-нибудь использовать его, как это? к сожалению, это порождает синтаксическую ошибку в '' поле '=> self :: languagesField() '. Думаю, вам не позволено вызывать функцию здесь? –

+0

Можете ли вы скопировать в само сообщение об ошибке. Я сделал это аналогичным образом, прежде чем да. SilverStripe сложно отлаживать, не видя при этом кода. –

+0

В противном случае игнорируйте метод languagesField() и просто поместите свое объявление поля прямо в поле «field» массива. Как правило, SilverStripe хочет только имя класса для данного поля. Итак, попробуйте с помощью поля ListboxField или Dropdown, так как я не уверен, что он достаточно умен, чтобы принимать несколько значений из списка. –

0

Да, это возможно. Вам просто нужно переопределить два метода: один в объекте данных Trainer и один в TrainerModelAdmin. Сначала создается поле, второе - фильтрация.

Trainer Данные объекта:

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; 
}