parent
7d20c4e994
commit
ac5bfa6c68
4 changed files with 177 additions and 0 deletions
@ -0,0 +1,29 @@ |
|||||||
|
--TEST-- |
||||||
|
Symfony pattern: array_reduce builds directive string from keyed arrays |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class SymfonyLikeContentSecurityPolicyHandler |
||||||
|
{ |
||||||
|
public function compileDirectives(array $directives): string |
||||||
|
{ |
||||||
|
return array_reduce( |
||||||
|
array_keys($directives), |
||||||
|
static fn ($result, $name) => ('' !== $result ? $result.'; ' : '').sprintf('%s %s', $name, implode(' ', $directives[$name])), |
||||||
|
'' |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$handler = new SymfonyLikeContentSecurityPolicyHandler(); |
||||||
|
|
||||||
|
var_dump($handler->compileDirectives([ |
||||||
|
'default-src' => ["'self'"], |
||||||
|
'script-src' => ["'self'", 'cdn.example.test'], |
||||||
|
])); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(54) "default-src 'self'; script-src 'self' cdn.example.test" |
||||||
@ -0,0 +1,39 @@ |
|||||||
|
--TEST-- |
||||||
|
Symfony pattern: array_uintersect with spaceship comparator for nested arrays |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class SymfonyLikeListenerPass |
||||||
|
{ |
||||||
|
public function intersectListeners(array $expected, array $actual): array |
||||||
|
{ |
||||||
|
return array_uintersect($expected, $actual, static fn (array $a, array $b) => $a <=> $b); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$pass = new SymfonyLikeListenerPass(); |
||||||
|
|
||||||
|
var_dump(array_values($pass->intersectListeners( |
||||||
|
[ |
||||||
|
['event' => 'request', 'method' => 'onRequest'], |
||||||
|
['event' => 'response', 'method' => 'onResponse'], |
||||||
|
], |
||||||
|
[ |
||||||
|
['event' => 'response', 'method' => 'onResponse'], |
||||||
|
['event' => 'terminate', 'method' => 'onTerminate'], |
||||||
|
] |
||||||
|
))); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(1) { |
||||||
|
[0]=> |
||||||
|
array(2) { |
||||||
|
["event"]=> |
||||||
|
string(8) "response" |
||||||
|
["method"]=> |
||||||
|
string(10) "onResponse" |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,50 @@ |
|||||||
|
--TEST-- |
||||||
|
Symfony pattern: current() over filtered find result with static arrow callback |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class SymfonyLikeProfiler |
||||||
|
{ |
||||||
|
public function __construct(private array $profiles) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public function find(?string $ip, ?string $url, int $limit, ?string $method, ?string $start, ?string $end, ?int $statusCode, callable $filter): array |
||||||
|
{ |
||||||
|
return array_slice(array_values(array_filter($this->profiles, $filter)), 0, $limit); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class SymfonyLikeProfilerController |
||||||
|
{ |
||||||
|
public function __construct(private SymfonyLikeProfiler $profiler) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public function latest(string $profileType): ?array |
||||||
|
{ |
||||||
|
if ($latest = current($this->profiler->find(null, null, 1, null, null, null, null, static fn ($profile) => $profileType === $profile['virtual_type']))) { |
||||||
|
return $latest; |
||||||
|
} |
||||||
|
|
||||||
|
return null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$controller = new SymfonyLikeProfilerController(new SymfonyLikeProfiler([ |
||||||
|
['token' => 'a', 'virtual_type' => 'command'], |
||||||
|
['token' => 'b', 'virtual_type' => 'request'], |
||||||
|
])); |
||||||
|
|
||||||
|
var_dump($controller->latest('request')); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(2) { |
||||||
|
["token"]=> |
||||||
|
string(1) "b" |
||||||
|
["virtual_type"]=> |
||||||
|
string(7) "request" |
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
--TEST-- |
||||||
|
Symfony pattern: object runtime class in arrow function array_map |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class SymfonyLikeTraceableAuthenticator |
||||||
|
{ |
||||||
|
public function __construct(private object $authenticator) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
public function getAuthenticator(): object |
||||||
|
{ |
||||||
|
return $this->authenticator; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class SymfonyLikePasswordAuthenticator |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
class SymfonyLikeTokenAuthenticator |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
class SymfonyLikeDebugFirewallCommand |
||||||
|
{ |
||||||
|
public function listAuthenticatorClasses(array $authenticators): array |
||||||
|
{ |
||||||
|
return array_map( |
||||||
|
static fn ($authenticator) => [($authenticator instanceof SymfonyLikeTraceableAuthenticator ? $authenticator->getAuthenticator() : $authenticator)::class], |
||||||
|
$authenticators |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$command = new SymfonyLikeDebugFirewallCommand(); |
||||||
|
|
||||||
|
var_dump($command->listAuthenticatorClasses([ |
||||||
|
new SymfonyLikeTraceableAuthenticator(new SymfonyLikePasswordAuthenticator()), |
||||||
|
new SymfonyLikeTokenAuthenticator(), |
||||||
|
])); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(2) { |
||||||
|
[0]=> |
||||||
|
array(1) { |
||||||
|
[0]=> |
||||||
|
string(32) "SymfonyLikePasswordAuthenticator" |
||||||
|
} |
||||||
|
[1]=> |
||||||
|
array(1) { |
||||||
|
[0]=> |
||||||
|
string(29) "SymfonyLikeTokenAuthenticator" |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue