directory_manager = $directory_manager ?? new Audio_Directory_Manager(); $this->file_writer = $file_writer ?? new Audio_File_Writer( $this->directory_manager ); } /** * Store audio content to file. * * @param string $audio_content Binary audio content. * @param int $post_id Post ID for filename generation. * @param string $format Audio format (default: mp3). * @return array Storage result. */ public function store_audio_content( string $audio_content, int $post_id, string $format = 'mp3' ): array { accessibility_audio_tts_debug_log( '[Audio_File_Storage] Storing audio content for post ID: ' . $post_id, true ); try { // Validate content. if ( empty( $audio_content ) ) { return $this->create_error_response( __( 'Audio content is empty', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } if ( strlen( $audio_content ) < 100 ) { return $this->create_error_response( __( 'Audio content is too small', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } // Only the legacy public writer depends on upload directory permissions. if ( ! class_exists( '\\Accessibility_Audio_TTS\\Core\\Audio_Access' ) && ! $this->directory_manager->check_and_fix_permissions() ) { return $this->create_error_response( __( 'Upload directory is not writable', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } // Store the file. $write_result = $this->file_writer->save_audio_file( $audio_content, $post_id ); if ( ! $write_result['success'] ) { return $this->create_error_response( $write_result['error'] ?? __( 'Failed to write audio file', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } accessibility_audio_tts_debug_log( '[Audio_File_Storage] Audio stored successfully: ' . $write_result['url'], true ); return array( 'success' => true, 'path' => $write_result['path'], 'url' => $write_result['url'], 'filename' => $write_result['filename'], 'size' => $write_result['size'], 'format' => $format, 'stored_at' => current_time( 'mysql' ), ); } catch ( \Throwable $e ) { accessibility_audio_tts_debug_log( '[Audio_File_Storage] Error storing audio: ' . $e->getMessage(), true ); return $this->create_error_response( __( 'Error storing audio file: ', 'accessibility-audio-tts-text-to-speech-for-articles' ) . $e->getMessage() ); } } /** * Store raw audio content to specific path. * * @param string $audio_content Binary audio content. * @param string $file_path Full file path. * @return array Storage result. */ public function store_raw_content( string $audio_content, string $file_path ): array { accessibility_audio_tts_debug_log( '[Audio_File_Storage] Storing raw audio content to: ' . $file_path, true ); try { // Validate content. if ( empty( $audio_content ) ) { return $this->create_error_response( __( 'Audio content is empty', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } // Ensure directory exists. $directory = dirname( $file_path ); if ( ! is_dir( $directory ) ) { if ( ! wp_mkdir_p( $directory ) ) { return $this->create_error_response( __( 'Cannot create directory: ', 'accessibility-audio-tts-text-to-speech-for-articles' ) . $directory ); } } // Write file. if ( ! $this->file_writer->save_raw_audio_content( $audio_content, $file_path ) ) { return $this->create_error_response( __( 'Failed to write raw audio content', 'accessibility-audio-tts-text-to-speech-for-articles' ) ); } $file_size = filesize( $file_path ); accessibility_audio_tts_debug_log( '[Audio_File_Storage] Raw audio stored successfully. Size: ' . $file_size . ' bytes', true ); return array( 'success' => true, 'path' => $file_path, 'size' => $file_size, 'stored_at' => current_time( 'mysql' ), ); } catch ( \Throwable $e ) { accessibility_audio_tts_debug_log( '[Audio_File_Storage] Error storing raw audio: ' . $e->getMessage(), true ); return $this->create_error_response( __( 'Error storing raw audio: ', 'accessibility-audio-tts-text-to-speech-for-articles' ) . $e->getMessage() ); } } /** * Check if file exists in storage. * * @param string $file_path File path to check. * @return bool True if file exists. */ public function file_exists( string $file_path ): bool { return file_exists( $file_path ) && is_readable( $file_path ); } /** * Get file size. * * @param string $file_path File path. * @return int File size in bytes, 0 if file doesn't exist. */ public function get_file_size( string $file_path ): int { return $this->file_exists( $file_path ) ? filesize( $file_path ) : 0; } /** * Get storage statistics. * * @return array Storage statistics. */ public function get_storage_stats(): array { $upload_path = $this->directory_manager->get_upload_path(); if ( ! is_dir( $upload_path ) ) { return array( 'total_files' => 0, 'total_size' => 0, 'directory_exists' => false, ); } $files = glob( $upload_path . '/*.mp3' ); $total_size = 0; foreach ( $files as $file ) { if ( is_file( $file ) ) { $total_size += filesize( $file ); } } return array( 'total_files' => count( $files ), 'total_size' => $total_size, 'total_size_formatted' => size_format( $total_size ), 'directory_exists' => true, // Use helper to avoid direct is_writable. 'directory_writable' => \Accessibility_Audio_TTS\API\File_Validation_Helper::is_directory_writable( $upload_path ), ); } /** * Generate filename for audio file. * * @param int $post_id Post ID. * @param string $format File format. * @return string Generated filename. */ private function generate_filename( int $post_id, string $format ): string { return $this->file_writer->generate_final_filename_for_post( $post_id, $format ); } /** * Create standardized error response. * * @param string $error_message Error message. * @return array Error response. */ private function create_error_response( string $error_message ): array { return array( 'success' => false, 'error' => $error_message, ); } }