Site Builder
Editing:
init-withtemp.php
writable 0666
<?php /***************************************************************** * OpenAI helper v1.3 (Aug‑2025) * path: /openai/init.php *****************************************************************/ declare(strict_types=1); /* ---------- constants ------------------------------------- */ const AI_COOKIE = 'openai_key'; const AI_SECRET = 'openai-shared-v1'; const AI_TTL = 30*24*3600; // 30 days /* ---------- cookie domain --------------------------------- */ $AI_ROOT=(static function(){ $h=$_SERVER['HTTP_HOST']??''; return (!filter_var($h,FILTER_VALIDATE_IP)&&preg_match('/([a-z0-9-]+\.[a-z]{2,})$/i',$h,$m)) ? '.'.$m[1] : ''; })(); /* ---------- crypto helpers -------------------------------- */ function ai_enc(string $v):string{ $m='aes-128-ctr';$k=substr(hash('sha256',AI_SECRET,true),0,16); $iv=random_bytes(openssl_cipher_iv_length($m)); return base64_encode(openssl_encrypt($v,$m,$k,0,$iv)."::{$iv}"); } function ai_dec(string $c):string{ [$ct,$iv]=explode('::',base64_decode($c),2)+['','']; $m='aes-128-ctr';$k=substr(hash('sha256',AI_SECRET,true),0,16); return openssl_decrypt($ct,$m,$k,0,$iv)?:''; } /* ---------- key helpers ----------------------------------- */ function ai_has_key():bool {return isset($_COOKIE[AI_COOKIE])&&ai_dec($_COOKIE[AI_COOKIE]);} function ai_get_key():string {return ai_has_key()?ai_dec($_COOKIE[AI_COOKIE]):'';} /* ---------- flash msg ------------------------------------- */ $AI_MSG=''; /* ---------- handle save / delete key ---------------------- */ function ai_handle_key_post():void{ global $AI_ROOT,$AI_MSG; if($_SERVER['REQUEST_METHOD']==='POST' && isset($_POST['save_key'])){ setcookie(AI_COOKIE,'',time()-3600,'/',$AI_ROOT,isset($_SERVER['HTTPS']),true); $raw=trim($_POST['api_key']??''); if($raw===''){ $AI_MSG='API key empty'; return; } $ctx=stream_context_create(['http'=>['method'=>'GET','header'=>"Authorization: Bearer $raw\r\n",'timeout'=>6]]); if(@file_get_contents('https://api.openai.com/v1/models',false,$ctx)){ setcookie(AI_COOKIE,ai_enc($raw),time()+AI_TTL,'/',$AI_ROOT,isset($_SERVER['HTTPS']),true); header('Location: '.$_SERVER['REQUEST_URI']);exit; } $AI_MSG='❌ Invalid API key (or network error).';return; } if(isset($_GET['logout'])){ setcookie(AI_COOKIE,'',time()-3600,'/',$AI_ROOT,isset($_SERVER['HTTPS']),true); header('Location: '.$_SERVER['PHP_SELF']);exit; } } /* ---------- key bar --------------------------------------- */ function ai_render_key_bar(array $extraModels=[]):void{ global $AI_MSG; $models=array_merge(['gpt-3.5-turbo','gpt-4o-mini','gpt-4'],$extraModels); ?> <style> .top-bar{background:#0d1117;padding:.25rem 1rem;display:flex;flex-wrap:wrap;align-items:center; justify-content:space-between;gap:.75rem;font-size:.9rem} .top-bar .left,.top-bar .right{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem} .top-bar h1{margin:0;font-size:1rem;color:#ffb63b;display:flex;align-items:center;gap:.4rem} .logout-btn{background:none;color:#e24d4b;font-size:1.1rem;font-weight:700;cursor:pointer;border:none} .gear-btn{background:#1e2430;color:#fff;border:none;border-radius:4px;width:34px;height:34px;font-size:1.05rem;cursor:pointer} .top-bar input[type=password],.top-bar select,.top-bar button[name=save_key]{ height:34px;font-size:.9rem;border:none;border-radius:4px;padding:0 .8rem;line-height:1} .top-bar input[type=password]{width:180px;background:#fff;color:#000} .top-bar button[name=save_key]{background:#004cff;color:#fff;font-weight:600;padding:0 1rem;cursor:pointer} .top-bar a{font-size:.85rem;color:#5af287;text-decoration:none;white-space:nowrap} .top-bar select{background:#1e2430;color:#fff} </style> <div class="top-bar"> <?php if(!ai_has_key()): ?> <div class="left"> <h1>Connect to OpenAI</h1> <a href="https://platform.openai.com/account/api-keys" target="_blank">Get an API key ↗</a> </div> <form method="post" autocomplete="off" class="right"> <input type="password" name="api_key" placeholder="sk-…" required> <button name="save_key">Save Key</button> </form> <?php if($AI_MSG):?><div style="width:100%;color:#e24d4b;font-weight:600;margin-top:.25rem"><?=$AI_MSG?></div><?php endif;?> <?php else: ?> <div class="left"> <h1>Connected to OpenAI <button class="logout-btn" onclick="location='?logout=1'" title="Delete key">×</button></h1> </div> <div class="right"> <button id="aiGear" class="gear-btn" title="Advanced settings">⚙</button> <select id="modelSel"><?php foreach($models as $m) echo "<option>$m</option>";?></select> <a href="https://platform.openai.com/account/usage" target="_blank">Check usage ↗</a> <?php if($AI_MSG):?><span style="color:#e24d4b;font-weight:600"><?=$AI_MSG?></span><?php endif;?> </div> <?php endif;?> </div> <!-- modal --> <div id="aiModal" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:9999"> <div style="background:#fff;padding:1.6rem;border-radius:8px;max-width:320px;width:90%; margin:8% auto;font-size:.95rem;box-shadow:0 4px 18px rgba(0,0,0,.2)"> <h3 style="margin-top:0">Advanced settings</h3> <label style="display:block;margin:.7rem 0 .25rem;font-weight:600" for="aiTemp">Temperature (0–1)</label> <input type="number" id="aiTemp" min="0" max="1" step="0.01" value="0.7" style="width:100%;padding:.5rem .7rem;border:1px solid #ccd4e8;border-radius:6px"> <label style="display:block;margin:.9rem 0 .25rem;font-weight:600" for="aiTok">Max tokens (1–4096)</label> <input type="number" id="aiTok" min="1" max="4096" value="800" style="width:100%;padding:.5rem .7rem;border:1px solid #ccd4e8;border-radius:6px"> <div style="display:flex;gap:.8rem;margin-top:1.4rem;justify-content:flex-end"> <button type="button" id="aiCancel" style="background:#e5e5e5;border:none;border-radius:6px;padding:.5rem 1rem;cursor:pointer">Cancel</button> <button type="button" id="aiSave" style="background:#004cff;color:#fff;border:none;border-radius:6px;padding:.5rem 1rem;font-weight:600;cursor:pointer">Save</button> </div> </div> </div> <script> /* ---------- sync model selector --------------------------- */ document.getElementById('modelSel')?.addEventListener('change',e=>{ document.querySelectorAll('input[name=model]').forEach(i=>i.value=e.target.value); }); /* ---------- advanced defaults ----------------------------- */ const gear=document.getElementById('aiGear'), modal=document.getElementById('aiModal'); if(gear&&modal){ const tI=document.getElementById('aiTemp'), mI=document.getElementById('aiTok'), save=document.getElementById('aiSave'), cancel=document.getElementById('aiCancel'); /* load previous defaults */ try{ const d=JSON.parse(localStorage.getItem('aiDefaults')||'{}'); if(d.temp) tI.value=d.temp; if(d.max) mI.value=d.max; }catch{} gear.onclick = ()=> modal.style.display='block'; cancel.onclick = ()=> modal.style.display='none'; modal.addEventListener('click',e=>{if(e.target===modal) modal.style.display='none';}); save.onclick = ()=>{ const obj={ temp:Math.max(0,Math.min(1,parseFloat(tI.value)||0.7)), max :Math.max(1,Math.min(4096,parseInt(mI.value,10)||800)) }; localStorage.setItem('aiDefaults',JSON.stringify(obj)); modal.style.display='none'; dispatchEvent(new CustomEvent('ai-defaults-changed',{detail:obj})); }; } /* ---------- inject defaults into every prompt form -------- */ (function applyDefaults(){ function inject(obj){ document.querySelectorAll('form').forEach(f=>{ if(!f.querySelector('textarea[name=prompt], textarea[id*=prompt]')) return; ['temperature','max_tokens'].forEach(k=>{ if(!f.querySelector(`input[name=${k}]`)){ const inp=document.createElement('input');inp.type='hidden';inp.name=k;f.appendChild(inp); } }); f.querySelector('input[name=temperature]').value=obj.temp??0.7; f.querySelector('input[name=max_tokens]').value =obj.max ??800; }); } let cur={temp:0.7,max:800}; try{cur={...cur,...JSON.parse(localStorage.getItem('aiDefaults')||'{}')} }catch{} inject(cur); addEventListener('ai-defaults-changed',e=>inject(e.detail)); })(); </script> <?php } /* ---------- chat wrapper ---------------------------------- */ function ai_chat(string $prompt,array $opts=[]):string{ $key=ai_get_key(); if(!$key) return ''; /* pick defaults from localStorage via $_POST (injected by JS helper) */ $temp=floatval($_POST['temperature']??0.7); $max =intval($_POST['max_tokens']??800); $body=[ 'model' =>$opts['model'] ?? 'gpt-3.5-turbo', 'messages' =>[['role'=>'user','content'=>$prompt]], 'temperature' =>$opts['temperature'] ?? $temp, 'max_tokens' =>$opts['max_tokens'] ?? $max, ]; $ch=curl_init('https://api.openai.com/v1/chat/completions'); curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>1,CURLOPT_POST=>1, CURLOPT_HTTPHEADER=>['Authorization: Bearer '.$key,'Content-Type: application/json'], CURLOPT_POSTFIELDS=>json_encode($body),CURLOPT_TIMEOUT=>60]); $raw=curl_exec($ch);curl_close($ch); return $raw?(json_decode($raw,true)['choices'][0]['message']['content']??''):''; }
Save changes
Create folder
writable 0777
Create
Cancel