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);
|
$this->todoModel->insert($data);
|
||||||
|
|
||||||
|
// Link category if provided
|
||||||
|
if (!empty($json['category_id'])) {
|
||||||
|
$this->linkCategory($data['id'], $json['category_id']);
|
||||||
|
}
|
||||||
|
|
||||||
// Manually log the activity
|
// Manually log the activity
|
||||||
try {
|
try {
|
||||||
$activityLogModel = new \App\Models\ActivityLogModel();
|
$activityLogModel = new \App\Models\ActivityLogModel();
|
||||||
@@ -79,9 +84,9 @@ class TodoController extends BaseController
|
|||||||
log_message('error', 'Failed to log activity: ' . $e->getMessage());
|
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)
|
public function show($id = null)
|
||||||
{
|
{
|
||||||
$userId = $this->getUserId();
|
$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->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);
|
$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'];
|
$allowedFields = ['title', 'description', 'status', 'due_date', 'due_time', 'sync_enabled', 'reminder_enabled', 'recurring_enabled', 'project_id'];
|
||||||
$updateData = array_intersect_key($json, array_flip($allowedFields));
|
$updateData = array_intersect_key($json, array_flip($allowedFields));
|
||||||
|
|
||||||
if (empty($updateData)) {
|
if (!empty($updateData)) {
|
||||||
return $this->errorResponse('No valid fields to update');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->todoModel->update($id, $updateData);
|
$this->todoModel->update($id, $updateData);
|
||||||
|
}
|
||||||
|
|
||||||
// Manually log the activity
|
// Manually log the activity
|
||||||
try {
|
try {
|
||||||
@@ -139,9 +156,9 @@ class TodoController extends BaseController
|
|||||||
log_message('error', 'Failed to log activity: ' . $e->getMessage());
|
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');
|
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
|
private function generateUuid(): string
|
||||||
{
|
{
|
||||||
return sprintf(
|
return sprintf(
|
||||||
|
|||||||
@@ -52,15 +52,23 @@ class TodoModel extends Model
|
|||||||
return $builder->get()->getResultArray();
|
return $builder->get()->getResultArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get todos by user with categories
|
// Get todos by user with categories (optionally filtered by todo id)
|
||||||
public function getByUserWithCategories($userId)
|
public function getByUserWithCategories($userId, $todoId = null)
|
||||||
{
|
{
|
||||||
return $this->select('todos.*, GROUP_CONCAT(categories.name) as category_names')
|
$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('todo_categories', 'todos.id = todo_categories.todo_id', 'left')
|
||||||
->join('categories', 'todo_categories.category_id = categories.id', 'left')
|
->join('categories', 'todo_categories.category_id = categories.id', 'left')
|
||||||
->where('todos.user_id', $userId)
|
->where('todos.user_id', $userId)
|
||||||
->groupBy('todos.id')
|
->groupBy('todos.id');
|
||||||
->get()
|
|
||||||
->getResultArray();
|
if ($todoId) {
|
||||||
|
$builder->where('todos.id', $todoId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $builder->get()->getResultArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user