Outbound email was relayed to the hub's /notify endpoint, so this install had
no SMTP configuration of its own and no way to see what had been sent. Bring
delivery back in-house, following the fotografia.andmore.pt stack rather than
inventing a second shape for it.
- Submodule bumped 603ff84 -> ea3616a, the pin fotografia already uses. That
is what provides functions_mail.php (shared transport), functions_settings.php
(platform_smtp_config + encrypted settings) and compat_secrets.php. Verified
no function-name collisions with this repo's own config/functions_settings.php:
platform-tools namespaces everything platform_*.
- PHPMailer 7.1.1 vendored at vendor/PHPMailer/src/. platform_mail_available()
looks for exactly this hand-vendored layout before falling back to composer's
autoloader, so the host needs no shell and no composer install. LGPL-2.1
license text included.
- config/functions_queue.php replaced: was a thin facade over the hub relay,
now fotografia's real queue. Rows are claimed atomically, retried with
exponential backoff up to max_attempts, and park in 'failed' with the real
SMTP rejection in last_error.
- SMTP resolution matches the fleet: .env wins for the SMTP_* constants, while
the actual send goes through platform_smtp_config($pdo), which is DB-first.
That ordering is deliberate -- the database is the half an operator can
change from the backoffice without shell access. Empty SMTP_HOST falls back
to PHP mail().
- Sistema -> Comunicações (views/sysadmin/comms.php): credentials plus a live
SMTP connection test and a verdict on what would happen to a message sent
right now. Secret-valued settings are write-only in the form and encrypted
at rest (AES-256-GCM, key from .env, never in the DB dump). Which keys count
as secret is platform_settings_is_secret()'s decision, not a list kept here.
- Sistema -> Mensagens (views/sysadmin/messages.php): the queue monitor.
Filters, per-message detail with last_error, and retry/cancel/archive.
Retry flushes inline so the operator sees the outcome immediately.
- cron.php drains the queue every 5 minutes, serialised with a lock file, and
runs retention once a day. Over HTTP it answers 404 until CRON_TOKEN is set
to something other than replace_me. Deliberately not a copy of fotografia's
cron: the session-reminder, download-digest and photo-archive steps have no
modules here and would be dead code.
- config/functions_notify_client.php deleted, and ANDMORE_ID_URL with it --
the hub relay was its only caller.
Verified without a database: PHP lint across the tree; PHPMailer builds a full
MIME message with RFC 2047 UTF-8 subject encoding from the three vendored files;
platform_mail_available() finds them; platform_mail_make() returns a correctly
configured mailer; the diagnosis states report Operacional / Não configurado.
NOT verified: the settings encryption round-trip -- this machine's PHP has no
openssl extension, so platform_secret_key() returns null and values pass through
in clear. The code degrades safely (stores the value rather than losing it) and
the Comunicações page warns when the key is unavailable.
Deployment: apply database/migration_20260913_message_queue.sql, set SMTP in
Comunicações or .env, set APP_SECRET_KEY, and schedule cron.php.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
30 lines
1.8 KiB
PHP
30 lines
1.8 KiB
PHP
<?php
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
// Static, secret-bearing configuration. Operational settings (APP_NAME, base
|
|
// URL, email-from headers, reminder_hours, Nextcloud URL/token, logo filenames)
|
|
// live in the `system_settings` table — see config/functions_settings.php and
|
|
// views/sysadmin/system_settings.php. Only credentials and tokens stay here so
|
|
// DB dumps never expose them.
|
|
//
|
|
// Values come from the .env file (loaded by config/db.php via config/env.php
|
|
// before this file runs). The fallback in each env() call keeps the platform
|
|
// running if .env is missing — never put real production secrets as defaults.
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
|
|
// ─── Environment ──────────────────────────────────────────────────────────────
|
|
define('APP_ENV', env('APP_ENV', 'prod'));
|
|
// Email/SMS delivery — including the dev redirect/print safety net — happens in
|
|
// this app. See config/functions_queue.php (message_queue + PHPMailer over SMTP)
|
|
// and config/functions.php for the SMTP_* constants.
|
|
|
|
if (APP_ENV !== 'prod') {
|
|
ini_set('display_errors', '1');
|
|
ini_set('display_startup_errors', '1');
|
|
error_reporting(E_ALL);
|
|
} else {
|
|
ini_set('display_errors', '0');
|
|
error_reporting(E_ALL); // still catch everything, just don't echo it
|
|
}
|
|
|
|
require_once __DIR__ . '/error_handler.php';
|