| Server IP : 188.114.96.3 / Your IP : 216.73.216.143 Web Server : Apache System : Linux sv058.home.net.pl 6.8.2 husak_dirty_pages_fix #1 SMP PREEMPT_DYNAMIC Tue Apr 2 22:06:51 CEST 2024 x86_64 User : ( 3194769) PHP Version : 8.5.12 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /polana/admin/ |
Upload File : |
<?php
declare(strict_types=1);
/** POLANA V19.0: on-demand, read-only multi-URL SEO audit. Same-domain only. */
require_once dirname(__DIR__).'/includes/functions.php';
require_admin_role();
header('Cache-Control: private, no-store');
header('X-Robots-Tag: noindex, nofollow');
const PA190_BASE = 'https://mojapolanasmakow.pl';
function pa190_e($s):string{return htmlspecialchars((string)$s,ENT_QUOTES|ENT_SUBSTITUTE,'UTF-8');}
function pa190_url(string $u):?string{
$p=parse_url($u);
if(!is_array($p)||strtolower((string)($p['scheme']??''))!=='https'||strtolower((string)($p['host']??''))!=='mojapolanasmakow.pl'||isset($p['port'])||isset($p['user'])||isset($p['pass'])||isset($p['fragment']))return null;
$path=$p['path']??'/';
if(!is_string($path)||!str_starts_with($path,'/')||str_starts_with($path,'//')||strlen($path)>450)return null;
return PA190_BASE.$path.(isset($p['query'])?'?'.$p['query']:'');
}
function pa190_fetch(string $url):array{
if(pa190_url($url)!==$url)throw new RuntimeException('Niedozwolony adres skanera.');
$status=0;$body='';$time=0;$redirect='';$error='';
if(function_exists('curl_init')){
$ch=curl_init($url);
curl_setopt_array($ch,[CURLOPT_RETURNTRANSFER=>true,CURLOPT_FOLLOWLOCATION=>false,CURLOPT_MAXREDIRS=>0,
CURLOPT_CONNECTTIMEOUT=>3,CURLOPT_TIMEOUT=>6,CURLOPT_SSL_VERIFYPEER=>true,CURLOPT_SSL_VERIFYHOST=>2,
CURLOPT_USERAGENT=>'Polana-SEO-AdminAudit/19.0 (+https://mojapolanasmakow.pl/)',
CURLOPT_HTTPHEADER=>['Accept: text/html,application/xml,text/plain;q=0.9','Cache-Control: no-cache'],
CURLOPT_ENCODING=>'']);
$t=microtime(true); $read=curl_exec($ch); $time=(int)round((microtime(true)-$t)*1000);
$status=(int)curl_getinfo($ch,CURLINFO_HTTP_CODE);
$redirect=(string)curl_getinfo($ch,CURLINFO_REDIRECT_URL);
$error=(string)curl_error($ch); curl_close($ch);
if(is_string($read))$body=substr($read,0,700000);
}else{
$ctx=stream_context_create(['http'=>['timeout'=>6,'follow_location'=>0,'max_redirects'=>0,'ignore_errors'=>true,
'header'=>"User-Agent: Polana-SEO-AdminAudit/19.0\r\nAccept: text/html,application/xml,text/plain\r\n"],
'ssl'=>['verify_peer'=>true,'verify_peer_name'=>true]]);
$t=microtime(true);$read=@file_get_contents($url,false,$ctx);$time=(int)round((microtime(true)-$t)*1000);
if(is_string($read))$body=substr($read,0,700000);
foreach(($http_response_header??[]) as $h){if(preg_match('~^HTTP/\S+\s+(\d{3})~',$h,$m))$status=(int)$m[1];if(preg_match('~^Location:\s*(.+)~i',$h,$m))$redirect=trim($m[1]);}
if($read===false)$error='Nie uzyskano odpowiedzi HTTPS (np. ograniczenie PHP lub Cloudflare).';
}
return ['status'=>$status,'body'=>$body,'time'=>$time,'redirect'=>$redirect,'error'=>$error];
}
function pa190_tag(string $html,string $name):string{
if(!preg_match('~<'.preg_quote($name,'~').'\b[^>]*>(.*?)</'.preg_quote($name,'~').'\s*>~is',$html,$m))return '';
return trim(html_entity_decode(strip_tags($m[1]),ENT_QUOTES|ENT_HTML5,'UTF-8'));
}
function pa190_attr(string $tag,string $attr):string{
$pattern='~\b'.preg_quote($attr,'~').'\s*=\s*(["\'])(.*?)\1~is';
return preg_match($pattern,$tag,$m)?trim(html_entity_decode($m[2],ENT_QUOTES|ENT_HTML5,'UTF-8')):'';
}
function pa190_meta(string $html,string $name):string{
if(preg_match_all('~<meta\b[^>]*>~i',$html,$tags))foreach($tags[0] as $tag){
if(strcasecmp(pa190_attr($tag,'name'),$name)===0)return pa190_attr($tag,'content');
}
return '';
}
function pa190_canonical(string $html):string{
if(preg_match_all('~<link\b[^>]*>~i',$html,$tags))foreach($tags[0] as $tag){
if(in_array('canonical',preg_split('~\s+~',strtolower(pa190_attr($tag,'rel'))),true))return pa190_attr($tag,'href');
}
return '';
}
$routes=['/','/andrzej-polan','/kontakt','/menu','/rezerwacja','/blog','/galeria','/wspolpraca','/alergeny','/polityka-prywatnosci'];
$error='';$report=[];$sitemapStatus='Nie sprawdzono';$robotsStatus='Nie sprawdzono';$urls=[];
if(($_SERVER['REQUEST_METHOD']??'GET')==='POST'){
verify_csrf();
$offset=min(200,max(0,(int)($_POST['offset']??0)));
try{
$xml=pa190_fetch(PA190_BASE.'/sitemap.xml');
$sitemapStatus='HTTP '.$xml['status'].($xml['error']!==''?' — '.$xml['error']:'');
if($xml['status']===200 && preg_match_all('~<loc\s*>\s*(.*?)\s*</loc>~si',$xml['body'],$match)){
foreach($match[1] as $entry){
$u=pa190_url(html_entity_decode(strip_tags($entry),ENT_QUOTES|ENT_XML1,'UTF-8'));
if($u!==null)$urls[$u]=$u;
if(count($urls)>=200)break;
}
}
// The site can fail to generate the sitemap: preserve an independent static fallback.
foreach($routes as $r){$u=PA190_BASE.$r;$urls[$u]=$u;}
$urls=array_values($urls);
$robots=pa190_fetch(PA190_BASE.'/robots.txt');
$robotsStatus='HTTP '.$robots['status'];
$max=min(count($urls),$offset+8);
for($i=$offset;$i<$max;$i++){
$u=$urls[$i];$r=pa190_fetch($u);$html=$r['body'];
$title=pa190_tag($html,'title');$h1=preg_match_all('~<h1(?:\s[^>]*)?>~i',$html);
$canonical=pa190_canonical($html);$robotsMeta=pa190_meta($html,'robots');
$issues=[];
if($r['status']!==200)$issues[]='HTTP '.$r['status'];
if($r['status']===200){
if($title==='')$issues[]='brak TITLE';
if($h1!==1)$issues[]='H1: '.$h1;
if($canonical==='')$issues[]='brak canonical';
elseif(!str_starts_with($canonical,PA190_BASE.'/'))$issues[]='canonical poza domeną';
if(stripos($robotsMeta,'noindex')!==false)$issues[]='noindex — oceń, czy celowe';
if(pa190_meta($html,'description')==='')$issues[]='brak opisu';
}
$report[]=['url'=>$u,'status'=>$r['status'],'ms'=>$r['time'],'title'=>$title,'h1'=>$h1,
'description'=>pa190_meta($html,'description'),'canonical'=>$canonical,'robots'=>$robotsMeta,
'issues'=>$issues,'error'=>$r['error'],'redirect'=>$r['redirect']];
}
}catch(Throwable $e){$error=$e->getMessage();}
}else{$offset=0;}
render_admin_header('POLANA SEO V19.0 — skan publicznych URL');
?>
<style>
.pa190{max-width:1200px;margin:20px auto 60px;padding:0 14px}.pa190 section{background:#fff;border:1px solid #e3e7e3;border-radius:12px;padding:19px;margin:16px 0}
.pa190 table{border-collapse:collapse;width:100%;font-size:13px}.pa190 th,.pa190 td{border-bottom:1px solid #e3e7e3;text-align:left;padding:10px 7px;vertical-align:top;overflow-wrap:anywhere}
.pa190 th{background:#f6f8f5}.pa190 .wrap{overflow-x:auto}.pa190 button{background:#1b5432;color:#fff;padding:10px 18px;border:0;border-radius:9px;cursor:pointer}
.pa190 .err{background:#ffeded;padding:12px}.pa190 small{color:#66766b}.pa190 a{color:#17643a;text-decoration:underline}
</style>
<div class="pa190">
<h1>Audyt SEO wszystkich publicznych podstron — partie po 8</h1>
<p>Skan na żywo odczytuje tylko adresy własnej domeny z <code>sitemap.xml</code> oraz główne ścieżki witryny. Nie zmienia plików, ustawień ani indeksacji. Dodatkowe adresy z mapy sprawdzisz partiami, bez przeciążania hostingu.</p>
<?php if($error):?><p class="err"><?=pa190_e($error)?></p><?php endif;?>
<section><p><b>Sitemap:</b> <?=pa190_e($sitemapStatus)?> · <b>robots.txt:</b> <?=pa190_e($robotsStatus)?></p>
<p><a href="/admin/polana-seo-v190.php">Powrót do instalatora V19.0</a> · <a href="/admin/polana-indexnow.php">IndexNow / Bing</a> · <a href="https://www.bing.com/webmasters/" target="_blank" rel="noopener">Bing Webmaster Tools</a></p>
<form method="post"><?=csrf_field()?><input type="hidden" name="offset" value="0"><button type="submit">Skanuj pierwsze 8 adresów</button></form>
</section>
<?php if($report):?><section><h2>Wyniki <?=($offset+1)?>–<?=($offset+count($report))?> z <?=count($urls)?> URL</h2><div class="wrap"><table>
<thead><tr><th>URL</th><th>HTTP / ms</th><th>Tytuł i H1</th><th>Canonical / robots</th><th>Uwagi</th></tr></thead><tbody>
<?php foreach($report as $r):?><tr>
<td><a href="<?=pa190_e($r['url'])?>" target="_blank" rel="noopener noreferrer"><?=pa190_e(preg_replace('~^https://mojapolanasmakow\.pl~','',$r['url'])?:'/')?></a></td>
<td><?= (int)$r['status']?> / <?= (int)$r['ms']?><br><small><?=pa190_e($r['error'] ?: $r['redirect'])?></small></td>
<td><?=pa190_e($r['title'])?><br><small>H1: <?= (int)$r['h1']?> · opis: <?=function_exists('mb_strlen')?mb_strlen($r['description'],'UTF-8'):strlen($r['description'])?> znaków</small></td>
<td><small><?=pa190_e($r['canonical'])?></small><br><?=pa190_e($r['robots'])?></td>
<td><?=pa190_e(implode('; ',$r['issues']) ?: 'Brak wykrytych problemów podstawowych')?></td>
</tr><?php endforeach;?></tbody></table></div>
<?php if($offset+count($report)<count($urls)):?><form method="post" style="margin-top:15px"><?=csrf_field()?><input type="hidden" name="offset" value="<?=($offset+count($report))?>"><button type="submit">Skanuj kolejne 8 adresów</button></form><?php endif;?>
<p><small>HTTP 301/302 i brak metadanych przy przekierowaniach nie oznacza awarii — sprawdź adres końcowy. Noindex może być prawidłowy dla treści pomocniczych. Ten skan nie potwierdza indeksacji Google/Bing.</small></p></section><?php endif;?>
</div>
<?php render_admin_footer(); ?>