Customising the default authentication in Laravel 5.4

Published 2 months ago by verism

I'm trying to add extra functionality to the registration portion of my Laravel application. I already ran make:auth to get the basics up and running, and have modified the user_name field ever-so-slightly. But I'm having trouble going much beyond that.

Users will opt to register with one role (via either a radio or select input), from a list of several. The form will then display the relevant fields to that role. The extra fields will also be stored in one or more table completely separately from the user table.

It seemed like overwriting the registered method from the RegistersUsers trait would be the right approach to this, but I'm having some difficulty. I tried customising the RegisterController like so:

class RegisterController extends Controller
{
    use RegistersUsers;
    use PortraitUploadTrait;

    protected $redirectTo = '/admin';

    public function __construct()
    {
        $this->middleware('guest');
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'first_name' => 'required|string|max:255',
            'last_name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|string|min:6|confirmed',
        ]);
    }

    protected function create(array $data)
    {
        $user = User::create([
            'first_name' => $data['first_name'],
            'last_name' => $data['last_name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);

        return $user;
    }

    // try adding an image...
    protected function registered(Request $request, $user)
    {
        $this->validate($request, [
            'user_portrait' => 'required|mimes:jpeg,png|dimensions:min_width=800,max_width:1800|max:2048'
        ]);

        $this->saveAndResize( $request->user_portrait, $user->id );
        return redirect($this->redirectPath());
    }
}

However this always attempts a redirect to the home route (which doesn't exist) for some reason. The user is created, but it never gets as far as adding the image - and I'm not even sure if this is the right place for the logic to go. Am I on the right tracks?

Best Answer (As Selected By verism)
Snapey

It looks like you are not getting the file. Have you set the form type to enctype="multipart/form-data"

ftrillo

I don't see anything wrong. Are you sure that the code in this Controller is being run and that the 'user_portrait' validation isn't failing?

verism

I've tested the trait from another controller on different page and it worked as expected.

The traits saveAndResize method takes the following arguments:

public function saveAndResize(File $inputFile, $user_id)
{
    ...
}

Even just inserting a dd($inputFile) at the top results in the same behaviour - an attempt to redirect to /home.

Snapey
Snapey
2 months ago (707,405 XP)

in replacing the registered method, have you omitted something that was in the original such as actually logging in?

I would move the validation to the main registration form validation

No, actually, I would not put any barrier in the way of registering. Register them first then later let them update their profile.

verism

I found the reason for the redirect, at least - it was set in the Auth middleware.

@Snapey would you mind expanding a little on why you'd separate them out? (If it makes any difference: the users won't actually be able to do anything apart from log in/out until they've chosen a role and filled the necessary fields.)

And no to your initial question... a user is created and logged in.

Snapey
Snapey
2 months ago (707,405 XP)

What I mean is that I might register for your site, and you ask me for an image on the registration page. I might not have one to hand, so I put off registering until I find one, and actually I never come back, the moment has passed.

verism

Ah I see - yeah we've talked a lot about the best UX approach. Whenever we ask for an image on the form it's for an actor's headshot - so it's largely expected that they'll have one already.

UX aside, I'm still not getting very far with the saveAndResize part...

Snapey
Snapey
2 months ago (707,405 XP)

is saveAndResize being called do you think?

ftrillo

So, now that you figured out that the middleware was in the way. Did you get the code to run? Did you get any other unexpected behaviour?

verism

@Snapey - it's getting called if I comment out this part:

$this->validate($request, [
    'user_portrait' => 'required|mimes:jpeg,png|dimensions:min_width=800,max_width:1800|max:2048'
]);

But even then it doesn't do what it's meant to, I get the following error: "Argument 1 passed to App\Http\Controllers\Auth\RegisterController::saveAndResize() must be an instance of App\Traits\File, string given"...

Snapey
Snapey
2 months ago (707,405 XP)

ok, so you have an issue with the file that is being passed, and presumably validation is failing.

Remove the validation for now, and dd(request()) before your code saveandResize. Is user_portait still an instance of uploadedFile class?

verism

@Snapey Yeah, I've ditched validation for now.

Following your advice, I'm not 100% sure whether I'm looking at the right data, but this looks like the most obvious candidate:

+request: ParameterBag {#39 ▼
    #parameters: array:7 [▼
      "_token" => "I1fE5XLskvzoCOu3nqjvbteIp4bMW2f8GDHJGngi"
      "first_name" => "firstname"
      "last_name" => "lastname"
      "email" => "[email protected]"
      "password" => "secret"
      "password_confirmation" => "secret"
      "user_portrait" => "ats_ppap_august-2017.png"
    ]
  }

I can't find any instances of a file-related class anywhere.

Snapey
Snapey
2 months ago (707,405 XP)

It looks like you are not getting the file. Have you set the form type to enctype="multipart/form-data"

verism

@Snapey Ah I can't believe I missed that. I had it in my test view, but just didn't update the registration form.

OK, so with that fixed, I'm now getting the following error:

Argument 1 passed to App\Http\Controllers\Auth\RegisterController::saveAndResize() must be an instance of App\Traits\File, instance of Illuminate\Http\UploadedFile given...

I was type-hinting with just the File type in my trait. I added use Illuminate\Http\UploadedFile to the top, and it all seems to be working perfectly!

I'll (embarrassingly) mark your last reply as the answer.

ftrillo

Looks like your saveAndRezise() method is expecting an object of another type. You can either change saveAnResize's signature and implementation a bit to accept UploadedFile as an argument, or build whatever object saveAndRezie's expecting.

You can get the file path by calling path() on the uploadedFile if you need.

It's very weird though, that your saveAndResize method is type hinting something in a folder called Traits. To my knowledge, traits can't be type hinted.

Please sign in or create an account to participate in this conversation.