Cakephp 4: Display results from 'multiple' list box in edit.php

In CakePHP 2, I could do the following to display multiple values in a multiselect field in my edit view:

Function call in controller:

// Get the list of indivduals involved for display on the form
$user_list = $this->IncidentReport->getUserList($current['IncidentReport']['id'], $current['IncidentReport']    
['indivs_involved']); 
$this->set(compact('user_list'));

Function in model:

// $indivs is a comma-delimited array
function getUserList($id = null, $indivs = null) {
	$users = $this->IndivsInvolved->find('list', array('fields' => array('id', 'full_name'),
		'conditions'=>array('id'=>explode(',',$indivs)),
	    'order'=>array('last_name'=>'ASC')
		)
	);
	return $users;
}

Form field in edit.ctp:

<?php echo $this->Form->input('indivs_involved', array(
    'label'=>'<b>Individuals Involved</b>', 
    'empty'=>'', 
    'default'=>'', 
    'div'=>false, 
    'multiple'=>true, 
    'class'=>'mul-select',
    'options'=>$people, 
    'value'=>array_keys($user_list))); ?>

Which yields this:

Here is my attempt in CakePHP 4.
Function call in controller:

$userList = $this->IncidentReports->getUserList($incidentReport->id, $incidentReport->indivs_involved); 
$this->set(compact('userList'));

Function in IncidentReports:

function getUserList($id = null, $indivs = null) 
{
    $users = $this->IndivsInvolved->find('list', [
        'keyField' => 'id',
        'valueField' => 'full_name',
        'conditions' => [
            'id' => explode(',', $indivs),
        ],
        'order' => [
            'last_name ASC'
        ],
    ]); 
	return $users; 
}

Form field in edit.php:

<?php echo $this->Form->control('indivs_involved', [
                        'label' => 'Individuals Involved', 
                        'options' => $people,
                        'multiple' => true,
                        'class' => 'mul-select',
                        'value' => array_keys($userList),
                        'empty' => ['' => ''],
                        ]); ?>

The problem: When this executes, I get the following error:

array_keys() expects parameter 1 to be array, object given

I’m guessing I need to set up the function in my model differently, but I don’t know how.

This is because $userList is, in fact, an object. A query object, to be precise. (debug($userList); is a super helpful thing to know about in cases like this; knowing exactly what you are dealing with is very often a pointer straight to the solution.) What you presumably need to add somewhere is a ->toArray() call on that query object; where to add that is up to you.

Also, note that where older versions of Cake added “IN” for you automatically when you gave them an array for a where condition, the ORM does NOT do this. So you probably really want

'id IN' => explode(',', $indivs)
1 Like

Thanks for those tips. Between them and debugging all over the model, I figured out that I needed to do a combination of things:

  1. Add the ‘IN’ to my WHERE clause

  2. Rejigger the return value like this:

    $data = $users->toArray();
    return $data;

The individual names are now appearing in my multiselect box in my edit view.