Skip to content

Commit ee9034a

Browse files
committed
Merge branch 'cleanup'
2 parents 1d30318 + 815cf63 commit ee9034a

File tree

177 files changed

+7226
-7072
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+7226
-7072
lines changed

.prettyphp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"src",
55
"tests/3rdparty",
66
"tests/fixtures",
7-
"tests/legacy",
87
"tests/stubs",
98
"tests/unit",
109
"tests/bootstrap.php",

docs/Benchmarks.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ Unscientific tests that have informed various decisions.
66

77
e.g. when waiting for a `proc_open()` process to terminate:
88

9-
| Statement | CPU time | % of elapsed time |
10-
| ---------------- | --------- | ----------------- |
11-
| none | 9984.34ms | 99.84% |
12-
| `usleep(1)` | 1234.08ms | 12.34% |
13-
| `usleep(10)` | 232.06ms | 2.32% |
14-
| `usleep(100)` | 94.29ms | 0.94% |
15-
| `usleep(1000)` | 25.15ms | 0.25% |
16-
| `usleep(10000)` | 6.00ms | 0.06% |
17-
| `usleep(100000)` | 2.34ms | 0.02% |
9+
| Statement | CPU time | % of elapsed time |
10+
| ------------------- | ---------- | ----------------- |
11+
| none | 9984.34ms | 99.84% |
12+
| `usleep(1)` | 1234.08ms | 12.34% |
13+
| `usleep(10)` | 232.06ms | 2.32% |
14+
| `usleep(100)` | 94.29ms | 0.94% |
15+
| `usleep(1000)` | 25.15ms | 0.25% |
16+
| **`usleep(10000)`** | **6.00ms** | **0.06%** |
17+
| `usleep(100000)` | 2.34ms | 0.02% |

docs/Http.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# HTTP
2+
3+
## Form data
4+
5+
There are several methods in [salient/http][] and [salient/curler][] (see the
6+
[list below][methods]) where data received via `mixed[] $query` and/or
7+
`mixed[]|object $data` parameters is encoded as HTML form data before it is
8+
applied to an HTTP message.
9+
10+
`true` and `false` are encoded as `1` and `0` respectively.
11+
12+
Keys other than `list` keys are preserved by default, but form data flags can be
13+
used to modify this behaviour, e.g. via [Curler::withFormDataFlags()][].
14+
15+
`DateTimeInterface` instances are converted to ISO-8601 strings unless a date
16+
formatter is given, e.g. via [Curler::withDateFormatter()][].
17+
18+
Before recursion, other objects are processed as follows:
19+
20+
1. `Arrayable`: replaced with return value of [toArray()][]
21+
2. `JsonSerializable`: serialized with [Json::encode()][] and deserialized with
22+
[Json::objectAsArray()][]
23+
3. `Jsonable`: replaced with return value of [toJson()][] after it is
24+
deserialized with [Json::objectAsArray()][]
25+
4. `Traversable`: passed to `iterator_to_array()` and replaced with its return
26+
value
27+
5. `object` with at least one public property: replaced with an array that maps
28+
public property names to values
29+
6. `Stringable`: cast to `string`
30+
31+
> Internally, [FormDataEncoder][] instances are used to recurse into query and
32+
> body data.
33+
>
34+
> If given, a callback is applied to objects other than `DateTimeInterface`
35+
> instances. It must return one of the following:
36+
>
37+
> - `null` to skip the value
38+
> - `false` to process the value as if no callback had been given
39+
> - the value as a `string`
40+
> - an `array` to recurse into
41+
> - an `object` to return without encoding
42+
>
43+
> If a `DateTimeInterface` is returned, it is converted to a string as above.
44+
45+
### Methods that encode HTTP message data
46+
47+
#### `Http`
48+
49+
- [HttpUtil::mergeQuery()][]
50+
- [HttpUtil::replaceQuery()][]
51+
- [Stream::fromData()][]
52+
53+
#### `Curler`
54+
55+
- [Curler::replaceQuery()][]
56+
- [Curler][] request methods: `head()`, `get()`, `post()`, `put()`, `patch()`,
57+
`delete()`
58+
- Paginated variants: `getP()`, `postP()`, `putP()`, `patchP()`, `deleteP()`
59+
- Raw variants (`$query` only): `postR()`, `putR()`, `patchR()`, `deleteR()`
60+
61+
[Curler]: https://salient-labs.github.io/toolkit/Salient.Curler.Curler.html
62+
[Curler::replaceQuery()]:
63+
https://salient-labs.github.io/toolkit/Salient.Curler.Curler.html#_replaceQuery
64+
[Curler::withDateFormatter()]:
65+
https://salient-labs.github.io/toolkit/Salient.Curler.Curler.html#_withDateFormatter
66+
[Curler::withFormDataFlags()]:
67+
https://salient-labs.github.io/toolkit/Salient.Curler.Curler.html#_withFormDataFlags
68+
[FormDataEncoder]: ../src/Toolkit/Http/Internal/FormDataEncoder.php
69+
[HttpUtil::mergeQuery()]:
70+
https://salient-labs.github.io/toolkit/Salient.Http.HttpUtil.html#_mergeQuery
71+
[HttpUtil::replaceQuery()]:
72+
https://salient-labs.github.io/toolkit/Salient.Http.HttpUtil.html#_replaceQuery
73+
[Json::encode()]:
74+
https://salient-labs.github.io/toolkit/Salient.Utility.Json.html#_encode
75+
[Json::objectAsArray()]:
76+
https://salient-labs.github.io/toolkit/Salient.Utility.Json.html#_objectAsArray
77+
[methods]: #methods-that-encode-http-message-data
78+
[salient/curler]: https://packagist.org/packages/salient/curler
79+
[salient/http]: https://packagist.org/packages/salient/http
80+
[Stream::fromData()]:
81+
https://salient-labs.github.io/toolkit/Salient.Http.Message.Stream.html#_fromData
82+
[toArray()]:
83+
https://salient-labs.github.io/toolkit/Salient.Contract.Core.Arrayable.html#_toArray
84+
[toJson()]:
85+
https://salient-labs.github.io/toolkit/Salient.Contract.Core.Jsonable.html#_toJson

