CodeIgniter Forums
Set username procedurally in SHIELD - Printable Version

+- CodeIgniter Forums (https://forum.codeigniter.com)
+-- Forum: CodeIgniter 4 (https://forum.codeigniter.com/forumdisplay.php?fid=28)
+--- Forum: CodeIgniter 4 Support (https://forum.codeigniter.com/forumdisplay.php?fid=30)
+--- Thread: Set username procedurally in SHIELD (/showthread.php?tid=92275)



Set username procedurally in SHIELD - Vespa - 01-04-2025

I'd like to add custom First name and Last name to the registration form and don't allow user to set his own username, I'd like to set this field procedurally... for example combining First Name and Last name.
So, I have created a custom registration form ( see code below ) to remove username field and added First and Last name fields
Code:
<form class="form-transparent-grey" action="<?= url_to('register') ?>" method="post">
                                <?= csrf_field() ?>

                                <div class="row">
                                    <div class="col-lg-12">
                                        <h3><?= lang('Auth.register') ?></h3>
                                        <p>Crea il tuo account compilando il modulo sottostante. Dopo la registrazione il tuo account dovrà essere validato da un amministratore per essere attivo.</p>
                                    </div>
                                    <div class="col-lg-6 form-group">
                                        <label for="floatingFirstnameInput" class="sr-only"><?= lang('Myauth.firstname') ?></label>
                                        <input type="text" class="form-control" id="floatingFirstnameInput" name="firstname" inputmode="text" autocomplete="firstname" placeholder="<?= lang('Myauth.firstname') ?>" value="<?= old('firstname') ?>" required>
                                    </div>
                                    <div class="col-lg-6 form-group">
                                        <label for="floatingLastnameInput" class="sr-only"><?= lang('Myauth.lastname') ?></label>
                                        <input type="text" class="form-control" id="floatingLastnameInput" name="lastname" inputmode="text" autocomplete="lastname" placeholder="<?= lang('Myauth.lastname') ?>" value="<?= old('lastname') ?>" required>
                                    </div>
                                    <div class="col-lg-6 form-group">
                                        <label for="floatingPasswordInput" class="sr-only"><?= lang('Auth.password') ?></label>
                                        <input type="password" class="form-control" id="floatingPasswordInput" name="password" inputmode="text" autocomplete="new-password" placeholder="<?= lang('Auth.password') ?>" required>
                                    </div>
                                    <div class="col-lg-6 form-group">
                                        <label for="floatingPasswordConfirmInput" class="sr-only"><?= lang('Auth.passwordConfirm') ?></label>
                                        <input type="password" class="form-control" id="floatingPasswordConfirmInput" name="password_confirm" inputmode="text" autocomplete="new-password" placeholder="<?= lang('Auth.passwordConfirm') ?>" required>
                                    </div>
                                    <div class="col-lg-12 form-group">
                                        <label for="floatingEmailInput" class="sr-only"><?= lang('Auth.email') ?></label>
                                        <input type="email" class="form-control" id="floatingEmailInput" name="email" inputmode="email" autocomplete="email" placeholder="<?= lang('Auth.email') ?>" value="<?= old('email') ?>" required>
                                    </div>
                                   
                                    <div class="col-lg-12 form-group">
                                        <button type="submit" class="btn btn-primary btn-block"><?= lang('Auth.register') ?></button>
                                    </div>
                                </div>
                            </form>

Added First and Last name validations rules in app\Config\Validation.php file
Code:
public $registration = [
        'firstname' => [
            'label' => 'Myauth.firstname',
            'rules' => [
                'required',
                'min_length[2]',
            ],
        ],
        'lastname' => [
            'label' => 'Myauth.lastname',
            'rules' => [
                'required',
                'min_length[2]',
            ],
        ],
        'email' => [
            'label' => 'Auth.email',
            'rules' => [
                'required',
                'max_length[254]',
                'valid_email',
                'is_unique[auth_identities.secret]',
            ],
        ],
        'password' => [
            'label' => 'Auth.password',
            'rules' => 'required|max_byte[72]|strong_password[]',
            'errors' => [
                'max_byte' => 'Auth.errorPasswordTooLongBytes'
            ]
        ],
        'password_confirm' => [
            'label' => 'Auth.passwordConfirm',
            'rules' => 'required|matches[password]',
        ],
    ];

Created a custom userModel in app\Models\UserModel.php
Code:
declare(strict_types=1);

namespace App\Models;

use CodeIgniter\Shield\Models\UserModel as ShieldUserModel;

class UserModel extends ShieldUserModel
{
    protected function initialize(): void
    {
        parent::initialize();

        $this->allowedFields = [
            ...$this->allowedFields,
            'firstname',
            'lastname',
        ];
    }
}

but I have no idea how to add procedurally username into the db...any suggestions?
Thanks a lot


RE: Set username procedurally in SHIELD - bloxter - 01-04-2025

You could try something like this:

PHP Code:
declare(strict_types=1);

namespace 
App\Models;

use 
CodeIgniter\Shield\Models\UserModel as ShieldUserModel;

class 
UserModel extends ShieldUserModel
{
    protected function initialize(): void
    
{
        parent::initialize();

        $this->allowedFields = [
            ...$this->allowedFields,
            'firstname',
            'lastname',
            'username', 
        
];

        // Add a callback for beforeInsert
        $this->beforeInsert[] = 'generateUsername';
    }

    /**
    * Generate a username based on firstname and lastname.
    *
    * @param array $data
    * @return array
    */
    protected function generateUsername(array $data): array
    {
        if (isset($data['data']['firstname']) && isset($data['data']['lastname'])) {
            // Combine firstname and lastname to generate the username
            $username strtolower($data['data']['firstname'] . '.' $data['data']['lastname']);
            
            
// Ensure the username is unique
            $baseUsername $username;
            $counter 1;

            while ($this->where('username'$username)->countAllResults() > 0) {
                $username $baseUsername $counter;
                $counter++;
            }

            $data['data']['username'] = $username;
        }

        return $data;
    }




RE: Set username procedurally in SHIELD - 4usol - 01-04-2025

may by events? 

https://shield.codeigniter.com/references/events/


RE: Set username procedurally in SHIELD - Vespa - 01-05-2025

Thanks for hints guys, helped me a lot.