loadDependencies(); // Hook'ları kaydet add_action('plugins_loaded', [$this, 'loadTextdomain']); // add_filter('plugin_locale', [$this, 'filterPluginLocale'], 10, 2); add_action('admin_menu', [$this, 'registerAdminMenu']); add_action('admin_enqueue_scripts', [$this, 'enqueueAdminAssets']); // AJAX action'ları kaydet add_action('wp_ajax_alldami_export', [$this, 'handleExportAjax']); add_action('wp_ajax_alldami_import', [$this, 'handleImportAjax']); add_action('wp_ajax_alldami_progress', [$this, 'handleProgressAjax']); add_action('wp_ajax_alldami_preflight', [$this, 'handlePreflightAjax']); add_action('wp_ajax_alldami_delete_temp', [$this, 'handleDeleteTempAjax']); // Standalone bypass (direct) endpoints carried over to standard AJAX add_action('wp_ajax_alldami_db_import_direct', [$this, 'handleDbImportDirect']); add_action('wp_ajax_alldami_file_restore_direct', [$this, 'handleFileRestoreDirect']); add_action('wp_ajax_alldami_finalize_direct', [$this, 'handleFinalizeDirect']); // Activation/Deactivation hook'ları register_activation_hook(__FILE__, [$this, 'activate']); register_deactivation_hook(__FILE__, [$this, 'deactivate']); // Settings form handler'ları add_action('admin_post_alldami_save_settings', [$this, 'handleSaveSettings']); add_action('admin_post_alldami_reset_settings', [$this, 'handleResetSettings']); } /** * Gerekli sınıfları yükler */ private function loadDependencies(): void { // Engine sınıfları require_once ALLDAMI_PLUGIN_DIR . 'engine/ChunkConfig.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/ProgressState.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/PreflightCheck.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/ReplaceEngine.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/DbExporter.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/FileArchiver.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/ExportManager.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/ImportManager.php'; require_once ALLDAMI_PLUGIN_DIR . 'engine/Settings.php'; } /** * Dil dosyasını yükle */ public function loadTextdomain(): void { // WordPress.org: This function is discouraged for hosted plugins. // Translations are automatically loaded from wp-content/languages/plugins/ // However, we load it here with the third parameter as a fallback for local offline usage & dev scenarios. load_plugin_textdomain( 'alldami-site-migration', false, dirname(plugin_basename(__FILE__)) . '/languages' ); } /** * Plugin dilini ayarlara göre filtrele * * @param string $locale Mevcut locale * @param string $domain Text domain * @return string Yeni locale */ public function filterPluginLocale($locale, $domain) { if ($domain !== 'alldami-site-migration') { return $locale; } // Settings sınıfı henüz yüklenmemiş olabilir, manuel kontrol if (!class_exists('\\AllDataMigration\\Engine\\Settings')) { require_once ALLDAMI_PLUGIN_DIR . 'engine/Settings.php'; } try { $settings = \AllDataMigration\Engine\Settings::getInstance(); $language = $settings->get('general_language', 'auto'); if (!empty($language) && $language !== 'auto') { return $language; } } catch (\Exception $e) { // Hata durumunda varsayılan locale return $locale; } return $locale; } /** * Admin menüsünü kaydeder */ public function registerAdminMenu(): void { // Ana menü add_menu_page( __('ALLDAMI Site Migration', 'alldami-site-migration'), __('ALLDAMI Site Migration', 'alldami-site-migration'), 'manage_options', 'alldami-site-migration', [$this, 'renderExportPage'], 'dashicons-migrate', 80 ); // Export alt menüsü add_submenu_page( 'alldami-site-migration', __('Export', 'alldami-site-migration'), __('Export', 'alldami-site-migration'), 'manage_options', 'alldami-site-migration', [$this, 'renderExportPage'] ); // Import alt menüsü add_submenu_page( 'alldami-site-migration', __('Import', 'alldami-site-migration'), __('Import', 'alldami-site-migration'), 'manage_options', 'alldami-import', [$this, 'renderImportPage'] ); // Settings alt menüsü add_submenu_page( 'alldami-site-migration', __('Ayarlar', 'alldami-site-migration'), __('Ayarlar', 'alldami-site-migration'), 'manage_options', 'alldami-settings', [$this, 'renderSettingsPage'] ); } /** * Admin sayfaları için CSS ve JS dosyalarını yükler * * @param string $hook Mevcut admin sayfasının hook adı */ public function enqueueAdminAssets(string $hook): void { // Sadece kendi sayfalarımızda yükle $allowedHooks = [ 'toplevel_page_alldami-site-migration', 'alldami-site-migration_page_alldami-import', 'alldami-site-migration_page_alldami-settings' ]; if (!in_array($hook, $allowedHooks)) { return; } // CSS wp_enqueue_style( 'alldami-admin', ALLDAMI_PLUGIN_URL . 'assets/css/admin.css', [], ALLDAMI_VERSION ); // JavaScript wp_enqueue_script( 'alldami-admin', ALLDAMI_PLUGIN_URL . 'assets/js/admin.js', ['jquery'], ALLDAMI_VERSION, true ); // JavaScript'e veri aktar wp_localize_script('alldami-admin', 'alldamiData', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'pluginUrl' => ALLDAMI_PLUGIN_URL, 'nonce' => wp_create_nonce('alldami_nonce'), 'strings' => [ 'confirmExport' => __('Export process will start. Do you want to continue?', 'alldami-site-migration'), 'confirmImport' => __('Import will overwrite existing data. Do you want to continue?', 'alldami-site-migration'), 'exportComplete' => __('Export completed!', 'alldami-site-migration'), 'importComplete' => __('Import completed!', 'alldami-site-migration'), 'error' => __('An error occurred:', 'alldami-site-migration'), 'connectionError' => __('Connection error. Server did not respond.', 'alldami-site-migration'), 'confirmCancel' => __('Are you sure you want to cancel the operation and delete temporary files?', 'alldami-site-migration'), ], 'importSteps' => [ 'init' => __('Initializing', 'alldami-site-migration'), 'upload' => __('File Upload', 'alldami-site-migration'), 'extract' => __('Extracting Archive', 'alldami-site-migration'), 'preflight' => __('Preflight Check', 'alldami-site-migration'), 'db_import' => __('Database Import', 'alldami-site-migration'), 'file_restore' => __('File Restore', 'alldami-site-migration'), 'replace' => __('URL Replacement', 'alldami-site-migration'), 'finalize' => __('Finalizing', 'alldami-site-migration'), ] ]); // Settings sayfasına özel inline CSS ve JS if ($hook === 'alldami-site-migration_page_alldami-settings') { $settings_css = ' .alldami-settings { max-width: 900px; } .alldami-settings h1 { display: flex; align-items: center; gap: 10px; margin-bottom: 20px; } .alldami-settings h1 .dashicons { font-size: 30px; width: 30px; height: 30px; } .alldami-tabs { margin-bottom: 0; border-bottom: 1px solid #c3c4c7; } .alldami-tabs .nav-tab { display: inline-flex; align-items: center; gap: 6px; padding: 10px 15px; background: #f0f0f1; border: 1px solid #c3c4c7; border-bottom: none; margin-left: 0; margin-right: 5px; margin-bottom: -1px; border-radius: 4px 4px 0 0; transition: all 0.2s ease; } .alldami-tabs .nav-tab:hover { background: #fff; } .alldami-tabs .nav-tab-active { background: #fff; border-bottom: 1px solid #fff; } .alldami-tabs .nav-tab .dashicons { font-size: 16px; width: 16px; height: 16px; } .alldami-settings-form { background: #fff; border: 1px solid #c3c4c7; border-top: none; border-radius: 0 0 4px 4px; padding: 20px; } .alldami-tab-content { display: none; } .alldami-tab-content.active { display: block; } .alldami-settings-section h2 { display: flex; align-items: center; gap: 8px; padding-bottom: 10px; border-bottom: 1px solid #eee; margin-bottom: 20px; font-size: 1.3em; } .alldami-form-table th { width: 200px; padding: 15px 10px 15px 0; } .alldami-form-table td { padding: 15px 10px; } .alldami-form-table .description { color: #666; font-style: italic; margin-top: 5px; } .alldami-toggle { position: relative; display: inline-block; width: 50px; height: 26px; } .alldami-toggle input { opacity: 0; width: 0; height: 0; } .alldami-toggle .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: 0.3s; border-radius: 26px; } .alldami-toggle .slider:before { position: absolute; content: ""; height: 20px; width: 20px; left: 3px; bottom: 3px; background-color: white; transition: 0.3s; border-radius: 50%; } .alldami-toggle input:checked + .slider { background-color: #2271b1; } .alldami-toggle input:checked + .slider:before { transform: translateX(24px); } .alldami-toggle input:disabled + .slider { opacity: 0.5; cursor: not-allowed; } .alldami-settings-footer { margin-top: 30px; padding-top: 20px; border-top: 1px solid #eee; display: flex; gap: 15px; } .alldami-settings-footer .button { display: inline-flex; align-items: center; gap: 6px; } .alldami-settings-footer .button .dashicons { font-size: 18px; width: 18px; height: 18px; } @media screen and (max-width: 782px) { .alldami-tabs .nav-tab { display: block; margin-bottom: 5px; border-radius: 4px; border: 1px solid #c3c4c7; } .alldami-tabs .nav-tab-active { border-bottom: 1px solid #c3c4c7; } .alldami-form-table th, .alldami-form-table td { display: block; width: 100%; padding: 10px 0; } }'; wp_add_inline_style('alldami-admin', $settings_css); $reset_url = esc_url(admin_url('admin-post.php?action=alldami_reset_settings&_wpnonce=' . wp_create_nonce('alldami_reset_nonce'))); $confirm_msg = esc_js(__('Tüm ayarlar varsayılan değerlere sıfırlanacak. Emin misiniz?', 'alldami-site-migration')); $settings_js = "jQuery(document).ready(function($) { $('#alldami-reset-settings').on('click', function() { if (confirm('" . $confirm_msg . "')) { window.location.href = '" . $reset_url . "'; } }); });"; wp_add_inline_script('alldami-admin', $settings_js); } } /** * Export sayfasını render eder */ public function renderExportPage(): void { // Yetki kontrolü if (!current_user_can('manage_options')) { wp_die(esc_html__('Bu sayfaya erişim yetkiniz yok.', 'alldami-site-migration')); } include ALLDAMI_PLUGIN_DIR . 'admin/export-page.php'; } /** * Import sayfasını render eder */ public function renderImportPage(): void { // Yetki kontrolü if (!current_user_can('manage_options')) { wp_die(esc_html__('Bu sayfaya erişim yetkiniz yok.', 'alldami-site-migration')); } include ALLDAMI_PLUGIN_DIR . 'admin/import-page.php'; } /** * Settings sayfasını render eder */ public function renderSettingsPage(): void { // Yetki kontrolü if (!current_user_can('manage_options')) { wp_die(esc_html__('Bu sayfaya erişim yetkiniz yok.', 'alldami-site-migration')); } include ALLDAMI_PLUGIN_DIR . 'admin/settings-page.php'; } /** * Settings form submit handler */ public function handleSaveSettings(): void { // Nonce kontrolü if (!wp_verify_nonce(isset($_POST['alldami_nonce']) ? sanitize_text_field(wp_unslash($_POST['alldami_nonce'])) : '', 'alldami_settings_nonce')) { wp_die(esc_html__('Güvenlik doğrulaması başarısız.', 'alldami-site-migration')); } // Yetki kontrolü $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { /* translators: %s: Required user role */ wp_die(sprintf(esc_html__('Bu işlem için yetkiniz yok. Gerekli yetki: %s', 'alldami-site-migration'), esc_html($required_role))); } $settings = \AllDataMigration\Engine\Settings::getInstance(); // POST verilerinden ayarları al ve kaydet $settingsToSave = []; $defaults = $settings->getDefaults(); foreach (array_keys($defaults) as $key) { if (isset($_POST[$key])) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized based on type logic below or sanitized by settings API $value = wp_unslash($_POST[$key]); $settingsToSave[$key] = $value; } else { // Checkbox'lar için - gönderilmezse false olarak ayarla if ( strpos($key, '_enabled') !== false || strpos($key, '_create_') !== false || strpos($key, '_disable_') !== false || strpos($key, '_skip_') !== false || strpos($key, '_encrypt_') !== false || strpos($key, '_auto_') !== false ) { $settingsToSave[$key] = false; } } } $settings->setMultiple($settingsToSave); // Aktif sekmeye geri dön $tab = sanitize_key(isset($_POST['tab']) ? $_POST['tab'] : 'export'); wp_safe_redirect(admin_url('admin.php?page=alldami-settings&tab=' . $tab . '&settings-updated=true')); exit; } /** * Settings reset handler */ public function handleResetSettings(): void { // Nonce kontrolü if (!wp_verify_nonce(isset($_GET['_wpnonce']) ? sanitize_text_field(wp_unslash($_GET['_wpnonce'])) : '', 'alldami_reset_nonce')) { wp_die(esc_html__('Güvenlik doğrulaması başarısız.', 'alldami-site-migration')); } // Yetki kontrolü $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { /* translators: %s: Required user role */ wp_die(sprintf(esc_html__('Bu işlem için yetkiniz yok. Gerekli yetki: %s', 'alldami-site-migration'), esc_html($required_role))); } $settings = \AllDataMigration\Engine\Settings::getInstance(); $settings->reset(); wp_safe_redirect(admin_url('admin.php?page=alldami-settings&settings-updated=true')); exit; } /** * Export AJAX isteğini işler */ public function handleExportAjax(): void { // Güvenlik kontrolleri check_ajax_referer('alldami_nonce', 'nonce'); // Dinamik yetki kontrolü (Settings'den) $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { wp_send_json_error(['message' => __('Bu işlem için yetkiniz yok. Gerekli yetki: ', 'alldami-site-migration') . $required_role]); } // AJAX handler dosyasını include et include ALLDAMI_PLUGIN_DIR . 'ajax/export.php'; exit; } /** * Import AJAX isteğini işler */ public function handleImportAjax(): void { // Güvenlik kontrolleri check_ajax_referer('alldami_nonce', 'nonce'); // Dinamik yetki kontrolü (Settings'den) $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { wp_send_json_error(['message' => __('Bu işlem için yetkiniz yok. Gerekli yetki: ', 'alldami-site-migration') . $required_role]); } // AJAX handler dosyasını include et include ALLDAMI_PLUGIN_DIR . 'ajax/import.php'; exit; } /** * DB Import - Directly processed via standard AJAX */ public function handleDbImportDirect(): void { // Standalone dosyasının mantığını WP yapısına uygun şekilde çağır include ALLDAMI_PLUGIN_DIR . 'ajax/import-direct.php'; exit; } /** * File Restore - Directly processed via standard AJAX */ public function handleFileRestoreDirect(): void { include ALLDAMI_PLUGIN_DIR . 'ajax/file-restore-direct.php'; exit; } /** * Finalize - Directly processed via standard AJAX */ public function handleFinalizeDirect(): void { include ALLDAMI_PLUGIN_DIR . 'ajax/finalize-direct.php'; exit; } /** * Progress AJAX isteğini işler - Mevcut işlem durumunu döndürür */ public function handleProgressAjax(): void { check_ajax_referer('alldami_nonce', 'nonce'); // Dinamik yetki kontrolü (Settings'den) $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { wp_send_json_error(['message' => __('Bu işlem için yetkiniz yok.', 'alldami-site-migration')]); } $jobId = sanitize_text_field(wp_unslash($_POST['job_id'] ?? '')); if (empty($jobId)) { wp_send_json_error(['message' => __('Job ID gerekli.', 'alldami-site-migration')]); } $progressState = new \AllDataMigration\Engine\ProgressState(); $progressState->load($jobId); wp_send_json_success($progressState->getProgress()); } /** * Preflight check AJAX isteğini işler - Import öncesi kontrolleri yapar */ public function handlePreflightAjax(): void { check_ajax_referer('alldami_nonce', 'nonce'); // Dinamik yetki kontrolü (Settings'den) $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { wp_send_json_error(['message' => __('Bu işlem için yetkiniz yok.', 'alldami-site-migration')]); } $zipPath = sanitize_text_field(wp_unslash($_POST['zip_path'] ?? '')); if (empty($zipPath) || !file_exists($zipPath)) { wp_send_json_error(['message' => __('Geçerli bir dosya yolu gerekli.', 'alldami-site-migration')]); } $preflightCheck = new \AllDataMigration\Engine\PreflightCheck(); $result = $preflightCheck->validate($zipPath); wp_send_json_success($result); } /** * Delete Temp AJAX isteğini işler (Manuel Temizlik) */ public function handleDeleteTempAjax(): void { check_ajax_referer('alldami_nonce', 'nonce'); // Dinamik yetki kontrolü (Settings'den) $required_role = \AllDataMigration\Engine\Settings::getInstance()->get('security_required_role', 'manage_options'); if (!current_user_can($required_role)) { wp_send_json_error(['message' => __('Bu işlem için yetkiniz yok.', 'alldami-site-migration')]); } $jobId = sanitize_text_field(wp_unslash($_POST['job_id'] ?? '')); if (empty($jobId)) { wp_send_json_error(['message' => __('Job ID gerekli.', 'alldami-site-migration')]); } // 1. Temp dizinini sil (wp-content/uploads/alldami-site-migration/temp/{jobId}) $jobTempDir = ALLDAMI_TEMP_DIR . $jobId . '/'; if (is_dir($jobTempDir)) { $this->recursiveDelete($jobTempDir); } // 2. State dosyasını sil (wp-content/alldami-site-migration/state/{jobId}.json) $jobStateFile = ALLDAMI_STATE_DIR . $jobId . '.json'; if (file_exists($jobStateFile)) { wp_delete_file($jobStateFile); } wp_send_json_success(['message' => __('Geçici dosyalar temizlendi.', 'alldami-site-migration')]); } /** * Plugin aktivasyon işlemleri */ public function activate(): void { // Gerekli dizinleri oluştur $directories = [ ALLDAMI_STORAGE_DIR, ALLDAMI_TEMP_DIR, ALLDAMI_STATE_DIR, ]; foreach ($directories as $dir) { if (!file_exists($dir)) { wp_mkdir_p($dir); } // .htaccess ile koruma ekle $htaccess = $dir . '.htaccess'; if (!file_exists($htaccess)) { file_put_contents($htaccess, 'deny from all'); } // index.php ile koruma ekle $index = $dir . 'index.php'; if (!file_exists($index)) { file_put_contents($index, 'installMuPlugin(); } /** * MU-Plugin'i wp-content/mu-plugins/ klasörüne kopyalar */ private function installMuPlugin(): void { $muPluginsDir = WP_CONTENT_DIR . '/mu-plugins/'; $sourceFile = ALLDAMI_PLUGIN_DIR . 'mu-plugin/alldami-bootstrap.php'; $targetFile = $muPluginsDir . 'alldami-bootstrap.php'; // mu-plugins klasörü yoksa oluştur if (!is_dir($muPluginsDir)) { wp_mkdir_p($muPluginsDir); } // Dosyayı kopyala if (file_exists($sourceFile)) { copy($sourceFile, $targetFile); } } /** * MU-Plugin'i kaldırır */ private function removeMuPlugin(): void { $targetFile = WP_CONTENT_DIR . '/mu-plugins/alldami-bootstrap.php'; if (file_exists($targetFile)) { wp_delete_file($targetFile); } } /** * Plugin deaktivasyon işlemleri */ public function deactivate(): void { // MU-Plugin'i kaldır $this->removeMuPlugin(); // Temp dosyalarını temizle $this->cleanupTempFiles(); } /** * Geçici dosyaları temizler */ private function cleanupTempFiles(): void { if (is_dir(ALLDAMI_TEMP_DIR)) { $files = glob(ALLDAMI_TEMP_DIR . '*'); foreach ($files as $file) { if (is_file($file)) { wp_delete_file($file); } elseif (is_dir($file)) { $this->recursiveDelete($file); } } } // State dosyalarını da temizle if (is_dir(ALLDAMI_STATE_DIR)) { $files = glob(ALLDAMI_STATE_DIR . '*.json'); foreach ($files as $file) { wp_delete_file($file); } } } /** * Dizini recursive olarak siler * * @param string $dir Silinecek dizin yolu */ private function recursiveDelete(string $dir): void { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object !== '.' && $object !== '..') { $path = $dir . '/' . $object; if (is_dir($path)) { $this->recursiveDelete($path); } else { wp_delete_file($path); } } } // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_rmdir @rmdir($dir); } } /** * Ortam bilgilerini döndürür (Export sayfası için) * * @return array */ public static function getEnvironmentInfo(): array { global $wpdb; // Disk alanı hesapla $freeSpace = @disk_free_space(WP_CONTENT_DIR); $totalSpace = @disk_total_space(WP_CONTENT_DIR); // wp-content boyutunu hesapla (yaklaşık) $wpContentSize = 0; $directories = ['uploads', 'plugins', 'themes']; foreach ($directories as $dir) { $path = WP_CONTENT_DIR . '/' . $dir; if (is_dir($path)) { $wpContentSize += self::getDirectorySize($path); } } // Veritabanı boyutunu hesapla $dbSize = 0; // phpcs:disable WordPress.DB.DirectDatabaseQuery -- INFO query // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared -- Variable table prefix $tables = $wpdb->get_results("SHOW TABLE STATUS LIKE '{$wpdb->prefix}%'"); // phpcs:enable foreach ($tables as $table) { $dbSize += $table->Data_length + $table->Index_length; } return [ 'php_version' => PHP_VERSION, 'wp_version' => get_bloginfo('version'), 'site_url' => site_url(), 'home_url' => home_url(), 'table_prefix' => $wpdb->prefix, 'disk_free_space' => $freeSpace, 'disk_total_space' => $totalSpace, 'wp_content_size' => $wpContentSize, 'db_size' => $dbSize, 'zip_archive_support' => class_exists('ZipArchive'), 'max_execution_time' => ini_get('max_execution_time'), 'memory_limit' => ini_get('memory_limit'), 'upload_max_filesize' => ini_get('upload_max_filesize'), 'post_max_size' => ini_get('post_max_size'), ]; } /** * Dizin boyutunu recursive olarak hesaplar * * @param string $dir Dizin yolu * @return int Byte cinsinden boyut */ private static function getDirectorySize(string $dir): int { $size = 0; if (!is_dir($dir)) { return $size; } $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($iterator as $file) { if ($file->isFile()) { $size += $file->getSize(); } } return $size; } /** * Byte değerini okunabilir formata çevirir * * @param int $bytes * @param int $precision * @return string */ public static function formatBytes($bytes, $precision = 2): string { $units = ['B', 'KB', 'MB', 'GB', 'TB']; $bytes = max($bytes, 0); $pow = floor(($bytes ? log($bytes) : 0) / log(1024)); $pow = min($pow, count($units) - 1); $bytes /= pow(1024, $pow); return round($bytes, $precision) . ' ' . $units[$pow]; } } // Plugin'i başlat AllDataMigration::getInstance();