-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
159 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} |