$atts Shortcode attributes. * @return string */ public function render( $atts ) { $atts = shortcode_atts( array( 'src' => '', 'title' => '', 'image' => '', 'playlist' => '', 'theme' => '', ), (array) $atts, 'audio_player' ); $settings = Settings::get(); $attrs = array( 'src' => $atts['src'], 'title' => $atts['title'], 'image' => $atts['image'], 'playlist' => $this->parse_playlist_attribute( $atts['playlist'] ), 'theme' => $atts['theme'] ? $atts['theme'] : $settings['default_theme'], 'useGlobalTheme' => empty( $atts['theme'] ), ); return Renderer::render_player( $attrs ); } /** * Parse playlist attribute into normalized track items. * * Supported formats: * - JSON array of objects with src/title/image * - Line-based entries: title|src|image * * @param string $playlist_raw Raw playlist value. * @return array> */ private function parse_playlist_attribute( $playlist_raw ) { $playlist_raw = trim( html_entity_decode( (string) $playlist_raw, ENT_QUOTES, get_bloginfo( 'charset' ) ) ); if ( '' === $playlist_raw ) { return array(); } $decoded = json_decode( $playlist_raw, true ); if ( is_array( $decoded ) ) { return $decoded; } $tracks = array(); $lines = preg_split( '/\r\n|\r|\n/', $playlist_raw ); foreach ( (array) $lines as $line ) { $line = trim( (string) $line ); if ( '' === $line ) { continue; } $parts = array_map( 'trim', explode( '|', $line ) ); $tracks[] = array( 'title' => $parts[0] ?? '', 'src' => $parts[1] ?? '', 'image' => $parts[2] ?? '', ); } return $tracks; } }