feat: add send method

This commit is contained in:
Jamie Barton 2024-10-27 08:54:11 +00:00
parent e4bf36ac07
commit 70b86118c7
5 changed files with 174 additions and 35 deletions

36
examples/send/README.md Normal file
View File

@ -0,0 +1,36 @@
# Send Example
This example demonstrates how to return different types of responses with Dumbo.
## Running the Example
1. Install dependencies:
```bash
composer install
```
2. Start the server:
```bash
composer start
```
3. Access the different routes:
```bash
# Get the SVG
curl -i http://localhost:8000/logo > logo.svg
# Get the JPEG
curl -i http://localhost:8000/image > image.jpeg
# Get the README
curl -i http://localhost:8000/readme
# Get the CSV
curl -i http://localhost:8000/export > users.csv
# Get the XML
curl -i http://localhost:8000/feed
```

View File

@ -0,0 +1,17 @@
{
"require": {
"notrab/dumbo": "@dev"
},
"repositories": [
{
"type": "path",
"url": "../../"
}
],
"scripts": {
"start": [
"Composer\\Config::disableProcessTimeout",
"php -S localhost:8000 -t ."
]
}
}

BIN
examples/send/dumbo.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

81
examples/send/index.php Normal file
View File

@ -0,0 +1,81 @@
<?php
require __DIR__ . "/vendor/autoload.php";
use Dumbo\Dumbo;
$app = new Dumbo();
$app->get("/", function ($c) {
$html = <<<HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Type Examples</title>
</head>
<body>
<h1>File Type Examples</h1>
<ul>
<li><a href="/logo">SVG</a> (image/svg+xml)</li>
<li><a href="/image">Image</a> (image/jpeg)</li>
<li><a href="/readme">README</a> (text/plain)</li>
<li><a href="/export">CSV Export</a> (text/csv)</li>
<li><a href="/feed">XML Feed</a> (application/xml)</li>
</ul>
</body>
</html>
HTML;
return $c->html($html);
});
$app->get("/logo", function ($c) {
$svg = <<<SVG
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="purple" />
</svg>
SVG;
return $c->send($svg, "image/svg+xml");
});
$app->get("/image", function ($c) {
$png = file_get_contents(__DIR__ . "/dumbo.jpeg");
return $c->send($png, "image/jpeg");
});
$app->get("/readme", function ($c) {
$text = file_get_contents(__DIR__ . "/README.md");
return $c->send($text, "text/plain");
});
$app->get("/export", function ($c) {
$csv = "Name,Email,Role\n";
$csv .= "John Doe,john@example.com,Admin\n";
$csv .= "Jane Smith,jane@example.com,User\n";
return $c->send($csv, "text/csv", 200, [
"Content-Disposition" => 'attachment; filename="users.csv"',
]);
});
$app->get("/feed", function ($c) {
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>My Feed</title>
<description>Latest updates</description>
<item>
<title>New Feature</title>
<description>Check out our latest feature!</description>
</item>
</channel>
</rss>
XML;
return $c->send($xml, "application/xml");
});
$app->run();

View File

@ -74,7 +74,7 @@ class Context
/**
* Send a JSON response
*
* @param mixed $data The data to be JSON encoded (optional)
* @param mixed $data The data to be JSON encoded
* @param int $status The HTTP status code
* @param array $headers Additional headers
* @return ResponseInterface The response object
@ -84,18 +84,7 @@ class Context
int $status = 200,
array $headers = []
): ResponseInterface {
$this->response = $this->response
->withStatus($status)
->withHeader("Content-Type", "application/json");
foreach ($headers as $name => $value) {
$this->response = $this->response->withHeader($name, $value);
}
$jsonData = $data !== null ? json_encode($data) : "null";
$this->response->getBody()->write($jsonData);
return $this->response;
return $this->send($data, "application/json", $status, $headers);
}
/**
@ -107,20 +96,11 @@ class Context
* @return ResponseInterface The response object
*/
public function text(
string $data,
string $text,
int $status = 200,
array $headers = []
): ResponseInterface {
$this->response = $this->response
->withStatus($status)
->withHeader("Content-Type", "text/plain");
foreach ($headers as $name => $value) {
$this->response = $this->response->withHeader($name, $value);
}
$this->response->getBody()->write($data);
return $this->response;
return $this->send($text, "text/plain", $status, $headers);
}
/**
@ -132,20 +112,11 @@ class Context
* @return ResponseInterface The response object
*/
public function html(
string $data,
string $html,
int $status = 200,
array $headers = []
): ResponseInterface {
$this->response = $this->response
->withStatus($status)
->withHeader("Content-Type", "text/html");
foreach ($headers as $name => $value) {
$this->response = $this->response->withHeader($name, $value);
}
$this->response->getBody()->write($data);
return $this->response;
return $this->send($html, "text/html", $status, $headers);
}
/**
@ -216,4 +187,38 @@ class Context
return $this->html(call_user_func_array($this->viewBuilder, $params));
}
/**
* Send a response with full control over the output
*
* @param mixed $body The response body
* @param string $contentType The content type header value
* @param int $status The HTTP status code
* @param array $headers Additional headers
* @return ResponseInterface The response object
*/
public function send(
mixed $body = "",
string $contentType = "text/plain",
int $status = 200,
array $headers = []
): ResponseInterface {
$this->response = $this->response
->withStatus($status)
->withHeader("Content-Type", $contentType);
foreach ($headers as $name => $value) {
$this->response = $this->response->withHeader($name, $value);
}
if (is_string($body) || is_numeric($body)) {
$this->response->getBody()->write((string) $body);
} elseif (is_array($body) || is_object($body)) {
$this->response->getBody()->write(json_encode($body));
} elseif ($body instanceof \Psr\Http\Message\StreamInterface) {
$this->response = $this->response->withBody($body);
}
return $this->response;
}
}