reset(); // Temel kontroller $this->checkZipExists($zipPath); $this->checkZipIntegrity($zipPath); if (!empty($this->errors)) { return $this->getResult(); } // Manifest okuma $manifest = $this->readManifest($zipPath); if ($manifest) { $this->sourceInfo = [ 'Site URL' => $manifest['site_url'] ?? 'Bilinmiyor', 'WordPress' => $manifest['wp_version'] ?? 'Bilinmiyor', 'PHP' => $manifest['php_version'] ?? 'Bilinmiyor', 'Tablo Prefix' => $manifest['table_prefix'] ?? 'Bilinmiyor', ]; // Versiyon kontrolleri $this->checkPhpVersion($manifest['php_version'] ?? ''); $this->checkWpVersion($manifest['wp_version'] ?? ''); $this->checkTablePrefix($manifest['table_prefix'] ?? ''); } else { $this->errors[] = 'manifest.json dosyası okunamadı veya geçersiz.'; } // Hedef ortam kontrolleri $this->collectTargetInfo(); $this->checkDiskSpace($zipPath); $this->checkWritePermissions(); $this->checkDatabaseAccess(); return $this->getResult(); } private function reset(): void { $this->errors = []; $this->warnings = []; $this->info = []; $this->sourceInfo = []; $this->targetInfo = []; } private function checkZipExists(string $zipPath): void { if (!file_exists($zipPath)) { $this->errors[] = 'Belirtilen dosya bulunamadı.'; } } private function checkZipIntegrity(string $zipPath): void { if (!class_exists('ZipArchive')) { $this->errors[] = 'ZipArchive PHP eklentisi yüklü değil.'; return; } $zip = new \ZipArchive(); // Önce basit açma deneyelim (CHECKCONS olmadan) $result = $zip->open($zipPath); if ($result !== true) { // Hata koduna göre detaylı mesaj $errorMessages = [ \ZipArchive::ER_EXISTS => 'Dosya zaten mevcut.', \ZipArchive::ER_INCONS => 'Zip dosyası tutarsız.', \ZipArchive::ER_INVAL => 'Geçersiz argüman.', \ZipArchive::ER_MEMORY => 'Bellek hatası.', \ZipArchive::ER_NOENT => 'Dosya bulunamadı.', \ZipArchive::ER_NOZIP => 'Bu bir zip dosyası değil.', \ZipArchive::ER_OPEN => 'Dosya açılamadı.', \ZipArchive::ER_READ => 'Okuma hatası.', \ZipArchive::ER_SEEK => 'Dosya konumlandırma hatası.', ]; $errorMessage = $errorMessages[$result] ?? "Bilinmeyen hata (kod: $result)"; $this->errors[] = "Zip dosyası açılamadı: $errorMessage"; } else { // Dosya sayısını ve manifest varlığını kontrol et $numFiles = $zip->numFiles; $hasManifest = ($zip->locateName('manifest.json') !== false); if ($numFiles === 0) { $this->errors[] = 'Zip dosyası boş.'; } elseif (!$hasManifest) { $this->errors[] = 'Zip dosyasında manifest.json bulunamadı. Bu geçerli bir WP Cloner yedeği değil.'; } $zip->close(); } } private function readManifest(string $zipPath): ?array { $zip = new \ZipArchive(); if ($zip->open($zipPath) !== true) { return null; } $content = $zip->getFromName('manifest.json'); $zip->close(); if (!$content) { return null; } return json_decode($content, true); } private function checkPhpVersion(string $sourceVersion): void { if (empty($sourceVersion)) return; $currentVersion = PHP_VERSION; if (version_compare($sourceVersion, $currentVersion, '>')) { $this->warnings[] = sprintf( 'Kaynak site PHP %s kullanıyor, bu site PHP %s. Uyumsuzluk olabilir.', $sourceVersion, $currentVersion ); } } private function checkWpVersion(string $sourceVersion): void { if (empty($sourceVersion)) return; $currentVersion = get_bloginfo('version'); if (version_compare($sourceVersion, $currentVersion, '>')) { $this->warnings[] = sprintf( 'Kaynak site WordPress %s, bu site %s. Önce WordPress güncellemeniz önerilir.', $sourceVersion, $currentVersion ); } } private function checkTablePrefix(string $sourcePrefix): void { global $wpdb; if (empty($sourcePrefix)) return; if ($sourcePrefix !== $wpdb->prefix) { $this->info[] = sprintf( 'Tablo prefix farklı: %s → %s (otomatik dönüştürülecek)', $sourcePrefix, $wpdb->prefix ); } } private function collectTargetInfo(): void { global $wpdb; $this->targetInfo = [ 'Site URL' => site_url(), 'WordPress' => get_bloginfo('version'), 'PHP' => PHP_VERSION, 'Tablo Prefix' => $wpdb->prefix, ]; } private function checkDiskSpace(string $zipPath): void { $upload_dir = wp_upload_dir(); $zipSize = filesize($zipPath); $freeSpace = @disk_free_space($upload_dir['basedir']); // İhtiyaç: zip boyutunun 3 katı (extract + işlem payı) $requiredSpace = $zipSize * 3; if ($freeSpace && $freeSpace < $requiredSpace) { $this->errors[] = sprintf( __('Yetersiz disk alanı. Gerekli: %s, Mevcut: %s', 'alldami-site-migration'), size_format($requiredSpace), size_format($freeSpace) ); } } private function checkWritePermissions(): void { $upload_dir = wp_upload_dir(); $directories = [ $upload_dir['basedir'], WP_PLUGIN_DIR, get_theme_root(), ALLDAMI_STORAGE_DIR ]; foreach ($directories as $dir) { if (is_dir($dir) && !is_writable($dir)) { $this->errors[] = sprintf(__('%s dizinine yazma izni yok.', 'alldami-site-migration'), basename($dir)); } } } private function checkDatabaseAccess(): void { global $wpdb; // phpcs:disable WordPress.DB.DirectDatabaseQuery -- Connectivity check $result = $wpdb->query("SELECT 1"); // phpcs:enable WordPress.DB.DirectDatabaseQuery if ($result === false) { $this->errors[] = 'Veritabanına erişilemiyor.'; } } private function getResult(): array { return [ 'passed' => empty($this->errors), 'errors' => $this->errors, 'warnings' => $this->warnings, 'info' => $this->info, 'sourceInfo' => $this->sourceInfo, 'targetInfo' => $this->targetInfo, ]; } public function getErrors(): array { return $this->errors; } public function getWarnings(): array { return $this->warnings; } public function getInfo(): array { return $this->info; } public function isPassed(): bool { return empty($this->errors); } }