uxf / core
3.56.3
2024-12-18 10:59 UTC
Requires
- php: ^8.3
- ext-json: *
- brick/money: ^0.10
- doctrine/orm: ^2.19 || ^3.0
- nette/utils: ^4.0
- ramsey/uuid: ^4.0
- symfony/http-kernel: ^6.4 || ^7.0
- symfony/property-access: ^6.4 || ^7.0
- symfony/property-info: ^6.4 || ^7.0
- symfony/validator: ^6.4 || ^7.0
- symfony/yaml: ^6.4 || ^7.0
- thecodingmachine/safe: ^2.0
- uxf/hydrator: 3.56.0
Suggests
- egulias/email-validator: Allow use Email
- giggsey/libphonenumber-for-php: Allow use Phone
- dev-main
- 3.56.3
- 3.56.2
- 3.56.1
- 3.56.0
- 3.55.9
- 3.55.8
- 3.55.7
- 3.55.5
- 3.55.0
- 3.54.5
- 3.54.3
- 3.54.2
- 3.54.0
- 3.53.7
- 3.53.3
- 3.53.2
- 3.53.1
- 3.53.0
- 3.51.2
- 3.51.0
- 3.50.6
- 3.50.5
- 3.50.3
- 3.50.2
- 3.50.1
- 3.50.0
- 3.49.2
- 3.49.1
- 3.49.0
- 3.48.0
- 3.47.2
- 3.47.0
- 3.46.11
- 3.44.6
- 3.44.5
- 3.44.4
- 3.44.3
- 3.44.2
- 3.44.0
- 3.43.2
- 3.43.0
- 3.42.0
- 3.41.2
- 3.41.1
- 3.41.0
- 3.40.4
- 3.40.3
- 3.40.2
- 3.40.1
- 3.40.0
- 3.39.4
- 3.39.3
- 3.39.2
- 3.39.1
- 3.38.0
- 3.37.1
- 3.37.0
- 3.36.3
- 3.36.2
- 3.36.0
- 3.35.5
- 3.35.4
- 3.35.2
- 3.34.3
- 3.34.0
- 3.32.4
- 3.32.3
- 3.30.1
- 3.29.1
- 3.29.0
- 3.27.3
- 3.26.0
- 3.24.2
- 3.24.1
- 3.24.0
- 3.23.3
- 3.23.1
- 3.23.0
- 3.22.0
- 3.21.4
- 3.21.3
- 3.21.0
- 3.20.0
- 3.19.4
- 3.19.2
- 3.18.0
- 3.17.4
- 3.17.3
- 3.17.1
- 3.17.0
- 3.15.6
- 3.15.5
- 3.13.2
- 3.13.0
- 3.11.3
- 3.11.0
- 3.10.1
- 3.10.0
- 3.9.2
- 3.8.2
- 3.8.1
- 3.8.0
- 3.7.3
- 3.7.1
- 3.7.0
- 3.6.0
- 3.5.0
- 3.4.0
- 3.3.0
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 1.9.1
- 1.9.0
- 1.8.1
- 1.8.0
- 1.7.7
- 1.7.6
- 1.7.5
- 1.7.4
- 1.7.3
- 1.7.2
- 1.7.1
- 1.7.0
- 1.6.0
- 1.5.1
- 1.5.0
- 1.4.3
- 1.4.2
- 1.4.1
- 1.4.0
- 1.3.0
- 1.2.1
- 1.2.0
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.1
- 1.0.0
- v0.3.5
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1
- dev-master
- dev-enum-validation
- dev-psr-12
This package is auto-updated.
Last update: 2024-12-18 10:03:47 UTC
README
Install
$ composer require uxf/core
Custom types
# time + date
$a = new UXF\Core\Type\Date('2020-10-30');
$b = new UXF\Core\Type\DateTime('2020-10-30 10:00:11');
$c = new UXF\Core\Type\Time('10:00:00');
# money
$x = UXF\Core\Type\Currency::CZK
$y = UXF\Core\Type\Money::of(666, $y);
# decimal
$d = UXF\Core\Type\Decimal::of(666);
# url
$e = UXF\Core\Type\Url::of('https://google.com/wow?hello[]=1#fragment');
# country
$f = UXF\Core\Type\Country::CZE;
# phone
$z = UXF\Core\Type\Phone::of('+420777666777');
# email
$z = UXF\Core\Type\Email::of('info@uxf.cz');
# national identification number for CZ - NinCze
$o = UXF\Core\Type\NationalIdentificationNumberCze::of('930201/3545');
# bank account number for CZ - BanCze
$p = UXF\Core\Type\BankAccountNumberCze::of('123/0300');
FromBody & FromQuery & FromHeader
use UXF\Core\Http\Request\FromBody;
use UXF\Core\Http\Request\FromQuery;
use UXF\Core\Http\Request\FromHeader;
class TestController
{
public function __invoke(
#[FromBody] TestRequestBody $body,
#[FromQuery] TestRequestQuery $query,
#[FromHeader] TestRequestHeader $header,
) {
...
}
}
FromBody array
use UXF\Core\Http\Request\FromBody;
class TestController
{
/**
* @param TestRequestBody[] $body
*/
public function __invoke(#[FromBody(TestRequestBody::class)] array $body)
{
...
}
}
PATCH method
class TestPatchRequestBody
{
public function __controller(
public readonly string | null | NotSet $string = new NotSet(),
) {
}
}
use UXF\Core\Http\Request\FromBody;
class TestController
{
public function __invoke(#[FromBody] TestPatchRequestBody $body)
{
if (!$body->string instanceof NotSet) {
...
}
}
}
Entity
Controller::__invoke method entity arguments (uri path params) are resolved by entity primary identifier (or by custom property specified by #[Entity('uuid')]
)
use UXF\Core\Http\Request\Entity;
#[ORM\Entity]
class File
{
#[ORM\Column, ORM\Id]
public int $id;
#[ORM\Column(type: 'uuid', unique: true)]
public UuidInterface $uuid;
}
class TestController
{
// eg. GET /4f94e4b0-e31a-4070-9ae0-59b32006d911/1
#[Route('/{file1}/{file2}')]
public function __invoke(#[Entity('uuid')] File $file1, File $file2)
{
...
}
}
Response with HydratorMap (Union)
use UXF\Hydrator\Attribute\HydratorMap;
// interface
#[HydratorMap(property: 'type', matrix: [
'o' => Orienteering::class,
'p' => Paragliding::class,
])]
interface ActivityResponse
{
}
// children
class OrienteeringResponse implements ActivityResponse
{
public function __construct(
public readonly int $card,
public readonly string $type = 'o',
) {
}
}
class ParaglidingResponse implements ActivityResponse
{
public function __construct(
public readonly string $glider,
public readonly string $type = 'p',
) {
}
}
// usage
class ClubController
{
public function __invoke(): ActivityResponse
{
return new ParaglidingResponse('GIN');
}
}
UXF\Core\Http\ResponseModifierInterface - modify symfony response
use Symfony\Component\HttpFoundation\Response;
use UXF\Core\Http\ResponseModifierInterface;
/**
* @implements ResponseModifierInterface<array<string, string>>
*/
final class ModifiedResponseController implements ResponseModifierInterface
{
/**
* @return array<string, string>
*/
public function __invoke(): array
{
return [];
}
public static function modifyResponse(Response $response, mixed $data): void
{
$response->setStatusCode(509);
$response->headers->set('X-Test', 'hello');
}
}
Utils
#[UXF\Core\Attribute\Internal]
# phpstan.neon
includes:
- vendor/uxf/core/config/extension.neon
use UXF\Core\Attribute\Internal;
final readonly class Funny
{
#[Internal(FunnyService::class)]
public function setState(State $state): void
{
...
}
}
UXF\Core\Type\Money
$a = Money::of(1.50, Currency::CZK);
$b = Money::of('1.40', Currency::CZK);
$z = Money::zero(Currency::CZK);
// +
$c = $a->plus($b);
// -
$c = $a->minus($b);
// *
$c = $a->multipliedBy($b);
// /
$c = $a->dividedBy($b);
// (int)
$c = $a->amountInt();
// (float)
$c = $a->amountFloat();
// (bool)
$c = $a->equals($b);
// (bool)
$c = $a->isZero();
UXF\Core\Type\Decimal
$a = Decimal::of(1.50);
$b = Decimal::of('1.40');
$z = Decimal::zero();
// +
$c = $a->plus($b);
// -
$c = $a->minus($b);
// *
$c = $a->multipliedBy($b);
// /
$c = $a->dividedBy($b);
// (int)
$c = $a->toInt();
// (float)
$c = $a->toFloat();
// (bool)
$c = $a->equals($b);
// (bool)
$c = $a->isZero();
UXF\Core\Type\Url
$url = Url::of('https://user:pass@google.com:443/hello?ok&test[]=1#fragment');
/**
# UXF\Core\Type\UrlComponents {
scheme: "https"
host: "google.com"
port: 443
user: "user"
pass: "pass"
path: "/hello"
query: [
"ok" => ""
"test" => [1]
]
fragment: "fragment"
}
*/
$components = $url->getComponents();
UXF\Core\Utils\Lst
// find
Lst::from([$a, $b])->find(fn (X $a): bool => $a->id = 1); // $a
// map
Lst::from([$a, $b])->map(fn (X $x): Y => $x->y); // Lst[$x, $y]
// filter
Lst::from([$a, $b])->filter(fn (X $a): bool => $a->id > 1); // Lst[$b]
// sort
Lst::from([$a, $b])->sort(fn (X $a, X $b): int => $a <=> $b); // Lst[$b, $a]
// unique
Lst::from([$a, $b, $b])->unique(); // Lst[$a, $b]
// concat
Lst::from([$a, $b])->concat(Lst::from([$c, $d])); // Lst[$a, $b, $c, $d]
// push
Lst::from([$a, $b])->push($c); // Lst[$a, $b, $c]
// unshift
Lst::from([$a, $b])->unshift($c); // Lst[$c, $a, $b]
// slice
Lst::from([$a, $b, $c])->slice(1, 1); // Lst[$b]
// join
Lst::from([1, 2, 3])->join(', '); // '1, 2, 3'
// aggregate
Lst::from([1, 2, 3])->aggregate(0, fn (int $sum, int $item) => $sum + $item)); // 6
// forEach
Lst::from([1, 2, 3])->forEach(fn (int $item) => $test->counter += $item); // void
// dictionary
Lst::from([$a, $b])->dictionary(fn (X $a) => $a->key, fn (X $a) => $a->name); // ['key1' => 'value1', 'key2' => 'value2']
// groupBy
Lst::from([$a, $b, $c])->groupBy(fn (X $a) => $a->key, fn (X $a) => $a); // ['key1' => [$a], 'key2' => [$b, $c]]
// first
Lst::from([$a, $b])->first(); // $a
Lst::from([])->first(); // null
// last
Lst::from([$a, $b])->last(); // $b
Lst::from([])->last(); // null
// count
Lst::from([$a, $b])->count(); // 2
// isEmpty
Lst::from([$a, $b])->isEmpty(); // false
// contains
Lst::from([$a, $b])->contains($a); // true
// getValues
Lst::from([$a, $b])->getValues(); // [$a, $b]
// full
$values = Lst::from([
Language::create(10, 'Z'),
Language::create(11, 'A'),
Language::create(12, 'C'),
Language::create(13, 'A'),
Language::create(14, 'D'),
])
->filter(fn (Language $l) => $l->getId() >= 12)
->sort(fn (Language $a, Language $b) => $a->getName() <=> $b->getName())
->map(fn (Language $l) => $l->getName())
->unique()
->getValues();