Skip to content

Commit

Permalink
feat: add send method (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
notrab authored Jan 24, 2025
1 parent 19819ca commit d79c08e
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 35 deletions.
36 changes: 36 additions & 0 deletions examples/send/README.md
Original file line number Diff line number Diff line change
@@ -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
```
17 changes: 17 additions & 0 deletions examples/send/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"require": {
"notrab/dumbo": "@dev"
},
"repositories": [
{
"type": "path",
"url": "../../"
}
],
"scripts": {
"start": [
"Composer\\Config::disableProcessTimeout",
"php -S localhost:8000 -t ."
]
}
}
Binary file added examples/send/dumbo.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
81 changes: 81 additions & 0 deletions examples/send/index.php
Original file line number Diff line number Diff line change
@@ -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();
75 changes: 40 additions & 35 deletions src/Context.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public function get(string $key): mixed
/**
* 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
Expand All @@ -84,18 +84,7 @@ public function json(
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);
}

/**
Expand All @@ -107,20 +96,11 @@ public function json(
* @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);
}

/**
Expand All @@ -132,20 +112,11 @@ public function text(
* @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);
}

/**
Expand Down Expand Up @@ -216,4 +187,38 @@ public function view(...$params)

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;
}
}

0 comments on commit d79c08e

Please # to comment.