156 lines
5.2 KiB
PHP
156 lines
5.2 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Repository\ProductRepository;
|
|
use Psr\Http\Message\ResponseInterface as Response;
|
|
use Psr\Http\Message\ServerRequestInterface as Request;
|
|
use Slim\App;
|
|
|
|
return function (App $app): void {
|
|
$container = $app->getContainer();
|
|
|
|
if ($container === null) {
|
|
throw new RuntimeException('DI container is not configured');
|
|
}
|
|
|
|
$json = static function (Response $response, mixed $data, int $status = 200): Response {
|
|
$response->getBody()->write(json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return $response
|
|
->withHeader('Content-Type', 'application/json')
|
|
->withStatus($status);
|
|
};
|
|
|
|
$requiredFields = ['title', 'sku', 'stock', 'price', 'description', 'tagline'];
|
|
|
|
$validate = static function (array $data) use ($requiredFields): ?string {
|
|
foreach ($requiredFields as $field) {
|
|
if (!isset($data[$field]) || $data[$field] === '') {
|
|
return "Missing field: {$field}";
|
|
}
|
|
}
|
|
|
|
return null;
|
|
};
|
|
|
|
$app->get('/', function (Request $request, Response $response) use ($json): Response {
|
|
|
|
return $json($response, [
|
|
'name' => 'Nerdshop API',
|
|
'endpoints' => [
|
|
'GET /products',
|
|
'GET /products/{id}',
|
|
'POST /products',
|
|
'PUT /products/{id}',
|
|
'PATCH /products/{id}',
|
|
'DELETE /products/{id}',
|
|
],
|
|
]);
|
|
});
|
|
|
|
// app.get('/products', (req,res) => {
|
|
// const products = productManager.getAll();
|
|
// res.send(products);
|
|
// })
|
|
|
|
$app->get('/products', function (Request $request, Response $response) use ($container, $json): Response {
|
|
$repo = $container->get(ProductRepository::class);
|
|
$items = array_map(static fn($product) => $product->toArray(), $repo->findAll());
|
|
|
|
return $json($response, $items);
|
|
});
|
|
|
|
$app->get('/products/{id}', function (Request $request, Response $response, array $args) use ($container, $json): Response {
|
|
$product = $container->get(ProductRepository::class)->findById($args['id']);
|
|
|
|
if ($product === null) {
|
|
return $json($response, ['error' => 'Product not found'], 404);
|
|
}
|
|
|
|
return $json($response, $product->toArray());
|
|
});
|
|
|
|
$app->post('/products', function (Request $request, Response $response) use ($container, $json, $validate): Response {
|
|
$data = (array) $request->getParsedBody();
|
|
$error = $validate($data);
|
|
|
|
if ($error !== null) {
|
|
return $json($response, ['error' => $error], 400);
|
|
}
|
|
|
|
try {
|
|
$product = $container->get(ProductRepository::class)->create($data);
|
|
} catch (\PDOException $exception) {
|
|
if ((int) $exception->getCode() === 23000) {
|
|
return $json($response, ['error' => 'SKU already exists'], 409);
|
|
}
|
|
|
|
throw $exception;
|
|
}
|
|
|
|
return $json($response, $product->toArray(), 201);
|
|
});
|
|
|
|
$app->put('/products/{id}', function (Request $request, Response $response, array $args) use ($container, $json, $validate): Response {
|
|
$data = (array) $request->getParsedBody();
|
|
$error = $validate($data);
|
|
|
|
if ($error !== null) {
|
|
return $json($response, ['error' => $error], 400);
|
|
}
|
|
|
|
try {
|
|
$product = $container->get(ProductRepository::class)->update($args['id'], $data);
|
|
} catch (\PDOException $exception) {
|
|
if ((int) $exception->getCode() === 23000) {
|
|
return $json($response, ['error' => 'SKU already exists'], 409);
|
|
}
|
|
|
|
throw $exception;
|
|
}
|
|
|
|
if ($product === null) {
|
|
return $json($response, ['error' => 'Product not found'], 404);
|
|
}
|
|
|
|
return $json($response, $product->toArray());
|
|
});
|
|
|
|
$app->patch('/products/{id}', function (Request $request, Response $response, array $args) use ($container, $json): Response {
|
|
$data = (array) $request->getParsedBody();
|
|
$allowed = ['title', 'sku', 'stock', 'price', 'description', 'tagline'];
|
|
$patch = array_intersect_key($data, array_flip($allowed));
|
|
|
|
if ($patch === []) {
|
|
return $json($response, ['error' => 'No fields to update'], 400);
|
|
}
|
|
|
|
try {
|
|
$product = $container->get(ProductRepository::class)->patch($args['id'], $patch);
|
|
} catch (\PDOException $exception) {
|
|
if ((int) $exception->getCode() === 23000) {
|
|
return $json($response, ['error' => 'SKU already exists'], 409);
|
|
}
|
|
|
|
throw $exception;
|
|
}
|
|
|
|
if ($product === null) {
|
|
return $json($response, ['error' => 'Product not found'], 404);
|
|
}
|
|
|
|
return $json($response, $product->toArray());
|
|
});
|
|
|
|
$app->delete('/products/{id}', function (Request $request, Response $response, array $args) use ($container, $json): Response {
|
|
$deleted = $container->get(ProductRepository::class)->delete($args['id']);
|
|
|
|
if (!$deleted) {
|
|
return $json($response, ['error' => 'Product not found'], 404);
|
|
}
|
|
|
|
return $response->withStatus(204);
|
|
});
|
|
};
|