create_audio_folder(); } public function test_connection() { check_ajax_referer('audio_diary_test_connection_nonce', 'nonce'); if (!isset($_POST['folder_id']) || empty($_POST['folder_id'])) { wp_send_json_error(__('Invalid Folder ID.', 'audio-diary')); } $folder_id = sanitize_text_field($_POST['folder_id']); require_once plugin_dir_path(__FILE__) . '../vendor/autoload.php'; $client = new Google_Client(); $client->setAuthConfig(plugin_dir_path(__FILE__) . '../config/service-account.json'); $client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY); $service = new Google_Service_Drive($client); try { $folder = $service->files->get($folder_id, ['fields' => 'id,name']); error_log("Test connection successful for folder ID: $folder_id, Name: " . $folder->getName()); wp_send_json_success(); } catch (Google_Service_Exception $e) { error_log("Test connection failed for $folder_id: " . $e->getMessage()); if ($e->getCode() == 404) { wp_send_json_error(__('Folder not found. Check the Folder ID.', 'audio-diary')); } elseif ($e->getCode() == 403) { wp_send_json_error(__('Permission denied. Ensure the Service Account has access to this folder.', 'audio-diary')); } else { wp_send_json_error(__('Failed to connect: ' . $e->getMessage(), 'audio-diary')); } } } function audio_diary_upload_to_google_drive() { $file_name = isset($_POST['file']) ? sanitize_file_name($_POST['file']) : ''; if (!$file_name) { error_log('Upload Error: No file specified.'); wp_send_json_error('No file specified.'); } $uploads = wp_upload_dir(); $file_path = $uploads['basedir'] . '/audio-diary/' . $file_name; if (!file_exists($file_path)) { error_log("Upload Error: File not found on server - $file_path"); wp_send_json_error('File not found on server.'); } require_once plugin_dir_path(__FILE__) . '../vendor/autoload.php'; $client = new Google_Client(); $client->setAuthConfig(plugin_dir_path(__FILE__) . '../config/service-account.json'); $client->addScope(Google_Service_Drive::DRIVE); // تغییر به DRIVE برای دسترسی کامل $service = new Google_Service_Drive($client); $target_folder_id = get_option('audio_diary_google_drive_folder_id', '1sBE78fuxRlcWouLs0mw12zLqTbWJg9jB'); $drive_file_id = get_option('google_drive_' . $file_name); error_log("Checking file: $file_name, Drive ID: " . ($drive_file_id ? $drive_file_id : 'None')); if ($drive_file_id) { try { $file = $service->files->get($drive_file_id, ['fields' => 'id,name,parents,trashed']); $parents = $file->getParents(); $trashed = $file->getTrashed(); error_log("File $file_name exists in Google Drive with ID: $drive_file_id, Name: " . $file->getName() . ", Parents: " . implode(',', $parents) . ", Trashed: " . ($trashed ? 'Yes' : 'No')); if (in_array($target_folder_id, $parents) && !$trashed) { wp_send_json_error('File already exists in the target Google Drive folder.'); } else { error_log("File $file_name is not in target folder or is trashed, proceeding to upload."); delete_option('google_drive_' . $file_name); } } catch (Google_Service_Exception $e) { error_log("Google Drive check failed for $file_name: " . $e->getMessage() . " (Code: " . $e->getCode() . ")"); if ($e->getCode() == 404) { delete_option('google_drive_' . $file_name); error_log("Deleted option for $file_name as it was not found in Google Drive."); } else { wp_send_json_error('Error checking file in Google Drive: ' . $e->getMessage()); } } } else { error_log("No Drive ID found for $file_name, proceeding to upload."); } error_log("Uploading $file_name to Google Drive..."); $file = new Google_Service_Drive_DriveFile(); $file->setName($file_name); $file->setParents([$target_folder_id]); $result = $service->files->create($file, [ 'data' => file_get_contents($file_path), 'mimeType' => 'audio/wav', 'uploadType' => 'multipart' ]); if ($result) { update_option('google_drive_' . $file_name, $result->id); error_log("Upload successful for $file_name, new ID: " . $result->id); wp_send_json_success(['file_id' => $result->id]); } else { error_log("Upload failed for $file_name"); wp_send_json_error('Upload failed.'); } } function audio_diary_delete_selected_audios() { $files = isset($_POST['files']) ? (array)$_POST['files'] : []; $delete_from_drive = isset($_POST['delete_from_drive']) && $_POST['delete_from_drive'] === 'true'; if (empty($files)) { wp_send_json_error('No files selected.'); } $uploads = wp_upload_dir(); $deleted_local = 0; $deleted_drive = 0; $drive_errors = []; if ($delete_from_drive) { require_once plugin_dir_path(__FILE__) . '../vendor/autoload.php'; $client = new Google_Client(); $client->setAuthConfig(plugin_dir_path(__FILE__) . '../config/service-account.json'); $client->addScope(Google_Service_Drive::DRIVE); $service = new Google_Service_Drive($client); } foreach ($files as $file) { $file_path = $uploads['basedir'] . '/audio-diary/' . sanitize_file_name($file); $drive_file_id = get_option('google_drive_' . $file); if ($delete_from_drive && $drive_file_id) { try { $service->files->delete($drive_file_id); delete_option('google_drive_' . $file); $deleted_drive++; error_log("Successfully deleted file $drive_file_id from Google Drive for $file."); } catch (Google_Service_Exception $e) { $drive_errors[] = "Failed to delete $file from Google Drive: " . $e->getMessage() . " (Code: " . $e->getCode() . ")"; error_log($drive_errors[count($drive_errors) - 1]); } } if (file_exists($file_path) && unlink($file_path)) { $deleted_local++; error_log("Successfully deleted local file: $file_path"); } else { error_log("No local file to delete or failed: $file_path"); } } if ($deleted_local > 0 || $deleted_drive > 0) { $response = ['success' => true, 'deleted_local' => $deleted_local, 'deleted_drive' => $deleted_drive]; if (!empty($drive_errors)) { $response['data'] = ['drive_errors' => implode("; ", $drive_errors)]; } wp_send_json($response); } else { wp_send_json_error('Failed to delete any files.'); } } function delete_old_zip_files() { $uploads = wp_upload_dir(); $files = glob($uploads['basedir'] . '/audio-diary-selected-*.zip'); $time_limit = 3600; // 1 hour in seconds foreach ($files as $file) { if (filemtime($file) < (time() - $time_limit)) { unlink($file); } } } function handle_download_zip() { $files = isset($_POST['files']) ? (array)$_POST['files'] : []; if (empty($files)) { wp_send_json_error('No files selected.'); } $uploads = wp_upload_dir(); $zip_name = 'audio-diary-' . time() . '.zip'; $zip_path = $uploads['basedir'] . '/' . $zip_name; $zip = new ZipArchive(); if ($zip->open($zip_path, ZipArchive::CREATE) === TRUE) { foreach ($files as $file) { $file_path = $uploads['basedir'] . '/audio-diary/' . sanitize_file_name($file); if (file_exists($file_path)) { $zip->addFile($file_path, $file); } } $zip->close(); $zip_url = $uploads['baseurl'] . '/' . $zip_name; wp_send_json_success(['zip_url' => $zip_url]); } else { wp_send_json_error('Failed to create ZIP file.'); } } function delete_audio() { if (!current_user_can('manage_options')) { wp_send_json_error('Unauthorized'); return; } if (empty($_POST['file_name'])) { wp_send_json_error('No file specified'); return; } $file_name = sanitize_file_name($_POST['file_name']); $uploads = wp_upload_dir(); $file_path = $uploads['basedir'] . '/audio-diary/' . $file_name; if (file_exists($file_path) && unlink($file_path)) { wp_send_json_success('File deleted'); } else { $error = file_exists($file_path) ? 'Failed to delete file' : 'File does not exist'; wp_send_json_error($error); } } function delete_selected_audios() { $files = isset($_POST['files']) ? (array)$_POST['files'] : []; if (empty($files)) { wp_send_json_error('No files selected.'); } $uploads = wp_upload_dir(); $deleted = 0; foreach ($files as $file) { $file_path = $uploads['basedir'] . '/audio-diary/' . sanitize_file_name($file); if (file_exists($file_path) && unlink($file_path)) { $deleted++; } } if ($deleted > 0) { wp_send_json_success('Deleted ' . $deleted . ' files.'); } else { wp_send_json_error('Failed to delete files.'); } } public function add_menu_item() { add_menu_page( 'Audio Diary', 'Audio Diary', 'manage_options', 'audio-diary', array($this, 'render_page'), 'dashicons-media-audio', 6 ); add_submenu_page( 'audio-diary', __('Recorded Audios', 'audio-diary'), __('Recorded Audios', 'audio-diary'), 'manage_options', 'audio-diary-list', array($this, 'render_list_page') ); add_submenu_page( 'audio-diary', __('setting', 'audio-diary'), __('setting', 'audio-diary'), 'manage_options', 'setting', array($this, 'setting_page') ); } public function enqueue_scripts() { wp_enqueue_style('audio-diary-style', plugin_dir_url(__FILE__) . '../assets/css/style.css'); wp_enqueue_style('audio-diary-toast-style', plugin_dir_url(__FILE__) . '../assets/css/jquery.toast.css'); wp_enqueue_script('audio-diary-script', plugin_dir_url(__FILE__) . "../assets/js/audio-diary.js", array('jquery'), '1.0', true); wp_enqueue_script('audio-diary-toast-script', plugin_dir_url(__FILE__) . "../assets/js/jquery.toast.js", array('jquery'), '1.0', true); } public function render_page() { include_once AUDIO_DIARY_MODULES_PATH . "audio-diary-admin-page.php"; } public function render_list_page() { include_once AUDIO_DIARY_MODULES_PATH . "audio-diary-admin-list-page.php"; } public function setting_page() { include_once AUDIO_DIARY_MODULES_PATH . "setting-admin-page.php"; } private function create_audio_folder() { $uploads = wp_upload_dir(); $audio_dir = $uploads['basedir'] . '/audio-diary'; if (!file_exists($audio_dir)) { wp_mkdir_p($audio_dir); } } public function save_audio() { if (!current_user_can('manage_options')) { wp_send_json_error('Unauthorized'); return; } if (empty($_FILES['audio_data'])) { wp_send_json_error('No file uploaded'); return; } $file = $_FILES['audio_data']; $uploads = wp_upload_dir(); $upload_path = $uploads['basedir'] . '/audio-diary/'; $date_time = date('Y-m-d-H-i-s'); $file_name = 'memory-' . $date_time . '.wav'; $file_path = $upload_path . $file_name; if (move_uploaded_file($file['tmp_name'], $file_path)) { wp_send_json_success(['message' => 'File uploaded', 'file_name' => $file_name]); } else { wp_send_json_error('File upload failed'); } } } Audio_Diary_Admin_Page::get_instance();