added bootstar, font awsome, and the project is in a useable state, bit needs some manual setup.
This commit is contained in:
289
ProjectKiln/api/project.php
Normal file
289
ProjectKiln/api/project.php
Normal file
@@ -0,0 +1,289 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
require_once __DIR__ . '/../db.php';
|
||||
require_once __DIR__ . '/../auth.php';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
function jsonResponse(array $data, int $status = 200): void
|
||||
{
|
||||
http_response_code($status);
|
||||
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
function getInputData(): array
|
||||
{
|
||||
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
|
||||
|
||||
if (str_contains($contentType, 'application/json')) {
|
||||
$raw = file_get_contents('php://input');
|
||||
$data = json_decode($raw, true);
|
||||
|
||||
return is_array($data) ? $data : [];
|
||||
}
|
||||
|
||||
return $_POST;
|
||||
}
|
||||
|
||||
function requireUserExists(int $userId): void
|
||||
{
|
||||
if ($userId <= 0) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project owner must be valid.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
$stmt = db()->prepare('SELECT id FROM users WHERE id = ? LIMIT 1');
|
||||
$stmt->execute([$userId]);
|
||||
|
||||
if (!$stmt->fetch()) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project owner not found.'
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
$user = requireApiAuth();
|
||||
|
||||
$api = $_GET['api'] ?? '';
|
||||
|
||||
switch ($api) {
|
||||
|
||||
case 'ListProjects': {
|
||||
if (userIsAdmin((int)$user['id'])) {
|
||||
$stmt = db()->query(
|
||||
'SELECT id
|
||||
FROM projects
|
||||
ORDER BY id ASC'
|
||||
);
|
||||
} else {
|
||||
$stmt = db()->prepare(
|
||||
'SELECT DISTINCT projects.id
|
||||
FROM projects
|
||||
LEFT JOIN user_access
|
||||
ON user_access.project_id = projects.id
|
||||
AND user_access.user_id = ?
|
||||
WHERE projects.owner = ?
|
||||
OR user_access.id IS NOT NULL
|
||||
ORDER BY projects.id ASC'
|
||||
);
|
||||
$stmt->execute([(int)$user['id'], (int)$user['id']]);
|
||||
}
|
||||
|
||||
jsonResponse([
|
||||
'success' => true,
|
||||
'projects' => $stmt->fetchAll(PDO::FETCH_COLUMN)
|
||||
]);
|
||||
}
|
||||
|
||||
case 'ProjectInfo': {
|
||||
$projectId = strtoupper(trim($_GET['project_id'] ?? ''));
|
||||
|
||||
if ($projectId === '') {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Missing project_id.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
requireProjectAccessForUser((int)$user['id'], $projectId);
|
||||
|
||||
$stmt = db()->prepare(
|
||||
'SELECT id, name, owner, created_date
|
||||
FROM projects
|
||||
WHERE id = ?
|
||||
LIMIT 1'
|
||||
);
|
||||
|
||||
$stmt->execute([$projectId]);
|
||||
$project = $stmt->fetch();
|
||||
|
||||
if (!$project) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project not found.'
|
||||
], 404);
|
||||
}
|
||||
|
||||
jsonResponse([
|
||||
'success' => true,
|
||||
'project' => $project
|
||||
]);
|
||||
}
|
||||
|
||||
case 'Create': {
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Create requires POST.'
|
||||
], 405);
|
||||
}
|
||||
|
||||
requireUserRight((int)$user['id'], 'Create Projects');
|
||||
|
||||
$data = getInputData();
|
||||
|
||||
$projectId = strtoupper(trim($data['id'] ?? ''));
|
||||
$name = trim($data['name'] ?? '');
|
||||
$owner = isset($data['owner']) && $data['owner'] !== ''
|
||||
? (int)$data['owner']
|
||||
: (int)$user['id'];
|
||||
|
||||
if (!preg_match('/^[A-Z0-9]{2,12}$/', $projectId)) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project id must be 2-12 characters and contain only A-Z and 0-9.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
if ($name === '') {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project name is required.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
if (strlen($name) > 128) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project name is too long.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
requireUserExists($owner);
|
||||
|
||||
$stmt = db()->prepare(
|
||||
'SELECT id FROM projects WHERE id = ? LIMIT 1'
|
||||
);
|
||||
|
||||
$stmt->execute([$projectId]);
|
||||
|
||||
if ($stmt->fetch()) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project id already exists.'
|
||||
], 409);
|
||||
}
|
||||
|
||||
$stmt = db()->prepare(
|
||||
'INSERT INTO projects (id, name, owner, created_date)
|
||||
VALUES (?, ?, ?, CURDATE())'
|
||||
);
|
||||
|
||||
$stmt->execute([
|
||||
$projectId,
|
||||
$name,
|
||||
$owner
|
||||
]);
|
||||
|
||||
jsonResponse([
|
||||
'success' => true,
|
||||
'project_id' => $projectId
|
||||
], 201);
|
||||
}
|
||||
|
||||
case 'Edit': {
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Edit requires POST.'
|
||||
], 405);
|
||||
}
|
||||
|
||||
$projectId = strtoupper(trim($_GET['project_id'] ?? ''));
|
||||
|
||||
if ($projectId === '') {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Missing project_id.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
requireProjectRight((int)$user['id'], $projectId, 'Edit Projects');
|
||||
|
||||
$data = getInputData();
|
||||
|
||||
$fields = [];
|
||||
$values = [];
|
||||
|
||||
if (array_key_exists('name', $data)) {
|
||||
$name = trim((string)$data['name']);
|
||||
|
||||
if ($name === '') {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project name cannot be empty.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
if (strlen($name) > 128) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project name is too long.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
$fields[] = 'name = ?';
|
||||
$values[] = $name;
|
||||
}
|
||||
|
||||
if (array_key_exists('owner', $data)) {
|
||||
$owner = (int)$data['owner'];
|
||||
requireUserExists($owner);
|
||||
|
||||
$fields[] = 'owner = ?';
|
||||
$values[] = $owner;
|
||||
}
|
||||
|
||||
if (empty($fields)) {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'No editable fields provided.'
|
||||
], 400);
|
||||
}
|
||||
|
||||
$values[] = $projectId;
|
||||
|
||||
$stmt = db()->prepare(
|
||||
'UPDATE projects
|
||||
SET ' . implode(', ', $fields) . '
|
||||
WHERE id = ?'
|
||||
);
|
||||
|
||||
$stmt->execute($values);
|
||||
|
||||
if ($stmt->rowCount() === 0) {
|
||||
$existsStmt = db()->prepare('SELECT id FROM projects WHERE id = ? LIMIT 1');
|
||||
$existsStmt->execute([$projectId]);
|
||||
|
||||
if ($existsStmt->fetch()) {
|
||||
jsonResponse([
|
||||
'success' => true,
|
||||
'project_id' => $projectId
|
||||
]);
|
||||
}
|
||||
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Project not found or nothing changed.'
|
||||
], 404);
|
||||
}
|
||||
|
||||
jsonResponse([
|
||||
'success' => true,
|
||||
'project_id' => $projectId
|
||||
]);
|
||||
}
|
||||
|
||||
default: {
|
||||
jsonResponse([
|
||||
'success' => false,
|
||||
'error' => 'Unknown API action.'
|
||||
], 404);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user