Move app into module structure
This commit is contained in:
+1
-148
@@ -1,151 +1,4 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
function parse_env_file(string $path): array
|
||||
{
|
||||
if (!is_file($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$result = [];
|
||||
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
if ($lines === false) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($lines as $line) {
|
||||
$trimmed = trim($line);
|
||||
if ($trimmed === '' || str_starts_with($trimmed, '#')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pos = strpos($trimmed, '=');
|
||||
if ($pos === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = trim(substr($trimmed, 0, $pos));
|
||||
$value = trim(substr($trimmed, $pos + 1));
|
||||
if ($key === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen($value) >= 2) {
|
||||
$first = $value[0];
|
||||
$last = $value[strlen($value) - 1];
|
||||
if (($first === '"' && $last === '"') || ($first === "'" && $last === "'")) {
|
||||
$value = substr($value, 1, -1);
|
||||
}
|
||||
}
|
||||
|
||||
$result[$key] = $value;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function expand_env_values(array $env): array
|
||||
{
|
||||
$expanded = $env;
|
||||
$pattern = '/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/';
|
||||
|
||||
foreach ($expanded as $key => $value) {
|
||||
$expanded[$key] = preg_replace_callback(
|
||||
$pattern,
|
||||
static function (array $matches) use (&$expanded): string {
|
||||
$lookup = $matches[1];
|
||||
return (string) ($expanded[$lookup] ?? getenv($lookup) ?: '');
|
||||
},
|
||||
(string) $value
|
||||
) ?? (string) $value;
|
||||
}
|
||||
|
||||
return $expanded;
|
||||
}
|
||||
|
||||
function env_value(string $key, array $localEnv, string $default = ''): string
|
||||
{
|
||||
$runtime = getenv($key);
|
||||
if ($runtime !== false && $runtime !== '') {
|
||||
return $runtime;
|
||||
}
|
||||
|
||||
if (isset($localEnv[$key]) && $localEnv[$key] !== '') {
|
||||
return (string) $localEnv[$key];
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
function connect_database(): PDO
|
||||
{
|
||||
$env = parse_env_file(__DIR__ . '/../.env');
|
||||
$env = expand_env_values($env);
|
||||
|
||||
$databaseUrl = env_value('DATABASE_URL', $env);
|
||||
if ($databaseUrl !== '') {
|
||||
$parts = parse_url($databaseUrl);
|
||||
if ($parts !== false && ($parts['scheme'] ?? '') === 'postgresql') {
|
||||
$host = (string) ($parts['host'] ?? '');
|
||||
$port = (string) ($parts['port'] ?? '5432');
|
||||
$dbName = ltrim((string) ($parts['path'] ?? ''), '/');
|
||||
$user = (string) ($parts['user'] ?? '');
|
||||
$pass = (string) ($parts['pass'] ?? '');
|
||||
if ($host !== '' && $dbName !== '' && $user !== '') {
|
||||
$dsn = "pgsql:host={$host};port={$port};dbname={$dbName}";
|
||||
return new PDO($dsn, $user, $pass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$host = env_value('DB_HOST', $env);
|
||||
$port = env_value('DB_PORT', $env, '5432');
|
||||
$dbName = env_value('DB_NAME', $env);
|
||||
$user = env_value('DB_USER', $env);
|
||||
$pass = env_value('DB_PASSWORD', $env);
|
||||
|
||||
if ($host === '' || $dbName === '' || $user === '') {
|
||||
throw new RuntimeException('Missing DB configuration');
|
||||
}
|
||||
|
||||
$dsn = "pgsql:host={$host};port={$port};dbname={$dbName}";
|
||||
return new PDO($dsn, $user, $pass, [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]);
|
||||
}
|
||||
|
||||
function parse_number(mixed $value): ?float
|
||||
{
|
||||
if ($value === null || $value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_int($value) || is_float($value)) {
|
||||
return (float) $value;
|
||||
}
|
||||
|
||||
if (!is_string($value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$normalized = str_replace(["\u{00A0}", ' '], '', trim($value));
|
||||
$normalized = str_replace(',', '.', $normalized);
|
||||
|
||||
if (!is_numeric($normalized)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (float) $normalized;
|
||||
}
|
||||
|
||||
function json_response(int $status, array $payload): void
|
||||
{
|
||||
http_response_code($status);
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
|
||||
exit;
|
||||
}
|
||||
require_once __DIR__ . '/../modules/shared/db.php';
|
||||
|
||||
@@ -1,42 +1,4 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
function throttle_webhook_channel(string $channel, int $minIntervalSeconds): void
|
||||
{
|
||||
if ($channel === '' || $minIntervalSeconds <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sanitizedChannel = preg_replace('/[^a-z0-9_-]+/i', '_', $channel) ?? 'default';
|
||||
$lockPath = sys_get_temp_dir() . '/erp_naurua_webhook_throttle_' . $sanitizedChannel . '.lock';
|
||||
|
||||
$handle = fopen($lockPath, 'c+');
|
||||
if ($handle === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!flock($handle, LOCK_EX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
rewind($handle);
|
||||
$raw = stream_get_contents($handle);
|
||||
$lastSentAt = is_string($raw) ? (float) trim($raw) : 0.0;
|
||||
$now = microtime(true);
|
||||
$waitSeconds = ($lastSentAt + $minIntervalSeconds) - $now;
|
||||
|
||||
if ($waitSeconds > 0) {
|
||||
usleep((int) ceil($waitSeconds * 1000000));
|
||||
}
|
||||
|
||||
$sentAt = microtime(true);
|
||||
rewind($handle);
|
||||
ftruncate($handle, 0);
|
||||
fwrite($handle, sprintf('%.6f', $sentAt));
|
||||
fflush($handle);
|
||||
} finally {
|
||||
flock($handle, LOCK_UN);
|
||||
fclose($handle);
|
||||
}
|
||||
}
|
||||
require_once __DIR__ . '/../modules/shared/webhook_throttle.php';
|
||||
|
||||
Reference in New Issue
Block a user