PluginProbe
Embed Privacy / trunk
Embed Privacy vtrunk
1.14.0 1.13.0 trunk 0.1 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.1.3 1.10.0 1.10.1 1.10.10 1.10.2 1.10.3 1.10.4 1.10.5 1.10.6 1.10.7 1.10.8 1.10.9 1.11.0 1.11.1 1.11.2 All 68 releases
embed-privacy / inc / embed / class-template.php

class-template.php in Embed Privacy trunk, at inc/embed/class-template.php

375 lines 12.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace epiphyt\Embed_Privacy\embed;
3
4 use epiphyt\Embed_Privacy\data\Providers;
5 use epiphyt\Embed_Privacy\Embed_Privacy;
6
7 /**
8 * Embed Privacy template related functionality.
9 *
10 * @author Epiphyt
11 * @license GPL2
12 * @package epiphyt\Embed_Privacy
13 * @since 1.10.0
14 */
15 final class Template {
16 /**
17 * Ensure content is localized, even if stored differently.
18 *
19 * @since 1.12.0
20 *
21 * @param string $content Content to localize
22 * @param \epiphyt\Embed_Privacy\embed\Provider $provider Provider object
23 * @param string $type Content type
24 * @return string Localized content, if possible
25 */
26 private static function ensure_localized_content( $content, $provider, $type = 'description' ) {
27 if ( \get_locale() === 'en_US' ) {
28 return $content;
29 }
30
31 if (
32 $type === 'description'
33 && $content === \sprintf(
34 \esc_html( 'Click here to display content from %s.' ),
35 \esc_html( $provider->get_title() )
36 )
37 ) {
38 /* translators: embed provider */
39 $content = \sprintf( \__( 'Click here to display content from %s.', 'embed-privacy' ), $provider->get_title() );
40 }
41
42 return $content;
43 }
44
45 /**
46 * Get an overlay template.
47 *
48 * @param \epiphyt\Embed_Privacy\embed\Provider|string $provider The embed provider
49 * @param string $output The output before replacing it
50 * @param array $attributes Additional attributes
51 * @return string The overlay template
52 */
53 public static function get( $provider, $output, $attributes = [] ) {
54 $embed_post = null;
55
56 if ( ! $provider instanceof Provider ) {
57 \_doing_it_wrong(
58 __METHOD__,
59 \sprintf(
60 /* translators: alternative method */
61 \esc_html__( 'Providing a string as parameter %1$s is deprecated. Use an object of type %2$s instead.', 'embed-privacy' ),
62 '$provider',
63 'epiphyt\Embed_Privacy\embed\Provider'
64 ),
65 '1.10.0'
66 );
67
68 $provider = Providers::get_instance()->get_by_name( Providers::sanitize_name( $provider ) );
69 }
70
71 /**
72 * Filter the overlay arguments.
73 *
74 * @deprecated 1.10.0 Use embed_privacy_template_attributes instead
75 * @since 1.9.0
76 *
77 * @param array $attributes Template arguments
78 * @param string $provider The embed provider
79 * @param string $provider_name The embed provider without spaces and in lowercase
80 * @param string $output The output before replacing it
81 */
82 $attributes = (array) \apply_filters_deprecated(
83 'embed_privacy_overlay_args',
84 [
85 $attributes,
86 $provider,
87 $provider->get_name(),
88 $output,
89 ],
90 '1.10.0',
91 'embed_privacy_template_attributes'
92 );
93
94 /**
95 * Filter the template attributes.
96 *
97 * @since 1.10.0
98 *
99 * @param array $attributes Template attributes
100 * @param \epiphyt\Embed_privacy\embed\Provider $provider The embed provider
101 * @param string $output The output before replacing it
102 */
103 $attributes = (array) \apply_filters( 'embed_privacy_template_attributes', $attributes, $provider, $output );
104
105 if ( ! empty( $attributes['post_id'] ) ) {
106 $embed_post = \get_post( $attributes['post_id'] );
107
108 if ( Providers::is_disabled( $embed_post ) ) {
109 return $output;
110 }
111 }
112 else if ( ! empty( $attributes['provider'] ) ) {
113 if ( $attributes['provider'] instanceof Provider && $attributes['provider']->is_disabled() ) {
114 return $output;
115 }
116 }
117 else {
118 $embed_post = $provider->get_post_object();
119 }
120
121 if ( $provider->is( 'youtube' ) ) {
122 $output = \str_replace( 'youtube.com', 'youtube-nocookie.com', $output );
123 }
124
125 $embed_class = 'embed-' . ( ! empty( $provider->get_name() ) ? $provider->get_name() : 'default' );
126 $embed_classes = $embed_class;
127 $style = new Style( $provider, null, $attributes );
128
129 if ( ! empty( $attributes['align'] ) ) {
130 $embed_classes .= ' align' . $attributes['align'];
131 }
132
133 if ( ! empty( $attributes['assets'] ) ) {
134 $output = Assets::get_static( $attributes['assets'], $provider->get_name() ) . $output;
135 }
136
137 $embed_md5 = \md5( $output . \wp_generate_uuid4() );
138 $checkbox_id = 'embed-privacy-store-' . $provider->get_name() . '-' . $embed_md5;
139
140 /**
141 * Fires before the template output is generated.
142 *
143 * @since 1.10.0
144 *
145 * @param \epiphyt\Embed_Privacy\embed\Provider $provider The embed provider
146 * @param \epiphyt\Embed_Privacy\embed\Style $style The overlay style object
147 * @param array $attributes Additional attributes
148 */
149 \do_action( 'embed_privacy_before_template_output', $provider, $style, $attributes );
150
151 \ob_start();
152 ?>
153 <p>
154 <?php
155 if ( ! empty( $provider->get_name() ) ) {
156 if ( $embed_post || ! empty( $provider->get_description() ) ) {
157 $allowed_tags = [
158 'a' => [
159 'href',
160 'rel',
161 'target',
162 ],
163 'span' => [
164 'class',
165 ],
166 ];
167
168 if ( $embed_post ) {
169 $description = $embed_post->post_content;
170 $privacy_policy = \get_post_meta( $embed_post->ID, 'privacy_policy_url', true );
171 }
172 else {
173 $description = $provider->get_description();
174 $privacy_policy = $provider->get_privacy_policy_url();
175 }
176
177 echo \wp_kses_post( self::ensure_localized_content( $description, $provider ) ) . \PHP_EOL;
178
179 if ( $privacy_policy ) {
180 ?>
181 <br>
182 <?php
183 \printf(
184 /* translators: 1: embed provider, 2: opening <a> tag to the privacy policy, 3: closing </a> */
185 \wp_kses( \__( 'Learn more in %2$s%1$s’s privacy policy%3$s.', 'embed-privacy' ), $allowed_tags ),
186 \esc_html( $provider->get_title() ),
187 '<a href="' . \esc_url( $privacy_policy ) . '" target="_blank" rel="noopener noreferrer">', '<span class="embed-privacy__new-tab-notice"> ' . \esc_html__( '(opens in a new tab)', 'embed-privacy' ) . '</span></a>'
188 );
189 }
190 }
191 else {
192 /* translators: embed provider */
193 \printf( \esc_html__( 'Click here to display content from %s.', 'embed-privacy' ), \esc_html( $provider->get_title() ) );
194 }
195 }
196 else {
197 \esc_html_e( 'Click here to display content from an external service.', 'embed-privacy' );
198 }
199 ?>
200 <noscript>
201 <br>
202 <?= \esc_html__( 'Please enable JavaScript in your browser to load this content.', 'embed-privacy' ); ?>
203 </noscript>
204 </p>
205 <p class="embed-privacy-input-wrapper">
206 <input id="<?php echo \esc_attr( $checkbox_id ); ?>" type="checkbox" value="1" class="embed-privacy-input" data-embed-provider="<?php echo \esc_attr( $provider->get_name() ); ?>">
207 <label for="<?php echo \esc_attr( $checkbox_id ); ?>" class="embed-privacy-label" data-embed-provider="<?php echo \esc_attr( $provider->get_name() ); ?>">
208 <?php
209 /* translators: the embed provider */
210 \printf( \esc_html__( 'Always display content from %s', 'embed-privacy' ), \esc_html( $provider->get_title() ) );
211 ?>
212 </label>
213 </p>
214 <?php
215 $content = \ob_get_clean();
216
217 /**
218 * Filter the content of the embed overlay.
219 *
220 * @deprecated 1.10.0 Use embed_privacy_template_content instead
221 *
222 * @param string $content The content
223 * @param string $provider The embed provider of this embed
224 */
225 $content = \apply_filters_deprecated(
226 'embed_privacy_content',
227 [
228 $content,
229 $provider->get_title(),
230 ],
231 '1.10.0',
232 'embed_privacy_template_content'
233 );
234
235 /**
236 * Filter the content of the embed overlay.
237 *
238 * @since 1.10.0
239 *
240 * @param string $content The content
241 * @param string $provider The embed provider of this embed
242 */
243 $content = \apply_filters( 'embed_privacy_template_content', $content, $provider );
244
245 \ob_start();
246
247 $footer_content = '';
248
249 if ( ! empty( $attributes['embed_url'] ) ) {
250 $footer_content = '<div class="embed-privacy-footer">';
251
252 if ( ! \get_option( 'embed_privacy_disable_link' ) ) {
253 $footer_content .= self::get_embed_link_markup( $attributes, $provider );
254 }
255
256 $footer_content .= '</div>' . \PHP_EOL;
257
258 /**
259 * Filter the overlay footer.
260 *
261 * @param string $footer_content The footer content
262 */
263 $footer_content = \apply_filters( 'embed_privacy_overlay_footer', $footer_content );
264 }
265
266 $container_style = $style->get( 'container' );
267 $logo_style = $style->get( 'logo' );
268 ?>
269 <div class="embed-privacy-container is-disabled <?php echo \esc_attr( $embed_classes ); ?>" data-embed-id="oembed_<?php echo \esc_attr( $embed_md5 ); ?>" data-embed-provider="<?php echo \esc_attr( $provider->get_name() ); ?>"<?php echo ! empty( $container_style ) ? ' style="' . \esc_attr( $container_style ) . '"' : ''; ?>>
270 <?php
271 /* translators: embed provider */
272 $button_text = \sprintf( \__( 'Display content from %s', 'embed-privacy' ), \esc_html( $provider->get_title() ) );
273
274 if ( ! empty( $attributes['embed_title'] ) ) {
275 /* translators: 1: embed title, 2: embed provider */
276 $button_text = \sprintf( \__( 'Display "%1$s" from %2$s', 'embed-privacy' ), $attributes['embed_title'], \esc_html( $provider->get_title() ) );
277 }
278
279 /* translators: embed provider */
280 $loaded_message = \sprintf( \__( 'Content from %s has been loaded.', 'embed-privacy' ), $provider->get_title() );
281 ?>
282 <button type="button" class="embed-privacy-enable screen-reader-text"><?php echo \esc_html( $button_text ); ?></button>
283 <div class="embed-privacy-sr-message screen-reader-text" role="status" data-message="<?php echo \esc_attr( $loaded_message ); ?>"></div>
284
285 <div class="embed-privacy-overlay">
286 <div class="embed-privacy-inner">
287 <?php
288 echo ! empty( $logo_style ) ? '<div class="embed-privacy-logo" style="' . \esc_attr( $logo_style ) . '" aria-hidden="true"></div>' . \PHP_EOL : '';
289 echo $content . \PHP_EOL; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
290 ?>
291 </div>
292
293 <?php echo $footer_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
294 </div>
295
296 <div class="embed-privacy-content">
297 <script>var _oembed_<?php echo $embed_md5; ?> = '<?php echo \addslashes( \wp_json_encode( [ 'embed' => \htmlentities( \preg_replace( '/\s+/S', ' ', $output ) ) ] ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>';</script>
298 </div>
299 </div>
300 <?php
301 $markup = \ob_get_clean();
302
303 /**
304 * Filter the complete markup of the embed.
305 *
306 * @deprecated 1.10.0 Use embed_privacy_template_markup instead
307 *
308 * @param string $markup The markup
309 * @param string $provider_name The embed provider name of this embed
310 */
311 $markup = \apply_filters_deprecated(
312 'embed_privacy_markup',
313 [
314 $markup,
315 $provider->get_title(),
316 ],
317 '1.10.0',
318 'embed_privacy_template_markup'
319 );
320
321 /**
322 * Filter the complete markup of the embed.
323 *
324 * @since 1.10.0
325 * @since 1.11.2 Added $attributes parameter
326 *
327 * @param string $markup The markup
328 * @param \epiphyt\Embed_Privacy\embed\Provider $provider The embed provider of this embed
329 * @param mixed[] $attributes Embed attributes
330 */
331 $markup = \apply_filters( 'embed_privacy_template_markup', $markup, $provider, $attributes );
332
333 Embed_Privacy::get_instance()->has_embed = true;
334
335 if ( ! empty( $attributes['strip_newlines'] ) ) {
336 $markup = \str_replace( \PHP_EOL, '', $markup );
337 }
338
339 return $markup;
340 }
341
342 /**
343 * Get the embed link markup.
344 *
345 * @param mixed[] $attributes Embed attributes
346 * @param \epiphyt\Embed_Privacy\embed\Provider $provider The embed provider of this embed
347 * @return string Embed link markup
348 */
349 private static function get_embed_link_markup( $attributes, $provider ) {
350 if ( ! empty( $attributes['embed_title'] ) ) {
351 $footer_link_title = \sprintf(
352 /* translators: content name */
353 \esc_html__( 'Open "%s" directly', 'embed-privacy' ),
354 \esc_html( $attributes['embed_title'] )
355 );
356 }
357 else if ( ! empty( $provider->get_content_name() ) ) {
358 $footer_link_title = \sprintf(
359 /* translators: content name */
360 \esc_html__( 'Open %s directly', 'embed-privacy' ),
361 $provider->get_content_name()
362 );
363 }
364 else {
365 $footer_link_title = \esc_html__( 'Open content directly', 'embed-privacy' );
366 }
367
368 return \sprintf(
369 '<span class="embed-privacy-url"><a href="%1$s">%2$s</a></span>',
370 \esc_url( $attributes['embed_url'] ),
371 $footer_link_title
372 );
373 }
374 }
375