Files
alrahma_sunday_school_api/app/Http/Controllers/Api/EmailExtractorController.php
T
2026-03-05 12:29:37 -05:00

171 lines
5.9 KiB
PHP
Executable File

<?php
namespace App\Http\Controllers\Api;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Response;
class EmailExtractorController extends BaseApiController
{
/**
* GET /api/emails
* Returns JSON: { users: string[], parents: string[] }
* Pulls emails from users.email and parents.secondparent_email
*/
public function getEmails()
{
try {
$users = [];
$parents = [];
// Fetch users.email (non-null, non-empty)
$userRows = DB::table('users')->select('email')->get();
foreach ($userRows as $row) {
$email = strtolower(trim((string)($row->email ?? '')));
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$users[] = $email;
}
}
// De-duplicate
$users = array_values(array_unique($users));
// Fetch parents.secondparent_email (non-null, non-empty)
$parentRows = DB::table('parents')->select('secondparent_email')->get();
foreach ($parentRows as $row) {
$email = strtolower(trim((string)($row->secondparent_email ?? '')));
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$parents[] = $email;
}
}
// De-duplicate
$parents = array_values(array_unique($parents));
return $this->success([
'users' => $users,
'parents' => $parents,
], 'Emails retrieved successfully');
} catch (\Throwable $e) {
Log::error('Email extraction error: ' . $e->getMessage());
return $this->respondError('Database error: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* POST /api/compare
* Accepts multipart/form-data with a CSV file named 'file' (optional),
* or JSON body with { csvEmails: string[] } (optional).
* Compares against DB and returns:
* {
* existed: string[], // in CSV AND in DB
* needToAdd: string[], // in DB BUT NOT in CSV
* counts: { csv: number, db: number, users: number, parents: number }
* }
*/
public function compare()
{
$csvEmails = [];
// 1) Try read from uploaded file
if ($this->laravelRequest->hasFile('file')) {
$file = $this->laravelRequest->file('file');
if ($file->isValid()) {
$contents = file_get_contents($file->getRealPath());
$csvEmails = $this->extractEmailsFromText($contents);
}
}
// 2) Or from JSON body
if (empty($csvEmails)) {
$data = $this->payloadData();
if (isset($data['csvEmails']) && is_array($data['csvEmails'])) {
$csvEmails = $this->normalizeEmailArray($data['csvEmails']);
}
}
// 3) Compare with DB
try {
// Fetch DB emails
$users = [];
$parents = [];
$userRows = DB::table('users')->select('email')->get();
foreach ($userRows as $row) {
$e = strtolower(trim((string)($row->email ?? '')));
if ($e !== '' && filter_var($e, FILTER_VALIDATE_EMAIL)) {
$users[] = $e;
}
}
$users = array_values(array_unique($users));
$parentRows = DB::table('parents')->select('secondparent_email')->get();
foreach ($parentRows as $row) {
$e = strtolower(trim((string)($row->secondparent_email ?? '')));
if ($e !== '' && filter_var($e, FILTER_VALIDATE_EMAIL)) {
$parents[] = $e;
}
}
$parents = array_values(array_unique($parents));
// Sets for comparison
$csvSet = array_flip(array_values(array_unique($csvEmails)));
$dbUnion = array_values(array_unique(array_merge($users, $parents)));
$dbSet = array_flip($dbUnion);
// existed: in CSV and in DB
$existed = [];
foreach ($csvSet as $email => $_) {
if (isset($dbSet[$email])) {
$existed[] = $email;
}
}
sort($existed);
// needToAdd: in DB but NOT in CSV
$needToAdd = [];
foreach ($dbSet as $email => $_) {
if (!isset($csvSet[$email])) {
$needToAdd[] = $email;
}
}
sort($needToAdd);
return $this->success([
'existed' => $existed,
'needToAdd' => $needToAdd,
'counts' => [
'csv' => count($csvEmails),
'db' => count($dbUnion),
'users' => count($users),
'parents' => count($parents),
],
], 'Comparison completed successfully');
} catch (\Throwable $e) {
Log::error('Email comparison error: ' . $e->getMessage());
return $this->respondError('Database error: ' . $e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
// Helpers
private function normalizeEmailArray(array $arr): array
{
$out = [];
foreach ($arr as $e) {
$email = strtolower(trim((string)$e));
if ($email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$out[] = $email;
}
}
return array_values(array_unique($out));
}
private function extractEmailsFromText(string $text): array
{
$pattern = '/[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/i';
preg_match_all($pattern, $text, $matches);
$emails = $matches[0] ?? [];
return $this->normalizeEmailArray($emails);
}
}