PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; $pdo = new PDO($dsn, DB_USER, DB_PASS, $options); } return $pdo; } // --- Helper Functions --- function e(string $str): string { return htmlspecialchars($str, ENT_QUOTES | ENT_HTML5, 'UTF-8'); } function slugify(string $text): string { $text = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $text); $text = preg_replace('/[^a-zA-Z0-9\s-]/', '', $text); $text = strtolower(trim($text)); $text = preg_replace('/[\s-]+/', '-', $text); return $text; } function truncate(string $text, int $length = 150): string { $text = strip_tags($text); if (mb_strlen($text) <= $length) return $text; return mb_substr($text, 0, $length) . '...'; } function timeAgo(string $datetime): string { $now = new DateTime(); $ago = new DateTime($datetime); $diff = $now->diff($ago); if ($diff->y > 0) return $diff->y . ' año' . ($diff->y > 1 ? 's' : ''); if ($diff->m > 0) return $diff->m . ' mes' . ($diff->m > 1 ? 'es' : ''); if ($diff->d > 0) return $diff->d . ' día' . ($diff->d > 1 ? 's' : ''); if ($diff->h > 0) return $diff->h . ' hora' . ($diff->h > 1 ? 's' : ''); return 'hace un momento'; } // Create uploads directory if not exists if (!is_dir(UPLOAD_DIR)) { mkdir(UPLOAD_DIR, 0755, true); }