WordPress多社交平台内容聚合短代码排序失效求助
WordPress社交聚合短代码修复方案
核心问题定位
你的代码无法正常运行的主要原因是函数调用名称不匹配,同时存在排序逻辑、兼容性和安全性的细节问题:
- 在
social_wall_shortcode中,你调用了不存在的my_instagram_feed_shortcode和display_twitch_videos函数,实际应该是你定义好的fetch_instagram_posts和fetch_twitch_videos - 默认排序是按日期升序(最早内容在前),不符合“最新内容优先”的常规需求
- Instagram使用
file_get_contents兼容性较差,WordPress环境推荐用官方的wp_remote_get - Twitch嵌入代码中的
parent=*存在安全风险,应该指定实际站点域名
修复后的完整代码
<?php /* Plugin Name: Social media crawler Description: 聚合Twitch、YouTube、Instagram内容并按日期排序 Version: 1.0 Author: License: GPL2 License URI: https://www.gnu.org/licenses/gpl-2.0.html Domain Path: /languages */ function fetch_youtube_videos($atts) { $atts = shortcode_atts(array( 'channel_id' => '***', 'max_results' => 5, 'date' => '2010-01-01', ), $atts); $api_key = '***'; $publishedAfter = $atts['date'] . 'T00:00:00Z'; $api_url = add_query_arg(array( 'part' => 'snippet', 'channelId' => $atts['channel_id'], 'maxResults' => $atts['max_results'], 'publishedAfter' => $publishedAfter, 'order' => 'date', 'type' => 'video', 'key' => $api_key ), 'https://www.googleapis.com/youtube/v3/search'); $response = wp_remote_get($api_url); if (is_wp_error($response)) { return []; } $body = wp_remote_retrieve_body($response); $data = json_decode($body); if (!isset($data->items)) { return []; } $posts = []; foreach ($data->items as $item) { $title = $item->snippet->title; $video_id = $item->id->videoId; $video_url = 'https://www.youtube.com/watch?v=' . $video_id; $embed_url = 'https://www.youtube.com/embed/' . $video_id; $publishedAt = $item->snippet->publishedAt; $html = '<div class="youtube-video">' . '<iframe width="560" height="315" src="' . esc_url($embed_url) . '" title="' . esc_attr($title) . '" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>' . '<p><a href="' . esc_url($video_url) . '" target="_blank">' . esc_html($title) . '</a></p>' . '</div>'; $posts[] = [ 'date' => $publishedAt, 'html' => $html ]; } return $posts; } function fetch_instagram_posts($atts) { $atts = shortcode_atts([ 'limit' => 10, ], $atts); $fields = "id,caption,media_type,media_url,permalink,thumbnail_url,timestamp,username"; $token = "*"; $limit = $atts['limit']; $api_url = add_query_arg(array( 'fields' => $fields, 'access_token' => $token, 'limit' => $limit ), 'https://graph.instagram.com/me/media'); $response = wp_remote_get($api_url); if (is_wp_error($response)) { return []; } $body = wp_remote_retrieve_body($response); $contents = json_decode($body, true); if (!isset($contents["data"]) || empty($contents["data"])) { return []; } $posts = []; foreach ($contents["data"] as $post) { $username = isset($post["username"]) ? $post["username"] : ""; $caption = isset($post["caption"]) ? $post["caption"] : ""; $media_url = isset($post["media_url"]) ? $post["media_url"] : ""; $permalink = isset($post["permalink"]) ? $post["permalink"] : ""; $media_type = isset($post["media_type"]) ? $post["media_type"] : ""; $timestamp = isset($post["timestamp"]) ? $post["timestamp"] : ""; $html = "<div class='ig_post_container'><div>"; if ($media_type == "VIDEO") { $html .= "<video controls style='width:100%; display: block !important;'><source src='" . esc_url($media_url) . "' type='video/mp4'>Your browser does not support the video tag.</video>"; } else { $html .= "<img src='" . esc_url($media_url) . "' alt='" . esc_attr($caption) . "' />"; } $html .= "</div><div class='ig_post_details'><div><strong>@" . esc_html($username) . "</strong> " . esc_html($caption) . "</div><div class='ig_view_link'><a href='" . esc_url($permalink) . "' target='_blank'>View on Instagram</a></div></div></div>"; $posts[] = [ 'date' => $timestamp, 'html' => $html ]; } return $posts; } function fetch_twitch_videos($atts) { $atts = shortcode_atts([ 'date' => '1970-01-01', ], $atts); $clientID = '*'; $clientSecret = '*'; $tokenUrl = 'https://id.twitch.tv/oauth2/token'; $params = [ 'client_id' => $clientID, 'client_secret' => $clientSecret, 'grant_type' => 'client_credentials', ]; $response = wp_remote_post($tokenUrl, array( 'body' => $params )); if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { return []; } $tokenData = json_decode(wp_remote_retrieve_body($response), true); if (!isset($tokenData['access_token'])) { return []; } $accessToken = $tokenData['access_token']; $broadcasterUserId = '*'; $site_domain = wp_parse_url(get_site_url(), PHP_URL_HOST); $videoClipsUrl = add_query_arg(array( 'broadcaster_id' => $broadcasterUserId ), 'https://api.twitch.tv/helix/clips'); $headers = [ 'Authorization: Bearer ' . $accessToken, 'Client-Id: ' . $clientID, ]; $response = wp_remote_get($videoClipsUrl, array( 'headers' => $headers )); if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) { return []; } $videoClipsData = json_decode(wp_remote_retrieve_body($response), true); if (!isset($videoClipsData['data']) || empty($videoClipsData['data'])) { return []; } $posts = array_map(function ($clip) use ($site_domain) { $clipDate = $clip['created_at']; $embed_url = add_query_arg('parent', $site_domain, $clip['embed_url']); $html = '<iframe src="' . esc_url($embed_url) . '" frameborder="0" allowfullscreen="true" scrolling="no" height="378" width="620"></iframe>'; return [ 'date' => $clipDate, 'html' => $html, ]; }, $videoClipsData['data']); $minDateTimestamp = strtotime($atts['date']); $filteredPosts = array_filter($posts, function ($post) use ($minDateTimestamp) { return strtotime($post['date']) >= $minDateTimestamp; }); return array_values($filteredPosts); } function social_wall_shortcode($atts) { ob_start(); // 修正函数调用名称 $youtubePosts = fetch_youtube_videos($atts); $instagramPosts = fetch_instagram_posts($atts); $twitchPosts = fetch_twitch_videos($atts); $allPosts = array_merge($youtubePosts, $instagramPosts, $twitchPosts); // 改为降序排序,最新内容在前 usort($allPosts, function($a, $b) { return strtotime($b['date']) <=> strtotime($a['date']); }); echo '<div class="social-wall-container">'; if (empty($allPosts)) { echo '<p>暂无社交内容展示</p>'; } else { foreach ($allPosts as $post) { echo $post['html']; } } echo '</div>'; $content = ob_get_clean(); return $content; } add_shortcode('social_wall', 'social_wall_shortcode');
关键修复点说明
- 函数名称修正:将
social_wall_shortcode中的错误函数调用替换为正确的fetch_instagram_posts和fetch_twitch_videos - 排序逻辑调整:把排序规则从升序改为降序,确保最新内容优先显示
- 兼容性优化:Instagram和Twitch的API调用改用WordPress原生的
wp_remote_get/wp_remote_post,替代file_get_contents和curl,避免主机环境限制 - 安全增强:Twitch嵌入链接的
parent参数设置为当前站点域名,替代通配符* - 错误提示补充:当没有任何内容时,显示友好提示
- 转义完善:给所有用户生成的内容添加
esc_url/esc_html/esc_attr,防止XSS风险 - URL构建优化:使用
add_query_arg构建API链接,避免手动拼接字符串导致的错误
内容的提问来源于stack exchange,提问作者Mats S
相关产品推荐
相关产品推荐

