CakePHP создает поле выбора из пользовательского массива

Таким образом, у нас есть множество страниц поиска, каждая из которых имеет разные критерии поиска, поэтому я решил написать компонент, который будет получать параметры, передаваемые ему из контроллера, собирать необходимые данные и возвращать массив, который я затем мог бы настроить для использования в моем просмотрите файл для заполнения раскрывающихся списков для фильтрации критериев.

Мне удалось получить все записи, где я должен использовать помощник cakePHP для создания динамического окна выбора. Я убежден, что делаю что-то не так, и если есть более простой способ сделать это и при этом сохранить его несколько динамичным, пожалуйста, помогите, где вы можете:

// COMPONENT METHOD:
 public function filterQueries($parameters) {

    // Get defaults from the user:
    $criteria = $parameters["custom"];
    $defaults = $parameters["defaults"];

    // Validate the defaults the user may want and assign them to the return array:
    if($defaults != "false") {
        foreach($defaults as $key => $value) {
            if(array_key_exists($value, $this->defaults)) {
                $this->returnArray["defaults"][$value] = $this->defaults[$value];
            }
        }
    }

    // Get all data for the custom requested form fields:
    if($criteria != false) {
        foreach($criteria as $model => $arguments) {
            $fields = $arguments["fields"];
            $conditions = $arguments["conditions"];
            $recursive = $arguments["recursive"];
            if(!in_array($model,$this->uses)) {
                $useModel = ClassRegistry::init($model);
            } else {
                $useModel = $this->$$model;
            }
            $array = $useModel->find("all",array("conditions" => $conditions, "fields" => $fields, "recursive" => $recursive));
            $this->returnArray["custom"][$model] = $array;
        }
    }

    return $this->returnArray;
}

Вышеупомянутая функция получит массив, который разбивает либо пользовательский поиск, либо значения по умолчанию (не включенные выше, но все это работает, она возвращает массив точно так, как я ожидал).

 // The code within my action to get the content from above:
// Load the Filters component to search data:
        $search = $this->Components->load("Filter");

        // Tell search what you want:
        $searchBoxes = array(
            "defaults" => array("statuses", "survey_type"),
            "custom" => array(
              "User" => array(
                  "fields" => array("User.id","User.first_name", "User.last_name"),
                  "conditions" => array("User.user_group_id" => "4f847c63-1840-446e-88be-3e4d29566cf0"),
                  "recursive" => -1
              )  
            )
        );

       $filterResults = $search->filterQueries($searchBoxes);
       $this->set("filters",$filterResults);

Итак, теперь я получаю этот многоассоциативный массив в своем файле представления (все по-прежнему в порядке), но теперь я хочу создать пример выпадающего списка пользователей на основе массива, созданного выше, но результат совсем не похож на то, что я ожидал:

echo $this->Form->input('user_id',
                        array(
                            "type" => "select",
                            "options" => $filters["custom"]["User"]
                        )
                     );

Вывод HTML не работает и отображает его следующим образом:

<option value="last_name">Doe</option>
<option value="first_name">Jihn</option>
<optgroup label="User"> </optgroup>
<optgroup label="1"> </optgroup>
<option value="last_name">Marilyn</option>
<option value="first_name">Monroe</option>

Я признаю, что у меня нет большого опыта работы с тортами, но я не могу понять, как просто получить результаты:

 <option value='USERID'>NAME</option> // Yes I know the names and surnames must be concatinated still

Будем очень признательны за любые советы или рекомендации о том, как это сделать и сделать это правильно :)

VARDUMP ON $filters['custom']['users']

  array
   0 => 
     array
       'User' => 
         array
            'id' => string '4f84840e-cda8-4704-8fdf-210729566cf0' (length=36)
            'first_name' => string 'Name' (length=4)
            'last_name' => string 'Surname' (length=11)
    1 => 
      array
        'User' => 
          array
            'id' => string '4f8488cb-53e0-4f72-af73-3de229566cf0' (length=36)
            'first_name' => string 'Name' (length=6)
            'last_name' => string 'Surname' (length=6)

