Files
domnitor/app/Controllers/SearchController.php
2025-10-08 14:23:07 +03:00

173 lines
5.4 KiB
PHP

<?php
namespace App\Controllers;
use Core\Controller;
use App\Models\Domain;
use App\Services\WhoisService;
class SearchController extends Controller
{
private Domain $domainModel;
private WhoisService $whoisService;
public function __construct()
{
$this->domainModel = new Domain();
$this->whoisService = new WhoisService();
}
public function index()
{
$query = trim($_GET['q'] ?? '');
if (empty($query)) {
$_SESSION['error'] = 'Please enter a search term';
$this->redirect('/domains');
return;
}
// Pagination parameters
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = max(10, min(100, (int)($_GET['per_page'] ?? 25)));
// Search existing domains in database
$allResults = $this->searchDomains($query);
$totalResults = count($allResults);
// Calculate pagination
$totalPages = ceil($totalResults / $perPage);
$page = min($page, max(1, $totalPages)); // Ensure page is within valid range
$offset = ($page - 1) * $perPage;
// Slice results for current page
$existingDomains = array_slice($allResults, $offset, $perPage);
// Check if query looks like a domain name
$isDomainLike = $this->isDomainFormat($query);
// If it looks like a domain and not found in database, offer WHOIS lookup
$whoisData = null;
$whoisError = null;
if ($isDomainLike && empty($allResults)) {
// Do WHOIS lookup
$whoisData = $this->whoisService->getDomainInfo($query);
if (!$whoisData) {
$whoisError = "Could not retrieve WHOIS information for '$query'";
}
}
$this->view('search/results', [
'query' => $query,
'existingDomains' => $existingDomains,
'whoisData' => $whoisData,
'whoisError' => $whoisError,
'isDomainLike' => $isDomainLike,
'pagination' => [
'current_page' => $page,
'per_page' => $perPage,
'total' => $totalResults,
'total_pages' => $totalPages,
'showing_from' => $totalResults > 0 ? $offset + 1 : 0,
'showing_to' => min($offset + $perPage, $totalResults)
],
'title' => 'Search Results'
]);
}
/**
* AJAX endpoint for live search suggestions
*/
public function suggest()
{
header('Content-Type: application/json');
$query = trim($_GET['q'] ?? '');
if (empty($query)) {
echo json_encode(['domains' => [], 'isDomainLike' => false]);
exit;
}
// Search existing domains (limit to 5 for quick results)
$db = \Core\Database::getConnection();
$sql = "SELECT d.id, d.domain_name, d.registrar, d.expiration_date, d.status, ng.name as group_name
FROM domains d
LEFT JOIN notification_groups ng ON d.notification_group_id = ng.id
WHERE d.domain_name LIKE ?
OR d.registrar LIKE ?
ORDER BY d.domain_name ASC
LIMIT 5";
$searchTerm = '%' . $query . '%';
$stmt = $db->prepare($sql);
$stmt->execute([$searchTerm, $searchTerm]);
$results = $stmt->fetchAll();
// Calculate days left for each domain
foreach ($results as &$domain) {
if (!empty($domain['expiration_date'])) {
$daysLeft = floor((strtotime($domain['expiration_date']) - time()) / 86400);
$domain['days_left'] = $daysLeft;
// Color coding
if ($daysLeft < 0) {
$domain['status_color'] = 'red';
} elseif ($daysLeft <= 30) {
$domain['status_color'] = 'orange';
} elseif ($daysLeft <= 90) {
$domain['status_color'] = 'yellow';
} else {
$domain['status_color'] = 'green';
}
} else {
$domain['days_left'] = null;
$domain['status_color'] = 'gray';
}
}
// Check if query looks like a domain
$isDomainLike = $this->isDomainFormat($query);
echo json_encode([
'domains' => $results,
'isDomainLike' => $isDomainLike,
'query' => $query
]);
exit;
}
/**
* Search domains in database
*/
private function searchDomains(string $query): array
{
$db = \Core\Database::getConnection();
$sql = "SELECT d.*, ng.name as group_name
FROM domains d
LEFT JOIN notification_groups ng ON d.notification_group_id = ng.id
WHERE d.domain_name LIKE ?
OR d.registrar LIKE ?
OR ng.name LIKE ?
ORDER BY d.domain_name ASC
LIMIT 50";
$searchTerm = '%' . $query . '%';
$stmt = $db->prepare($sql);
$stmt->execute([$searchTerm, $searchTerm, $searchTerm]);
return $stmt->fetchAll();
}
/**
* Check if string looks like a domain name
*/
private function isDomainFormat(string $query): bool
{
// Basic domain validation
return preg_match('/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}$/i', $query);
}
}