Existing input dirs
No input directories yet.
=h(basename($d))?> ยท =h(count(list_files($d)))?> files
Edit input dir
in-dir/=h(basename($editDir))?>
filemtime($b)<=>filemtime($a)); return $dirs; } function safe_input_dir($base, $name){ $name = basename((string)$name); $path = realpath($base . '/' . $name); $root = realpath($base); if (!$path || !$root || !str_starts_with($path, $root . DIRECTORY_SEPARATOR) || !is_dir($path)) throw new RuntimeException('Invalid input directory.'); return $path; } function read_data($dir){ $data = ['title'=>'','date'=>'','place'=>'','description'=>'']; $file = $dir . '/data.txt'; if (!is_file($file)) return $data; $header = []; $description = []; $inDescription = false; foreach (file($file, FILE_IGNORE_NEW_LINES) as $line) { $line = trim($line); if ($line === '' && ($header || $inDescription)) { $inDescription = true; continue; } if ($line === '' || str_starts_with($line, '#')) continue; if (str_contains($line, ':')) continue; // key:value is only for per-file captions if ($inDescription) $description[] = $line; else $header[] = $line; } if ($header) $data['title'] = $header[0]; if (count($header) > 1) $data['place'] = $header[1]; if (count($header) > 2) $data['date'] = $header[2]; if ($description) $data['description'] = implode("\n", $description); return $data; } function write_data($dir, $post){ $title = trim($post['title'] ?? ''); $place = trim($post['place'] ?? ''); $date = trim($post['date'] ?? ''); $description = trim($post['description'] ?? ''); $lines = []; if ($title !== '') $lines[] = $title; if ($place !== '') $lines[] = $place; if ($place !== '' && $date !== '') $lines[] = $date; if ($description !== '') { $lines[] = ''; $lines[] = $description; } file_put_contents($dir . '/data.txt', implode("\n", $lines) . "\n"); } function list_files($dir){ $files = array_values(array_filter(scandir($dir), fn($f)=>$f!=='.' && $f!=='..' && is_file($dir.'/'.$f) && $f !== 'data.txt')); natcasesort($files); return $files; } function save_uploads($field, $dest, $allowed){ if (empty($_FILES[$field])) return []; $files = $_FILES[$field]; $saved = []; $count = is_array($files['name']) ? count($files['name']) : 0; for ($i=0; $i<$count; $i++) { if ($files['error'][$i] === UPLOAD_ERR_NO_FILE) continue; if ($files['error'][$i] !== UPLOAD_ERR_OK) throw new RuntimeException("Upload failed: ".$files['name'][$i]); $ext = strtolower(pathinfo($files['name'][$i], PATHINFO_EXTENSION)); if (!in_array($ext, $allowed, true)) throw new RuntimeException("File type not allowed: ".$files['name'][$i]); $base = preg_replace('/[^A-Za-z0-9._-]+/', '_', basename($files['name'][$i])); $target = $dest . '/' . sprintf('%03d_', count(glob($dest.'/*') ?: [])+count($saved)+1) . $base; if (!move_uploaded_file($files['tmp_name'][$i], $target)) throw new RuntimeException("Cannot save upload"); $saved[] = basename($target); } return $saved; } $msg = $err = null; $allowedMedia = ['jpg','jpeg','png','webp','gif','mp4','mov','m4v','avi','mkv','webm']; $allowedAudio = ['mp3','wav','m4a','aac','ogg','flac']; try { if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? 'create'; if ($action === 'create') { $title = trim($_POST['title'] ?? ''); if ($title === '') throw new RuntimeException('Title is required.'); $slug = date('Ymd_His') . '_' . slugify($title); $dir = $config['uploads_dir'] . '/' . $slug; if (!mkdir($dir, 0775, true)) throw new RuntimeException('Cannot create input directory.'); $media = save_uploads('media', $dir, $allowedMedia); if (!$media) { rrmdir($dir); throw new RuntimeException('Upload at least one image or video.'); } save_uploads('audio', $dir, $allowedAudio); write_data($dir, $_POST); $msg = "Created movmaker input directory: in-dir/$slug"; $_GET['edit'] = $slug; } elseif ($action === 'update') { $dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? ''); write_data($dir, $_POST); save_uploads('media', $dir, $allowedMedia); save_uploads('audio', $dir, $allowedAudio); $msg = 'Updated input directory: in-dir/' . basename($dir); $_GET['edit'] = basename($dir); } elseif ($action === 'delete_file') { $dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? ''); $file = basename((string)($_POST['file'] ?? '')); if ($file === '' || $file === 'data.txt' || !is_file($dir.'/'.$file)) throw new RuntimeException('Invalid file.'); unlink($dir.'/'.$file); $msg = 'Removed file: ' . $file; $_GET['edit'] = basename($dir); } elseif ($action === 'delete_dir') { $dir = safe_input_dir($config['uploads_dir'], $_POST['dir'] ?? ''); $name = basename($dir); rrmdir($dir); $msg = 'Deleted input directory: in-dir/' . $name; } } } catch (Throwable $e) { $err = $e->getMessage(); } $dirs = input_dirs($config['uploads_dir']); $editName = $_GET['edit'] ?? ''; $editDir = null; $editData = ['title'=>'','date'=>'','place'=>'','description'=>'']; $editFiles = []; if ($editName !== '') { try { $editDir = safe_input_dir($config['uploads_dir'], $editName); $editData = read_data($editDir); $editFiles = list_files($editDir); } catch (Throwable $e) { $err = $e->getMessage(); } } ?>
No input directories yet.
in-dir/=h(basename($editDir))?>