- Updated CRON documentation to include DataForSEO metrics synchronization. - Enhanced SettingsController to manage DataForSEO API credentials and settings. - Modified SiteController to handle DataForSEO domain input. - Updated Site model to accommodate DataForSEO data handling. - Added methods in SiteSeoMetric model for DataForSEO data retrieval and validation. - Implemented SiteSeoSyncService to synchronize SEO metrics from both SEMSTORM and DataForSEO. - Enhanced dashboard templates to display indexed pages data. - Updated settings and site creation/edit templates to include DataForSEO fields. - Created migration for adding DataForSEO related columns in the database. - Developed DataForSeoService to fetch indexed pages count from DataForSEO API.
159 lines
8.5 KiB
PHP
159 lines
8.5 KiB
PHP
<h2 class="mb-4">Statystyki SEO (ostatnie dane)</h2>
|
|
|
|
<?php
|
|
$currentSort = (string) ($currentSort ?? 'traffic');
|
|
$currentDir = (string) ($currentDir ?? 'desc');
|
|
|
|
$sortLink = static function (string $column) use ($currentSort, $currentDir): string {
|
|
$nextDir = ($currentSort === $column && $currentDir === 'asc') ? 'desc' : 'asc';
|
|
return '/seo/stats?sort=' . urlencode($column) . '&dir=' . urlencode($nextDir);
|
|
};
|
|
|
|
$sortMark = static function (string $column) use ($currentSort, $currentDir): string {
|
|
if ($currentSort !== $column) {
|
|
return '';
|
|
}
|
|
return $currentDir === 'asc' ? ' ↑' : ' ↓';
|
|
};
|
|
|
|
$formatDelta = static function ($current, $previous): string {
|
|
if ($previous === null || $previous === '') {
|
|
return '<span class="text-muted">n/a</span>';
|
|
}
|
|
|
|
$curr = (float) $current;
|
|
$prev = (float) $previous;
|
|
|
|
if ($prev == 0.0) {
|
|
if ($curr == 0.0) {
|
|
return '<span class="text-muted">0%</span>';
|
|
}
|
|
return '<span class="text-muted">n/a</span>';
|
|
}
|
|
|
|
$delta = (($curr - $prev) / $prev) * 100.0;
|
|
$class = $delta > 0 ? 'text-success' : ($delta < 0 ? 'text-danger' : 'text-muted');
|
|
$sign = $delta > 0 ? '+' : '';
|
|
|
|
return '<span class="' . $class . '">' . $sign . number_format($delta, 1, '.', '') . '%</span>';
|
|
};
|
|
?>
|
|
|
|
<div class="card">
|
|
<div class="card-body p-0 table-responsive">
|
|
<table class="table table-sm table-hover mb-0 align-middle small">
|
|
<thead>
|
|
<tr>
|
|
<th>Strona</th>
|
|
<th>Status</th>
|
|
<th>Miesiac</th>
|
|
<th class="text-nowrap"><a class="link-dark text-decoration-none" href="<?= htmlspecialchars($sortLink('top3')) ?>">TOP3<?= htmlspecialchars($sortMark('top3')) ?></a></th>
|
|
<th class="text-nowrap"><a class="link-dark text-decoration-none" href="<?= htmlspecialchars($sortLink('top10')) ?>">TOP10<?= htmlspecialchars($sortMark('top10')) ?></a></th>
|
|
<th class="text-nowrap"><a class="link-dark text-decoration-none" href="<?= htmlspecialchars($sortLink('top20')) ?>">TOP20<?= htmlspecialchars($sortMark('top20')) ?></a></th>
|
|
<th class="text-nowrap"><a class="link-dark text-decoration-none" href="<?= htmlspecialchars($sortLink('top50')) ?>">TOP50<?= htmlspecialchars($sortMark('top50')) ?></a></th>
|
|
<th class="text-nowrap"><a class="link-dark text-decoration-none" href="<?= htmlspecialchars($sortLink('traffic')) ?>">Ruch<?= htmlspecialchars($sortMark('traffic')) ?></a></th>
|
|
<th class="text-nowrap"><a class="link-dark text-decoration-none" href="<?= htmlspecialchars($sortLink('indexed_pages')) ?>">Zaindeksowane<?= htmlspecialchars($sortMark('indexed_pages')) ?></a></th>
|
|
<th>Aktualizacja</th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($rows)): ?>
|
|
<tr>
|
|
<td colspan="11" class="text-center text-muted py-4">Brak danych SEO.</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($rows as $row): ?>
|
|
<?php
|
|
$siteUrl = (string) ($row['site_url'] ?? '');
|
|
$host = parse_url($siteUrl, PHP_URL_HOST);
|
|
$domain = is_string($host) && $host !== '' ? $host : $siteUrl;
|
|
?>
|
|
<tr>
|
|
<td class="text-nowrap" style="max-width: 260px;">
|
|
<a href="/sites/<?= (int) $row['site_id'] ?>/seo" class="text-decoration-none fw-semibold">
|
|
<?= htmlspecialchars($domain) ?>
|
|
</a>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if ((int) ($row['is_active'] ?? 0) === 1): ?>
|
|
<span class="badge bg-success">ON</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-secondary">OFF</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= htmlspecialchars(date('m.Y', strtotime((string) $row['metric_month']))) ?>
|
|
<?php else: ?>
|
|
<span class="text-muted">-</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= (int) $row['top3'] ?>
|
|
<small><?= $formatDelta($row['top3'], $row['prev_top3'] ?? null) ?></small>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= (int) $row['top10'] ?>
|
|
<small><?= $formatDelta($row['top10'], $row['prev_top10'] ?? null) ?></small>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= (int) $row['top20'] ?>
|
|
<small><?= $formatDelta($row['top20'], $row['prev_top20'] ?? null) ?></small>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= (int) $row['top50'] ?>
|
|
<small><?= $formatDelta($row['top50'], $row['prev_top50'] ?? null) ?></small>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= (int) $row['traffic'] ?>
|
|
<small><?= $formatDelta($row['traffic'], $row['prev_traffic'] ?? null) ?></small>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['metric_month'])): ?>
|
|
<?= (int) ($row['indexed_pages'] ?? 0) ?>
|
|
<small><?= $formatDelta($row['indexed_pages'] ?? 0, $row['prev_indexed_pages'] ?? null) ?></small>
|
|
<?php else: ?>
|
|
-
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<?php if (!empty($row['updated_at'])): ?>
|
|
<?= htmlspecialchars(date('d.m.Y H:i', strtotime((string) $row['updated_at']))) ?>
|
|
<?php else: ?>
|
|
<span class="text-muted">-</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
<td class="text-nowrap">
|
|
<a href="/sites/<?= (int) $row['site_id'] ?>/seo" class="btn btn-sm btn-outline-primary" title="SEO Panel">
|
|
<i class="bi bi-graph-up"></i>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|