Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get valid fields from the Form #196

Open
btamas86 opened this issue Dec 28, 2015 · 4 comments
Open

Get valid fields from the Form #196

btamas86 opened this issue Dec 28, 2015 · 4 comments

Comments

@btamas86
Copy link

Just an idea ... I think we need a method that return the name of the fields in the Form. This process should only return the items we really need to process.
Example:

class UserProfileForm extends Form
{

    public function buildForm()
    {
        $this->add('name', 'text', [
            'rules' => 'required|max:32',
        ]);

        $this->add('password', 'repeated', [
            'rules' => 'required',
        ]);
    }

}

But I send these fields:

[
    'name' => 'Foo',
    'password' => 'Pass',
    'email' => '[email protected]',
]

Then, the following code will save everything:
Example:

public function update(Request $request, $id)
{
    $user = User::findOrFail($id);
    $form = $this->form(UserProfileForm::class);

    if (!$form->isValid()) {
        return redirect()->back()->withErrors($form->getErrors())->withInput();
    }

    $user->fill($request->all());
    $user->save();
}

If it's like that, it does not:
Example:

public function update(Request $request, $id)
{
    ...
    // $form->validFields(): ['name', 'password', 'password_confirmation']
    $user->fill($request->only($form->validFields()));
    $user->save();
}

The validFields would return with the fields specified in the form.
Do You think that's possible? Perhaps the Collection and ChildForm would be problematic.

@kristijanhusak
Copy link
Owner

Setting protected $fillable on your Model should prevent saving fields that are unwanted. More info here https://laravel.com/docs/5.2/eloquent#mass-assignment

I could add that validFields() method , which would use Validator's valid() method (this one), but i'm not sure how would that work for Child forms and Collection type. You can try it by adding this method to your form class:

public function validFields()
{
    return $this->validator->valid();
}

and than use it as you put in your update example. Please test it out and let me know how it works.

@btamas86
Copy link
Author

The fillable's settings are not working for us, because its using many permission levels, and in each level the attributes are different. The validator valid() command is also not working in our use because it unfortunately returning the items which are not defined in the form.

I was thinking something like these, which is mostly working well for us:

public function validFields()
{
    $validFields = [];
    $fieldParse  = function ($fields) use (&$fieldParse, &$validFields) {
        foreach ($fields as $field => $fieldObj) {
            if ($fieldObj instanceof CollectionType) {
                foreach ($fieldObj->getChildren() as $child) {
                    $fieldParse($child->getForm()->getFields());
                }
            } else {
                $validFields[] = $fieldObj->getNameKey();
            }
        }
    };
    $fieldParse($this->fields);

    return $validFields;
}

@kristijanhusak
Copy link
Owner

How is this method determining if field is valid or not?

@btamas86
Copy link
Author

btamas86 commented Jan 8, 2016

Sorry, the method name is not correct. Rather use: getFormFieldNames. It just collects the fields defined in the form. Validation executes beforehand. :) My completed form class:

public function getFormFieldNames()
{
    $fieldsTmp  = [];
    $fieldParse = function ($fields) use (&$fieldParse, &$fieldsTmp) {
        foreach ($fields as $field => $fieldObj) {
            if ($fieldObj instanceof CollectionType) {
                foreach ($fieldObj->getChildren() as $child) {
                    $fieldParse($child->getForm()->getFields());
                }
            } else {
                $fieldsTmp[] = $fieldObj->getNameKey();
            }
        }
    };
    $fieldParse($this->fields);

    return $fieldsTmp;
}

public function getOnlyFormFieldsFromRequest()
{
    return $this->getRequest()->only($this->getFormFieldNames());
}

Controller example:

public function update($id)
{
    ...
    $form = $this->form(ExampleEditForm::class);
    if (!$form->isValid()) {
        return redirect()->back()->withErrors($form->getErrors())->withInput();
    }

    $data = $form->getOnlyFormFieldsFromRequest();

    $model->fill($data);
    $result = $model->save();
    ...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants