PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.9.2
Jetpack – WP Security, Backup, Speed, & Growth v14.9.2
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 1 year ago podcast-player.php 1 year ago
podcast-player.php
296 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 Automattic\Jetpack\Status\Request;
14 use Jetpack_Gutenberg;
15 use Jetpack_Podcast_Helper;
16
17 if ( ! class_exists( 'Jetpack_Podcast_Helper' ) ) {
18 require_once JETPACK__PLUGIN_DIR . '/_inc/lib/class-jetpack-podcast-helper.php';
19 }
20
21 /**
22 * Registers the block for use in Gutenberg. This is done via an action so that
23 * we can disable registration if we need to.
24 */
25 function register_block() {
26 Blocks::jetpack_register_block(
27 __DIR__,
28 array(
29 'render_callback' => __NAMESPACE__ . '\render_block',
30 // Since Gutenberg #31873.
31 'style' => 'wp-mediaelement',
32
33 )
34 );
35 }
36 add_action( 'init', __NAMESPACE__ . '\register_block' );
37
38 /**
39 * Returns the error message wrapped in HTML if current user
40 * has the capability to edit the post. Public visitors will
41 * never see errors.
42 *
43 * @param string $message The error message to display.
44 * @return string
45 */
46 function render_error( $message ) {
47 // Suppress errors for users unable to address them.
48 if ( ! current_user_can( 'edit_posts' ) ) {
49 return '';
50 }
51 return '<p>' . esc_html( $message ) . '</p>';
52 }
53
54 /**
55 * Podcast Player block registration/dependency declaration.
56 *
57 * @param array $attributes Array containing the Podcast Player block attributes.
58 * @param string $content Fallback content - a direct link to RSS, as rendered by save.js.
59 * @return string
60 */
61 function render_block( $attributes, $content ) {
62 // Don't render an interactive version of the block outside the frontend context.
63 if ( ! Request::is_frontend() ) {
64 return $content;
65 }
66
67 // Test for empty URLS.
68 if ( empty( $attributes['url'] ) ) {
69 return render_error( __( 'No Podcast URL provided. Please enter a valid Podcast RSS feed URL.', 'jetpack' ) );
70 }
71
72 // Test for invalid URLs.
73 if ( ! wp_http_validate_url( $attributes['url'] ) ) {
74 return render_error( __( 'Your podcast URL is invalid and couldn\'t be embedded. Please double check your URL.', 'jetpack' ) );
75 }
76
77 if ( ! empty( $attributes['selectedEpisodes'] ) ) {
78 $guids = array_map(
79 function ( $episode ) {
80 return $episode['guid'];
81 },
82 $attributes['selectedEpisodes']
83 );
84 $player_args = array( 'guids' => $guids );
85 } else {
86 $player_args = array();
87 }
88
89 // Sanitize the URL.
90 $attributes['url'] = esc_url_raw( $attributes['url'] );
91 $player_data = ( new Jetpack_Podcast_Helper( $attributes['url'] ) )->get_player_data( $player_args );
92
93 if ( is_wp_error( $player_data ) ) {
94 return render_error( $player_data->get_error_message() );
95 }
96
97 return render_player( $player_data, $attributes );
98 }
99
100 /**
101 * Renders the HTML for the Podcast player and tracklist.
102 *
103 * @param array $player_data The player data details.
104 * @param array $attributes Array containing the Podcast Player block attributes.
105 * @return string The HTML for the podcast player.
106 */
107 function render_player( $player_data, $attributes ) {
108 // If there are no tracks (it is possible) then display appropriate user facing error message.
109 if ( empty( $player_data['tracks'] ) ) {
110 return render_error( __( 'No tracks available to play.', 'jetpack' ) );
111 }
112
113 if ( is_wp_error( $player_data['tracks'] ) ) {
114 return render_error( $player_data['tracks']->get_error_message() );
115 }
116
117 // Only use the amount of tracks requested.
118 $player_data['tracks'] = array_slice(
119 $player_data['tracks'],
120 0,
121 absint( $attributes['itemsToShow'] )
122 );
123
124 // Generate a unique id for the block instance.
125 $instance_id = wp_unique_id( 'jetpack-podcast-player-block-' . get_the_ID() . '-' );
126 $player_data['playerId'] = $instance_id;
127
128 // Generate object to be used as props for PodcastPlayer.
129 $player_props = array_merge(
130 // Add all attributes.
131 array( 'attributes' => $attributes ),
132 // Add all player data.
133 $player_data
134 );
135
136 $primary_colors = get_colors( 'primary', $attributes, 'color' );
137 $secondary_colors = get_colors( 'secondary', $attributes, 'color' );
138 $background_colors = get_colors( 'background', $attributes, 'background-color' );
139
140 $player_classes_name = trim( "{$secondary_colors['class']} {$background_colors['class']}" );
141 $player_inline_style = trim( "{$secondary_colors['style']} {$background_colors['style']}" );
142 $player_inline_style .= get_css_vars( $attributes );
143 $wrapper_attributes = \WP_Block_Supports::get_instance()->apply_block_supports();
144 $block_classname = Blocks::classes( Blocks::get_block_feature( __DIR__ ), $attributes, array( 'is-default' ) );
145 $is_amp = Blocks::is_amp_request();
146
147 ob_start();
148 ?>
149 <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 ); ?>">
150 <section
151 class="jetpack-podcast-player <?php echo esc_attr( $player_classes_name ); ?>"
152 style="<?php echo esc_attr( $player_inline_style ); ?>"
153 >
154 <?php
155 render(
156 'podcast-header',
157 array_merge(
158 $player_props,
159 array(
160 'primary_colors' => $primary_colors,
161 'player_id' => $player_data['playerId'],
162 )
163 )
164 );
165 ?>
166 <?php if ( count( $player_data['tracks'] ) > 1 ) : ?>
167 <ol class="jetpack-podcast-player__tracks">
168 <?php foreach ( $player_data['tracks'] as $track_index => $attachment ) : ?>
169 <?php
170 render(
171 'playlist-track',
172 array(
173 'is_active' => 0 === $track_index,
174 'attachment' => $attachment,
175 'primary_colors' => $primary_colors,
176 'secondary_colors' => $secondary_colors,
177 )
178 );
179 ?>
180 <?php endforeach; ?>
181 </ol>
182 <?php endif; ?>
183 </section>
184 <?php if ( ! $is_amp ) : ?>
185 <script type="application/json"><?php echo wp_json_encode( $player_props ); ?></script>
186 <?php endif; ?>
187 </div>
188 <?php
189 /**
190 * Enqueue necessary scripts and styles.
191 */
192 if ( ! $is_amp ) {
193 wp_enqueue_style( 'wp-mediaelement' );
194 }
195 Jetpack_Gutenberg::load_assets_as_required( __DIR__, array( 'mediaelement' ) );
196
197 return ob_get_clean();
198 }
199
200 /**
201 * Given the color name, block attributes and the CSS property,
202 * the function will return an array with the `class` and `style`
203 * HTML attributes to be used straight in the markup.
204 *
205 * @example
206 * $color = get_colors( 'secondary', $attributes, 'border-color'
207 * => array( 'class' => 'has-secondary', 'style' => 'border-color: #333' )
208 *
209 * @param string $name Color attribute name, for instance `primary`, `secondary`, ...
210 * @param array $attrs Block attributes.
211 * @param string $property Color CSS property, fo instance `color`, `background-color`, ...
212 * @return array Colors array.
213 */
214 function get_colors( $name, $attrs, $property ) {
215 $attr_color = "{$name}Color";
216 $attr_custom = 'custom' . ucfirst( $attr_color );
217
218 $color = isset( $attrs[ $attr_color ] ) ? $attrs[ $attr_color ] : null;
219 $custom_color = isset( $attrs[ $attr_custom ] ) ? $attrs[ $attr_custom ] : null;
220
221 $colors = array(
222 'class' => '',
223 'style' => '',
224 );
225
226 if ( $color || $custom_color ) {
227 $colors['class'] .= "has-{$name}";
228
229 if ( $color ) {
230 $colors['class'] .= " has-{$color}-{$property}";
231 } elseif ( $custom_color ) {
232 $colors['style'] .= "{$property}: {$custom_color};";
233 }
234 }
235
236 return $colors;
237 }
238
239 /**
240 * It generates a string with CSS variables according to the
241 * block colors, prefixing each one with `--jetpack-podcast-player'.
242 *
243 * @param array $attrs Podcast Block attributes object.
244 * @return string CSS variables depending on block colors.
245 */
246 function get_css_vars( $attrs ) {
247 $colors_name = array( 'primary', 'secondary', 'background' );
248
249 $inline_style = '';
250 foreach ( $colors_name as $color ) {
251 $hex_color = 'hex' . ucfirst( $color ) . 'Color';
252 if ( ! empty( $attrs[ $hex_color ] ) ) {
253 $inline_style .= " --jetpack-podcast-player-{$color}: {$attrs[ $hex_color ]};";
254 }
255 }
256 return $inline_style;
257 }
258
259 /**
260 * Render the given template in server-side.
261 * Important note:
262 * The $template_props array will be extracted.
263 * This means it will create a var for each array item.
264 * Keep it mind when using this param to pass
265 * properties to the template.
266 *
267 * @html-template-var array $template_props
268 *
269 * @param string $name Template name, available in `./templates` folder.
270 * @param array $template_props Template properties. Optional.
271 * @param bool $print Render template. True as default.
272 * @return string|null HTML markup or null.
273 */
274 function render( $name, $template_props = array(), $print = true ) {
275 if ( ! strpos( $name, '.php' ) ) {
276 $name = $name . '.php';
277 }
278
279 $template_path = __DIR__ . '/templates/' . $name;
280
281 if ( ! file_exists( $template_path ) ) {
282 return '';
283 }
284
285 if ( $print ) {
286 include $template_path;
287 } else {
288 ob_start();
289 include $template_path;
290 $markup = ob_get_contents();
291 ob_end_clean();
292
293 return $markup;
294 }
295 }
296