=h($m['title'])?>=h($m['title'])?>
=h($m['title'])?>=h($m['title'])?>
=render_description_html($m['description'])?>
“=h(trim((string)$m['quote_da'], "\"“”"))?>”
' . $m[0] . ' (opens in new tab)'; }, $html); return nl2br($linked ?? $html, false); } function nice_title($s){ return trim(ucwords(str_replace(['_','-'], ' ', (string)$s))); } function lower_text($s){ return function_exists('mb_strtolower') ? mb_strtolower((string)$s, 'UTF-8') : strtolower((string)$s); } function fold_text($s){ $s = strtr((string)$s, [ 'æ'=>'ae','Æ'=>'ae','ø'=>'o','Ø'=>'o','å'=>'aa','Å'=>'aa', 'ä'=>'ae','Ä'=>'ae','ö'=>'oe','Ö'=>'oe','ü'=>'ue','Ü'=>'ue','ß'=>'ss','ẞ'=>'ss', 'č'=>'c','Č'=>'c','ć'=>'c','Ć'=>'c','ž'=>'z','Ž'=>'z','š'=>'s','Š'=>'s','đ'=>'d','Đ'=>'d', ]); if (function_exists('iconv')) { $x = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); if ($x !== false) $s = $x; } $s = lower_text($s); return preg_replace('/[^a-z0-9]+/', ' ', $s) ?? ''; } function ci_contains($haystack, $needle){ $haystack = (string)$haystack; $needle = (string)$needle; if ($needle === '') return true; if (function_exists('mb_stripos') && mb_stripos($haystack, $needle, 0, 'UTF-8') !== false) return true; if (strpos(lower_text($haystack), lower_text($needle)) !== false) return true; $foldHay = fold_text($haystack); $foldNeedle = trim(fold_text($needle)); if ($foldNeedle === '') return false; return strpos($foldHay, $foldNeedle) !== false; } function keep_non_empty(array $params): array { return array_filter($params, fn($v)=>$v !== '' && $v !== null); } function query_url(array $params): string { $params = keep_non_empty($params); return $params ? ('?' . http_build_query($params)) : 'index.php'; } function hidden_video_outputs($config){ $hidden = []; foreach (glob($config['uploads_dir'].'/*', GLOB_ONLYDIR) ?: [] as $dir) { if (!is_file($dir . '/.mvlog-hidden')) continue; $state = is_file($dir . '/.movmaker-state.json') ? json_decode((string)file_get_contents($dir . '/.movmaker-state.json'), true) : []; if (is_array($state) && !empty($state['output'])) $hidden[basename((string)$state['output'])] = true; } return $hidden; } function map_hidden_outputs($config){ $hidden = []; foreach (glob($config['uploads_dir'].'/*', GLOB_ONLYDIR) ?: [] as $dir) { if (!is_file($dir . '/.mvlog-hide-map')) continue; $state = is_file($dir . '/.movmaker-state.json') ? json_decode((string)file_get_contents($dir . '/.movmaker-state.json'), true) : []; if (is_array($state) && !empty($state['output'])) $hidden[basename((string)$state['output'])] = true; } return $hidden; } function shown_video_paths($config){ $videos = []; $seen = []; foreach (glob($config['uploads_dir'].'/*', GLOB_ONLYDIR) ?: [] as $dir) { // Public index shows only items explicitly enabled with the admin "Show" switch. if (is_file($dir . '/.mvlog-hidden')) continue; $stateFile = $dir . '/.movmaker-state.json'; if (!is_file($stateFile)) continue; $state = json_decode((string)file_get_contents($stateFile), true); if (!is_array($state)) continue; $name = basename((string)($state['output'] ?? '')); if ($name === '' || preg_match('/_preview\.(mp4|webm|mov|m4v)$/i', $name)) continue; $path = $config['videos_dir'] . '/' . $name; if (!is_file($path) || isset($seen[$name])) continue; $seen[$name] = true; $videos[] = $path; } return $videos; } function permalink_video_paths($config, $articleId){ $articleId = strtolower(trim((string)$articleId)); if (!preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $articleId)) return []; foreach (glob($config['uploads_dir'].'/*', GLOB_ONLYDIR) ?: [] as $dir) { if (!is_file($dir . '/.mvlog-permalink')) continue; if (read_article_id($dir) !== $articleId) continue; $stateFile = $dir . '/.movmaker-state.json'; if (!is_file($stateFile)) return []; $state = json_decode((string)file_get_contents($stateFile), true); if (!is_array($state)) return []; $name = basename((string)($state['output'] ?? '')); if ($name === '' || preg_match('/_preview\.(mp4|webm|mov|m4v)$/i', $name)) return []; $path = $config['videos_dir'] . '/' . $name; return is_file($path) ? [$path] : []; } return []; } function public_url_path($path){ $path = str_replace('\\', '/', trim((string)$path)); if ($path === '') return ''; $parts = array_values(array_filter(explode('/', $path), static fn($p) => $p !== '')); return implode('/', array_map('rawurlencode', $parts)); } function video_thumb_public_url($config, $videoName){ $videoName = basename((string)$videoName); if ($videoName === '') return ''; $info = function_exists('video_thumb_source_info') ? video_thumb_source_info($config, $videoName) : []; $sourcePath = (string)($info['source_path'] ?? ''); if ($sourcePath !== '') { $abs = str_starts_with($sourcePath, '/') ? $sourcePath : __DIR__ . '/' . ltrim($sourcePath, '/'); if (is_file($abs)) return public_url_path($sourcePath) . '?v=' . filemtime($abs); } $sourceFile = basename((string)($info['source_file'] ?? '')); $inputDir = basename((string)($info['input_dir'] ?? '')); if ($sourceFile !== '' && $inputDir !== '') { $rel = 'in-dir/' . $inputDir . '/' . $sourceFile; $abs = __DIR__ . '/' . $rel; if (is_file($abs)) return public_url_path($rel) . '?v=' . filemtime($abs); } return ''; } function video_thumb_source_info($config, $videoName){ $videoName = basename((string)$videoName); if ($videoName === '') return []; $base = pathinfo($videoName, PATHINFO_FILENAME); $file = $config['videos_dir'] . '/' . $base . '_thumb.json'; if (!is_file($file)) return []; $data = json_decode((string)file_get_contents($file), true); return is_array($data) ? $data : []; } function video_article_id($config, $videoName){ $videoName = basename((string)$videoName); if ($videoName === '') return ''; foreach (glob($config['uploads_dir'].'/*', GLOB_ONLYDIR) ?: [] as $dir) { $stateFile = $dir . '/.movmaker-state.json'; if (!is_file($stateFile)) continue; $state = json_decode((string)file_get_contents($stateFile), true); if (!is_array($state)) continue; $output = basename((string)($state['output'] ?? '')); $previewOutput = basename((string)($state['preview_output'] ?? '')); if ($videoName === $output || $videoName === $previewOutput) return (string)($state['article_id'] ?? ''); } return ''; } function input_dirs($base){ return glob($base.'/*', GLOB_ONLYDIR) ?: []; } function read_article_id($dir){ $idFile = rtrim((string)$dir, '/').'/.mvlog-id'; if (!is_file($idFile)) return ''; $id = trim((string)file_get_contents($idFile)); return preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $id) ? $id : ''; } function input_dir_permalink($dir){ return is_file($dir . '/.mvlog-permalink'); } function article_permalink_enabled($config, $articleId){ static $cache = null; if ($cache === null) { $cache = []; foreach (input_dirs($config['uploads_dir']) as $dir) { $id = read_article_id($dir); if ($id !== '') $cache[$id] = input_dir_permalink($dir); } } $articleId = strtolower(trim((string)$articleId)); if (!preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $articleId)) return false; return !empty($cache[$articleId]); } function article_og_image_url($articleId){ $articleId = strtolower(trim((string)$articleId)); if (!preg_match('/^[0-9]{14}[a-f0-9]{16}$/', $articleId)) return ''; $path = __DIR__ . '/out-dir/' . $articleId . '_og.jpg'; if (!is_file($path)) return ''; return 'https://bubulescu.org/out-dir/' . rawurlencode($articleId . '_og.jpg'); } function render_404_page(){ http_response_code(404); include __DIR__ . '/404.php'; exit; } function render_blank_page(){ $headerTitles = require __DIR__ . '/header_titles.php'; $siteHeaderTitle = $headerTitles[array_rand($headerTitles)]; $brandUrl = '/'; $ogImageUrl = 'https://bubulescu.org/assets/img/bubulescuorg.jpg'; ?>
No videos found for current filter.
=render_description_html($m['description'])?>
“=h(trim((string)$m['quote_da'], "\"“”"))?>”