'', 'results' => [], 'scope_used' => 'unscoped-raw', 'scope_label' => 'all years/semesters (raw)', 'total_found' => 0, ]; } $rawTokens = preg_split('/[,\s]+/u', $q, -1, PREG_SPLIT_NO_EMPTY) ?: []; $tokens = array_values(array_filter(array_map('trim', $rawTokens))); $phoneMap = []; foreach ($tokens as $t) { $digits = preg_replace('/\D+/', '', $t); if ($digits === '') { continue; } $v = []; if (strlen($digits) >= 7) { $v[] = $digits; if (strlen($digits) === 10) { $v[] = sprintf('(%s)-%s-%s', substr($digits, 0, 3), substr($digits, 3, 3), substr($digits, 6)); $v[] = sprintf('%s-%s-%s', substr($digits, 0, 3), substr($digits, 3, 3), substr($digits, 6)); $v[] = sprintf('%s %s %s', substr($digits, 0, 3), substr($digits, 3, 3), substr($digits, 6)); $v[] = '1' . $digits; $v[] = '+1' . $digits; $v[] = '+1 ' . sprintf('(%s) %s-%s', substr($digits, 0, 3), substr($digits, 3, 3), substr($digits, 6)); $v[] = '+1-' . sprintf('%s-%s-%s', substr($digits, 0, 3), substr($digits, 3, 3), substr($digits, 6)); } elseif (strlen($digits) === 11 && str_starts_with($digits, '1')) { $ten = substr($digits, 1); $v[] = $ten; $v[] = sprintf('(%s)-%s-%s', substr($ten, 0, 3), substr($ten, 3, 3), substr($ten, 6)); $v[] = sprintf('%s-%s-%s', substr($ten, 0, 3), substr($ten, 3, 3), substr($ten, 6)); $v[] = sprintf('%s %s %s', substr($ten, 0, 3), substr($ten, 3, 3), substr($ten, 6)); $v[] = '+1' . $ten; $v[] = '+1 ' . sprintf('(%s) %s-%s', substr($ten, 0, 3), substr($ten, 3, 3), substr($ten, 6)); $v[] = '+1-' . sprintf('%s-%s-%s', substr($ten, 0, 3), substr($ten, 3, 3), substr($ten, 6)); } } if (!empty($v)) { $phoneMap[$t] = array_values(array_unique($v)); } } $applyMultiTokenLike = function ($qb, array $columns, array $tokens, array $phoneCols = []) use ($phoneMap) { foreach ($tokens as $t) { $qb->where(function ($sub) use ($columns, $phoneCols, $phoneMap, $t) { foreach ($columns as $col) { $sub->orWhere($col, 'like', '%' . $t . '%'); } if (!empty($phoneMap[$t]) && !empty($phoneCols)) { foreach ($phoneMap[$t] as $pv) { foreach ($phoneCols as $pcol) { $sub->orWhere($pcol, 'like', '%' . $pv . '%'); } } } }); } return $qb; }; $uQB = DB::table('users') ->select('id', 'firstname', 'lastname', 'email', 'cellphone', 'school_id', 'city', 'state', 'school_year', 'semester'); $applyMultiTokenLike($uQB, ['firstname', 'lastname', 'email', 'cellphone', 'school_id', 'city', 'state'], $tokens, ['cellphone']); $users = $uQB->limit(150)->get()->map(fn($r) => (array) $r)->all(); $sQB = DB::table('students') ->select('id', 'parent_id', 'school_id', 'firstname', 'lastname', 'dob', 'gender', 'school_year', 'semester', 'rfid_tag'); $applyMultiTokenLike($sQB, ['firstname', 'lastname', 'school_id', 'rfid_tag', 'dob', 'gender'], $tokens); $students = $sQB->limit(150)->get()->map(fn($r) => (array) $r)->all(); $pQB = DB::table('parents') ->select('id', 'firstparent_id', 'secondparent_firstname', 'secondparent_lastname', 'secondparent_email', 'secondparent_phone', 'school_year', 'semester'); $applyMultiTokenLike($pQB, ['secondparent_firstname', 'secondparent_lastname', 'secondparent_email', 'secondparent_phone'], $tokens, ['secondparent_phone']); foreach ($tokens as $t) { if (ctype_digit($t)) { $pQB->orWhere('firstparent_id', (int) $t)->orWhere('id', (int) $t); } } $parents = $pQB->limit(150)->get()->map(fn($r) => (array) $r)->all(); $stQB = DB::table('staff') ->select('id', 'user_id', 'firstname', 'lastname', 'email', 'phone', 'role_name', 'school_year', 'active_role'); $applyMultiTokenLike($stQB, ['firstname', 'lastname', 'email', 'role_name', 'phone'], $tokens, ['phone']); $staff = $stQB->limit(150)->get()->map(fn($r) => (array) $r)->all(); $ecQB = DB::table('emergency_contacts') ->select('id', 'parent_id', 'emergency_contact_name', 'relation', 'cellphone', 'email', 'school_year', 'semester'); $applyMultiTokenLike($ecQB, ['emergency_contact_name', 'relation', 'email', 'cellphone'], $tokens, ['cellphone']); $emergency = $ecQB->limit(150)->get()->map(fn($r) => (array) $r)->all(); return [ 'query' => $q, 'results' => [ 'users' => $users, 'students' => $students, 'parents' => $parents, 'staff' => $staff, 'emergency_contacts' => $emergency, ], 'scope_used' => 'unscoped-raw', 'scope_label' => 'all years/semesters (raw, tokenized)', 'total_found' => count($users) + count($students) + count($parents) + count($staff) + count($emergency), ]; } }