source = new Source($pdo); $this->syncLog = new SyncLog($pdo); } // List all sources public function index(Request $request, Response $response, array $args): Response { $sources = $this->source->all(); return $this->render($response, 'admin/sources.twig', [ 'sources' => $sources, 'current_route' => 'sources' ]); } // Show create form public function create(Request $request, Response $response, array $args): Response { return $this->render($response, 'admin/sources/create.twig', [ 'current_route' => 'sources' ]); } // Store new source public function store(Request $request, Response $response, array $args): Response { $data = $request->getParsedBody(); // Basic validation if (empty($data['name']) || empty($data['type']) || empty($data['path'])) { $this->flash->addMessage('error', 'Name, type, and path are required'); return $response->withHeader('Location', '/admin/sources/create')->withStatus(302); } try { $sourceData = [ 'name' => $data['name'], 'type' => $data['type'], 'path' => $data['path'], 'username' => $data['username'] ?? null, 'password' => !empty($data['password']) ? password_hash($data['password'], PASSWORD_DEFAULT) : null, 'is_active' => isset($data['is_active']) ? 1 : 0, 'created_at' => date('Y-m-d H:i:s'), 'updated_at' => date('Y-m-d H:i:s') ]; $this->source->create($sourceData); $this->flash->addMessage('success', 'Source created successfully'); return $response->withHeader('Location', '/admin/sources')->withStatus(302); } catch (\Exception $e) { $this->flash->addMessage('error', 'Error creating source: ' . $e->getMessage()); return $response->withHeader('Location', '/admin/sources/create')->withStatus(302); } } // Show edit form public function edit(Request $request, Response $response, array $args): Response { $id = $args['id']; $source = $this->source->find($id); if (!$source) { $this->flash->addMessage('error', 'Source not found'); return $response->withHeader('Location', '/admin/sources')->withStatus(302); } return $this->render($response, 'admin/sources/edit.twig', [ 'source' => $source, 'current_route' => 'sources' ]); } // Update source public function update(Request $request, Response $response, array $args): Response { $id = $args['id']; $data = $request->getParsedBody(); try { $sourceData = [ 'name' => $data['name'], 'type' => $data['type'], 'path' => $data['path'], 'username' => $data['username'] ?? null, 'is_active' => isset($data['is_active']) ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s') ]; // Only update password if provided if (!empty($data['password'])) { $sourceData['password'] = password_hash($data['password'], PASSWORD_DEFAULT); } $this->source->update($id, $sourceData); $this->flash->addMessage('success', 'Source updated successfully'); return $response->withHeader('Location', '/admin/sources')->withStatus(302); } catch (\Exception $e) { $this->flash->addMessage('error', 'Error updating source: ' . $e->getMessage()); return $response->withHeader('Location', '/admin/sources/' . $id . '/edit')->withStatus(302); } } // Delete source public function destroy(Request $request, Response $response, array $args): Response { $id = $args['id']; try { $this->source->delete($id); $this->flash->addMessage('success', 'Source deleted successfully'); } catch (\Exception $e) { $this->flash->addMessage('error', 'Error deleting source: ' . $e->getMessage()); } return $response->withHeader('Location', '/admin/sources')->withStatus(302); } // Start sync for a source public function startSync(Request $request, Response $response, array $args): Response { $sourceId = $args['id']; $source = $this->source->find($sourceId); if (!$source) { return $this->json($response, [ 'success' => false, 'message' => 'Source not found' ], 404); } try { // Create a sync log entry $logId = $this->syncLog->create([ 'source_id' => $sourceId, 'type' => 'full', 'status' => 'pending', 'started_at' => date('Y-m-d H:i:s'), 'created_at' => date('Y-m-d H:i:s') ]); // Start sync in background (you'll need to implement this) $this->startBackgroundSync($sourceId, $logId); return $this->json($response, [ 'success' => true, 'message' => 'Sync started', 'log_id' => $logId ]); } catch (\Exception $e) { return $this->json($response, [ 'success' => false, 'message' => 'Error starting sync: ' . $e->getMessage() ], 500); } } // Get sync status public function syncStatus(Request $request, Response $response, array $args): Response { $logId = $args['log_id'] ?? null; if (!$logId) { return $this->json($response, [ 'success' => false, 'message' => 'Log ID is required' ], 400); } $log = $this->syncLog->find($logId); if (!$log) { return $this->json($response, [ 'success' => false, 'message' => 'Sync log not found' ], 404); } return $this->json($response, [ 'success' => true, 'status' => $log['status'], 'progress' => $log['progress'] ?? 0, 'message' => $log['message'] ?? '' ]); } // Start background sync process private function startBackgroundSync($sourceId, $logId) { // This is a simplified example - you'll need to implement this based on your needs $command = sprintf( 'php %s/console.php sync:source %d --log=%d > /dev/null 2>&1 &', dirname(__DIR__, 3), $sourceId, $logId ); exec($command); } }