add_action('admin_post_b2_trigger_manual_backup', 'b2_backup_handle_manual_trigger');
function b2_backup_handle_manual_trigger() {
// 1. Verificare permisiuni utilizator
if (!current_user_can('manage_options')) {
wp_die(__('Nu ai permisiuni suficiente.', 'b2-backup-express'));
}
// 2. Verificare CSRF via Nonce
$nonce = sanitize_text_field($_POST['_wpnonce'] ?? '');
if (!wp_verify_nonce($nonce, 'b2_backup_manual_action')) {
wp_die(__('Sesiune expirată. Reîncearcă.', 'b2-backup-express'));
}
// 3. Preluare opțiuni sanitizate
$bucket_name = sanitize_text_field($_POST['b2_bucket_name'] ?? '');
if (empty($bucket_name)) {
wp_redirect(admin_url('admin.php?page=b2-backup&status=missing_bucket'));
exit;
}
// Execută job-ul în fundal
b2_backup_run_process($bucket_name);
wp_redirect(admin_url('admin.php?page=b2-backup&status=success'));
exit;
}Salutare tuturor! M-am săturat să dau câte 50$ pe an per site pentru soluții comerciale de backup pline de opțiuni de care n-am nevoie. Așa că acum trei luni am decis să-mi scriu propriul plugin minimalist care aruncă arhivele direct în Backblaze B2, l-am pus pe GitHub și l-am trimis la rețeaua oficială WordPress.org.
A fost o experiență interesantă, mai ales procesul de code review cu echipa lor, așa că m-am gândit să las aici câteva concluzii practice.
De ce Backblaze B2 și nu AWS S3?
Răspunsul scurt: banii. La AWS S3 plătești stocarea, dar te rup taxele de ieșire din rețea (egress fees) și request-urile de API. La un portofoliu de 14 site-uri de clienți pe care le administrez, adunam vreo 180 GB de arhive. În AWS dădeam aproape 12$ pe lună. În Backblaze B2 plătesc fix 1.08$ pe lună pentru exact aceeași chestie.
În plus, B2 are un API compatibil S3 foarte simplu. N-am avut nevoie să trag tot SDK-ul uriaș de la AWS în plugin (care ar fi umflat folderul la 20MB). Am scris un client HTTP minimalist folosind direct wp_remote_post() și câteva antete de autentificare Signature V4.
Palma primită la review-ul WordPress.org
Credeam că le știu pe toate după 10 ani de PHP, dar băieții de la review-ul oficial mi-au dat codul înapoi în 48 de ore cu o listă lungă de respingeri. Au fost trei chestii mari la care au strigat „NIMIC DE GENUL ĂSTA AICI”:
- Sanitizare și Escaping obsesiv: Eu folosisem
$_POST['b2_key']direct într-un query scurt, crezând că dacă e în wp-admin e safe. Greșit. Fiecare variabilă din suprafata de administrare trebuie trecută prinsanitize_text_field()la intrare și prinesc_attr()sauesc_html()la afișare. - Nonce-uri lipsă: Pe butonul de manual backup făceam un request simplu. Mi-au blocat aprobarea până n-am pus verificare de nonce pentru prevenirea CSRF.
- Pollution în namespace global: Definisem o funcție ajutătoare
format_bytes(). A trebuit să o mut într-o clasă sau să o prefixez strict cumy_plugin_b2_format_bytes()ca să nu fac conflict cu alte 60.000 de plugin-uri.
Trade-off-uri reale
Să fim sinceri, soluția mea nu e un argint viu pentru orice proiect:
- Unde e genială: Site-uri mici și medii (sub 2 GB). Scriptul rulează pe cron-ul din WP sau prin CLI, face zip-ul în bucăți mici, consumă sub 20 MB RAM și trimite fisierul la B2 în fundal.
- Unde suferă: Dacă ai un magazin WooCommerce cu un wp-content de 15 GB și hosting ieftin de 2 euro, PHP-ul va da timeout garantat. Nu am implementat încă chunking avansat multi-part uploads pentru că ar fi crescut complexitatea codului de 4 ori.
Sub capotă, verificările pe care le cere echipa WordPress sunt enervante la început, dar fac codul mult mai stabil. Mai jos aveți modelul de handler curat pe care am fost obligat să-l scriu pentru acțiunile din admin.