Jump to content

Recommended Posts

Hello everyone.

I am wanting to prevent duplicate entries. This task is using laravel which I know little to nothing about. I'm putting this in PHP help because the file has php at the top of it. If this is the wrong place for this, then I apologize.

The issue is that I googled for days and either I can't find the answer, or I can't translate what I find to fit what I need to do.
The goal here is to prevent new users that sign up, to choose a username or screen name that already exists. I'm putting the code down below that I have to register the new users.
The reason for this is because lately, I've had too many people replicating the same user names to make new accounts, either because they don't feel like asking for help when they forget the password or because they don't remember the answer to the question they created, or because they think making a new account gets them something new.

So what I want to do is prevent duplicate user and screen names

This laravel stuff is so far over my head that it's like trying to translate ancient egyptian cymbals for me. It took me over a week just to find where this file was haha
Andy and all help is appreciated greatly

NOTE: I didn't try to add any code to it yet because I'm incredibly nervous to destroy what is built because I don't understand this at all.

<?php

namespace App\Http\Controllers\Auth;

use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use App\Http\Controllers\Controller;
use App\Services\ImageUploadService;
use Illuminate\Support\Facades\Hash;
use Illuminate\Auth\Events\Registered;
use App\Providers\RouteServiceProvider;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after registration.
     *
     * @var string
     */
    protected $redirectTo = RouteServiceProvider::HOME;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
			'fname' => ['required', 'string', 'max:255', 'alpha'],
        'username' => ['required', 'string', 'max:255', 'alpha_num'],
            //'lname' => ['required', 'string', 'max:255'],
            'password' => ['required', 'string', 'min:8'],
            'image' => ['image', 'mimes:jpg,jpeg,png','mimetypes:image/jpg,image/jpeg,image/png'],
            'question' => ['required', 'string', 'max:255'],
            'answer' => ['required', 'string', 'max:255'],
            'ip_address' => ['required', 'string', 'max:255'],
        ]);
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return \App\Models\User
     */
    protected function create(array $data)
    {
		
        return User::create([
            'fname' => $data['fname'],
            //'lname' => $data['lname'],
            'email' => $data['username'],
            'question' => $data['question'],
            'answer' => $data['answer'],
            'password' => Hash::make($data['password']),
            'unique_id' => rand(time(), 100000000),
			'ip_address' => $data['ip_address'], // Save the user's IP address
        ]);
    }

    /**
     * Handle a registration request for the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
     */
    public function register(Request $request)
    {
        $this->validator($request->all())->validate();

        $user = $this->create($request->all());
        event(new Registered($user));

        /*$filename = now().$request->file('image')->getClientOriginalName();
        $request->image->storeAs('images',$filename,'public');*/
		
        //$filename =  (new ImageUploadService())->upload($request->file('image'), 'images');

        //$user->update(['img'=>$filename]);

        $users = User::where('id','!=',$user->id)->get()->modelKeys();
        foreach($users as $u){
            $user->conversations()->create()->users()->attach($u);
        }

        $this->guard()->login($user);

        if ($response = $this->registered($request, $user)) {
            return $response;
        }

        return $request->wantsJson()
                    ? new JsonResponse([], 201)
                    : redirect('login.php');
                    //: redirect($this->redirectPath());
    }
}

 

Edited by PNewCode

The best way is to define the username as a unique key in your user table. That way you can't add another with the same name (an exception with be thrown if you attempt to add a second).

Then check for duplicate key errors when adding users in you code.

43 minutes ago, Barand said:

The best way is to define the username as a unique key in your user table.

Thank you. The column name is "fname". Is that what you mean? In regular php I know how to check for duplicates and list them but thats as far as my knowledge goes. Laravel is a wild mess to me haha

The basic code is

    /*   Current user data
            +----+----------+--------------+
            | id | username | fullname     |
            +----+----------+--------------+
            | 1  | lucy     | Lucy Lastik  |
            | 2  | hugh     | Hugh Jass    |
            | 3  | tom      | Tom DiCanari |
            +----+----------+--------------+
    */
    
    try {
        $stmt = $pdo->prepare("INSERT INTO user (username, fullname)    
                               VALUES (?, ?)
                               ");
        $stmt->execute( [ 'lucy', 'Lucy Smith' ] );                       // attempt duplicate insert
    }
    catch (PDOException $e) {
        if ($stmt->errorInfo()[1] == 1062)  {                             // duplicate key error code
            $_SESSION['errors']['username'] = 'username already exists';  // error message to display to user when form redisplayed
        }                                                                   
        else throw $e;                                                    // let php handle the error
    }

Just convert it to Laravelese.

Even better, Laravel will throw an Illuminate\Database\UniqueConstraintViolationException when you try to insert a record that violates the SQL unique constraint. Just catch that before the PDOException or general Exception and you can handle it.

Looking at your code, you don't have a username column in your create method. The POST['username'] field is assigned to the email column in the table, which is a bit confusing. Either way, heed Barand's advice to add a unique constraint on whatever your username column is, wrap your create() statement in a try...catch() that catches the UniqueConstraintViolationException, and make sure your create() method is inserting data into that column.

  • 1 month later...

@Barand and @maxxd thank you for that info. Unfortunately I have no idea how to convert that to "Laravelese" as you said. Though that was a cool way of putting it haha. 
And yes the email is the username, because after getting a lot of grief from users in todays world of paranoid entries (and for good reason for many cases) I just changed it to entering a username instead of an email so that no email addresses are stored. There were already a few hundred pages that relied on it for other functions so I just left the column name in the database the same.

I can't make heads or tales out of Laravel no matter how much I study it. It's like car mechanics to me... I can change the oil but rebuilding a motor is something my brain doesn't want me to know.
Laravel, as it seems, is the motor. Spent the last month trying to comprehend this. No luck.

I don't suppose either of you are for hire to make this function for me? :)

I get the username -> email thing; it's one of those wonderful side effects of tech debt and the mitigation thereof. As far as the Laravelese, yeah - laravel is a very opinionated framework. What you can easily do for the validation on username/email is this: https://laravel.com/docs/11.x/validation#rule-unique

So if I'm not mistaken (and it's late and I've had some wine so I may very well be mistaken) you can use

'username' => ['required', 'string', 'max:255', 'alpha_num', 'unique:App\Models\User,email'],

PS - I'm not for hire, but if your timeline is very slow I'd be glad to help out when I've got time. Post here or DM me, but I can't guarantee I'll be able to respond quickly.

Edited by maxxd

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.