PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 12.7.3
Jetpack – WP Security, Backup, Speed, & Growth v12.7.3
12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 14.4.2 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / extensions / blocks / podcast-player / podcast-player.php
jetpack / extensions / blocks / podcast-player Last commit date
templates 4 years ago podcast-player.php 3 years ago
podcast-player.php
320 lines
1 <?php
2 /**
3 * Podcast Player Block.
4 *
5 * @since 8.4.0
6 *
7 * @package automattic/jetpack
8 */
9
10 namespace Automattic\Jetpack\Extensions\Podcast_Player;
11
12 use Automattic\Jetpack\Blocks;
13 use Jetpack_Gutenberg;
14 use Jetpack_Podcast_Helper;
15
16 const FEATURE_NAME = 'podcast-player';
17 const BLOCK_NAME = 'jetpack/' . FEATURE_NAME;
18
19 if ( ! class_exists( 'Jetpack_Podcast_Helper' ) ) {
20 require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-podcast-helper.php';
21 }
22
23 /**
24 * Registers the block for use in Gutenberg. This is done via an action so that
25 * we can disable registration if we need to.
26 */
27 function register_block() {
28 Blocks::jetpack_register_block(
29 BLOCK_NAME,
30 array(
31 'attributes' => array(
32 'url' => array(
33 'type' => 'string',
34 ),
35 'itemsToShow' => array(
36 'type' => 'integer',
37 'default' => 5,
38 ),
39 'showCoverArt' => array(
40 'type' => 'boolean',
41 'default' => true,
42 ),
43 'showEpisodeTitle' => array(
44 'type' => 'boolean',
45 'default' => true,
46 ),
47 'showEpisodeDescription' => array(
48 'type' => 'boolean',
49 'default' => true,
50 ),
51 ),
52 'render_callback' => __NAMESPACE__ . '\render_block',
53 'supports' => array(
54 'align' => array( 'wide', 'full' ),
55 'spacing' => array(
56 'padding' => true,
57 'margin' => true,
58 ),
59 ),
60 // Since Gutenberg #31873.
61 'style' => 'wp-mediaelement',
62
63 )
64 );
65 }
66 add_action( 'init', __NAMESPACE__ . '\register_block' );
67
68 /**
69 * Returns the error message wrapped in HTML if current user
70 * has the capability to edit the post. Public visitors will
71 * never see errors.
72 *
73 * @param string $message The error message to display.
74 * @return string
75 */
76 function render_error( $message ) {
77 // Suppress errors for users unable to address them.
78 if ( ! current_user_can( 'edit_posts' ) ) {
79 return '';
80 }
81 return '<p>' . esc_html( $message ) . '</p>';
82 }
83
84 /**
85 * Podcast Player block registration/dependency declaration.
86 *
87 * @param array $attributes Array containing the Podcast Player block attributes.
88 * @param string $content Fallback content - a direct link to RSS, as rendered by save.js.
89 * @return string
90 */
91 function render_block( $attributes, $content ) {
92 // Don't render an interactive version of the block outside the frontend context.
93 if ( ! jetpack_is_frontend() ) {
94 return $content;
95 }
96
97 // Test for empty URLS.
98 if ( empty( $attributes['url'] ) ) {
99 return render_error( __( 'No Podcast URL provided. Please enter a valid Podcast RSS feed URL.', 'jetpack' ) );
100 }
101
102 // Test for invalid URLs.
103 if ( ! wp_http_validate_url( $attributes['url'] ) ) {
104 return render_error( __( 'Your podcast URL is invalid and couldn\'t be embedded. Please double check your URL.', 'jetpack' ) );
105 }
106
107 if ( ! empty( $attributes['selectedEpisodes'] ) ) {
108 $guids = array_map(
109 function ( $episode ) {
110 return $episode['guid'];
111 },
112 $attributes['selectedEpisodes']
113 );
114 $player_args = array( 'guids' => $guids );
115 } else {
116 $player_args = array();
117 }
118
119 // Sanitize the URL.
120 $attributes['url'] = esc_url_raw( $attributes['url'] );
121 $player_data = ( new Jetpack_Podcast_Helper( $attributes['url'] ) )->get_player_data( $player_args );
122
123 if ( is_wp_error( $player_data ) ) {
124 return render_error( $player_data->get_error_message() );
125 }
126
127 return render_player( $player_data, $attributes );
128 }
129
130 /**
131 * Renders the HTML for the Podcast player and tracklist.
132 *
133 * @param array $player_data The player data details.
134 * @param array $attributes Array containing the Podcast Player block attributes.
135 * @return string The HTML for the podcast player.
136 */
137 function render_player( $player_data, $attributes ) {
138 // If there are no tracks (it is possible) then display appropriate user facing error message.
139 if ( empty( $player_data['tracks'] ) ) {
140 return render_error( __( 'No tracks available to play.', 'jetpack' ) );
141 }
142
143 // Only use the amount of tracks requested.
144 $player_data['tracks'] = array_slice(
145 $player_data['tracks'],
146 0,
147 absint( $attributes['itemsToShow'] )
148 );
149
150 // Generate a unique id for the block instance.
151 $instance_id = wp_unique_id( 'jetpack-podcast-player-block-' . get_the_ID() . '-' );
152 $player_data['playerId'] = $instance_id;
153
154 // Generate object to be used as props for PodcastPlayer.
155 $player_props = array_merge(
156 // Add all attributes.
157 array( 'attributes' => $attributes ),
158 // Add all player data.
159 $player_data
160 );
161
162 $primary_colors = get_colors( 'primary', $attributes, 'color' );
163 $secondary_colors = get_colors( 'secondary', $attributes, 'color' );
164 $background_colors = get_colors( 'background', $attributes, 'background-color' );
165
166 $player_classes_name = trim( "{$secondary_colors['class']} {$background_colors['class']}" );
167 $player_inline_style = trim( "{$secondary_colors['style']} {$background_colors['style']}" );
168 $player_inline_style .= get_css_vars( $attributes );
169 $wrapper_attributes = \WP_Block_Supports::get_instance()->apply_block_supports();
170 $block_classname = Blocks::classes( FEATURE_NAME, $attributes, array( 'is-default' ) );
171 $is_amp = Blocks::is_amp_request();
172
173 ob_start();
174 ?>
175 <div class="<?php echo esc_attr( $block_classname ); ?>"<?php echo ! empty( $wrapper_attributes['style'] ) ? ' style="' . esc_attr( $wrapper_attributes['style'] ) . '"' : ''; ?> id="<?php echo esc_attr( $instance_id ); ?>">
176 <section
177 class="jetpack-podcast-player <?php echo esc_attr( $player_classes_name ); ?>"
178 style="<?php echo esc_attr( $player_inline_style ); ?>"
179 >
180 <?php
181 render(
182 'podcast-header',
183 array_merge(
184 $player_props,
185 array(
186 'primary_colors' => $primary_colors,
187 'player_id' => $player_data['playerId'],
188 )
189 )
190 );
191 ?>
192 <?php if ( count( $player_data['tracks'] ) > 1 ) : ?>
193 <ol class="jetpack-podcast-player__tracks">
194 <?php foreach ( $player_data['tracks'] as $track_index => $attachment ) : ?>
195 <?php
196 render(
197 'playlist-track',
198 array(
199 'is_active' => 0 === $track_index,
200 'attachment' => $attachment,
201 'primary_colors' => $primary_colors,
202 'secondary_colors' => $secondary_colors,
203 )
204 );
205 ?>
206 <?php endforeach; ?>
207 </ol>
208 <?php endif; ?>
209 </section>
210 <?php if ( ! $is_amp ) : ?>
211 <script type="application/json"><?php echo wp_json_encode( $player_props ); ?></script>
212 <?php endif; ?>
213 </div>
214 <?php
215 /**
216 * Enqueue necessary scripts and styles.
217 */
218 if ( ! $is_amp ) {
219 wp_enqueue_style( 'wp-mediaelement' );
220 }
221 Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'mediaelement' ) );
222
223 return ob_get_clean();
224 }
225
226 /**
227 * Given the color name, block attributes and the CSS property,
228 * the function will return an array with the `class` and `style`
229 * HTML attributes to be used straight in the markup.
230 *
231 * @example
232 * $color = get_colors( 'secondary', $attributes, 'border-color'
233 * => array( 'class' => 'has-secondary', 'style' => 'border-color: #333' )
234 *
235 * @param string $name Color attribute name, for instance `primary`, `secondary`, ...
236 * @param array $attrs Block attributes.
237 * @param string $property Color CSS property, fo instance `color`, `background-color`, ...
238 * @return array Colors array.
239 */
240 function get_colors( $name, $attrs, $property ) {
241 $attr_color = "{$name}Color";
242 $attr_custom = 'custom' . ucfirst( $attr_color );
243
244 $color = isset( $attrs[ $attr_color ] ) ? $attrs[ $attr_color ] : null;
245 $custom_color = isset( $attrs[ $attr_custom ] ) ? $attrs[ $attr_custom ] : null;
246
247 $colors = array(
248 'class' => '',
249 'style' => '',
250 );
251
252 if ( $color || $custom_color ) {
253 $colors['class'] .= "has-{$name}";
254
255 if ( $color ) {
256 $colors['class'] .= " has-{$color}-{$property}";
257 } elseif ( $custom_color ) {
258 $colors['style'] .= "{$property}: {$custom_color};";
259 }
260 }
261
262 return $colors;
263 }
264
265 /**
266 * It generates a string with CSS variables according to the
267 * block colors, prefixing each one with `--jetpack-podcast-player'.
268 *
269 * @param array $attrs Podcast Block attributes object.
270 * @return string CSS variables depending on block colors.
271 */
272 function get_css_vars( $attrs ) {
273 $colors_name = array( 'primary', 'secondary', 'background' );
274
275 $inline_style = '';
276 foreach ( $colors_name as $color ) {
277 $hex_color = 'hex' . ucfirst( $color ) . 'Color';
278 if ( ! empty( $attrs[ $hex_color ] ) ) {
279 $inline_style .= " --jetpack-podcast-player-{$color}: {$attrs[ $hex_color ]};";
280 }
281 }
282 return $inline_style;
283 }
284
285 /**
286 * Render the given template in server-side.
287 * Important note:
288 * The $template_props array will be extracted.
289 * This means it will create a var for each array item.
290 * Keep it mind when using this param to pass
291 * properties to the template.
292 *
293 * @param string $name Template name, available in `./templates` folder.
294 * @param array $template_props Template properties. Optional.
295 * @param bool $print Render template. True as default.
296 * @return false|string HTML markup or false.
297 */
298 function render( $name, $template_props = array(), $print = true ) {
299 if ( ! strpos( $name, '.php' ) ) {
300 $name = $name . '.php';
301 }
302
303 $template_path = __DIR__ . '/templates/' . $name;
304
305 if ( ! file_exists( $template_path ) ) {
306 return '';
307 }
308
309 if ( $print ) {
310 include $template_path;
311 } else {
312 ob_start();
313 include $template_path;
314 $markup = ob_get_contents();
315 ob_end_clean();
316
317 return $markup;
318 }
319 }
320