100) { $limit = 100; } $offset = (int) ($options['offset'] ?? 0); if ($offset < 0) { $offset = 0; } $search = trim((string) ($options['search'] ?? '')); $order = (string) ($options['order'] ?? 'created_at'); $dir = strtolower((string) ($options['dir'] ?? 'desc')); $status = trim((string) ($options['status'] ?? '')); $createdFrom = trim((string) ($options['created_from'] ?? '')); $createdTo = trim((string) ($options['created_to'] ?? '')); $allowedOrder = ['id', 'created_at', 'sent_at', 'to_email', 'subject', 'status']; if (!in_array($order, $allowedOrder, true)) { $order = 'created_at'; } if (!in_array($dir, ['asc', 'desc'], true)) { $dir = 'desc'; } $where = []; $params = []; if ($search !== '') { $like = '%' . $search . '%'; $where[] = '(to_email like ? or subject like ? or template like ?)'; $params[] = $like; $params[] = $like; $params[] = $like; } if ($status !== '') { $where[] = 'status = ?'; $params[] = $status; } if ($createdFrom !== '') { $where[] = 'created_at >= ?'; $params[] = $createdFrom . ' 00:00:00'; } if ($createdTo !== '') { $where[] = 'created_at <= ?'; $params[] = $createdTo . ' 23:59:59'; } $whereSql = $where ? (' where ' . implode(' and ', $where)) : ''; $count = DB::selectValue('select count(*) from mail_log' . $whereSql, ...$params); $total = $count ? (int) $count : 0; $query = 'select id, to_email, subject, template, status, created_at, sent_at, error_message, provider_message_id from mail_log' . $whereSql . sprintf(' order by `%s` %s limit ? offset ?', $order, $dir); $queryParams = array_merge($params, [(string) $limit, (string) $offset]); $rows = call_user_func_array(['MintyPHP\\DB', 'select'], array_merge([$query], $queryParams)); return [ 'total' => $total, 'rows' => self::unwrapList($rows), ]; } public static function find(int $id): ?array { $row = DB::selectOne( 'select id, to_email, subject, template, status, created_at, sent_at, error_message, provider_message_id from mail_log where id = ? limit 1', (string) $id ); return self::unwrap($row); } }