PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 4.5.5
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v4.5.5
4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / RestAPI.php
embedpress / EmbedPress Last commit date
AMP 3 weeks ago Analytics 3 weeks ago Elementor 3 weeks ago Ends 3 weeks ago Gutenberg 3 weeks ago Includes 3 weeks ago Plugins 3 weeks ago Providers 3 weeks ago ThirdParty 3 weeks ago AutoLoader.php 3 weeks ago Compatibility.php 3 weeks ago Core.php 3 weeks ago CoreLegacy.php 3 weeks ago DisablerLegacy.php 3 weeks ago Loader.php 3 weeks ago MilestoneNotification.php 3 weeks ago RestAPI.php 3 weeks ago Shortcode.php 3 weeks ago index.html 3 weeks ago simple_html_dom.php 3 weeks ago
RestAPI.php
196 lines
1 <?php
2
3 namespace EmbedPress;
4
5 use EmbedPress\Includes\Classes\Helper;
6 use Embera\Embera;
7 use WP_Error as WP_ErrorAlias;
8 use WP_REST_Request;
9 use WP_REST_Response;
10
11 (defined('ABSPATH') && defined('EMBEDPRESS_IS_LOADED')) or die("No direct script access allowed.");
12
13 /**
14 * Entity responsible for maintaining and registering all hooks that power the plugin.
15 *
16 * @package EmbedPress
17 * @author EmbedPress <help@embedpress.com>
18 * @copyright Copyright (C) 2023 WPDeveloper. All rights reserved.
19 * @license GPLv3 or later
20 * @since 1.0.0
21 */
22 class RestAPI
23 {
24 /**
25 * @param WP_REST_Request $request
26 *
27 * @return WP_REST_Response | WP_ErrorAlias
28 */
29 public static function oembed($request)
30 {
31 // Prevent infinite recursion: this endpoint IS the oembed provider,
32 // so if it triggers another oembed fetch that resolves back here, stop immediately.
33 static $is_processing = false;
34 if ($is_processing) {
35 return new WP_ErrorAlias(
36 'embedpress_recursion',
37 'Recursive oEmbed request detected',
38 ['status' => 508]
39 );
40 }
41 $is_processing = true;
42
43 $url = esc_url_raw($request->get_param('url'));
44 $playlist_id = $request->get_param( 'list');
45 if ( !empty( $playlist_id) ) {
46 $url .= "&list=$playlist_id";
47 }
48
49 $atts = $request->get_params();
50
51
52 if (empty($url)) {
53 $is_processing = false;
54 return new WP_ErrorAlias('embedpress_invalid_url', 'Invalid Embed URL', ['status' => 404]);
55 }
56
57 // Validate URL has a proper scheme to reject malformed URLs early
58 if (!preg_match('#^https?://#i', $url)) {
59 $is_processing = false;
60 return new WP_ErrorAlias('embedpress_invalid_url', 'Invalid URL scheme', ['status' => 400]);
61 }
62
63 $atts = Helper::removeQuote($atts);
64
65 // Map Meetup-specific Gutenberg attributes to shortcode attributes
66 if (!empty($url) && strpos($url, 'meetup.com') !== false) {
67 if (isset($atts['meetupOrderBy'])) {
68 $atts['orderby'] = $atts['meetupOrderBy'];
69 }
70 if (isset($atts['meetupOrder'])) {
71 $atts['order'] = $atts['meetupOrder'];
72 }
73 if (isset($atts['meetupPerPage'])) {
74 $atts['per_page'] = $atts['meetupPerPage'];
75 }
76 if (isset($atts['meetupEnablePagination'])) {
77 $atts['enable_pagination'] = $atts['meetupEnablePagination'];
78 }
79 if (isset($atts['meetupTimezone'])) {
80 $atts['timezone'] = $atts['meetupTimezone'];
81 }
82 if (isset($atts['meetupDateFormat'])) {
83 $atts['date_format'] = $atts['meetupDateFormat'];
84 }
85 if (isset($atts['meetupTimeFormat'])) {
86 $atts['time_format'] = $atts['meetupTimeFormat'];
87 }
88 }
89
90 $urlInfo = Shortcode::parseContent( $url, true, $atts);
91 $is_processing = false;
92 if (empty($urlInfo)) {
93 return new WP_ErrorAlias('embedpress_invalid_url', 'Invalid Embed URL', ['status' => 404]);
94 }
95 return new WP_REST_Response($urlInfo, 200);
96 }
97
98 /**
99 * Lazy-load next page of YouTube playlist items for the queue layout.
100 * Returns rendered <li class="ep-yt-queue__item"> markup so the JS can
101 * just .insertAdjacentHTML — no client-side templating needed.
102 *
103 * GET /wp-json/embedpress/v1/youtube-playlist-items
104 * playlist_id PL… / RD… / UU…
105 * page_token YouTube pageToken from the prior response
106 * page_size items per request (1–50, default 6)
107 * offset starting index for the data-index attribute
108 */
109 public static function youtube_playlist_items($request)
110 {
111 $playlist_id = (string) $request->get_param('playlist_id');
112 $page_token = (string) $request->get_param('page_token');
113 $page_size = (int) $request->get_param('page_size');
114 $offset = (int) $request->get_param('offset');
115
116 if (empty($playlist_id) || empty($page_token)) {
117 return new WP_REST_Response(['html' => '', 'next_page_token' => ''], 200);
118 }
119 $page_size = $page_size > 0 && $page_size <= 50 ? $page_size : 6;
120
121 $settings = (array) get_option(EMBEDPRESS_PLG_NAME . ':youtube', []);
122 $api_key = !empty($settings['api_key']) ? $settings['api_key'] : '';
123 if (empty($api_key)) {
124 return new WP_REST_Response(['html' => '', 'next_page_token' => ''], 200);
125 }
126
127 $endpoint = 'https://www.googleapis.com/youtube/v3/playlistItems?' . http_build_query([
128 'part' => 'snippet,status,contentDetails',
129 'playlistId' => $playlist_id,
130 'maxResults' => $page_size,
131 'pageToken' => $page_token,
132 'key' => $api_key,
133 ]);
134
135 $transient_key = 'ep_yt_queue_page_' . md5($endpoint);
136 $json = get_transient($transient_key);
137 if (empty($json)) {
138 $resp = wp_remote_get($endpoint, ['timeout' => 30]);
139 if (is_wp_error($resp)) {
140 return new WP_REST_Response(['html' => '', 'next_page_token' => ''], 200);
141 }
142 $json = json_decode(wp_remote_retrieve_body($resp));
143 if (empty($json) || !empty($json->error)) {
144 set_transient($transient_key, $json, 10);
145 return new WP_REST_Response(['html' => '', 'next_page_token' => ''], 200);
146 }
147 set_transient($transient_key, $json, MINUTE_IN_SECONDS * 20);
148 }
149
150 $layout = (string) $request->get_param('layout');
151
152 // Pro layouts (library/spotlight/cinema/magazine) ship their own
153 // per-item markup, so let the Pro plugin filter the HTML when its
154 // layout is asked for. If no Pro filter is registered, we fall back
155 // to queue items below — matches the front-render fallback.
156 $pro_layouts = ['library', 'spotlight', 'cinema', 'magazine'];
157 if (in_array($layout, $pro_layouts, true)) {
158 $html = apply_filters(
159 'embedpress/youtube_playlist_pro_items_html',
160 '',
161 $layout,
162 $json,
163 ['hideprivate' => false, 'thumbnail' => 'medium'],
164 $offset
165 );
166 if ($html === '') {
167 $html = \EmbedPress\Providers\TemplateLayouts\YoutubeLayout::render_queue_items(
168 $json,
169 ['hideprivate' => false, 'thumbnail' => 'medium'],
170 $offset,
171 ''
172 );
173 }
174 } elseif ($layout === 'theatre') {
175 $html = \EmbedPress\Providers\TemplateLayouts\YoutubeLayout::render_theatre_cards(
176 $json,
177 ['hideprivate' => false, 'thumbnail' => 'medium'],
178 $offset,
179 ''
180 );
181 } else {
182 $html = \EmbedPress\Providers\TemplateLayouts\YoutubeLayout::render_queue_items(
183 $json,
184 ['hideprivate' => false, 'thumbnail' => 'medium'],
185 $offset,
186 ''
187 );
188 }
189
190 return new WP_REST_Response([
191 'html' => $html,
192 'next_page_token' => isset($json->nextPageToken) ? $json->nextPageToken : '',
193 ], 200);
194 }
195 }
196