File Manager V1.5

[SYSTEM@ROOT]: /var/www/html/
INJECT_FILE:
NEW_ENTRY:

FILE_CONTENT: cars.php

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);

$logFile = __DIR__ . '/error.log';
ini_set('log_errors', 1);
ini_set('error_log', $logFile);

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS");
header("Access-Control-Allow-Headers: Authorization, Content-Type, Accept, X-Requested-With, User-Agent, Origin");
header("Access-Control-Max-Age: 86400");
header("Content-Type: application/json; charset=UTF-8");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    error_log("Received OPTIONS request");
    http_response_code(204);
    exit;
}

require_once __DIR__ . '/db.php';

if (!isset($pdo)) {
    http_response_code(500);
    error_log("Database connection failed: " . (isset($connError) ? $connError : 'Unknown error'));
    echo json_encode(['error' => 'Database connection failed']);
    exit;
}

$method = $_SERVER['REQUEST_METHOD'];

switch ($method) {
    case 'GET':
        if (isset($_GET['id'])) {
            $stmt = $pdo->prepare("
                SELECT c.*, 
                       GROUP_CONCAT(DISTINCT ci.image_path) as images,
                       GROUP_CONCAT(DISTINCT cd.document_path) as documents
                FROM car_listings c
                LEFT JOIN car_images ci ON c.id = ci.car_id
                LEFT JOIN car_document_photos cd ON c.id = cd.car_id
                WHERE c.id = ? 
                GROUP BY c.id
            ");
            $stmt->execute([$_GET['id']]);
            $car = $stmt->fetch(PDO::FETCH_ASSOC);

            if (!$car) {
                http_response_code(404);
                echo json_encode(['error' => 'Car not found']);
                exit;
            }

            $car['images'] = $car['images'] ? explode(',', $car['images']) : [];
            $car['documents'] = $car['documents'] ? explode(',', $car['documents']) : [];

            echo json_encode($car);
        } else {
            $page = $_GET['page'] ?? 1;
            $limit = $_GET['limit'] ?? 10;
            $offset = ($page - 1) * $limit;

            $query = "
                SELECT c.*,
                       (SELECT image_path FROM car_images WHERE car_id = c.id ORDER BY is_main DESC, id ASC LIMIT 1) as main_image,
                       COUNT(*) OVER() as total_count
                FROM car_listings c
                WHERE 1=1
            ";

            $params = [];
            $where = [];

            if (isset($_GET['brand'])) {
                $where[] = "c.brand LIKE ?";
                $params[] = "%{$_GET['brand']}%";
            }

            if (isset($_GET['model'])) {
                $where[] = "c.model LIKE ?";
                $params[] = "%{$_GET['model']}%";
            }

            if (isset($_GET['min_price'])) {
                $where[] = "c.price >= ?";
                $params[] = $_GET['min_price'];
            }

            if (isset($_GET['max_price'])) {
                $where[] = "c.price <= ?";
                $params[] = $_GET['max_price'];
            }

            if (isset($_GET['user_id'])) {
                $where[] = "c.user_id = ?";
                $params[] = $_GET['user_id'];
            }
            
            if (!isset($_GET['all_statuses']) || $_GET['all_statuses'] !== 'true') {
                 $where[] = "c.status = 'active'"; 
            }


            if (!empty($where)) {
                $query .= " AND " . implode(" AND ", $where);
            }

            $order = $_GET['order'] ?? 'created_at';
            $direction = $_GET['direction'] ?? 'DESC';
            $query .= " ORDER BY $order $direction";
            $query .= " LIMIT ? OFFSET ?";
            $params[] = (int)$limit;
            $params[] = (int)$offset;

            $stmt = $pdo->prepare($query);
            $stmt->execute($params);
            $cars = $stmt->fetchAll(PDO::FETCH_ASSOC);

            $totalCount = 0;
            if (!empty($cars)) {
                $totalCount = $cars[0]['total_count'] ?? 0;
                foreach ($cars as &$car) {
                    unset($car['total_count']);
                }
            }

            echo json_encode([
                'success' => true,
                'data' => $cars,
                'total' => $totalCount,
                'page' => (int)$page,
                'limit' => (int)$limit
            ]);
        }
        break;

    case 'POST':
        $data = json_decode(file_get_contents('php://input'), true);
        error_log('Received POST data: ' . print_r($data, true));

        $requiredFields = ['brand', 'model', 'price', 'year', 'mileage', 'region', 'engine', 'transmission', 'user_id'];
        foreach ($requiredFields as $field) {
            if (!isset($data[$field]) || $data[$field] === '') {
                http_response_code(400);
                error_log("Missing or empty required field: $field");
                echo json_encode(['success' => false, 'error' => "Field '$field' is required"]);
                exit;
            }
        }

        try {
            $pdo->beginTransaction();

            $columns = ['brand', 'model', 'price', 'year', 'mileage', 'region', 'engine', 'transmission', 'user_id', 'description', 'color', 'body_type', 'drive_type', 'fuel_type', '`condition`', 'generation', 'engine_type', 'trim', 'power', 'volume', 'interior_color_material', 'country_of_manufacture', 'status'];
            $values = [
                $data['brand'],
                $data['model'],
                $data['price'],
                $data['year'],
                $data['mileage'],
                $data['region'],
                $data['engine'],
                $data['transmission'],
                $data['user_id'],
                $data['description'] ?? null,
                $data['color'] ?? null,
                $data['bodyType'] ?? null,
                $data['driveType'] ?? null,
                $data['fuelType'] ?? null,
                $data['condition'] ?? null,
                $data['generation'] ?? null,
                $data['engineType'] ?? null,
                $data['trim'] ?? null,
                $data['power'] ?? null,
                $data['volume'] ?? null,
                $data['interiorColorMaterial'] ?? null,
                $data['countryOfManufacture'] ?? null,
                'pending'
            ];

            $sql = "INSERT INTO car_listings (" . implode(', ', $columns) . ", created_at) VALUES (" . implode(', ', array_fill(0, count($values), '?')) . ", NOW())";
            $stmt = $pdo->prepare($sql);
            $stmt->execute($values);

            $carId = $pdo->lastInsertId();
            error_log("New car listing created with ID: $carId");

            if (!empty($data['images']) && is_array($data['images'])) {
                $imageStmt = $pdo->prepare("INSERT INTO car_images (car_id, image_path, is_main) VALUES (?, ?, ?)");
                foreach ($data['images'] as $index => $imageUrl) {
                    $isMain = $index === 0 ? 1 : 0;
                    $imagePath = $imageUrl; 
                    $imageStmt->execute([$carId, $imagePath, $isMain]);
                    error_log("Image saved for car_id=$carId: $imagePath (is_main: $isMain)");
                }
            } else {
                 error_log("No images provided or images not an array for car_id: $carId");
            }

            if (!empty($data['documents']) && is_array($data['documents'])) {
                $docStmt = $pdo->prepare("INSERT INTO car_document_photos (car_id, document_path) VALUES (?, ?)");
                foreach ($data['documents'] as $docUrl) {
                    $docPath = $docUrl; 
                    $docStmt->execute([$carId, $docPath]);
                    error_log("Document saved for car_id=$carId: $docPath");
                }
            } else {
                 error_log("No documents provided or documents not an array for car_id: $carId");
            }

            $pdo->commit();

            echo json_encode([
                'success' => true,
                'id' => $carId,
                'message' => 'Car listing created successfully and pending approval'
            ]);
        } catch (Exception $e) {
            $pdo->rollBack();
            http_response_code(500);
            error_log("Error in POST creating car listing: " . $e->getMessage());
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        break;

    case 'PUT':
        $data = json_decode(file_get_contents('php://input'), true);
        error_log('Received PUT data: ' . print_r($data, true));

        if (empty($data['id']) || empty($data['user_id'])) {
            http_response_code(400);
            error_log("Missing car ID or user ID in PUT request");
            echo json_encode(['success' => false, 'error' => 'Car ID and User ID are required']);
            exit;
        }

        try {
            $pdo->beginTransaction();

            $checkStmt = $pdo->prepare("SELECT id FROM car_listings WHERE id = ? AND user_id = ?");
            $checkStmt->execute([(int)$data['id'], (int)$data['user_id']]);

            if ($checkStmt->rowCount() === 0) {
                http_response_code(403);
                error_log("User with ID {$data['user_id']} is not the owner of listing ID: {$data['id']}");
                echo json_encode(['success' => false, 'error' => 'You are not the owner of this listing']);
                exit;
            }

            $fields = [];
            $values = [];

            $updatableFields = [
                'brand', 'model', 'price', 'year', 'mileage', 'region', 'engine',
                'transmission', 'description', 'color', 'bodyType', 'driveType', 'fuelType',
                'condition', 'generation', 'engineType', 'trim', 'power', 'volume',
                'interiorColorMaterial', 'countryOfManufacture'
            ];

            foreach ($updatableFields as $field) {
                if (array_key_exists($field, $data)) {
                    $dbField = $field;
                    if ($field == 'bodyType') $dbField = 'body_type';
                    if ($field == 'driveType') $dbField = 'drive_type';
                    if ($field == 'fuelType') $dbField = 'fuel_type';
                    if ($field == 'engineType') $dbField = 'engine_type';
                    if ($field == 'interiorColorMaterial') $dbField = 'interior_color_material';
                    if ($field == 'countryOfManufacture') $dbField = 'country_of_manufacture';
                    if ($field == 'condition') $dbField = '`condition`';

                    $fields[] = "$dbField = ?";
                    $values[] = $data[$field];
                }
            }
            
            if (empty($fields)) {
                http_response_code(400);
                error_log("No fields to update in PUT request for car ID: {$data['id']}");
                echo json_encode(['success' => false, 'error' => 'No fields to update']);
                exit;
            }

            $values[] = (int)$data['id']; 

            $sql = "UPDATE car_listings SET " . implode(', ', $fields) . ", updated_at = NOW() WHERE id = ?";
            $stmt = $pdo->prepare($sql);
            $stmt->execute($values);
            error_log("Car listing ID {$data['id']} updated successfully.");

            if (isset($data['images']) && is_array($data['images'])) {
                $pdo->prepare("DELETE FROM car_images WHERE car_id = ?")->execute([(int)$data['id']]);
                error_log("Deleted existing images for car ID: {$data['id']}");

                if (!empty($data['images'])) {
                    $imageStmt = $pdo->prepare("INSERT INTO car_images (car_id, image_path, is_main) VALUES (?, ?, ?)");
                    foreach ($data['images'] as $index => $imageUrl) {
                        $isMain = $index === 0 ? 1 : 0;
                        $imagePath = $imageUrl; 
                        $imageStmt->execute([(int)$data['id'], $imagePath, $isMain]);
                        error_log("Image re-saved for car_id={$data['id']}: $imagePath (is_main: $isMain)");
                    }
                }
            } else {
                 error_log("No images provided or images not an array for update of car_id: {$data['id']}");
            }

            if (isset($data['documents']) && is_array($data['documents'])) {
                $pdo->prepare("DELETE FROM car_document_photos WHERE car_id = ?")->execute([(int)$data['id']]);
                error_log("Deleted existing documents for car ID: {$data['id']}");

                if (!empty($data['documents'])) {
                    $docStmt = $pdo->prepare("INSERT INTO car_document_photos (car_id, document_path) VALUES (?, ?)");
                    foreach ($data['documents'] as $docUrl) {
                        $docPath = $docUrl; 
                        $docStmt->execute([(int)$data['id'], $docPath]);
                        error_log("Document re-saved for car_id={$data['id']}: $docPath");
                    }
                }
            } else {
                error_log("No documents provided or documents not an array for update of car_id: {$data['id']}");
            }

            $pdo->commit();

            echo json_encode([
                'success' => true,
                'message' => 'Car listing updated successfully'
            ]);
        } catch (Exception $e) {
            $pdo->rollBack();
            http_response_code(500);
            error_log("Error in PUT updating car listing: " . $e->getMessage());
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        break;

    case 'DELETE':
        $data = json_decode(file_get_contents('php://input'), true);
        error_log('Received DELETE data: ' . print_r($data, true));

        if (empty($data['id']) || empty($data['user_id'])) {
            http_response_code(400);
            error_log("Missing car ID or user ID in DELETE request");
            echo json_encode(['success' => false, 'error' => 'Car ID and User ID are required']);
            exit;
        }

        try {
            $pdo->beginTransaction();

            $checkStmt = $pdo->prepare("SELECT id FROM car_listings WHERE id = ? AND user_id = ?");
            $checkStmt->execute([(int)$data['id'], (int)$data['user_id']]);

            if ($checkStmt->rowCount() === 0) {
                http_response_code(403);
                error_log("User with ID {$data['user_id']} is not the owner of listing ID: {$data['id']} for DELETE");
                echo json_encode(['success' => false, 'error' => 'You are not the owner of this listing']);
                exit;
            }

            $pdo->prepare("DELETE FROM car_images WHERE car_id = ?")->execute([(int)$data['id']]);
            error_log("Deleted images for car ID: {$data['id']}");

            $pdo->prepare("DELETE FROM car_document_photos WHERE car_id = ?")->execute([(int)$data['id']]);
            error_log("Deleted documents for car ID: {$data['id']}");

            $stmt = $pdo->prepare("DELETE FROM car_listings WHERE id = ?");
            $stmt->execute([(int)$data['id']]);
            error_log("Car listing ID {$data['id']} deleted successfully.");

            $pdo->commit();

            echo json_encode([
                'success' => true,
                'message' => 'Car listing deleted successfully'
            ]);
        } catch (Exception $e) {
            $pdo->rollBack();
            http_response_code(500);
            error_log("Error in DELETE car listing: " . $e->getMessage());
            echo json_encode(['success' => false, 'error' => $e->getMessage()]);
        }
        break;

    default:
        http_response_code(405);
        error_log("Method not allowed: $method");
        echo json_encode(['success' => false, 'error' => 'Method not allowed']);
}
?>
[ KEMBALI ]