phpstan-baseline-7.4.neon

Lines changed: 0 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

phpstan-baseline-8.3.neon

Lines changed: 0 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/check-coverage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
'Cache' => ['Cache', true, true, '2025-02-23: code review finalised'],
3232
'Console' => ['Console', true, true, '2025-03-28: code review finalised except `Formatter` rewrite'],
3333
'Container' => ['Container', true, true, '2025-03-11: code review finalised except `Container` rewrite sans Dice'],
34-
'Http' => ['HTTP', null, null, null],
34+
'Http' => ['HTTP', null, true, null],
3535
'Db' => ['Db', null, null, null],
3636
'Cli' => ['CLI', null, null, null],
3737
'Sync' => ['Sync', null, null, null],

src/Toolkit/Cli/CliUtil.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Salient\Cli;
4+
5+
use Salient\Cli\Exception\CliInvalidArgumentsException;
6+
use Salient\Utility\AbstractUtility;
7+
use Salient\Utility\File;
8+
use Salient\Utility\Json;
9+
use JsonException;
10+
11+
/**
12+
* @api
13+
*/
14+
final class CliUtil extends AbstractUtility
15+
{
16+
/**
17+
* Get data from a user-supplied JSON file
18+
*
19+
* If `$filename` is `"-"`, JSON is read from `STDIN`.
20+
*
21+
* @return mixed[]|object
22+
*/
23+
public static function getJson(string $filename, bool $associative = true)
24+
{
25+
$json = File::getContents($filename === '-' ? 'php://stdin' : $filename);
26+
27+
try {
28+
$json = $associative
29+
? Json::objectAsArray($json)
30+
: Json::parse($json);
31+
} catch (JsonException $ex) {
32+
$message = $ex->getMessage();
33+
throw new CliInvalidArgumentsException(
34+
$filename === '-'
35+
? sprintf('invalid JSON: %s', $message)
36+
: sprintf("invalid JSON in '%s': %s", $filename, $message)
37+
);
38+
}
39+
40+
if (!is_array($json) && ($associative || !is_object($json))) {
41+
throw new CliInvalidArgumentsException(
42+
$filename === '-'
43+
? 'invalid payload'
44+
: sprintf('invalid payload: %s', $filename)
45+
);
46+
}
47+
48+
return $json;
49+
}
50+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace Salient\Collection;
4+
5+
/**
6+
* @api
7+
*
8+
* @template TKey of array-key
9+
* @template TValue
10+
*/
11+
trait ArrayableCollectionTrait
12+
{
13+
/** @use HasItems<TKey,TValue> */
14+
use HasItems;
15+
16+
/**
17+
* @inheritDoc
18+
*/
19+
public function toArray(bool $preserveKeys = true): array
20+
{
21+
return $preserveKeys
22+
? $this->Items
23+
: array_values($this->Items);
24+
}
25+
}

src/Toolkit/Collection/Collection.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
* @template TKey of array-key
1212
* @template TValue
1313
*
14-
* @implements CollectionInterface<TKey,TValue>
14+
* @implements CollectionInterface<TKey,TValue,mixed[]>
1515
* @implements IteratorAggregate<TKey,TValue>
1616
*/
1717
class Collection implements CollectionInterface, IteratorAggregate
1818
{
1919
/** @use CollectionTrait<TKey,TValue,static<TKey|int,TValue>> */
2020
use CollectionTrait;
21+
/** @use RecursiveArrayableCollectionTrait<TKey,TValue> */
22+
use RecursiveArrayableCollectionTrait;
2123
}

0 commit comments

Comments
 (0)