PluginProbe
Code Embed / 2.6.1
Code Embed v2.6.1
2.6.4 2.6.3 2.6.2 2.6.1 trunk 1.0 1.1 1.2 1.3 1.4.1 1.5.1 1.6.1 2.0.2 2.1.2 2.2.2 2.3.9 2.4 2.5.1 2.5.2 2.6
simple-embed-code / includes / add-embeds.php

add-embeds.php in Code Embed 2.6.1, at includes/add-embeds.php

335 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Add Embed to Posts
4 *
5 * Functions to add embed code to posts.
6 *
7 * @package simple-embed-code
8 */
9
10 // Exit if accessed directly.
11
12 if ( ! defined( 'ABSPATH' ) ) {
13 exit;
14 }
15
16 /**
17 * Add filter to add embed code
18 *
19 * Filter to add embed to any posts.
20 *
21 * @uses ce_get_embed_code Get embed code from other posts.
22 * @uses ce_quick_replace Perform a quick/replace of content.
23 * @uses. ce_generate_code Create the appropriate embed code.
24 *
25 * @param string $content Post content without embedded code.
26 * @return string Post content with embedded code.
27 */
28 function ce_filter( $content ) {
29
30 global $post;
31
32 if ( ! isset( $post->ID ) ) {
33 return $content;
34 }
35
36 // Set initial values.
37 static $options = null;
38 if ( null === $options ) {
39 $options = get_option( 'artiss_code_embed' );
40 }
41
42 if ( ! is_array( $options ) ) {
43 return $content;
44 }
45
46 $found_pos = strpos( $content, $options['opening_ident'] . $options['keyword_ident'], 0 );
47 $prefix_len = strlen( $options['opening_ident'] . $options['keyword_ident'] );
48
49 // Loop around the post content looking for all requests for code embeds.
50
51 while ( false !== $found_pos ) {
52
53 // Get the position of the closing identifier - ignore if one is not found!
54
55 $end_pos = strpos( $content, $options['closing_ident'], $found_pos + $prefix_len );
56 if ( false !== $end_pos ) {
57
58 // Extract the suffix.
59
60 $suffix_len = $end_pos - ( $found_pos + $prefix_len );
61 if ( 0 === $suffix_len ) {
62 $suffix = '';
63 } else {
64 $suffix = substr( $content, $found_pos + $prefix_len, $suffix_len );
65 }
66 $full_suffix = $suffix;
67
68 // Check for responsive part of suffix.
69
70 $responsive = false;
71 $max_width = false;
72 $res_pos = false;
73 if ( 1 < strlen( $suffix ) ) {
74 $res_pos = strpos( $suffix, '_RES', 1 );
75 }
76
77 if ( false !== $res_pos ) {
78
79 // If responsive section found, check it's at the end or has an underscore afterwards.
80 // Otherwise it may be part of something else.
81
82 if ( strlen( $suffix ) - 4 === $res_pos ) {
83 $responsive = true;
84 } elseif ( '_' === substr( $suffix, $res_pos + 4, 1 ) ) {
85 $responsive = true;
86 $max_width = substr( $suffix, $res_pos + 5 );
87 if ( ! is_numeric( $max_width ) ) {
88 $max_width = '';
89 }
90 }
91
92 if ( $responsive ) {
93 $suffix = substr( $suffix, 0, $res_pos );
94 }
95 }
96
97 // Get the meta for the current post.
98
99 $post_meta = get_post_meta( $post->ID, $options['keyword_ident'] . $suffix, false );
100 if ( isset( $post_meta[0] ) ) {
101 $html = $post_meta[0];
102 } else {
103 // No meta found, so look for it elsewhere.
104 $html = ce_get_embed_code( $options['keyword_ident'], $suffix );
105 }
106
107 // Build the string to search for.
108
109 $search = $options['opening_ident'] . $options['keyword_ident'] . $full_suffix . $options['closing_ident'];
110
111 // Build the string of code to replace with.
112
113 $replace = ce_generate_code( $html, $responsive, $max_width );
114
115 // Now modify all references.
116
117 $content = str_replace( $search, $replace, $content );
118
119 }
120 $found_pos = strpos( $content, $options['opening_ident'] . $options['keyword_ident'], $found_pos + 1 );
121 }
122
123 // Loop around the post content looking for HTTP addresses.
124
125 if ( '1' === get_post_meta( $post->ID, '_ce_allow_url_embeds', true ) ) {
126 $content = ce_quick_replace( $content, $options, 'http://' );
127
128 // Loop around the post content looking for HTTPS addresses.
129
130 $content = ce_quick_replace( $content, $options, 'https://' );
131 }
132
133 return $content;
134 }
135
136 add_filter( 'the_content', 'ce_filter' );
137 add_filter( 'widget_text_content', 'ce_filter' );
138 add_action( 'save_post', 'ce_save_url_embed_permission' );
139
140 /**
141 * Save URL Embed Permission
142 *
143 * On post save, records whether the post author has the unfiltered_html
144 * capability, so that URL embed tokens are only expanded at render time
145 * for content authored by trusted users.
146 *
147 * @param string $post_id The post ID.
148 */
149 function ce_save_url_embed_permission( $post_id ) {
150
151 if ( wp_is_post_revision( $post_id ) ) {
152 return;
153 }
154
155 $post = get_post( $post_id );
156 $allowed = user_can( $post->post_author, 'unfiltered_html' ) ? '1' : '0';
157 update_post_meta( $post_id, '_ce_allow_url_embeds', $allowed );
158 }
159
160 /**
161 * Quick Replace
162 *
163 * Function to do a quick search/replace of the content.
164 *
165 * @param string $content The content.
166 * @param array $options The options array.
167 * @param string $search The string to search for.
168 * @return string The updated content.
169 */
170 function ce_quick_replace( $content = '', $options = '', $search = '' ) {
171
172 $start_pos = strpos( $content, $options['opening_ident'] . $search, 0 );
173
174 while ( false !== $start_pos ) {
175
176 $end_pos = strpos( $content, $options['closing_ident'], $start_pos + 1 );
177
178 if ( false !== $end_pos ) {
179 $url = substr( $content, $start_pos + strlen( $options['opening_ident'] ), $end_pos - ( $start_pos + strlen( $options['opening_ident'] ) ) );
180 $file = ce_get_file( $url );
181 if ( false === $file ) {
182 $file = ce_report_error( __( 'File could not be fetched', 'simple-embed-code' ), 'Code Embed', false );
183 }
184 $content = str_replace( $options['opening_ident'] . $url . $options['closing_ident'], wp_kses_post( $file ), $content );
185 $start_pos = strpos( $content, $options['opening_ident'] . $search, 0 );
186 } else {
187 $start_pos = strpos( $content, $options['opening_ident'] . $search, $start_pos + 1 );
188 }
189 }
190
191 return $content;
192 }
193
194 /**
195 * Generate Embed Code
196 *
197 * Function to generate the embed code that will be output.
198 *
199 * @param string $html The embed code (required).
200 * @param bool $responsive Responsive output required? (optional).
201 * @param string|bool $max_width Maximum width of responsive output (optional).
202 * @return string The embed code.
203 */
204 function ce_generate_code( $html, $responsive = false, $max_width = false ) {
205
206 $code = '';
207
208 if ( false !== $max_width && '' !== $max_width ) {
209 $code .= '<div style="width: ' . $max_width . 'px; max-width: 100%">';
210 }
211
212 if ( $responsive ) {
213 $code .= '<div class="ce-video-container">';
214 }
215
216 $code .= $html;
217
218 if ( $responsive ) {
219 $code .= '</div>';
220 }
221
222 if ( false !== $max_width && '' !== $max_width ) {
223 $code .= '</div>';
224 }
225
226 return $code;
227 }
228
229 /**
230 * Get the Global Embed Code
231 *
232 * Function to look for and, if available, return the global embed code.
233 *
234 * @uses ce_report_error Generate an error message
235 *
236 * @param string $ident The embed code opening identifier.
237 * @param string $suffix The embed code suffix.
238 * @return string The embed code (or error).
239 */
240 function ce_get_embed_code( $ident, $suffix ) {
241
242 // Meta was not found in the current post, so look across the meta table.
243
244 $meta_name = $ident . $suffix;
245 global $wpdb;
246 $meta = $wpdb->get_results( $wpdb->prepare( "SELECT meta_value, post_title, ID FROM $wpdb->postmeta INNER JOIN $wpdb->posts ON post_id = ID WHERE meta_key = %s AND post_status NOT IN ('trash', 'auto-draft', 'inherit')", $meta_name ) ); // @codingStandardsIgnoreLine -- requires the latest data when called, so caching is inappropriate
247
248 $total_records = count( $meta );
249
250 if ( 0 < $total_records ) {
251
252 // Results were found - count how many distinct embed code values exist.
253
254 $records = count( array_unique( wp_list_pluck( $meta, 'meta_value' ) ) );
255
256 if ( 1 === $records ) {
257
258 // Only one unique code result returned, so assume this is the global embed.
259
260 $html = $meta[0]->meta_value;
261
262 } else {
263
264 // More than one unique code result returned, so output the list of posts.
265
266 /* translators: %1$s: the embed code name, %2$d: the number of pieces of embed code being stored with that name, %3$d: the number of posts using that embed name */
267 $error = sprintf( __( 'Cannot use %1$s as a global code as it is being used to store %2$d unique pieces of code in %3$d posts', 'simple-embed-code' ), $meta_name, $records, $total_records );
268 $html = ce_report_error( $error, 'Code Embed', false );
269 }
270 } else {
271
272 // No meta code was found, so write out an error.
273
274 /* translators: %s: the name of the embed */
275 $html = ce_report_error( sprintf( __( 'No embed code was found for %s', 'simple-embed-code' ), $meta_name ), 'Code Embed', false );
276
277 }
278 return $html;
279 }
280
281 /**
282 * Fetch a file
283 *
284 * Use WordPress API to fetch a file and check the results.
285 *
286 * @param string $filein File name to fetch.
287 * @return string|false File contents as a string, or false on failure.
288 */
289 function ce_get_file( $filein ) {
290
291 if ( function_exists( 'vip_safe_wp_remote_get' ) ) {
292
293 $response = vip_safe_wp_remote_get( $filein, '', 3, 3 );
294
295 } else {
296
297 $response = wp_safe_remote_get( $filein, array( 'timeout' => 3 ) ); // @codingStandardsIgnoreLine -- for non-VIP environments
298
299 }
300
301 if ( is_array( $response ) ) {
302
303 return $response['body'];
304
305 } else {
306
307 return false;
308
309 }
310 }
311
312 /**
313 * Report an error
314 *
315 * Function to report an error.
316 *
317 * @param string $error Error message.
318 * @param string $plugin_name The name of the plugin.
319 * @param bool $echo_out True or false, depending on whether you wish to return or echo the results.
320 * @return bool|string Returns the error message or true when echoing or if not a user with edit capabilities.
321 */
322 function ce_report_error( $error, $plugin_name, $echo_out = true ) {
323
324 $output = '<p role="alert" style="color: #b91c1c; font-weight: bold;">' . esc_html( $plugin_name ) . ': ' . esc_html( $error ) . "</p>\n";
325
326 if ( $echo_out || ! current_user_can( 'edit_posts' ) ) {
327 if ( current_user_can( 'edit_posts' ) ) {
328 echo $output; // @codingStandardsIgnoreLine -- being escaped above so this is a false positive
329 }
330 return true;
331 } else {
332 return $output;
333 }
334 }
335