# 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).