feat: integrated OAuth2 server

This commit is contained in:
Björn Fromme
2025-04-24 20:28:27 +02:00
parent c418ae6399
commit adbfb49c11
84 changed files with 2542 additions and 312 deletions
+78
View File
@@ -0,0 +1,78 @@
<?php
namespace App\BusProNet\Traits;
use App\BusProNet\Exception\ApiClientException;
trait ApiClientTrait
{
/**
* @throws ApiClientException
*/
private function connect(string $host, int $port, int $maxRetries = 25)
{
$tries = 1;
$errNo = $errStr = '';
$errorCodesForRetry = [
SOCKET_ECONNREFUSED,
SOCKET_EBADF,
];
$openSocket = function (&$errNo, &$errStr) use ($host, $port) {
return @fsockopen(
$host,
$port,
$errNo,
$errStr,
10
);
};
$socket = $openSocket($errNo, $errStr);
while (false === $socket && true === in_array($errNo, $errorCodesForRetry) && $maxRetries > $tries) {
$this->logger->warning('Could not connect to socket, retrying', [
'error_message' => $errStr,
'error_number' => $errNo,
]);
++$tries;
sleep(1);
$socket = $openSocket($errNo, $errStr);
}
if (false !== $socket) {
stream_set_timeout($socket, 60);
} else {
$this->logger->error('Unable to open socket', [
'error_message' => $errStr,
'error_number' => $errNo,
]);
throw new ApiClientException('Unable to open socket');
}
return $socket;
}
private function send($socket, string $data): void
{
// message length is prepended to actual message
$send = sprintf('%010s', strlen($data)).$data;
fwrite($socket, $send);
}
private function receive($socket): string
{
$response = '';
while (false === feof($socket)) {
$response .= fread($socket, 4096);
}
return $response;
}
private function disconnect($socket): void
{
@fclose($socket);
}
}
@@ -0,0 +1,76 @@
<?php
namespace App\BusProNet\Traits;
use Carbon\Carbon;
use Carbon\Exceptions\InvalidFormatException;
trait TypeConversionTrait
{
protected function stringToArray(?string $string, string $separator = ','): array
{
if (true === empty($string)) {
return [];
}
return explode($separator, $string);
}
protected function stringToFloat(?string $string): ?float
{
if (true === empty($string)) {
return null;
}
return (float) str_replace(['.', ','], ['', '.'], $string);
}
protected function floatToString(float $float): string
{
return number_format($float, 2, ',', '');
}
protected function stringToBool(?string $string): bool
{
if (true === empty($string)) {
return false;
}
return 'True' === $string || 'J' === $string;
}
protected function boolToString(bool $bool): string
{
return $bool ? 'True' : 'False';
}
protected function stringToDate(?string $string): ?\DateTimeImmutable
{
if (true === empty($string)) {
return null;
}
try {
$date = Carbon::createFromFormat('d.m.Y', $string)->startOfDay();
return $date->toDateTimeImmutable();
} catch (InvalidFormatException $e) {
return null;
}
}
protected function stringToDateTime(?string $string): ?\DateTimeImmutable
{
if (true === empty($string)) {
return null;
}
try {
$dateTime = Carbon::createFromFormat('d.m.Y H:i', substr($string, 0, 16))->startOfDay();
return $dateTime->toDateTimeImmutable();
} catch (InvalidFormatException $e) {
return null;
}
}
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace App\BusProNet\Traits;
use Symfony\Component\DomCrawler\Crawler;
trait XmlParserTrait
{
protected function getStringOrNullValue(Crawler $node): ?string
{
return 0 < $node->count() ? $node->text() : null;
}
protected function getIntOrNullValue(Crawler $node): ?int
{
return 0 < $node->count() ? (int) $node->text() : null;
}
}