- 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.
134 lines
4.8 KiB
Markdown
134 lines
4.8 KiB
Markdown
# BackPRO - Konfiguracja CRON
|
|
|
|
## Opis
|
|
Skrypt `cron/publish.php` jest uruchamiany automatycznie co godzinę przez CRON serwera. Odpowiada za sprawdzenie, czy któraś ze stron wymaga nowej publikacji, i jeśli tak - generuje artykuł z obrazkiem i publikuje go na WordPressie.
|
|
|
|
## Algorytm działania
|
|
|
|
```
|
|
1. Załaduj konfigurację (.env) i autoloader (vendor/autoload.php)
|
|
2. Pobierz wszystkie aktywne strony (is_active = 1)
|
|
3. Filtruj: zostaw strony, gdzie:
|
|
- last_published_at IS NULL (nigdy nie publikowano)
|
|
- LUB NOW() - last_published_at >= publish_interval_days dni
|
|
4. Sortuj po last_published_at ASC (NULL first = najwyższy priorytet)
|
|
5. Weź PIERWSZĄ stronę z listy (tylko jedna publikacja na uruchomienie)
|
|
6. TopicBalancer → wybierz temat z najmniejszą liczbą artykułów
|
|
7. Pobierz ostatnie 20 tytułów artykułów z tego tematu
|
|
8. OpenAIService → wygeneruj artykuł (prompt zawiera istniejące tytuły)
|
|
9. ImageService → wygeneruj/pobierz obrazek
|
|
10. WordPressService → upload obrazka jako media
|
|
11. WordPressService → utwórz post z featured image i kategorią
|
|
12. Zapisz artykuł w bazie (tabela articles, status=published)
|
|
13. Zaktualizuj topics.article_count (+1)
|
|
14. Zaktualizuj sites.last_published_at = NOW()
|
|
15. Zaloguj wynik do storage/logs/publish_YYYY-MM-DD.log
|
|
```
|
|
|
|
**Ważne:** Skrypt publikuje MAKSYMALNIE 1 artykuł na uruchomienie. Dzięki temu:
|
|
- Nie obciążamy API zbyt wieloma zapytaniami naraz
|
|
- Mamy lepszą kontrolę nad tempem publikacji
|
|
- W razie błędu tracimy tylko 1 artykuł, nie całą partię
|
|
|
|
## Konfiguracja CRON na Hostido
|
|
|
|
### Panel DirectAdmin / cPanel
|
|
W panelu hostingu dodaj zadanie CRON:
|
|
|
|
```
|
|
# Co godzinę (minuta 0 każdej godziny)
|
|
0 * * * * /usr/bin/php /home/username/public_html/cron/publish.php >> /home/username/public_html/storage/logs/cron.log 2>&1
|
|
```
|
|
|
|
Lub jeśli dostępny jest `php` w PATH:
|
|
```
|
|
0 * * * * php /home/username/public_html/cron/publish.php >> /home/username/public_html/storage/logs/cron.log 2>&1
|
|
```
|
|
|
|
### Alternatywne interwały
|
|
```
|
|
# Co 2 godziny
|
|
0 */2 * * * php /path/to/cron/publish.php
|
|
|
|
# Co 6 godzin
|
|
0 */6 * * * php /path/to/cron/publish.php
|
|
|
|
# Raz dziennie o 8:00
|
|
0 8 * * * php /path/to/cron/publish.php
|
|
|
|
# Dwa razy dziennie (8:00 i 20:00)
|
|
0 8,20 * * * php /path/to/cron/publish.php
|
|
```
|
|
|
|
## Zabezpieczenia
|
|
|
|
### Blokada dostępu HTTP
|
|
Plik `cron/.htaccess`:
|
|
```apache
|
|
Deny from all
|
|
```
|
|
Skrypty CRON są uruchamiane z linii komend (CLI), nie przez HTTP.
|
|
|
|
### Blokada wielokrotnego uruchomienia
|
|
Skrypt używa pliku lockfile (`storage/logs/publish.lock`):
|
|
- Na początku sprawdza czy lockfile istnieje
|
|
- Jeśli tak i nie jest starszy niż 30 minut → kończy działanie (inny proces w toku)
|
|
- Jeśli nie → tworzy lockfile
|
|
- Na końcu (lub w razie błędu) → usuwa lockfile
|
|
|
|
## Logowanie
|
|
|
|
Logi zapisywane w `storage/logs/publish_YYYY-MM-DD.log`:
|
|
|
|
```
|
|
[2026-02-15 10:00:01] INFO: Rozpoczynam publikację
|
|
[2026-02-15 10:00:01] INFO: Wybrano stronę: example.com (ID: 3)
|
|
[2026-02-15 10:00:01] INFO: Wybrany temat: Ogrodnictwo (ID: 7)
|
|
[2026-02-15 10:00:05] INFO: Wygenerowano artykuł: "10 roślin idealnych na balkon"
|
|
[2026-02-15 10:00:08] INFO: Wygenerowano obrazek (Freepik)
|
|
[2026-02-15 10:00:10] INFO: Upload mediów na WP: media_id=142
|
|
[2026-02-15 10:00:12] INFO: Opublikowano post: wp_post_id=523
|
|
[2026-02-15 10:00:12] INFO: Zakończono pomyślnie
|
|
```
|
|
|
|
## Ręczne uruchomienie
|
|
|
|
### Z linii komend
|
|
```bash
|
|
php /path/to/cron/publish.php
|
|
```
|
|
|
|
### Z panelu BackPRO
|
|
Przycisk "Opublikuj teraz" na dashboardzie wywołuje `PublishController@run`, który uruchamia ten sam proces co CRON, ale synchronicznie z poziomu przeglądarki.
|
|
|
|
## Monitoring
|
|
|
|
### Sprawdzanie statusu
|
|
- Dashboard BackPRO pokazuje datę ostatniej publikacji dla każdej strony
|
|
- Lista artykułów z filtrem po statusie (published/failed)
|
|
- Logi w `storage/logs/`
|
|
|
|
### Typowe problemy
|
|
| Problem | Przyczyna | Rozwiązanie |
|
|
|---------|-----------|-------------|
|
|
| Brak publikacji | CRON nie uruchomiony | Sprawdź konfigurację CRON w panelu |
|
|
| Status: failed | Błąd API | Sprawdź error_message w artykule i logi |
|
|
| Lockfile blokuje | Poprzedni proces nie zakończył się | Usuń `storage/logs/publish.lock` |
|
|
| 401 z WordPress | Złe dane API | Sprawdź api_user/api_token w konfiguracji strony |
|
|
| 429 z OpenAI | Rate limit | Zwiększ interwał CRON lub poczekaj |
|
|
|
|
## Miesieczna synchronizacja metryk SEO (SEMSTORM + DataForSEO)
|
|
|
|
Dodaj osobne zadanie CRON uruchamiane raz w miesiacu:
|
|
|
|
```bash
|
|
0 3 1 * * php /path/to/cron/semstorm.php >> /path/to/storage/logs/cron_semstorm.log 2>&1
|
|
```
|
|
|
|
Skrypt:
|
|
- pobiera aktywne strony (`sites.is_active = 1`),
|
|
- pobiera metryki z SEMSTORM dla domeny strony,
|
|
- pobiera liczbe zaindeksowanych stron (zapytanie `site:domena`) z DataForSEO,
|
|
- zapisuje dane do `site_seo_metrics` dla biezacego miesiaca,
|
|
- pomija rekord, jesli miesiac jest juz zapisany (idempotencja).
|