'framex', 'hash' => true]) * echo asset('js/app.js', ['absolute' => true, 'hash' => true]); * echo asset('images/logo.png', ['fallback' => '/images/default-logo.png']); */ function asset($path, $options = []) { // Default options $defaults = [ 'absolute' => false, 'fallback' => null, // Fallback URL if file doesn't exist 'prefix' => 'v', // Version parameter prefix 'hash' => false // Use file hash instead of timestamp ]; $options = array_merge($defaults, $options); // Remove leading slash $path = ltrim($path, '/'); $documentRoot = $_SERVER['DOCUMENT_ROOT']; $fullPath = $documentRoot . '/' . $path; // Generate version parameter $version = ''; if (file_exists($fullPath)) { if ($options['hash']) { // Use file hash (more reliable for cache busting) $version = '?' . $options['prefix'] . '=' . substr(md5_file($fullPath), 0, 8); } else { // Use modification time $version = '?' . $options['prefix'] . '=' . filemtime($fullPath); } } elseif ($options['fallback']) { // Return fallback URL if provided return $options['fallback']; } else { error_log("Asset not found: " . $fullPath); } // Build URL if ($options['absolute']) { $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST']; return $protocol . '://' . $host . '/' . $path . $version; } else { return '/' . $path . $version; } } /** * Get Partials * * @param string $name The name of the partial to include. * @throws Exception If the partial does not exist. */ function partial(string $name): void { $path = TEMPLATES . '/partials/' . $name . '.php'; if (file_exists($path)) { include $path; } else { throw new Exception("Partial '{$name}' doesn't exist"); } } function codeBlock($code, $language = 'php') { // 1. Convert special characters to HTML entities to prevent execution/bugs $safe_code = htmlspecialchars($code, ENT_QUOTES, 'UTF-8'); // 2. Wrap in
 and  tags with the appropriate class
    $output = '
';
    $output .= $safe_code;
    $output .= '
'; return $output; } /** * Pre Helper * * @param mixed $array The data to print. * @param bool|null $die Whether to stop execution after printing. * @param bool $report Whether to echo the data directly. */ function pre($array, ?bool $die = null, bool $report = false): void { if ($report) { echo $array; } echo '
' . print_r($array, true) . '
'; if ($die) { die(); } } /** * Get Random Image * * @param int $width The width of the image. * @param int $height The height of the image. * @return string The URL of the random image. */ function image(int $width = 960, int $height = 576): string { return 'https://picsum.photos/' . $width . '/' . $height . '?v=' . rand(); } /** * Sanitize Input * * @param string $data The data to sanitize. * @return string The sanitized data. */ function e(string $data): string { return htmlspecialchars($data, ENT_QUOTES, 'UTF-8'); } /** * Summarize Text * * @param string $text The text to summarize. * @param int $maxLength The maximum length of the summary. * @return string The summarized text. */ function summarize(string $text, int $maxLength = 100): string { if (strlen($text) <= $maxLength) { return $text; } $summary = substr($text, 0, $maxLength); return $summary . '...'; } function urlSlug($value, $transliteration = true) { if (extension_loaded('intl') && $transliteration == true) { $transliterator = \Transliterator::create('Any-Latin; Latin-ASCII'); $value = $transliterator->transliterate($value); } $slug = html_entity_decode($value, ENT_QUOTES, 'UTF-8'); $slug = preg_replace('~[^\pL\d]+~u', '-', $slug); $slug = trim($slug, '-'); $slug = strtolower($slug); return $slug; }