person mauzilla    schedule 25.04.2012    source источник
comment
Как выглядит var_dump($filters["custom"]["User"])?   -  person Jack    schedule 25.04.2012
comment
массив 0 => массив 'Пользователь' => массив 'id' => строка '4f84840e-cda8-4704-8fdf-210729566cf0' (длина = 36) 'first_name' => строка 'ИМЯ' (длина = 4) 'last_name' => строка «ФАМИЛИЯ» (длина = 11) 1 => массив «Пользователь» => массив «id» => строка «4f8488cb-53e0-4f72-af73-3de229566cf0» (длина = 36) «first_name» => строка ' ИМЯ' (длина = 6) 'last_name' => строка 'ФАМИЛИЯ' (длина = 6) ..... Он также возвращает всех других пользователей   -  person mauzilla    schedule 25.04.2012
comment
О, вы можете отредактировать свой вопрос, чтобы опубликовать его там. Тяжело читать комментарии без форматирования.   -  person Jack    schedule 25.04.2012


Ответы (5)


Вы можете улучшить результат, выполнив следующие действия:

1) для объединения двух полей таблицы вы можете использовать "virtualfields" в модели следующим образом: Например, если у вас есть пользовательская модель, вы можете определить следующим образом:

 public $virtualFields = array(
  'full_name' => 'CONCAT(first_name, " ",last_name)'
 );

Итак, теперь поле «full_name» будет получаться всякий раз, когда вы вызываете метод find модели User.

2) Для получения данных из таблицы для поля выбора вы можете использовать метод find('list'). Например, для модели User, если вам нужна id,full_name (last and first name combined using the virtual fields) таблицы, это можно сделать следующим образом:

$this->User->find('list',array('fields'=>array('id','full_name'),'conditions'=>$conditions))

Надеюсь, это поможет..

person Prabhuram    schedule 25.04.2012
comment
Суть этого заключается в параметре list для метода find. Это помогает помощнику формы выяснить, каким должно быть значение и что должно отображаться. - person Arno; 02.05.2012
comment
Большое спасибо. - person Manish Shrivastava; 21.04.2017

Ну, я думаю, что вы хотите сделать, это создать еще один массив с отформатированными параметрами.

foreach ($filters["custom"]["User"] as $arr)
{
    $options[$arr['id']] = $arr['first_name'] . ' ' . $arr['last_name'];
}

тогда

echo $this->Form->select('user_id', $options);
person Jack    schedule 25.04.2012
comment
Эй, Джек, я понимаю, к чему ты клонишь, и я рад сделать это таким образом, но не посоветуешь ли ты мне сделать это таким образом или есть более эффективный способ сделать то, что я пытаюсь достичь выше? - person mauzilla; 25.04.2012
comment
Я не верю, что есть какой-то другой способ, поскольку вам нужно, чтобы параметры были отформатированы определенным образом. Форма CakePHP->select использует ключ массива в качестве name="value" и значение массива в качестве текста формы. book.cakephp.org/1.3/view/1430/select, но ваш $results array из запроса поиска возвращает многомерный массив массивов. - person Jack; 25.04.2012

Я думаю, вам нужно что-то вроде этого:

$result = Set::combine($filters["custom"]["User"], 

                       '{n}.User.id', // this is the value of select box

                         array(
                               '{0} {1}', 
                               '{n}.User.first_name', 
                               '{n}.User.last_name'
                              ) // this is the text of select box
                      );

pr($result);
person thecodeparadox    schedule 25.04.2012

$this->form->input('inputname', array('label' => false, 'options' => array('Select optionstype','a','b'), 'class'=>array( 'form-a', 'b'), 'id' => 'bacid', 'style' => 'width:280px;','value'=>$abc['model']['array_attribute']) );

person debasish    schedule 20.12.2013

На CakePHP 3 я пока не могу использовать «виртуальные поля», но могу использовать следующее:

//In PostsController
$users = $this->Posts->Users->find('list', 
['keyField'   => 'id', 
 'valueField' => 'full_name', //Don't forget to call concatened field here
 'conditions' => $conditions, 
 'order'      => $orderBy 
]);

//here the magic happens
$concat = $users->func()->concat(
['Users.first_name' => 'identifier', 
 ' ', 
 'Users.last_name' => 'identifier'
]);

//selecting fields
$users->select(['id', 'full_name' => $concat]);

//sending to view
$this->set('users', $users->toArray());

Надеюсь, это поможет разработчикам CakePHP 3.

person Renee Maksoud    schedule 12.05.2017