Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add UserModel::createNewUser() and RegisterController uses it #1196

Merged
merged 8 commits into from
Feb 6, 2025

Conversation

kenjis
Copy link
Member

@kenjis kenjis commented Sep 8, 2024

Description
Supersedes #1172

  • add UserModel::createNewUser()
  • refactor

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@kenjis kenjis added the enhancement New feature or request label Sep 8, 2024
@kenjis kenjis force-pushed the add-UserModel-createNewUser branch from 5002391 to 729af3a Compare September 8, 2024 03:03
Copy link
Collaborator

@datamweb datamweb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@datamweb datamweb merged commit 2601a59 into codeigniter4:develop Feb 6, 2025
32 of 34 checks passed
@bgeneto
Copy link
Contributor

bgeneto commented Feb 7, 2025

Interesting the auth()->user() seems not to return a subclass of CodeIgniter\Shield\Entities\User so we can't use a custom/inherited entity class (very useful when Adding Attributes to Users).
But, interesting, something like auth()->getProvider()->findById(\user_id()) can be used. Is it possible @kenjis to normalize this kind of situation using returnType?

@datamweb
Copy link
Collaborator

datamweb commented Feb 8, 2025

Interesting the auth()->user() seems not to return a subclass of CodeIgniter\Shield\Entities\User so we can't use a custom/inherited entity class (very useful when Adding Attributes to Users).

What do you mean exactly? Could you clarify?
The output for me is as follows:

image

@bgeneto
Copy link
Contributor

bgeneto commented Feb 9, 2025

What do you mean exactly? Could you clarify? The output for me is as follows:

Maybe I'm confused here or maybe I'm missing something... But I thought that:

auth()->user() was equivalent to auth()->getProvider()->findById(user_id()).

But, in this case, when using the first approach, I'm getting a call to undefined method error: auth()->user()->getName()
I will provide a MWE below to make things clear and also to help other confused users like me :-)

<?php
// app/Config/Auth.php
public string $userProvider = \App\Models\UserModel::class;

My custom user model:

<?php

declare(strict_types=1);

namespace App\Models;

use App\Entities\User;
use CodeIgniter\Shield\Models\UserModel as ShieldUserModel;

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

        $this->allowedFields = [
            ...$this->allowedFields,
            'name', // Added
        ];
        $this->returnType = User::class;
    }
}

And finally our custom entity class:

<?php

declare(strict_types=1);

namespace App\Entities;

use CodeIgniter\Shield\Entities\User as ShieldUser;

/**
 * @property string|null  $name
 */
class User extends ShieldUser
{
    private ?string $name = null;

    public function getName(): ?string {
        return $this->name;
    }

    public function setName(string $name): void {
        $this->name = $name;
    }
}

Now in any controller that extends the BaseController:

<?php

// this works by calling method App\Entities\User::getName()
$name = auth()->getProvider()->findById(\user_id())->getName();

// this gives error: Call to undefined method CodeIgniter\Shield\Entities\User::getName()
$name = auth()->user()->getName();

My question/concern is whether the getAuthenticator()->getUser() method called in auth()->user() shouldn't return the derived entity App\Entities\User instead of CodeIgniter\Shield\Entities\User for the sake of library uniformity. Maybe I can use the new createNewUser() here also, but I don't think so...

image

PS1: Migration class for adding new fields to the user table omitted.
PS2: I'm using CI 4.6.0 and Shield develop branch.

@datamweb
Copy link
Collaborator

datamweb commented Feb 9, 2025

Please review the subject with the following changes:

<?php

declare(strict_types=1);

namespace App\Models;

use App\Entities\User;
use CodeIgniter\Shield\Models\UserModel as ShieldUserModel;

class UserModel extends ShieldUserModel
{
++protected $returnType = User::class;

    protected function initialize(): void
    {
        parent::initialize();

        $this->allowedFields = [
            ...$this->allowedFields,
            'name', // Added
        ];
--$this->returnType = User::class;
    }
}

@bgeneto
Copy link
Contributor

bgeneto commented Feb 9, 2025

Wow... that was tricky! Thanks @datamweb for such a prompt reply. I'm always a bit confused when methods such as initController() and initialize() will be used and by whom :-(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants