mirror of
https://github.com/JGH0/Todo-App-Backend.git
synced 2026-06-03 13:28:47 +02:00
fix todo create/update: link category via todo_categories junction table, return single object (not array), include category_ids in response
This commit is contained in:
@@ -63,6 +63,11 @@ class TodoController extends BaseController
|
||||
|
||||
$this->todoModel->insert($data);
|
||||
|
||||
// Link category if provided
|
||||
if (!empty($json['category_id'])) {
|
||||
$this->linkCategory($data['id'], $json['category_id']);
|
||||
}
|
||||
|
||||
// Manually log the activity
|
||||
try {
|
||||
$activityLogModel = new \App\Models\ActivityLogModel();
|
||||
@@ -79,9 +84,9 @@ class TodoController extends BaseController
|
||||
log_message('error', 'Failed to log activity: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
$todo = $this->todoModel->getByUserWithCategories($userId, $data['id']);
|
||||
$todos = $this->todoModel->getByUserWithCategories($userId, $data['id']);
|
||||
|
||||
return $this->successResponse($todo, 'Todo created successfully', 201);
|
||||
return $this->successResponse($todos[0] ?? null, 'Todo created successfully', 201);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,13 +96,13 @@ class TodoController extends BaseController
|
||||
public function show($id = null)
|
||||
{
|
||||
$userId = $this->getUserId();
|
||||
$todo = $this->todoModel->getByUserWithCategories($userId, $id);
|
||||
$todos = $this->todoModel->getByUserWithCategories($userId, $id);
|
||||
|
||||
if (!$todo) {
|
||||
if (empty($todos)) {
|
||||
return $this->errorResponse('Todo not found', 404);
|
||||
}
|
||||
|
||||
return $this->successResponse($todo, 'Todo retrieved successfully');
|
||||
return $this->successResponse($todos[0], 'Todo retrieved successfully');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,14 +119,26 @@ class TodoController extends BaseController
|
||||
}
|
||||
|
||||
$json = $this->request->getJSON(true);
|
||||
|
||||
// Handle category update separately (not a column in todos table)
|
||||
$hasCategoryUpdate = array_key_exists('category_id', $json);
|
||||
if ($hasCategoryUpdate) {
|
||||
$categoryId = $json['category_id'];
|
||||
// Remove all existing category links
|
||||
$this->todoCategoryModel->where('todo_id', $id)->delete();
|
||||
// Link the new category
|
||||
if (!empty($categoryId)) {
|
||||
$this->linkCategory($id, $categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
// Update todo fields
|
||||
$allowedFields = ['title', 'description', 'status', 'due_date', 'due_time', 'sync_enabled', 'reminder_enabled', 'recurring_enabled', 'project_id'];
|
||||
$updateData = array_intersect_key($json, array_flip($allowedFields));
|
||||
|
||||
if (empty($updateData)) {
|
||||
return $this->errorResponse('No valid fields to update');
|
||||
if (!empty($updateData)) {
|
||||
$this->todoModel->update($id, $updateData);
|
||||
}
|
||||
|
||||
$this->todoModel->update($id, $updateData);
|
||||
|
||||
// Manually log the activity
|
||||
try {
|
||||
@@ -139,9 +156,9 @@ class TodoController extends BaseController
|
||||
log_message('error', 'Failed to log activity: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
$todo = $this->todoModel->getByUserWithCategories($userId, $id);
|
||||
$updated = $this->todoModel->getByUserWithCategories($userId, $id);
|
||||
|
||||
return $this->successResponse($todo, 'Todo updated successfully');
|
||||
return $this->successResponse($updated[0] ?? null, 'Todo updated successfully');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,6 +255,34 @@ class TodoController extends BaseController
|
||||
return $this->successResponse(null, 'Category removed from todo successfully');
|
||||
}
|
||||
|
||||
/**
|
||||
* Link a category to a todo
|
||||
*/
|
||||
private function linkCategory(string $todoId, string $categoryId): void
|
||||
{
|
||||
$userId = $this->getUserId();
|
||||
|
||||
// Verify category belongs to user
|
||||
$categoryModel = new \App\Models\CategoryModel();
|
||||
$category = $categoryModel->where('id', $categoryId)->where('user_id', $userId)->first();
|
||||
if (!$category) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if link already exists
|
||||
$existing = $this->todoCategoryModel
|
||||
->where('todo_id', $todoId)
|
||||
->where('category_id', $categoryId)
|
||||
->first();
|
||||
|
||||
if (!$existing) {
|
||||
$this->todoCategoryModel->insert([
|
||||
'todo_id' => $todoId,
|
||||
'category_id' => $categoryId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function generateUuid(): string
|
||||
{
|
||||
return sprintf(
|
||||
|
||||
@@ -52,15 +52,23 @@ class TodoModel extends Model
|
||||
return $builder->get()->getResultArray();
|
||||
}
|
||||
|
||||
// Get todos by user with categories
|
||||
public function getByUserWithCategories($userId)
|
||||
// Get todos by user with categories (optionally filtered by todo id)
|
||||
public function getByUserWithCategories($userId, $todoId = null)
|
||||
{
|
||||
return $this->select('todos.*, GROUP_CONCAT(categories.name) as category_names')
|
||||
->join('todo_categories', 'todos.id = todo_categories.todo_id', 'left')
|
||||
->join('categories', 'todo_categories.category_id = categories.id', 'left')
|
||||
->where('todos.user_id', $userId)
|
||||
->groupBy('todos.id')
|
||||
->get()
|
||||
->getResultArray();
|
||||
$builder = $this->select('
|
||||
todos.*,
|
||||
GROUP_CONCAT(DISTINCT categories.id SEPARATOR \',\') as category_ids,
|
||||
GROUP_CONCAT(DISTINCT categories.name SEPARATOR \', \') as category_names
|
||||
')
|
||||
->join('todo_categories', 'todos.id = todo_categories.todo_id', 'left')
|
||||
->join('categories', 'todo_categories.category_id = categories.id', 'left')
|
||||
->where('todos.user_id', $userId)
|
||||
->groupBy('todos.id');
|
||||
|
||||
if ($todoId) {
|
||||
$builder->where('todos.id', $todoId);
|
||||
}
|
||||
|
||||
return $builder->get()->getResultArray();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user