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