4

I've been using CakePHP to develop an application and I have some basic permissions that are aimed to restrict the ability of the users and help to prevent errors.

I have a form where someone with the a certain permission or higher can create a new member of staff. One of the fields in the form allows them to associate a school to a member of staff. If they have the minimum access required I would like selection to auto-fill as the school the creator has associated with them and then if they are an admin they have the option of choosing from the selection.

In the controller I am calling this line which populates the array of schools:

$this->set('schools', $this->Staff->School->find('list', array('conditions' => array('School.active' => !null), 'order' => array('name' => 'ASC'))));

And the array looks like this:

array(4) {
  [2]=> string(15) "School A"
  [3]=> string(15) "School B"
  [1]=> string(17) "School C"
  [6]=> string(21) "School D"
}

The AuthComponent stores the school id in the following way: AuthComponent::user('school_id') and for the purpose of this the value is set to 1.

In the add view the conditions for showing the selection look like this:

if (AuthComponent::user('admin') == 1) {
    echo $this->Form->input('school_id', array('label' => 'School *',    'options' => array($schools), 'required' => 'required'));
} else {
    echo $this->Form->input('school_id', array('label' => 'School *', 'value' => $schools[AuthComponent::user('school_id')], 'disabled' => 'disabled'));
}

For some reason the disabled view defaults to showing the first school in the list. I have used var_dump($schools[AuthComponent::user('school_id')]; which returns String(8) => "School C"so I am confused on why the selection will not show correctly.

Does anyone have any suggestions or an alternative solution to achieving the same outcome?

1 Answer 1

4

There are a few oddities in the code in the question:

Conditions

'conditions' => array('School.active' => !null)

!null is simply true, this is identical to using:

'conditions' => array('School.active' => true)

If you want to check for not-null the condition to use is:

'conditions' => array('School.active NOT' => null)

OR

'conditions' => array('NOT' => ('School.active' => null))

Options

'options' => array($schools)

$schools is already an array - this is creating a nested array, which will be interpreted as a select with an optGroup named "0". I.e. like this:

<select name="data[User][school_id]" id="UserSchoolId">
    <optgroup label="0">
        <option value="2">School A</option>
        <option value="3">School B</option>
        <option value="1">School C</option>
        <option value="6">School D</option>
    </optgroup>
</select>

It's always a select

You haven't explicitly said so, but whether the user is an admin or not, the input is a select. It sounds like you're expecting a disabled text input, always look at the html source to verify what exactly you're looking at.

This occurs because CakePHP will automatically convert a field named schools_id to a select if there is a view variable named schools. This is also the reason why the first school is always selected irrespective of the auth'ed user's school, the code in the question is effectively:

echo $this->Form->input(
    'school_id',
    array(
        'label' => 'School *',
        'options' => $schools, // implicit
        'value' => $schools[AuthComponent::user('school_id')],
        'disabled' => 'disabled'
    )
);

The result is markup like this:

<select name="data[User][school_id]" value="School C" id="UserSchoolId">
    <option value="2">School A</option>
    <option value="3">School B</option>
    <option value="1">School C</option>
    <option value="6">School D</option>
</select>

There is no school with that value - so the html will act like it's not there and pick the first one.

Solution

You'll need code equivalent to this:

$options = ['label' => 'School *'];
if (!AuthComponent::user('admin')) {
    $options += [
        'value' => AuthComponent::user('school_id'),
        'disabled' => 'disabled'
    ];
}
echo $this->Form->input('school_id', $options);

Obviously, do not rely on the form for security of any kind - a disabled input does not prevent a user editing the html, enabling it and changing the value. Either use the security component (which prevents form tampering), forcefully ensure that the school_id (and any other fields that are relevant) match the auth'ed user's data in the controller action before saving/changing records or both.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much @AD7six, I'm fairly new to CakePHP and your answer has really helped me to understand what goes on in the background. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.