Skip to content

Commit

Permalink
v3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
fenric committed Oct 30, 2024
1 parent ca8c382 commit fa195a7
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 5 deletions.
29 changes: 24 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ composer require sunrise/http-message
## Documentation Navigation

- [Server Request from Global Environment](#server-request-from-global-environment)
- [JSON and HTML Messages](#json-and-html-messages)
- - [JSON Request](#json-request)
- - [JSON Response](#json-response)
- - [HTML Response](#html-response)
- [Typed Messages](#typed-messages)
- [Streams](#streams)
- - [File Stream](#file-stream)
- - [PHP Input Stream](#php-input-stream)
Expand All @@ -43,7 +40,7 @@ use Sunrise\Http\Message\ServerRequestFactory;
$request = ServerRequestFactory::fromGlobals();
```

### JSON and HTML Messages
### Typed Messages

#### JSON Request

Expand All @@ -61,6 +58,28 @@ You can also specify [encoding flags](https://www.php.net/manual/en/json.constan
$request = new JsonRequest('GET', '/', $data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE, 512);
```

#### URL Encoded Request

```php
use Sunrise\Http\Message\Request\UrlEncodedRequest;

/** @var $data mixed */

$request = new UrlEncodedRequest('GET', '/', $data);
```

You can also specify [encoding type](https://www.php.net/manual/ru/url.constants.php#constant.php-query-rfc1738) like below:

```php
use Sunrise\Http\Message\Request\UrlEncodedRequest;

$encodingType = UrlEncodedRequest::ENCODING_TYPE_RFC1738;
// or
$encodingType = UrlEncodedRequest::ENCODING_TYPE_RFC3986;

$request = new UrlEncodedRequest('GET', '/', $data, $encodingType);
```

#### JSON Response

```php
Expand Down
81 changes: 81 additions & 0 deletions src/Request/UrlEncodedRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php declare(strict_types=1);

/**
* It's free open-source software released under the MIT License.
*
* @author Anatoly Nekhay <afenric@gmail.com>
* @copyright Copyright (c) 2018, Anatoly Nekhay
* @license https://github.com/sunrise-php/http-message/blob/master/LICENSE
* @link https://github.com/sunrise-php/http-message
*/

namespace Sunrise\Http\Message\Request;

use Psr\Http\Message\StreamInterface;
use Sunrise\Http\Message\Exception\InvalidArgumentException;
use Sunrise\Http\Message\Request;
use Sunrise\Http\Message\Stream\PhpTempStream;
use TypeError;

use function gettype;
use function http_build_query;
use function is_array;
use function is_object;
use function sprintf;

use const PHP_QUERY_RFC1738;
use const PHP_QUERY_RFC3986;

/**
* @since 3.1.0
*/
final class UrlEncodedRequest extends Request
{
public const ENCODING_TYPE_RFC1738 = PHP_QUERY_RFC1738;
public const ENCODING_TYPE_RFC3986 = PHP_QUERY_RFC3986;

/**
* @param mixed $uri
* @param array<array-key, mixed>|object $data
* @param self::ENCODING_TYPE_* $encodingType
*
* @throws InvalidArgumentException
*/
public function __construct(string $method, $uri, $data, int $encodingType = self::ENCODING_TYPE_RFC1738)
{
/**
* @psalm-suppress DocblockTypeContradiction
* @phpstan-ignore-next-line
*/
if (!is_array($data) && !is_object($data)) {
throw new TypeError(sprintf(
'Argument #3 ($data) must be of type string, %s given',
gettype($data),
));
}

parent::__construct($method, $uri);

$this->setBody(self::createBody($data, $encodingType));
$this->setHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
}

/**
* @param array<array-key, mixed>|object $data
* @param self::ENCODING_TYPE_* $encodingType
*/
private static function createBody($data, int $encodingType): StreamInterface
{
if ($data instanceof StreamInterface) {
return $data;
}

$encodedData = http_build_query($data, '', null, $encodingType);

$stream = new PhpTempStream('r+b');
$stream->write($encodedData);
$stream->rewind();

return $stream;
}
}
54 changes: 54 additions & 0 deletions tests/Request/UrlEncodedRequestTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

declare(strict_types=1);

namespace Request;

use PHPUnit\Framework\TestCase;
use Psr\Http\Message\StreamInterface;
use Sunrise\Http\Message\Request\UrlEncodedRequest;

class UrlEncodedRequestTest extends TestCase
{
public function testConstructorWithArray(): void
{
$request = new UrlEncodedRequest('POST', '/', ['foo' => 'bar']);

$this->assertSame('POST', $request->getMethod());
$this->assertSame('/', (string) $request->getUri());
$this->assertSame('application/x-www-form-urlencoded; charset=utf-8', $request->getHeaderLine('Content-Type'));
$this->assertStringStartsWith('php://temp', $request->getBody()->getMetadata('uri'));
$this->assertTrue($request->getBody()->isReadable());
$this->assertTrue($request->getBody()->isWritable());
$this->assertSame('foo=bar', $request->getBody()->__toString());
}

public function testConstructorWithObject(): void
{
$request = new UrlEncodedRequest('POST', '/', (object) ['foo' => 'bar']);

$this->assertSame('foo=bar', $request->getBody()->__toString());
}

public function testConstructorWithDefaultEncodingType(): void
{
$request = new UrlEncodedRequest('POST', '/', ['foo' => 'bar baz']);

$this->assertSame('foo=bar+baz', $request->getBody()->__toString());
}

public function testConstructorWithEncodingType(): void
{
$request = new UrlEncodedRequest('POST', '/', ['foo' => 'bar baz'], UrlEncodedRequest::ENCODING_TYPE_RFC3986);

$this->assertSame('foo=bar%20baz', $request->getBody()->__toString());
}

public function testConstructorWithStream(): void
{
$body = $this->createMock(StreamInterface::class);
$request = new UrlEncodedRequest('POST', '/', $body);

$this->assertSame($body, $request->getBody());
}
}

0 comments on commit fa195a7

Please sign in to comment.