Siteβ―Builder
Editing:
import.php
writable 0666
<?php /* MelanieΒ AI β Site Importer 1.1 Upload ZIP β review β selective extract -------------------------------------------------------------------- */ /* ββ security gate βββββββββββββββββββββββββββββββββββββββββββββββ */ 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(); /* β devβfriendly error display (remove on prod) */ ini_set('display_errors',1); error_reporting(E_ALL); /* ββ prerequisites βββββββββββββββββββββββββββββββββββββββββββββββ */ if(!class_exists('ZipArchive')) die('ZipArchive extension missing.'); if(!is_writable(sys_get_temp_dir())) die('Temporary directory not writable.'); /* ββ config ββββββββββββββββββββββββββββββββββββββββββββββββββββββ */ define('MAX_ZIP_SIZE', 50*1024*1024); // 50Β MB define('TMP_DIR', sys_get_temp_dir()); define('WEB_ROOT', realpath($_SERVER['DOCUMENT_ROOT'])); /* ββ helpers βββββββββββββββββββββββββββββββββββββββββββββββββββββ */ function clean($p){return ltrim(str_replace(['\\','..'],['/',''],$p),'/');} function nice($b){return $b>1048576?round($b/1048576,1).'β―MB':round($b/1024).'Β KB';} /* ββ state (kept in session) ββββββββββββββββββββββββββββββββββββ */ $state = &$_SESSION['imp']; /* no state yet β upload screen */ if(!$state) $state=['step'=>'upload']; //////////////////////////////////////////////////////////////////////// // STEP 1 β scan archive //////////////////////////////////////////////////////////////////////// if(isset($_POST['step']) && $_POST['step']==='scan'){ if($_FILES['zip']['error']??1) die('Upload failed.'); if($_FILES['zip']['size']>MAX_ZIP_SIZE) die('File too large.'); $zipTmp = TMP_DIR.'/imp_'.bin2hex(random_bytes(4)).'.zip'; move_uploaded_file($_FILES['zip']['tmp_name'],$zipTmp); $target = clean($_POST['folder']??''); if(!$target) die('No target folder.'); $extract = WEB_ROOT.'/'.$target; $zip = new ZipArchive; if($zip->open($zipTmp)!==true) die('Bad ZIP.'); $list=[]; for($i=0;$i<$zip->numFiles;$i++){ $name = clean($zip->getNameIndex($i)); if(!$name || substr($name,-1)==='/') continue; $list[]=[ 'name'=>$name, 'size'=>$zip->statIndex($i)['size'], 'exists'=>file_exists($extract.'/'.$name) ]; } $zip->close(); /* β store list in tmp json file (not in session) */ $meta = TMP_DIR.'/imp_'.bin2hex(random_bytes(4)).'.json'; file_put_contents($meta,json_encode($list)); $state=[ 'step' => 'review', 'zip' => $zipTmp, 'meta' => $meta, 'extract'=> $extract ]; } //////////////////////////////////////////////////////////////////////// // STEP 2 β extract selected //////////////////////////////////////////////////////////////////////// if(isset($_POST['step']) && $_POST['step']==='import' && $state['step']==='review'){ $pick = array_map('intval',$_POST['pick']??[]); $fileList = json_decode(file_get_contents($state['meta']),true)??[]; $zip=new ZipArchive; $zip->open($state['zip']); foreach($pick as $idx){ if(!isset($fileList[$idx])) continue; $ent=$fileList[$idx]; $src=$zip->getStream($ent['name']); if(!$src) continue; $destPath=$state['extract'].'/'.$ent['name']; $dir=dirname($destPath); if(!is_dir($dir)) mkdir($dir,0755,true); $dest=fopen($destPath,'w'); stream_copy_to_stream($src,$dest); fclose($src); fclose($dest); chmod($destPath,0644); } $zip->close(); unlink($state['zip']); unlink($state['meta']); $state=['step'=>'done','extract'=>$state['extract']]; } //////////////////////////////////////////////////////////////////////// // HTML output //////////////////////////////////////////////////////////////////////// ?><!DOCTYPE html><html><head><meta charset="utf-8"> <title>Site Importer</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;background:var(--bg);color:var(--fg);display:flex;flex-direction:column;min-height:100vh} h1{margin:0;background:var(--panel);padding:1rem 2rem;font-size:1.4rem} main{flex:1;display:flex;justify-content:center;align-items:flex-start;padding:2rem} section{background:var(--panel);padding:1.6rem 2rem;border-radius:var(--radius);min-width:320px;max-width:650px} input[type=file],input[type=text]{width:100%;padding:.5rem;margin:.4rem 0;border:none;border-radius:8px;background:#2b2c3b;color:var(--fg)} button{background:var(--accent);color:#fff;border:none;padding:.6rem 1.4rem;border-radius:40px;font-weight:600;cursor:pointer} table{width:100%;border-collapse:collapse;font-size:.9rem;margin-top:1rem} td,th{padding:.35rem .5rem} th{text-align:left;font-weight:600} tr:nth-child(even){background:#23242f} .exists{color:#ffb063} </style></head><body> <h1>Site Importer</h1><main><section> <?php if($state['step']==='upload'): ?> <h2>1Β· Upload ZIP</h2> <form method="post" enctype="multipart/form-data"> <input type="file" name="zip" accept=".zip" required> <input type="text" name="folder" placeholder="target folder (e.g. maiβmyshop)" required> <p style="font-size:.8rem;opacity:.7;margin-top:0">Folder is created if it doesnβt exist.</p> <button name="step" value="scan">Scan Archive</button> </form> <?php elseif($state['step']==='review'): $list=json_decode(file_get_contents($state['meta']),true)??[]; ?> <h2>2Β· Review files</h2> <form method="post"> <table> <thead><tr><th></th><th>file</th><th>size</th><th></th></tr></thead><tbody> <?php foreach($list as $idx=>$f): ?> <tr> <td><input type="checkbox" name="pick[]" value="<?=$idx?>" <?=$f['exists']?'':'checked'}></td> <td><?=htmlspecialchars($f['name'])?></td> <td><?=nice($f['size'])?></td> <td><?= $f['exists']?'<span class="exists">β overwrite</span>':'β new' ?></td> </tr> <?php endforeach;?></tbody></table> <p style="font-size:.85rem;opacity:.7">Tick the files you want to extract (overwrites are unchecked by default).</p> <button name="step" value="import">Import Selected</button> </form> <?php elseif($state['step']==='done'): ?> <h2>Import complete β</h2> <p>Your files were extracted to:<br><code><?=$state['extract']?></code></p> <p><a href="/">Go to site</a></p> <?php endif; ?> </section></main></body></html>
Save changes
Create folder
writable 0777
Create
Cancel