- Add shared pagination params and meta output for commits and pull requests API endpoints. - Switch dashboard lists to page-based loading with prev/next controls and total counters. - Add safer HTML escaping and initial empty-state placeholders in gitea dashboard.
266 lines
7.1 KiB
PHP
266 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Controllers\Api;
|
|
|
|
use App\Controllers\BaseController;
|
|
use App\Libraries\GiteaSyncService;
|
|
use CodeIgniter\API\ResponseTrait;
|
|
|
|
class GitApi extends BaseController
|
|
{
|
|
use ResponseTrait;
|
|
|
|
private function ensureLoggedIn()
|
|
{
|
|
if (!session()->get('userid')) {
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'message' => 'Unauthorized',
|
|
], 401);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private function ensureAdmin()
|
|
{
|
|
$level = (int) session()->get('level');
|
|
if (!in_array($level, [0, 1, 2], true)) {
|
|
return $this->respond([
|
|
'status' => 'error',
|
|
'message' => 'Forbidden. Admin only.',
|
|
], 403);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function summary()
|
|
{
|
|
if ($response = $this->ensureLoggedIn()) {
|
|
return $response;
|
|
}
|
|
|
|
$db = \Config\Database::connect();
|
|
|
|
$usersCount = $db->table('git_users')->countAllResults();
|
|
$repositoriesCount = $db->table('git_repositories')->countAllResults();
|
|
$commitsCount = $db->table('git_commits')->countAllResults();
|
|
$pullRequestsCount = $db->table('git_pull_requests')->countAllResults();
|
|
|
|
$latestCommit = $db->table('git_commits')->selectMax('committed_at', 'latest')->get()->getRowArray();
|
|
$latestPullRequest = $db->table('git_pull_requests')->selectMax('updated_at_gitea', 'latest')->get()->getRowArray();
|
|
$latestRepoSync = $db->table('git_repositories')->selectMax('last_synced_at', 'latest')->get()->getRowArray();
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => 'Summary fetched',
|
|
'data' => [
|
|
'users' => $usersCount,
|
|
'repositories' => $repositoriesCount,
|
|
'commits' => $commitsCount,
|
|
'pull_requests' => $pullRequestsCount,
|
|
'latest_commit_at' => $latestCommit['latest'] ?? null,
|
|
'latest_pull_request_at' => $latestPullRequest['latest'] ?? null,
|
|
'last_synced_at' => $latestRepoSync['latest'] ?? null,
|
|
],
|
|
], 200);
|
|
}
|
|
|
|
public function users()
|
|
{
|
|
if ($response = $this->ensureLoggedIn()) {
|
|
return $response;
|
|
}
|
|
|
|
$db = \Config\Database::connect();
|
|
$rows = $db->table('git_users')
|
|
->select('id, gitea_user_id, username, full_name, email, is_active, is_admin, last_synced_at')
|
|
->orderBy('username', 'ASC')
|
|
->get()
|
|
->getResultArray();
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => 'Users fetched',
|
|
'data' => $rows,
|
|
], 200);
|
|
}
|
|
|
|
public function repositories()
|
|
{
|
|
if ($response = $this->ensureLoggedIn()) {
|
|
return $response;
|
|
}
|
|
|
|
$db = \Config\Database::connect();
|
|
$rows = $db->table('git_repositories r')
|
|
->select('r.id, r.gitea_repo_id, r.name, r.full_name, r.owner_username, r.default_branch, r.is_private, r.last_pushed_at, r.last_synced_at, u.username as owner_login')
|
|
->join('git_users u', 'u.id = r.owner_user_id', 'left')
|
|
->orderBy('r.full_name', 'ASC')
|
|
->get()
|
|
->getResultArray();
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => 'Repositories fetched',
|
|
'data' => $rows,
|
|
], 200);
|
|
}
|
|
|
|
private function getPaginationParams(): array
|
|
{
|
|
$page = (int) ($this->request->getGet('page') ?? 1);
|
|
if ($page <= 0) {
|
|
$page = 1;
|
|
}
|
|
|
|
$perPage = (int) ($this->request->getGet('per_page') ?? $this->request->getGet('limit') ?? 25);
|
|
if ($perPage <= 0 || $perPage > 100) {
|
|
$perPage = 25;
|
|
}
|
|
|
|
return [$page, $perPage];
|
|
}
|
|
|
|
public function commits()
|
|
{
|
|
if ($response = $this->ensureLoggedIn()) {
|
|
return $response;
|
|
}
|
|
|
|
$repoId = $this->request->getGet('repo_id');
|
|
$userId = $this->request->getGet('user_id');
|
|
$startDate = $this->request->getGet('start_date');
|
|
$endDate = $this->request->getGet('end_date');
|
|
[$page, $perPage] = $this->getPaginationParams();
|
|
$offset = ($page - 1) * $perPage;
|
|
|
|
$db = \Config\Database::connect();
|
|
$baseBuilder = $db->table('git_commits c')
|
|
->join('git_repositories r', 'r.id = c.repository_id', 'inner')
|
|
->join('git_users u', 'u.id = c.author_user_id', 'left');
|
|
|
|
if (!empty($repoId)) {
|
|
$baseBuilder->where('c.repository_id', (int) $repoId);
|
|
}
|
|
|
|
if (!empty($userId)) {
|
|
$baseBuilder->where('c.author_user_id', (int) $userId);
|
|
}
|
|
|
|
if (!empty($startDate)) {
|
|
$baseBuilder->where('c.committed_at >=', $startDate . ' 00:00:00');
|
|
}
|
|
|
|
if (!empty($endDate)) {
|
|
$baseBuilder->where('c.committed_at <=', $endDate . ' 23:59:59');
|
|
}
|
|
|
|
$total = (int) (clone $baseBuilder)
|
|
->countAllResults();
|
|
|
|
$rows = $baseBuilder
|
|
->select('c.id, c.sha, c.short_sha, c.message, c.author_name, c.author_email, c.committed_at, c.html_url, r.id as repository_id, r.full_name as repository_full_name, u.id as user_id, u.username as user_username')
|
|
->orderBy('c.committed_at', 'DESC')
|
|
->limit($perPage, $offset)
|
|
->get()
|
|
->getResultArray();
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => 'Commits fetched',
|
|
'data' => $rows,
|
|
'meta' => [
|
|
'total' => $total,
|
|
'page' => $page,
|
|
'per_page' => $perPage,
|
|
'total_pages' => $perPage > 0 ? (int) ceil($total / $perPage) : 0,
|
|
],
|
|
], 200);
|
|
}
|
|
|
|
public function pullRequests()
|
|
{
|
|
if ($response = $this->ensureLoggedIn()) {
|
|
return $response;
|
|
}
|
|
|
|
$repoId = $this->request->getGet('repo_id');
|
|
$userId = $this->request->getGet('user_id');
|
|
$state = $this->request->getGet('state');
|
|
$startDate = $this->request->getGet('start_date');
|
|
$endDate = $this->request->getGet('end_date');
|
|
[$page, $perPage] = $this->getPaginationParams();
|
|
$offset = ($page - 1) * $perPage;
|
|
|
|
$db = \Config\Database::connect();
|
|
$baseBuilder = $db->table('git_pull_requests p')
|
|
->join('git_repositories r', 'r.id = p.repository_id', 'inner')
|
|
->join('git_users u', 'u.id = p.author_user_id', 'left');
|
|
|
|
if (!empty($repoId)) {
|
|
$baseBuilder->where('p.repository_id', (int) $repoId);
|
|
}
|
|
|
|
if (!empty($userId)) {
|
|
$baseBuilder->where('p.author_user_id', (int) $userId);
|
|
}
|
|
|
|
if (!empty($state)) {
|
|
$baseBuilder->where('p.state', $state);
|
|
}
|
|
|
|
if (!empty($startDate)) {
|
|
$baseBuilder->where('p.updated_at_gitea >=', $startDate . ' 00:00:00');
|
|
}
|
|
|
|
if (!empty($endDate)) {
|
|
$baseBuilder->where('p.updated_at_gitea <=', $endDate . ' 23:59:59');
|
|
}
|
|
|
|
$total = (int) (clone $baseBuilder)
|
|
->countAllResults();
|
|
|
|
$rows = $baseBuilder
|
|
->select('p.id, p.number, p.title, p.state, p.is_draft, p.is_merged, p.created_at_gitea, p.updated_at_gitea, p.merged_at, p.closed_at, p.html_url, r.id as repository_id, r.full_name as repository_full_name, u.id as user_id, u.username as user_username')
|
|
->orderBy('p.updated_at_gitea', 'DESC')
|
|
->limit($perPage, $offset)
|
|
->get()
|
|
->getResultArray();
|
|
|
|
return $this->respond([
|
|
'status' => 'success',
|
|
'message' => 'Pull requests fetched',
|
|
'data' => $rows,
|
|
'meta' => [
|
|
'total' => $total,
|
|
'page' => $page,
|
|
'per_page' => $perPage,
|
|
'total_pages' => $perPage > 0 ? (int) ceil($total / $perPage) : 0,
|
|
],
|
|
], 200);
|
|
}
|
|
|
|
public function sync()
|
|
{
|
|
if ($response = $this->ensureLoggedIn()) {
|
|
return $response;
|
|
}
|
|
|
|
if ($response = $this->ensureAdmin()) {
|
|
return $response;
|
|
}
|
|
|
|
$service = new GiteaSyncService();
|
|
$result = $service->syncAll();
|
|
|
|
$statusCode = $result['success'] ? 200 : 500;
|
|
return $this->respond([
|
|
'status' => $result['success'] ? 'success' : 'error',
|
|
'message' => $result['message'],
|
|
'data' => $result['stats'] ?? [],
|
|
], $statusCode);
|
|
}
|
|
}
|