Site Builder
Editing:
export.php
writable 0666
<?php /* Melanie AI – Site Exporter 1.4 Wrapper script sets $_SERVER vars before including each page -------------------------------------------------------------------- */ require_once $_SERVER['DOCUMENT_ROOT'].'/members/lib/auth.php'; require_login(); if (current_user()['role']!=='admin') forbidden_page(); if (session_status()===PHP_SESSION_NONE) session_start(); define('ROOT_PREG','/^mai-[a-z0-9\-]+$/'); define('WEBROOT', realpath($_SERVER['DOCUMENT_ROOT'])); define('TMP_DIR', sys_get_temp_dir()); /* ------------ helpers ------------------------------------------------ */ function roots(){ return array_map('basename', glob(WEBROOT.'/mai-*',GLOB_ONLYDIR)); } function tree($base,$rel=''){ $h=''; foreach(scandir($base) as $f){ if($f[0]==='.') continue; $full="$base/$f"; $p="$rel/$f"; if(is_dir($full)) $h.="<details><summary>$f/</summary>".tree($full,$p).'</details>'; else $h.="<label><input type='checkbox' name='pick[]' value=\"".htmlspecialchars(ltrim($p,'/'))."\" checked> $f</label><br>"; } return $h; } /* locate CLI php */ function find_cli(): ?string{ $cands=[]; if(function_exists('shell_exec') && stripos(ini_get('disable_functions'),'shell_exec')===false){ $w=trim(shell_exec('which php 2>/dev/null')); if($w) $cands[]=$w; } $cands[] = PHP_BINDIR.'/php'; $cands[] = '/usr/bin/php'; $cands[] = '/usr/local/bin/php'; foreach(glob('/opt/cpanel/ea-php*/root/usr/bin/php') as $p) $cands[]=$p; foreach(array_unique($cands) as $p) if(is_executable($p)) return $p; return null; } $CLI=find_cli(); /* render using a temporary wrapper */ function render_php(string $page,string $cli): string{ $wrapper = TMP_DIR.'/render_'.md5($page.microtime(true)).'.php'; $dir = addslashes(dirname($page)); $file = addslashes(basename($page)); $docroot = addslashes(WEBROOT); $host = addslashes($_SERVER['HTTP_HOST'] ?? 'localhost'); file_put_contents($wrapper, "<?php ". "\$_SERVER['DOCUMENT_ROOT']='$docroot';". "\$_SERVER['HTTP_HOST']='$host';". "chdir('$dir');". "include '$file';" ); $des=[1=>['pipe','w']]; $proc=proc_open([$cli,$wrapper],$des,$pipes); $out = is_resource($proc)?stream_get_contents($pipes[1]):''; if(isset($pipes[1])) fclose($pipes[1]); if(is_resource($proc)) proc_close($proc); unlink($wrapper); return $out; } /* ---------- inputs --------------------------------------------------- */ $root = $_POST['root']??($_GET['root']??''); $do = $_POST['do'] ?? ''; $render = isset($_POST['render']); $picked = $_POST['pick'] ?? []; $msg = ''; /* ---------- export --------------------------------------------------- */ if($do==='zip' && preg_match(ROOT_PREG,$root) && is_dir(WEBROOT.'/'.$root)){ try{ $zipName="export-$root-".date('Ymd-His').'.zip'; $tmpZip = TMP_DIR.'/'.$zipName; $zip=new ZipArchive; if($zip->open($tmpZip,ZipArchive::CREATE|ZipArchive::OVERWRITE)!==true) throw new RuntimeException('Cannot create ZIP'); $rootAbs=WEBROOT.'/'.$root; foreach($picked as $rel){ $rel=ltrim($rel,'/'); $abs=realpath("$rootAbs/$rel"); if(!$abs||strpos($abs,$rootAbs)!==0||is_dir($abs)) continue; $ext=strtolower(pathinfo($rel,PATHINFO_EXTENSION)); if($ext==='php' && $render && $CLI){ $html=render_php($abs,$CLI); $zip->addFromString(preg_replace('/\.php$/','.html',$rel),$html); }else{ $zip->addFile($abs,$rel); } } $zip->close(); header('Content-Type: application/zip'); header("Content-Disposition: attachment; filename=\"$zipName\""); readfile($tmpZip); unlink($tmpZip); exit; }catch(Throwable $e){ $msg='Export failed: '.$e->getMessage(); } }elseif($do==='zip' && !$CLI && $render){ $msg='Server has no PHP CLI binary; exporting original .php files instead.'; } /* ---------- UI (unchanged) ------------------------------------------ */ ?><!DOCTYPE html><html><head><meta charset="utf-8"> <title>Site Exporter</title><meta name="viewport" content="width=device-width,initial-scale=1"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet"> <style> :root{--bg:#101119;--panel:#1c1d27;--accent:#ff4ecd;--fg:#e9e9f2;--radius:12px;font-family:Inter,system-ui,sans-serif} body{margin:0;min-height:100vh;background:var(--bg);color:var(--fg);display:flex;flex-direction:column} h1{margin:0;background:var(--panel);padding:1rem 2rem;font-size:1.4rem} main{flex:1;display:grid;grid-template-columns:320px 1fr;gap:2rem;padding:2rem} section{background:var(--panel);padding:1.2rem;border-radius:var(--radius)} button{background:var(--accent);border:none;color:#fff;padding:.7rem 1.4rem;border-radius:40px;width:100%;cursor:pointer;font-weight:600} details{margin-left:.8rem}label{font-size:.92rem}.note{opacity:.7}.err{color:#ff9898} </style></head><body> <h1>Site Exporter</h1><main> <section> <h2>Select root</h2> <form><select name="root" style="width:100%;padding:.5rem;border-radius:8px;margin-bottom:1rem"> <?php foreach(roots() as $r) echo "<option".($r===$root?' selected':'').">$r</option>";?> </select><button>Open</button></form> <?php if($msg) echo "<p class='".(strpos($msg,'failed')!==false?'err':'note')."'>$msg</p>";?> <?php if(!$CLI) echo "<p class='note'>Note: PHP CLI not found; cannot render .php to .html.</p>";?> </section> <?php if($root && is_dir(WEBROOT.'/'.$root)): ?> <section> <h2><?=htmlspecialchars($root)?></h2> <form method="post"> <input type="hidden" name="root" value="<?=htmlspecialchars($root)?>"> <input type="hidden" name="do" value="zip"> <label><input type="checkbox" name="render" <?=$render?'checked':''?> <?= $CLI?'':'disabled'?>> Render PHP to HTML</label> <div style="max-height:55vh;overflow:auto;border:1px solid #333;padding:.6rem;border-radius:8px;margin-top:.7rem"> <?=tree(WEBROOT.'/'.$root)?> </div> <button style="margin-top:1rem">Download ZIP</button> </form> </section> <?php endif;?></main></body></html>
Save changes
Create folder
writable 0777
Create
Cancel