Authentication process (substitution "currentUser" method)

Silverstripe Version: 3.6.0

Question: Hello. How can I substitution(replace) “currentUser” method which locate in framework/security/Member.php:877

For example: I’m working on a module which modify authentication and registration process. I want to get information about user from API, not from a database. Can you help me to find decision, please?

There aren’t any extension hooks in that method so you would probably have to swap out the whole class using the Injector. But if you don’t want to use the database to store user information and manage authentication then you might not want to use the Member class at all.

Hello, thank you for your response. But I want to clarify some details. I don’t want to
give up of Member class, because it consists of a lot of methods which are used everywhere in code including the core of the cms. When you say about: “swap out the whole class using the Injector”, did you mean that I can create new class with my special “currentMember” method and inject this class everywhere where currentMember is used and replace it (with my “currentMember” method)? Do I understand correct?

If u use injector to replace (not extend) Member with your CustomMember, you should implement all functions in Member (and possibly its extensions)

You dun have to “inject it everywhere”; all calls to member using the injector signature should puck up your class instead; although places where calls are like “new Member()” will still be pulling the old class, as well as places where direct db access is called “Dataobject::get(‘Member’)”

Need expert clarification on the latter though

Sorry, but I don’t understand how I can inject my customMember class to replace base Member class. Could you write some simple example how and where I need to do this injection (to make this only one time), please?

First you will need to create your own Member class. Let’s call it CustomMember. Ideally you would be able to subclass Member to create CustomMember, and just replace the one or two methods you want to override. That way any updates to the Member class overtime will be inherited automatically. It’s worth a shot, but since we’re dealing with a DataObject I think you possibly might run in to a problem if you try to replace Member with a subclass of Member (I’ve had trouble with this before).

The more stable option (IMO) would be to copy the Member.php file to your mysite/code folder and rename the file and class to CustomMember. Edit the methods you want to change and add this yml to your config file to instruct the Injector to use CustomMember instead of Member:

Injector:
  Member:
    class: CustomMember

The drawback to this approach is that if the Member class is updated in any future releases of SilverStripe you would have to manually reproduce those changes in CustomMember to benefit from them.

Hello, thank you for your example. I tried this decision, maybe I lost some detail.
I copy Member class to CustomMember file and use class name CustomMember which located in testmodule/code folder and added to _config/config.yml next:
Injector:
Member:
class: CustomMember

But anyway when Member::currentUser method called, it invoke basic Member class (which located in framework folder). I tried to do the same in mysite/code folder too.

Hmmm the Injector may not do enough for you after all. Looks like static methods aren’t swapped out by the injector (see this discussion). If there is code you can’t edit that is calling Member::currentUser() you may be out of luck, but in your own code you can try:

$member = Injector::inst()->get('Member');
$user = $member->currentUser();

If you need to customise core code I’ve heard of people using a composer command to automatically patch in their own edits after an update, but can’t recall where I saw that.

Thank you very much for your time and attention.