░▒▓████████████████████████████████▓▒░ ░▒▓█ ▓▒░ ░▒▓█ ~ S W A M P ~ ▓▒░ ░▒▓█ ▓▒░ ░▒▓████████████████████████████████▓▒░
lon105.truehost.cloud
LOCATION:
/home/ilrtztmy/floraandcreations.com/api/Controllers/AccountApi
☗ ROOT
↻ REFRESH
✎ CARVE FLESH
EDITING: AccountController.php
<?php /** * Flora and Creations — Customer Account Controller * * All routes require authentication (customer or higher role). */ namespace App\Controllers\AccountApi; use App\Database; use App\Utils\Response; use App\Utils\Request; use App\Utils\Validator; class AccountController { /** * GET /api/account/orders * List orders for the authenticated user. */ public function orders(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $query = Request::query(); $sql = "SELECT o.* FROM orders o WHERE o.user_id = :uid OR o.customer_email = :email ORDER BY o.created_at DESC"; $bindings = [':uid' => $authUser['id'], ':email' => $authUser['email']]; // Optional status filter if (!empty($query['status'])) { $sql .= " AND o.order_status = :status"; $bindings[':status'] = $query['status']; } // Pagination $page = max(1, (int) ($query['page'] ?? 1)); $perPage = min(50, max(1, (int) ($query['per_page'] ?? 20))); $offset = ($page - 1) * $perPage; $countSql = "SELECT COUNT(*) as total FROM ($sql) as count_query"; $countStmt = $db->prepare($countSql); $countStmt->execute($bindings); $total = $countStmt->fetch()['total']; $sql .= " LIMIT :offset, :per_page"; $bindings[':offset'] = $offset; $bindings[':per_page'] = $perPage; $stmt = $db->prepare($sql); $stmt->execute($bindings); $orders = $stmt->fetchAll(); // Attach item count to each order foreach ($orders as &$order) { $ic = $db->prepare("SELECT COUNT(*) as cnt FROM order_items WHERE order_id = :oid"); $ic->execute([':oid' => $order['id']]); $order['item_count'] = $ic->fetchColumn(); } Response::paginated($orders, (int) $total, $page, $perPage); } /** * GET /api/account/orders/:id * Detailed view of a specific order. */ public function orderDetail(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $orderId = (int) $params['id']; $stmt = $db->prepare("SELECT * FROM orders WHERE id = :id AND (user_id = :uid OR customer_email = :email)"); $stmt->execute([':id' => $orderId, ':uid' => $authUser['id'], ':email' => $authUser['email']]); $order = $stmt->fetch(); if (!$order) { Response::notFound('Order not found.'); } // Order items $itemStmt = $db->prepare("SELECT oi.*, p.name as product_name, p.slug as product_slug, p.base_price FROM order_items oi JOIN products p ON p.id = oi.product_id WHERE oi.order_id = :oid"); $itemStmt->execute([':oid' => $order['id']]); $items = $itemStmt->fetchAll(); foreach ($items as &$item) { if ($item['variant_id']) { $vs = $db->prepare("SELECT id, size, color, sku, stock_status FROM product_variants WHERE id = :id"); $vs->execute([':id' => $item['variant_id']]); $item['variant'] = $vs->fetch(); } $as = $db->prepare("SELECT oia.*, a.name as add_on_name FROM order_item_addons oia JOIN add_ons a ON a.id = oia.add_on_id WHERE oia.order_item_id = :oiid"); $as->execute([':oiid' => $item['id']]); $item['add_ons'] = $as->fetchAll(); } // Payment proofs $ppStmt = $db->prepare("SELECT * FROM payment_proofs WHERE order_id = :oid ORDER BY submitted_at DESC"); $ppStmt->execute([':oid' => $order['id']]); $order['items'] = $items; $order['payment_proofs'] = $ppStmt->fetchAll(); Response::ok($order); } // ─── Addresses ────────────────────────────────────────────── /** * GET /api/account/addresses */ public function addresses(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $stmt = $db->prepare("SELECT * FROM addresses WHERE user_id = :uid ORDER BY id DESC"); $stmt->execute([':uid' => $authUser['id']]); $addresses = $stmt->fetchAll(); Response::ok($addresses); } /** * POST /api/account/addresses * Add a new address. */ public function storeAddress(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $body = Request::body(); $errors = Validator::make($body, [ 'label' => 'required', 'recipient_name' => 'required', 'recipient_phone' => 'required', 'area' => 'required', 'street_address' => 'required', ]); if ($errors) { Response::validationError($errors); } // Verify area exists in delivery zones $dz = $db->prepare("SELECT id FROM delivery_zones WHERE area_name = :area LIMIT 1"); $dz->execute([':area' => $body['area']]); if (!$dz->fetch()) { Response::validationError(['area' => 'Area must match one of our delivery zones.']); } $stmt = $db->prepare("INSERT INTO addresses (user_id, label, recipient_name, recipient_phone, area, street_address, landmark) VALUES (:uid, :label, :rname, :rphone, :area, :street, :landmark)"); $stmt->execute([ ':uid' => $authUser['id'], ':label' => $body['label'], ':rname' => $body['recipient_name'], ':rphone' => $body['recipient_phone'], ':area' => $body['area'], ':street' => $body['street_address'], ':landmark' => $body['landmark'] ?? null, ]); $addressId = $db->lastInsertId(); $stmt = $db->prepare("SELECT * FROM addresses WHERE id = :id"); $stmt->execute([':id' => $addressId]); Response::created($stmt->fetch()); } /** * PUT /api/account/addresses/:id */ public function updateAddress(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $addressId = (int) $params['id']; $body = Request::body(); // Verify ownership $stmt = $db->prepare("SELECT id FROM addresses WHERE id = :id AND user_id = :uid"); $stmt->execute([':id' => $addressId, ':uid' => $authUser['id']]); if (!$stmt->fetch()) { Response::notFound('Address not found.'); } $updates = []; $bindings = [':id' => $addressId, ':uid' => $authUser['id']]; if (isset($body['label'])) $updates['label'] = 'label'; if (isset($body['recipient_name'])) $updates['recipient_name'] = 'rname'; if (isset($body['recipient_phone'])) $updates['recipient_phone'] = 'rphone'; if (isset($body['area'])) { // Verify area $dz = $db->prepare("SELECT id FROM delivery_zones WHERE area_name = :area LIMIT 1"); $dz->execute([':area' => $body['area']]); if (!$dz->fetch()) { Response::validationError(['area' => 'Area must match one of our delivery zones.']); } $updates['area'] = 'area'; } if (isset($body['street_address'])) $updates['street_address'] = 'street'; if (isset($body['landmark'])) $updates['landmark'] = 'landmark'; if (empty($updates)) { Response::badRequest('No fields to update.'); } $setClause = implode(', ', array_map(fn($col, $param) => "$col = :$param", array_keys($updates), array_values($updates))); $sql = "UPDATE addresses SET $setClause WHERE id = :id AND user_id = :uid"; foreach ($updates as $col => $param) { $bindings[":$param"] = $body[array_search($param, $updates)]; } $stmt = $db->prepare($sql); $stmt->execute($bindings); $stmt = $db->prepare("SELECT * FROM addresses WHERE id = :id AND user_id = :uid"); $stmt->execute([':id' => $addressId, ':uid' => $authUser['id']]); Response::ok($stmt->fetch()); } /** * DELETE /api/account/addresses/:id */ public function deleteAddress(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $addressId = (int) $params['id']; $stmt = $db->prepare("DELETE FROM addresses WHERE id = :id AND user_id = :uid"); $stmt->execute([':id' => $addressId, ':uid' => $authUser['id']]); if ($stmt->rowCount() === 0) { Response::notFound('Address not found.'); } Response::noContent(); } // ─── Wishlist ─────────────────────────────────────────────── /** * GET /api/account/wishlist */ public function wishlist(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $stmt = $db->prepare("SELECT p.id, p.name, p.slug, p.base_price, p.featured, p.status FROM wishlists w JOIN products p ON p.id = w.product_id WHERE w.user_id = :uid ORDER BY w.product_id DESC"); $stmt->execute([':uid' => $authUser['id']]); $items = $stmt->fetchAll(); Response::ok($items); } /** * POST /api/account/wishlist/:productId */ public function addToWishlist(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $productId = (int) $params['productId']; // Verify product exists $stmt = $db->prepare("SELECT id FROM products WHERE id = :id"); $stmt->execute([':id' => $productId]); if (!$stmt->fetch()) { Response::notFound('Product not found.'); } $stmt = $db->prepare("INSERT IGNORE INTO wishlists (user_id, product_id) VALUES (:uid, :pid)"); $stmt->execute([':uid' => $authUser['id'], ':pid' => $productId]); Response::ok(['message' => 'Added to wishlist.', 'product_id' => $productId]); } /** * DELETE /api/account/wishlist/:productId */ public function removeFromWishlist(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $productId = (int) $params['productId']; $stmt = $db->prepare("DELETE FROM wishlists WHERE user_id = :uid AND product_id = :pid"); $stmt->execute([':uid' => $authUser['id'], ':pid' => $productId]); if ($stmt->rowCount() === 0) { Response::notFound('Item not found in wishlist.'); } Response::noContent(); } // ─── Profile ──────────────────────────────────────────────── /** * PUT /api/account/profile */ public function updateProfile(array $params): void { $db = Database::getConnection(); $authUser = $_SERVER['AUTH_USER']; $body = Request::body(); $updates = []; $bindings = [':id' => $authUser['id']]; if (isset($body['name'])) { $updates['name'] = 'name'; $bindings[':name'] = trim($body['name']); } if (isset($body['email'])) { // Check uniqueness if changing $stmt = $db->prepare("SELECT id FROM users WHERE email = :email AND id != :uid"); $stmt->execute([':email' => strtolower($body['email']), ':uid' => $authUser['id']]); if ($stmt->fetch()) { Response::validationError(['email' => 'Email already in use.']); } $updates['email'] = 'email'; $bindings[':email'] = strtolower($body['email']); } if (isset($body['phone'])) { $updates['phone'] = 'phone'; $bindings[':phone'] = trim($body['phone']); } if (isset($body['password'])) { $updates['password_hash'] = 'hash'; $bindings[':hash'] = password_hash($body['password'], PASSWORD_BCRYPT); } if (empty($updates)) { Response::badRequest('No fields to update.'); } $setClause = implode(', ', array_map(fn($col, $param) => "$col = :$param", array_keys($updates), array_values($updates))); $sql = "UPDATE users SET $setClause, updated_at = NOW() WHERE id = :id"; $stmt = $db->prepare($sql); $stmt->execute($bindings); // Refresh token claims $stmt = $db->prepare("SELECT id, name, email, phone, role FROM users WHERE id = :id"); $stmt->execute([':id' => $authUser['id']]); $user = $stmt->fetch(); $cfg = require __DIR__ . '/../../../config/config.php'; Response::ok([ 'user' => $user, 'message' => 'Profile updated successfully.', ]); } }
CANCEL
Name
Type
Size
Modified
Actions
↩ ..
DIR
—
—
📄 AccountController.php
PHP
13 KB
2026-07-15 09:17
EDIT