1

I have a front-end user registration form that generates a username automatically based on the first and last name inputs. This works as intended but on the off chance that two people have the same name, a check needs to be run on submit to see if the username already exists in the system. I'm currently utilizing {{ actionInput('users/save-user') }} to handle the form submit. I'm looking for a way to run a check before the action users/save-user returns the defualt duplicate username error. I've created a module to listen for the save event but it doesn't appear to be firing as intended. Within the module's init() function I'm running:

Event::on(
 User::class,
 User::EVENT_BEFORE_SAVE,
 function (ModelEvent $event) {

  $loginName = $this->request->getRequiredBodyParam('username');
   
  if($user = Craft::$app->getUsers()->getUserByUsernameOrEmail($loginName)){

   // Change the username to username-(duplicateCount+1)
   // Create New User 

  } // else {

   // Create New User 

  // }
  }
);

using use craft\elements\User;

Disclaimer: I'm a novice when it comes to modules/plugins/controllers so any advice would be greatly appreciated. Thanks!

4
  • The code looks ok at first glance – how are you checking if it's being executed? Try sticking a \Craft::dd($loginName) to see if the hook is actually firing. In this case it might just be down to a simple logic error.
    – MoritzLost
    Apr 12 at 7:24
  • To troubleshoot, I've been using die(); within the event. The event fires correctly when a new user is created but fails to fire when loginName is a duplicate. Craft's default duplicate check appears to prevent EVENT_BEFORE_SAVE from firing. Apr 12 at 14:17
  • 1
    I see, that makes sense. If there are validation errors, Craft won't try to save the user, so the hook won't fire. Try using EVENT_BEFORE_VALIDATE instead!
    – MoritzLost
    Apr 12 at 14:30
  • 1
    Somehow managed to miss that in the documentation, that worked. Thank you! Apr 12 at 16:36

1 Answer 1

1

Got it working using:

use yii\base\ModelEvent;

use craft\elements\User;

Event::on(
User::class,
User::EVENT_BEFORE_VALIDATE,
function (ModelEvent $event) {

    // username format: john-doe
    $senderUsername = $this->request->getRequiredBodyParam('username');
    $senderEmail = $this->request->getRequiredBodyParam('email');
    $count = 1;

    if (!Craft::$app->getUsers()->getUserByUsernameOrEmail($senderEmail)){
        
        while(Craft::$app->getUsers()->getUserByUsernameOrEmail($senderUsername)){

            $name = explode("-", $senderUsername);
            $senderUsername = $name[0] . '-' . $name[1] . '-' . $count++;

        }
        
        $event->sender->username = $senderUsername;
    }
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.