Vendor platform-tools: everything this site runs is now in one repo
shared/platform-tools was a git submodule. On this branch it is a plain
directory of tracked files, frozen at ea3616abae30106df283e73a3e2f9e5bb0e6ae90
— the same commit fotografia.andmore.pt pins. Contents are byte-identical to
that tree, verified blob by blob.
The submodule caused every deployment failure this site has had:
- .gitmodules named no `branch`, so the update fell back to
refs/remotes/origin/HEAD — a ref a plain server-side clone never writes.
"Atualizar submódulo" failed with "Unable to find refs/remotes/origin/HEAD
revision in submodule path".
- Its URL was http://, which the origin answers with 523.
- This install is deployed by uploading files, and a submodule is invisible
to that. The tree moved forward while shared/platform-tools stayed on the
old pin, config/functions_secrets.php died on a missing compat_secrets.php,
and the whole site — public pages included — went down.
Each of those was separately fixable. Together they mean a second repository
nobody can see from the deployment path, gating whether the first one boots. A
plain directory deploys like every other file and cannot fall out of step.
The cost is that platform-tools updates no longer arrive by bumping a pin; they
are a copy-over-and-commit. shared/platform-tools/VENDORED.md records the
upstream SHA, the procedure, and which four files differ from upstream in line
endings only (social/*.js, .css, functions_publications.php — CRLF upstream,
normalised to LF here; content otherwise identical).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e034232e9
commit
4d40adbf64
67 files changed
+17478
-5
No files matched your search
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* Configuração partilhada pelos scripts de backup.
|
||||
* Assumed location: <host>/shared/platform-tools/backups/config.php
|
||||
*
|
||||
* Valores vêm do .env na raiz do projecto (<host>/.env, gitignored). Os
|
||||
* fallbacks abaixo só são usados se o .env estiver ausente — em produção,
|
||||
* mete sempre o .env preenchido.
|
||||
*/
|
||||
|
||||
$host_root = dirname(__DIR__, 3);
|
||||
|
||||
// Three host patterns coexist:
|
||||
// - fotografia-style : config/env.php exposes env_load(), needs an explicit call
|
||||
// - dsa/moremio-style: config/env.php auto-loads .env via an IIFE; require is enough
|
||||
// - surf-style : no config/ directory at all -- src/config.php plus
|
||||
// vlucas/phpdotenv, which has already populated $_ENV and
|
||||
// getenv() by the time a web request reaches here.
|
||||
// Requiring config/env.php unconditionally fataled on the third layout.
|
||||
if (is_file($host_root . '/config/env.php')) {
|
||||
require_once $host_root . '/config/env.php';
|
||||
if (function_exists('env_load')) {
|
||||
env_load($host_root . '/.env');
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback reader for hosts with no config/env.php, and for CLI invocations
|
||||
// that run before any framework bootstrap: parse .env directly rather than
|
||||
// assuming something else already did.
|
||||
if (!function_exists('env')) {
|
||||
function env(string $key, $default = null) {
|
||||
$v = getenv($key);
|
||||
if ($v === false && array_key_exists($key, $_ENV)) $v = $_ENV[$key];
|
||||
if ($v !== false && $v !== null) return $v;
|
||||
|
||||
static $parsed = null;
|
||||
if ($parsed === null) {
|
||||
$parsed = [];
|
||||
$f = dirname(__DIR__, 3) . '/.env';
|
||||
if (is_file($f) && is_readable($f)) {
|
||||
foreach (file($f, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
|
||||
$line = trim($line);
|
||||
if ($line === '' || $line[0] === '#' || !str_contains($line, '=')) continue;
|
||||
[$k, $val] = array_pad(explode('=', $line, 2), 2, '');
|
||||
$parsed[trim($k)] = trim(trim($val), " \"'");
|
||||
}
|
||||
}
|
||||
}
|
||||
return array_key_exists($key, $parsed) ? $parsed[$key] : $default;
|
||||
}
|
||||
}
|
||||
|
||||
define('BACKUP_TOKEN', env('BACKUP_TOKEN', 'replace_me'));
|
||||
define('BACKUP_KEEP_DAYS', (int) env('BACKUP_KEEP_DAYS', 7));
|
||||
|
||||
// Pasta (relativa à raiz do host) que o backup de ficheiros arquiva. Só os
|
||||
// uploads têm informação externa — todo o resto é reconstituível a partir do
|
||||
// git — por isso o default é 'uploads'. Overridável no .env se um host
|
||||
// guardar os uploads noutro sítio.
|
||||
define('BACKUP_FILES_DIR', trim((string) env('BACKUP_FILES_DIR', 'uploads'), '/'));
|
||||
|
||||
// Credenciais da base de dados — sem fallbacks reais: se o .env faltar, a
|
||||
// ligação falha alto em vez de tentar um host/utilizador "mágico".
|
||||
define('DB_HOST', env('DB_HOST', 'localhost'));
|
||||
define('DB_PORT', (int) env('DB_PORT', 3306));
|
||||
define('DB_NAME', env('DB_NAME', ''));
|
||||
define('DB_USER', env('DB_USER', ''));
|
||||
define('DB_PASS', env('DB_PASS', ''));
|
||||
define('DB_CHARSET', 'utf8mb4');
|
||||
|
||||
/**
|
||||
* Apaga backups mais antigos que BACKUP_KEEP_DAYS na pasta indicada.
|
||||
* $pattern — glob pattern para identificar os ficheiros (ex: 'backup_*.zip')
|
||||
*/
|
||||
function cleanOldBackups(string $dir, string $pattern): void
|
||||
{
|
||||
$cutoff = time() - (BACKUP_KEEP_DAYS * 86400);
|
||||
$files = glob($dir . '/' . $pattern) ?: [];
|
||||
$deleted = 0;
|
||||
|
||||
foreach ($files as $file) {
|
||||
if (filemtime($file) < $cutoff) {
|
||||
if (@unlink($file)) {
|
||||
$deleted++;
|
||||
echo "Apagado (antigo): " . basename($file) . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($deleted === 0) {
|
||||
echo "Rotação: nenhum backup antigo para apagar.\n";
|
||||
} else {
|
||||
echo "Rotação: $deleted ficheiro(s) apagado(s).\n";
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user