2

I'm creating users programmatically, and in some cases, they won't have an email address. In these cases, I would like to just set the email address to [email protected] where 1234 is the User ID.

It's completely illogical, but is it possible to get the User ID at this point? Is there anything with dirty fields I can use? Otherwise, any suggestions on what I could use?

2 Answers 2

3

Assuming this is Craft 4, it's actually possible to programmatically save a user without an email address (they will automatically be an inactive user).

But to your question, no - you can't get the ID before the user is saved (because it doesn't exist yet in the database).

An alternative approach could be to use user UIDs instead of IDs – because unlike IDs, you can safely create a UID yourself, set it to the user model being saved, and Craft will respect that UID and use it for the new user's uid database table column when it's saved.

Additionally, by using UIDs instead of IDs, you avoid a potential security issue in exposing the sequential primary key (i.e. the ID), in the event that these emails are ever displayed publicly.

use Craft;
use craft\helpers\StringHelper;
use craft\elements\User;

...

$user = new User();
$user->uid = StringHelper::UUID();
$user->email = $user->uid . '@mysite.com';

$success = Craft::$app->getElements()->saveElement($user);
3
  • Thank you! This works great.
    – supazu
    Commented Jun 15, 2023 at 10:41
  • CraftCMS can be configured to use a Postgresql database. In Postgresql getting the next ID and saving the row to the database are 2 different operations (usually done at the same time via a default value in the primary key field). Technicallt, you can always ask the database for the next ID and then make a user with that specific id
    – Ferrybig
    Commented Jun 15, 2023 at 18:55
  • @Ferrybig Myeah, you're not going to be able to "make a user with [a] specific id", regardless of the database engine – at least not going through the core Craft APIs (i.e. Craft::$app->getElements()->saveElement()). That said, you're certainly correct that it's technically possible to figure out what the new user's ID is going to be, using either database engine (the IDs are sequential, after all). Commented Jun 15, 2023 at 21:43
3

It's impossible to get the user ID before the user is saved, because the ID is returned by the database, and that only happens once the user has been saved for the first time.

If you really need the emails in this format, you could:

  1. Set the email to a temporary, randomly generated address:
    $user->email = uniqid() . '@mysite.com'
  2. Save the user.
  3. Get the ID and set the e-mail to your desired format:
    $user->email = $user->id . '@mysite.com'
  4. Save the user again.

However, consider if you really need steps three and four. The email doesn't work anyway, so is there any benefit to having the user ID in place of a random string?

1
  • 1
    Thanks for the reply! I'd mark this as the answer as well if I could.
    – supazu
    Commented Jun 15, 2023 at 10:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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