fix registration issue and split parent controller into services
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Parents;
|
||||
|
||||
use App\Controllers\View\EmailController;
|
||||
use App\Models\AuthorizedUserModel;
|
||||
use App\Models\UserModel;
|
||||
use App\Services\SchoolIdService;
|
||||
use CodeIgniter\Database\BaseConnection;
|
||||
use Exception;
|
||||
|
||||
class ParentAccountService
|
||||
{
|
||||
public function __construct(
|
||||
private readonly BaseConnection $db,
|
||||
private readonly UserModel $userModel,
|
||||
private readonly AuthorizedUserModel $authorizedUsersModel,
|
||||
) {
|
||||
}
|
||||
|
||||
public function canAccessUserRecord(int $requestedUserId, int $sessionUserId, array $sessionRoles): bool
|
||||
{
|
||||
if ($sessionUserId <= 0 || $requestedUserId <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($sessionUserId === $requestedUserId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$roles = array_map(
|
||||
static fn ($role): string => strtolower(trim((string) $role)),
|
||||
array_filter($sessionRoles)
|
||||
);
|
||||
|
||||
return (bool) array_intersect($roles, ['administrator', 'administrative staff', 'principal', 'admin']);
|
||||
}
|
||||
|
||||
public function isEmailUnique(string $email): bool
|
||||
{
|
||||
foreach (['users' => 'email', 'emergency_contacts' => 'email'] as $table => $column) {
|
||||
if ($this->db->table($table)->where($column, $email)->countAllResults() > 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function createRelatedUser(array $userData, string $relationToStudent, string $semester, string $schoolYear): int|false
|
||||
{
|
||||
$schoolIdService = new SchoolIdService();
|
||||
$token = bin2hex(random_bytes(48));
|
||||
$tokenHash = hash('sha256', $token);
|
||||
$userType = in_array(strtolower($relationToStudent), ['wife', 'husband'], true) ? 'Secondary' : 'Tertiary';
|
||||
|
||||
$validation = \Config\Services::validation();
|
||||
$validation->setRules([
|
||||
'firstname' => [
|
||||
'label' => 'First Name',
|
||||
'rules' => 'required|min_length[2]|max_length[100]|regex_match[/^[A-Za-z\s\-]+$/]',
|
||||
'errors' => ['regex_match' => 'First name may only contain letters, spaces, and dashes.'],
|
||||
],
|
||||
'lastname' => [
|
||||
'label' => 'Last Name',
|
||||
'rules' => 'required|min_length[2]|max_length[100]|regex_match[/^[A-Za-z\s\-]+$/]',
|
||||
'errors' => ['regex_match' => 'Last name may only contain letters, spaces, and dashes.'],
|
||||
],
|
||||
'email' => [
|
||||
'label' => 'Email Address',
|
||||
'rules' => 'required|valid_email|max_length[150]|is_unique[users.email]',
|
||||
'errors' => ['is_unique' => 'This email is already registered.'],
|
||||
],
|
||||
'cellphone' => [
|
||||
'label' => 'Cell Phone',
|
||||
'rules' => 'required|regex_match[/^\d{10}$/]',
|
||||
'errors' => ['regex_match' => 'Phone number must be exactly 10 digits.'],
|
||||
],
|
||||
'gender' => 'required|in_list[Male,Female]',
|
||||
'city' => 'required|max_length[100]',
|
||||
'state' => 'required|max_length[100]',
|
||||
'zip' => 'required|regex_match[/^\d{5}$/]',
|
||||
]);
|
||||
|
||||
if (! $validation->run($userData)) {
|
||||
log_message('error', 'User creation failed due to invalid data: ' . json_encode($validation->getErrors()));
|
||||
return false;
|
||||
}
|
||||
|
||||
$userEntry = [
|
||||
'firstname' => ucfirst(strtolower($userData['firstname'])),
|
||||
'lastname' => ucfirst(strtolower($userData['lastname'])),
|
||||
'gender' => $userData['gender'],
|
||||
'cellphone' => $userData['cellphone'],
|
||||
'email' => strtolower($userData['email']),
|
||||
'address_street' => $userData['address_street'] ?? '',
|
||||
'apt' => $userData['apt'] ?? null,
|
||||
'city' => ucfirst(strtolower($userData['city'])),
|
||||
'state' => strtoupper($userData['state']),
|
||||
'zip' => $userData['zip'],
|
||||
'accept_school_policy' => $userData['accept_school_policy'] ?? 0,
|
||||
'token' => $tokenHash,
|
||||
'is_verified' => 0,
|
||||
'status' => 'Inactive',
|
||||
'user_type' => $userType,
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'school_id' => $schoolIdService->generateUserSchoolId(),
|
||||
];
|
||||
|
||||
try {
|
||||
if (! $this->userModel->insert($userEntry)) {
|
||||
log_message('error', 'Failed to insert user: ' . print_r($this->userModel->errors(), true));
|
||||
return false;
|
||||
}
|
||||
|
||||
$userId = (int) $this->userModel->getInsertID();
|
||||
$this->sendActivationEmail((string) $userData['email'], $token);
|
||||
log_message('info', "User with ID $userId created successfully and activation email sent.");
|
||||
|
||||
return $userId;
|
||||
} catch (Exception $e) {
|
||||
log_message('error', 'Exception during user creation: ' . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function updateAuthorizedUsers(int $userId, array $data): void
|
||||
{
|
||||
$validation = \Config\Services::validation();
|
||||
$validation->setRules([
|
||||
'email' => [
|
||||
'label' => 'Email',
|
||||
'rules' => 'required|valid_email|max_length[150]',
|
||||
'errors' => [
|
||||
'required' => 'Email is required.',
|
||||
'valid_email' => 'Please provide a valid email address.',
|
||||
'max_length' => 'Email must be less than 150 characters.',
|
||||
],
|
||||
],
|
||||
'name' => [
|
||||
'label' => 'Name',
|
||||
'rules' => 'required|min_length[3]|max_length[100]|regex_match[/^[A-Za-z\s\-]+$/]',
|
||||
'errors' => [
|
||||
'required' => 'Name is required.',
|
||||
'regex_match' => 'Name can only contain letters, spaces, and dashes.',
|
||||
'min_length' => 'Name must be at least 3 characters long.',
|
||||
'max_length' => 'Name must be less than 100 characters.',
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
if (! $validation->run($data)) {
|
||||
log_message('error', 'Invalid authorized user data: ' . json_encode($validation->getErrors()));
|
||||
return;
|
||||
}
|
||||
|
||||
$existingAuthorizedUser = $this->authorizedUsersModel
|
||||
->where('user_id', $userId)
|
||||
->where('email', $data['email'])
|
||||
->first();
|
||||
|
||||
if ($existingAuthorizedUser) {
|
||||
$this->authorizedUsersModel->update($existingAuthorizedUser['id'], $data);
|
||||
return;
|
||||
}
|
||||
|
||||
$data['user_id'] = $userId;
|
||||
$data['status'] = 'Pending';
|
||||
$this->authorizedUsersModel->insert($data);
|
||||
}
|
||||
|
||||
private function sendActivationEmail(string $email, string $token): void
|
||||
{
|
||||
$emailController = new EmailController();
|
||||
$subject = 'Activate Your Account';
|
||||
$activationLink = site_url('/user/confirm/' . $token);
|
||||
$message = "Please click the following link to confirm your email and set your password: $activationLink";
|
||||
|
||||
if ($emailController->sendEmail($email, $subject, $message)) {
|
||||
log_message('info', 'Activation email sent successfully to ' . $email);
|
||||
} else {
|
||||
log_message('error', 'Failed to send activation email to ' . $email);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user