Pular para o conteúdo principal

Custom Fields

You can extend the UserModel to add custom fields that match your database schema.

When to Use This

This guide is for adding new fields beyond the standard user fields. If you just need to map existing database columns to the standard fields, see Database Storage instead.

Extending UserModel

Creating a Custom User Model

<?php
namespace App\Model;

use ByJG\Authenticate\Model\UserModel;
use ByJG\MicroOrm\Attributes\FieldAttribute;

class CustomUserModel extends UserModel
{
#[FieldAttribute(fieldName: 'phone')]
protected ?string $phone = null;

#[FieldAttribute(fieldName: 'department')]
protected ?string $department = null;

#[FieldAttribute(fieldName: 'title')]
protected ?string $title = null;

#[FieldAttribute(fieldName: 'profile_picture')]
protected ?string $profilePicture = null;

public function __construct(
string $name = "",
string $email = "",
string $username = "",
string $password = "",
string $admin = "no",
string $phone = "",
string $department = ""
) {
parent::__construct($name, $email, $username, $password, $admin);
$this->phone = $phone;
$this->department = $department;
}

public function getPhone(): ?string
{
return $this->phone;
}

public function setPhone(?string $phone): void
{
$this->phone = $phone;
}

public function getDepartment(): ?string
{
return $this->department;
}

public function setDepartment(?string $department): void
{
$this->department = $department;
}

public function getTitle(): ?string
{
return $this->title;
}

public function setTitle(?string $title): void
{
$this->title = $title;
}

public function getProfilePicture(): ?string
{
return $this->profilePicture;
}

public function setProfilePicture(?string $profilePicture): void
{
$this->profilePicture = $profilePicture;
}
}

Database Schema

Add the custom fields to your users table:

CREATE TABLE users
(
userid INTEGER AUTO_INCREMENT NOT NULL,
name VARCHAR(50),
email VARCHAR(120),
username VARCHAR(15) NOT NULL,
password CHAR(40) NOT NULL,
created_at DATETIME,
updated_at DATETIME,
deleted_at DATETIME,
role VARCHAR(20),
-- Custom fields
phone VARCHAR(20),
department VARCHAR(50),
title VARCHAR(50),
profile_picture VARCHAR(255),

CONSTRAINT pk_users PRIMARY KEY (userid)
) ENGINE=InnoDB;

Using the Custom Model

Initializing the Service

<?php
use ByJG\Authenticate\Enum\LoginField;
use ByJG\Authenticate\Service\UsersService;
use ByJG\Authenticate\Repository\UsersRepository;
use ByJG\Authenticate\Repository\UserPropertiesRepository;
use ByJG\Authenticate\Model\UserPropertiesModel;
use ByJG\AnyDataset\Db\DatabaseExecutor;
use ByJG\AnyDataset\Db\Factory;
use App\Model\CustomUserModel;

// Database connection
$dbDriver = Factory::getDbInstance('mysql://user:password@localhost/database');
$db = DatabaseExecutor::using($dbDriver);

// Initialize repositories with custom model
$usersRepo = new UsersRepository($db, CustomUserModel::class);
$propsRepo = new UserPropertiesRepository($db, UserPropertiesModel::class);

// Create service
$users = new UsersService($usersRepo, $propsRepo, LoginField::Email);

// Using the model directly
$user = new CustomUserModel();
$user->setName('John Doe');
$user->setEmail('[email protected]');
$user->setUsername('johndoe');
$user->setPassword('SecurePass123');
$user->setPhone('+1-555-1234');
$user->setDepartment('Engineering');
$user->setTitle('Senior Developer');

$users->save($user);

Retrieving Users

<?php
$user = $users->getById($userId);

// Access custom fields
echo $user->getName();
echo $user->getPhone();
echo $user->getDepartment();
echo $user->getTitle();

Updating Custom Fields

<?php
$user = $users->getById($userId);
$user->setDepartment('Sales');
$user->setTitle('Sales Manager');
$users->save($user);

Read-Only Fields

You can mark fields as read-only to prevent updates using the ReadOnlyMapper:

<?php
use ByJG\MicroOrm\MapperFunctions\ReadOnlyMapper;
use ByJG\MicroOrm\Attributes\FieldAttribute;

class CustomUserModel extends UserModel
{
// Read-only field - can be set on creation but not updated
#[FieldAttribute(fieldName: 'created_at', updateFunction: ReadOnlyMapper::class, insertFunction: NowUtcMapper::class)]
protected ?string $createdAt = null;

// Read-only custom field
#[FieldAttribute(fieldName: 'phone', updateFunction: ReadOnlyMapper::class)]
protected ?string $phone = null;
}

Read-only fields:

  • Can be set during creation
  • Cannot be updated after creation
  • Are ignored during updates

Field Transformation

You can transform fields during read/write operations using mappers. See Mappers for details.

JSON Fields

For storing JSON data in custom fields:

<?php
use ByJG\MicroOrm\FieldMapping\FieldHandler;
use ByJG\MicroOrm\Attributes\FieldAttribute;

class CustomUserModel extends UserModel
{
#[FieldAttribute(
fieldName: 'metadata',
updateFunction: [FieldHandler::class, 'toJson'],
selectFunction: [FieldHandler::class, 'fromJson']
)]
protected ?array $metadata = null;
}

Date/Time Fields

<?php
use ByJG\MicroOrm\FieldMapping\FieldHandler;
use ByJG\MicroOrm\Attributes\FieldAttribute;

class CustomUserModel extends UserModel
{
#[FieldAttribute(
fieldName: 'created_at',
selectFunction: [FieldHandler::class, 'toDate']
)]
protected ?\DateTime $createdAt = null;
}

Complete Example

<?php
namespace App;

use ByJG\Authenticate\Enum\LoginField;
use ByJG\Authenticate\Service\UsersService;
use ByJG\Authenticate\Repository\UsersRepository;
use ByJG\Authenticate\Repository\UserPropertiesRepository;
use ByJG\Authenticate\Model\UserPropertiesModel;
use ByJG\AnyDataset\Db\Factory;
use ByJG\AnyDataset\Db\DatabaseExecutor;
use App\Model\CustomUserModel;

// Database connection
$dbDriver = Factory::getDbInstance('mysql://user:password@localhost/database');
$db = DatabaseExecutor::using($dbDriver);

// Initialize repositories with custom model
$usersRepo = new UsersRepository($db, CustomUserModel::class);
$propsRepo = new UserPropertiesRepository($db, UserPropertiesModel::class);

// Initialize user service
$users = new UsersService($usersRepo, $propsRepo, LoginField::Email);

// Create a user
$user = new CustomUserModel();
$user->setName('Jane Smith');
$user->setEmail('[email protected]');
$user->setUsername('janesmith');
$user->setPassword('SecurePass123');
$user->setPhone('+1-555-5678');
$user->setDepartment('Marketing');
$user->setTitle('Marketing Director');

$savedUser = $users->save($user);

// Retrieve and update
$user = $users->getById($savedUser->getUserid());
$user->setTitle('VP of Marketing');
$users->save($user);

When to Use Custom Fields vs Properties

Use Custom Fields WhenUse Properties When
Field is used frequentlyField is rarely used
Field is searched/filteredField is key-value metadata
Field is fixed schemaField is dynamic/flexible
Better performance neededSchema flexibility needed
Field is requiredField is optional

Next Steps