table('users')->select('email'); $userRows = $builderUsers->get()->getResultArray(); 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) $builderParents = $db->table('parents')->select('secondparent_email'); $parentRows = $builderParents->get()->getResultArray(); 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->response->setJSON([ 'users' => $users, 'parents' => $parents, ])->setStatusCode(ResponseInterface::HTTP_OK); } catch (DatabaseException $e) { return $this->response->setJSON([ 'error' => 'Database error: ' . $e->getMessage(), ])->setStatusCode(ResponseInterface::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() { $request = $this->request; $csvEmails = []; // 1) Try read from uploaded file $file = $request->getFile('file'); if ($file && $file->isValid()) { $contents = file_get_contents($file->getTempName()); $csvEmails = $this->extractEmailsFromText($contents); } // 2) Or from JSON body if (empty($csvEmails) && $request->getHeaderLine('Content-Type')) { $contentType = $request->getHeaderLine('Content-Type'); if (stripos($contentType, 'application/json') !== false) { $json = $request->getJSON(true); if (isset($json['csvEmails']) && is_array($json['csvEmails'])) { $csvEmails = $this->normalizeEmailArray($json['csvEmails']); } } } // 3) Compare with DB $db = db_connect(); // Fetch DB emails $users = []; $parents = []; $userRows = $db->table('users')->select('email')->get()->getResultArray(); 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()->getResultArray(); 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->response->setJSON([ 'existed' => $existed, 'needToAdd' => $needToAdd, 'counts' => [ 'csv' => count($csvEmails), 'db' => count($dbUnion), 'users' => count($users), 'parents' => count($parents), ], ]); } // 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); } }