Silverstripe: Pass URL Variable to Form Action
Asked Answered
G

1

7

is there a way to pass a URL variable to a form action? I've got it working on a user details form, but when I'm trying to do it with a user file upload it won't work.

As you will see below, I have a form and a save action for saving user details. That works fine.

When I try to pass the URL variable to the User File Upload form, it doesn't work. It says that I'm trying to get a value of a non-object.

// Get Client ID from URL Parameters
    public function getUser() {
        if( isset($this->urlParams['ID']) && is_numeric($this->urlParams['ID']) ) { 
            return $user = Member::get()->byID($this->urlParams['ID']);
        } else {
            return $user = $this->request->postVars();
        }
    }

// Edit/Save a User's details
    public function EditUserDetails() {
        //Include JS for updating details
        Requirements::javascript('module-memberprofiles/javascript/MemberProfileUpdate.js');
        Requirements::set_force_js_to_bottom(true);

        $fields = new FieldList(
            $leftCol = CompositeField::create(
                TextField::create('FirstName', 'First Name')
                    ->setFieldHolderTemplate('UserDetails_FieldHolder'),
                TextField::create('Surname', 'Surname')
                    ->setFieldHolderTemplate('UserDetails_FieldHolder'),
                CompositeField::create(
                    TextField::create('Address', ''),
                    TextField::create('Suburb', ''),
                    CompositeField::create(
                        DropdownField::create('State', '', singleton('Member')->dbObject('State')->enumValues())->setFieldHolderTemplate('UserDetails_StatePostCode'),
                        TextField::create('PostCode', '')->setFieldHolderTemplate('UserDetails_StatePostCode')
                    )->addExtraClass('row')
                )
                    ->addExtraClass('userdetails-address wrap')
                    ->setFieldHolderTemplate('UserDetails_AddressHolder'),
                TextField::create('Phone', 'Phone')
                    ->setFieldHolderTemplate('UserDetails_FieldHolder'),
                TextField::create('Email', 'Email')
                    ->setFieldHolderTemplate('UserDetails_FieldHolder')
            )->setFieldHolderTemplate('UserDetails_CompositeField')
        );

        $actions = new FieldList(new FormAction('SaveUserDetails', 'Save Profile'));
        $validation = new RequiredFields(array('FirstName','Surname','Email'));

        $form = new Form ( $this, 'EditUserDetails', $fields, $actions, $validation);
        $form->loadDataFrom($this->getUser());
        $form->setTemplate('MemberProfilePage_UserDetailsForm');
        return $form;
    }

    public function SaveUserDetails($data, $form) {
        $table = Member::get()->byID($this->getUser());

        $members = Member::get();
        $emailExists = $members->filter(array(
            'Email' => $data['Email'],
            'ID:not' => $table->ID
        ));

        if( $emailExists->count() > 0 ) {
            $form->sessionMessage('Sorry, that email address already exists. Please try again','bad');
            return $this->redirectBack();
        } else {
            $form->sessionMessage('You have successfully updated this user\'s details.','good');
        }

        $form->saveInto($table);
        $table->write();
        $this->redirectBack();

        return $this;
    }

    //User file upload function
    public function UploadUserFile() {

        $fields = FieldList::create(
            FileField::create('UserFiles', 'Upload files')
        );

        $actions = FieldList::create(FormAction::create('SaveUserFile', 'Upload files'));

        $form = Form::create($this, __FUNCTION__, $fields, $actions, null);

        $form->loadDataFrom($this->getUser());

        return $form;
    }

    //Refresh files function
    public function SaveUserFile($data, $form) {

        $up = new Upload();

        $file = Object::create('File');
        $file->setFileName('newname');
        $up->loadIntoFile($data['UserFiles'], $file, 'User-Files');

        if($up->isError()) {
            //handle error here
            //var_dump($up->getErrors());
        }else {
            //file uploaded
            //$file->OwnerID = 3;
            //$file->write(); 

            //$this->redirectBack();
            return $this; 
        }
    }
Gonzalez answered 30/8, 2016 at 6:46 Comment(4)
Using the record ID in the URL params is generally a bad idea. Users get to change other Member Records than their own, by changing the ID in the URL. Why not use Member::currentUser or a HiddenField with the member ID in it?Argive
@FatalError I have functions set up that only allows a "Moderator" group to change the details of other users. So that's not an issue. I probably should have been clearer regarding what I'm building. The "moderators" upload files for other users. So Member::currentUser isn't applicable here. I don't want to attach the current User's ID to a file. I want to change the OwnerID to the ID that's in the URL. When I tried to use a hidden field, it says "non-object" after the form is submitted. I passed the URL ID to the field with the getUser() function.Gonzalez
If you pass the User ID in a hidden field you need to retreve that record in the submit function $ownerMember = Member::get()->byID($data['OwnerID']);Oligosaccharide
@Oligosaccharide thanks for the reply. When I pass the URL variable to the hidden field (set value of field) it works when the form loads. However when i click submit, it says that $this->getUser()->ID is a non-object. I believe this is because the ID is removed from the URL on submit and the function can't see it any more. How can I submit this form without removing the URL variable?Gonzalez
G
1

OK, I managed to figure this one out...

I had to set a form action to direct the upload function to the correct URL. It appears that the ID was being removed from the URL when I clicked submit, so the "getUser" function couldn't see the value.

Here's the working code for the Upload Form function:

public function UploadUserFile() {

        $fields = FieldList::create(
            FileField::create('UserFiles', 'Upload files'),
            HiddenField::create('ID','',$this->getUser()->ID)
        );

        $actions = FieldList::create(
            FormAction::create('SaveUserFile', 'Upload files')
                ->addExtraClass('button rounded solid')
        );

        $form = Form::create($this, 'UploadUserFile', $fields, $actions);
        $form->setFormAction($this->Link().'UploadUserFile/'.$this->getUser()->ID);

        return $form;
    }
Gonzalez answered 12/9, 2016 at 4:37 Comment(1)
You shoulf be able to pass the id saving it a hidden field. I wonder id the issue is that you're saving it under ID, which is too generic and likely conflicts with controller security. Have you tried passing it via another field name?Oligosaccharide

© 2022 - 2024 — McMap. All rights reserved.