I’m creating an authentication / login system using Slim 3 PHP on the back-end and Angular on the front-end and I’m trying to understand the ‘domain object’ and ‘data mapper’ part of a model layer within an MVC structure. I’ve read a lot of useful answers on various questions such as this, from which I understand the model should be comprised of ‘domain objects’, ‘data mappers’ and ‘services’.
However I’m not exactly sure what how this should be structured in the context of a user being able to register and log in to a website.
From my understanding I could have a user 'domain object' that has properties such as username and password. It could also have methods such as register or log in to represent business logic.
Would I then have a service class that creates a new instance of a user object, in which I would pass the form data into the object? So now my user object instance would have set username and password values?
Now i'm not sure how this objects property data would be inserted into the database. Would I use the user objects register method to insert the data into the database by passing in the username and password as parameters?
Apparently the service should be where the domain object and the data mapper interact, but i'm not sure how this would work if the register method is in the user domain object.
I was hoping someone could show me some code examples of what should be in the service class and how the interaction between the domain object and data mapper might work in the context of a user registering and logging in.
Note I don't want to use any frameworks, I want to try and implement a proper MVC structure manually as I feel i'd learn more.
So far I have this structure for registering a user:
I have an AuthenticationController with the method registerUser to allow a user to create an account:
class AuthenticationController
{
protected $authenticationService;
public function __construct(AuthenticationService $authenticationService)
{
$this->authenticationService = $authenticationService;
}
public function registerUser($request, $response)
{
$this->authenticationService->registerUser($request, $response);
}
}
I then have the AuthenticationService class with the registerUser method:
class AuthenticationService
{
protected $database;
public function __construct(PDO $database)
{
$this->database = $database;
}
public function registerUser ($request, $response)
{
$strings = $request→getParsedBody(); // will be sanitised / validated later
$username = $strings['username'];
$password = $strings['password'];
$email = "temp random email";
$stmt = $this->database->prepare("INSERT INTO users (email, username, password) values (:email, :username, :password)");
$stmt->bindParam(':email', $email);
$stmt->bindParam(':username', $username);
$stmt->bindParam(':password', $password);
$stmt->execute();
}
}
Later on I intend to put the SQL into an AuthenticationRepository and the PDO logic into it’s own class. This AuthenticationService method will also make sure the user details are sanitised using PHP’s built in functions.
I’m not sure if the proposed PDO database class or AuthenticationRepository would count as a data mapper or not.
Here a registration example. I didn't test it at all. For more details see the resources list at the end of this answer. Maybe begin with the last one, which - I just realized - is the answer to a question of yours.
Used file system structure:
a) Extended "MyApp/UI":
b) Extended "MyApp/Domain":
The controller:
The service:
The exception thrown when trying to register an already existing user:
The domain object (entity):
The value objects used by the entity:
The exceptions thrown by the value objects:
The repository interface:
The repository:
The data mapper interface:
The data mapper:
Resources: