- Added optional SEMSTORM domain input field in site creation and editing forms. - Introduced SEO panel links in site dashboard and edit pages. - Created a new cron job for SEMSTORM data synchronization. - Implemented database migrations for cron logs and site SEO metrics. - Developed SiteSeoSyncService to handle SEMSTORM data fetching and storage. - Added logging functionality for cron events. - Created a new LogController to display cron logs with filtering options. - Added SEO statistics dashboard with visual representation of metrics. - Implemented site SEO metrics model for data retrieval and manipulation.
287 lines
12 KiB
PHP
287 lines
12 KiB
PHP
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2>WP Dashboard: <?= htmlspecialchars($site['name']) ?></h2>
|
|
<div class="d-flex gap-2">
|
|
<a href="/sites/<?= (int) $site['id'] ?>/seo" class="btn btn-outline-primary">
|
|
<i class="bi bi-graph-up me-1"></i>SEO Panel
|
|
</a>
|
|
<a href="/sites/<?= $site['id'] ?>/edit" class="btn btn-outline-secondary">
|
|
<i class="bi bi-pencil me-1"></i>Edytuj strone
|
|
</a>
|
|
<a href="/sites" class="btn btn-outline-dark">
|
|
<i class="bi bi-arrow-left me-1"></i>Lista stron
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-lg-7">
|
|
<div class="card">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Permalinki</h5>
|
|
<?php if (!empty($permalinkStatus['success'])): ?>
|
|
<?php if (!empty($permalinkStatus['pretty_enabled'])): ?>
|
|
<span class="badge bg-success">Przyjazne linki ON</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-warning text-dark">Przyjazne linki OFF</span>
|
|
<?php endif; ?>
|
|
<?php else: ?>
|
|
<span class="badge bg-secondary">Brak danych</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="mb-2">
|
|
<strong>Aktualna struktura:</strong>
|
|
<code><?= htmlspecialchars((string) ($permalinkStatus['permalink_structure'] ?? '')) ?: '(pusta)' ?></code>
|
|
</p>
|
|
<p class="text-muted small mb-4">
|
|
<?= htmlspecialchars((string) ($permalinkStatus['message'] ?? 'Brak informacji z WordPress.')) ?>
|
|
</p>
|
|
|
|
<form method="post" action="/sites/<?= $site['id'] ?>/dashboard/permalinks/enable" class="d-flex gap-2 flex-wrap" data-confirm="Usunac index.php ze struktury linkow permanentnych na tej stronie WordPress?">
|
|
<button
|
|
type="submit"
|
|
class="btn btn-primary"
|
|
>
|
|
<i class="bi bi-link-45deg me-1"></i>Usun index.php z permalinkow
|
|
</button>
|
|
<a href="/sites/<?= $site['id'] ?>/dashboard" class="btn btn-outline-secondary">
|
|
<i class="bi bi-arrow-clockwise me-1"></i>Odswiez status
|
|
</a>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card mt-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Motyw BackPRO News</h5>
|
|
<span class="badge bg-primary">Blog/Magazine</span>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="mb-2">
|
|
Lekki motyw inspirowany ukladem magazynowym.
|
|
</p>
|
|
<p class="small text-muted mb-3">
|
|
Strona glowna tworzy sekcje automatycznie z kategorii glownych (parent=0).
|
|
Jesli masz 10 kategorii glownych, pojawi sie 10 boksow. Jesli 2, pojawia sie 2.
|
|
</p>
|
|
|
|
<form method="post" action="/sites/<?= (int) $site['id'] ?>/dashboard/theme/install" data-confirm="Zainstalowac i aktywowac motyw BackPRO News na tej stronie?">
|
|
<button
|
|
type="submit"
|
|
class="btn btn-outline-primary"
|
|
>
|
|
<i class="bi bi-brush me-1"></i>Zainstaluj i aktywuj motyw
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card border-danger mt-4">
|
|
<div class="card-header bg-danger-subtle d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0 text-danger">Reinstalacja WordPress</h5>
|
|
<span class="badge bg-danger">Operacja destrukcyjna</span>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="mb-2">
|
|
Reinstalacja usunie cala zawartosc z katalogu FTP strony i wyczysci cala baze danych WordPress.
|
|
</p>
|
|
<p class="small text-muted mb-3">
|
|
Nastepnie BackPRO zainstaluje WordPress na nowo z zapisanych danych tej strony i opcjonalnie ponownie opublikuje wszystkie wczesniej opublikowane artykuly z BackPRO.
|
|
</p>
|
|
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="republishArticles" checked>
|
|
<label class="form-check-label" for="republishArticles">
|
|
Po reinstalacji opublikuj ponownie wczesniej wyslane artykuly
|
|
</label>
|
|
</div>
|
|
|
|
<button type="button" id="btnReinstallWp" class="btn btn-danger">
|
|
<i class="bi bi-arrow-repeat me-1"></i>Reinstaluj WordPress
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="reinstallProgressPanel" class="mt-4" style="display: none;">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0"><i class="bi bi-hourglass-split me-2"></i>Postep reinstalacji</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="progress mb-3" style="height: 24px;">
|
|
<div id="reinstallProgressBar" class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar" style="width: 0%;">0%</div>
|
|
</div>
|
|
<div id="reinstallProgressMessage" class="text-muted">Oczekiwanie na start...</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-5">
|
|
<div class="card mb-4">
|
|
<div class="card-header d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0">Plik serwisowy BackPRO</h5>
|
|
<?php
|
|
$localVersion = (string) ($remoteServiceStatus['local_version'] ?? 'brak');
|
|
$remoteVersion = (string) ($remoteServiceStatus['remote_version'] ?? 'brak');
|
|
$versionMatch = $localVersion !== '' && $remoteVersion !== '' && $localVersion === $remoteVersion;
|
|
?>
|
|
<?php if (!empty($remoteServiceStatus['success']) && $versionMatch): ?>
|
|
<span class="badge bg-success">Aktualny</span>
|
|
<?php elseif (!empty($remoteServiceStatus['success'])): ?>
|
|
<span class="badge bg-warning text-dark">Wymaga aktualizacji</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-secondary">Brak odpowiedzi</span>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="mb-2"><strong>Wersja lokalna:</strong> <code><?= htmlspecialchars($localVersion) ?></code></p>
|
|
<p class="mb-2"><strong>Wersja na serwerze:</strong> <code><?= htmlspecialchars($remoteVersion) ?></code></p>
|
|
<p class="mb-3 small text-muted">
|
|
<?= htmlspecialchars((string) ($remoteServiceStatus['message'] ?? '')) ?>
|
|
</p>
|
|
<p class="mb-3 small">
|
|
<strong>Endpoint:</strong>
|
|
<code><?= htmlspecialchars((string) ($remoteServiceStatus['service_url'] ?? '')) ?></code>
|
|
</p>
|
|
|
|
<form method="post" action="/sites/<?= (int) $site['id'] ?>/dashboard/remote-service/update" data-confirm="Wymusic aktualizacje pliku backpro-remote-service.php na serwerze?">
|
|
<button
|
|
type="submit"
|
|
class="btn btn-outline-primary"
|
|
>
|
|
<i class="bi bi-arrow-repeat me-1"></i>Wymus aktualizacje pliku serwisowego
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">Info techniczne</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<ul class="mb-0">
|
|
<li class="mb-2">BackPRO uzywa pliku serwisowego backpro-remote-service.php do zdalnych zmian.</li>
|
|
<li class="mb-2">Gdy pliku brak, system automatycznie probuje go wgrac przez FTP.</li>
|
|
<li class="mb-2">Wymagane sa dane FTP: host, port, user, haslo, ftp_path.</li>
|
|
<li>To miejsce jest przygotowane pod kolejne ustawienia WordPress (np. pluginy).</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function () {
|
|
var btn = document.getElementById('btnReinstallWp');
|
|
var republishCheckbox = document.getElementById('republishArticles');
|
|
var panel = document.getElementById('reinstallProgressPanel');
|
|
var bar = document.getElementById('reinstallProgressBar');
|
|
var message = document.getElementById('reinstallProgressMessage');
|
|
var intervalId = null;
|
|
|
|
function generateProgressId() {
|
|
var chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
var out = '';
|
|
for (var i = 0; i < 20; i++) {
|
|
out += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
}
|
|
return out;
|
|
}
|
|
|
|
function setProgress(percent, text) {
|
|
var safe = Math.max(0, Math.min(100, parseInt(percent, 10) || 0));
|
|
bar.style.width = safe + '%';
|
|
bar.textContent = safe + '%';
|
|
message.textContent = text || '';
|
|
}
|
|
|
|
function pollStatus(progressId) {
|
|
fetch('/installer/status/' + progressId)
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (data) {
|
|
if (!data || data.status === 'waiting') {
|
|
return;
|
|
}
|
|
setProgress(data.percent || 0, data.message || '');
|
|
})
|
|
.catch(function () {});
|
|
}
|
|
|
|
if (!btn) {
|
|
return;
|
|
}
|
|
|
|
btn.addEventListener('click', async function () {
|
|
var ok = await backproConfirm(
|
|
'To usunie wszystkie pliki z katalogu FTP i wyczysci baze danych WordPress. Czy na pewno kontynuowac?',
|
|
{
|
|
title: 'Reinstalacja WordPress',
|
|
confirmText: 'Tak, reinstaluj',
|
|
cancelText: 'Anuluj',
|
|
confirmClass: 'btn-danger'
|
|
}
|
|
);
|
|
if (!ok) {
|
|
return;
|
|
}
|
|
|
|
var progressId = generateProgressId();
|
|
var formData = new FormData();
|
|
formData.append('progress_id', progressId);
|
|
formData.append('republish_articles', republishCheckbox && republishCheckbox.checked ? '1' : '0');
|
|
|
|
btn.disabled = true;
|
|
panel.style.display = '';
|
|
setProgress(0, 'Uruchamianie reinstalacji...');
|
|
panel.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
|
|
intervalId = setInterval(function () {
|
|
pollStatus(progressId);
|
|
}, 2000);
|
|
|
|
fetch('/sites/<?= (int) $site['id'] ?>/dashboard/reinstall', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(function (r) { return r.json(); })
|
|
.then(function (result) {
|
|
if (intervalId) {
|
|
clearInterval(intervalId);
|
|
}
|
|
|
|
bar.classList.remove('progress-bar-animated');
|
|
if (result && result.success) {
|
|
bar.classList.remove('bg-danger');
|
|
bar.classList.add('bg-success');
|
|
setProgress(100, result.message || 'Reinstalacja zakonczona.');
|
|
backproNotify(result.message || 'Reinstalacja zakonczona.', 'success');
|
|
setTimeout(function () {
|
|
window.location.reload();
|
|
}, 2500);
|
|
return;
|
|
}
|
|
|
|
bar.classList.add('bg-danger');
|
|
message.textContent = (result && result.message) ? result.message : 'Wystapil blad reinstalacji.';
|
|
backproNotify(message.textContent, 'danger');
|
|
btn.disabled = false;
|
|
})
|
|
.catch(function () {
|
|
if (intervalId) {
|
|
clearInterval(intervalId);
|
|
}
|
|
bar.classList.remove('progress-bar-animated');
|
|
bar.classList.add('bg-danger');
|
|
message.textContent = 'Blad polaczenia z serwerem.';
|
|
backproNotify(message.textContent, 'danger');
|
|
btn.disabled = false;
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
|
|
|
|
|