Completed
Push — update/podcast-header-ss-rende... ( d453fc )
by
unknown
162:54 queued 155:50
created

podcast-player.php ➔ render()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 6
nop 3
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php
2
/**
3
 * Podcast Player Block.
4
 *
5
 * @since 8.4.0
6
 *
7
 * @package Jetpack
8
 */
9
10
namespace Automattic\Jetpack\Extensions\Podcast_Player;
11
12
use WP_Error;
13
use Jetpack_Gutenberg;
14
use Jetpack_Podcast_Helper;
15
use Jetpack_AMP_Support;
16
17
const FEATURE_NAME = 'podcast-player';
18
const BLOCK_NAME   = 'jetpack/' . FEATURE_NAME;
19
20
if ( ! class_exists( 'Jetpack_Podcast_Helper' ) ) {
21
	\jetpack_require_lib( 'class-jetpack-podcast-helper' );
22
}
23
24
/**
25
 * Registers the block for use in Gutenberg
26
 * This is done via an action so that we can disable
27
 * registration if we need to.
28
 */
29
function register_block() {
30
	jetpack_register_block(
31
		BLOCK_NAME,
32
		array(
33
			'attributes'      => array(
34
				'url'                    => array(
35
					'type' => 'url',
36
				),
37
				'itemsToShow'            => array(
38
					'type'    => 'integer',
39
					'default' => 5,
40
				),
41
				'showCoverArt'           => array(
42
					'type'    => 'boolean',
43
					'default' => true,
44
				),
45
				'showEpisodeDescription' => array(
46
					'type'    => 'boolean',
47
					'default' => true,
48
				),
49
			),
50
			'render_callback' => __NAMESPACE__ . '\render_block',
51
		)
52
	);
53
}
54
add_action( 'init', __NAMESPACE__ . '\register_block' );
55
56
/**
57
 * Podcast Player block registration/dependency declaration.
58
 *
59
 * @param array $attributes Array containing the Podcast Player block attributes.
60
 * @return string
61
 */
62
function render_block( $attributes ) {
63
64
	// Test for empty URLS.
65
	if ( empty( $attributes['url'] ) ) {
66
		return '<p>' . esc_html__( 'No Podcast URL provided. Please enter a valid Podcast RSS feed URL.', 'jetpack' ) . '</p>';
67
	}
68
69
	// Test for invalid URLs.
70
	if ( ! wp_http_validate_url( $attributes['url'] ) ) {
71
		return '<p>' . esc_html__( 'Your podcast URL is invalid and couldn\'t be embedded. Please double check your URL.', 'jetpack' ) . '</p>';
72
	}
73
74
	// Sanitize the URL.
75
	$attributes['url'] = esc_url_raw( $attributes['url'] );
76
77
	$player_data = Jetpack_Podcast_Helper::get_player_data( $attributes['url'] );
78
79
	if ( is_wp_error( $player_data ) ) {
80
		return '<p>' . esc_html( $player_data->get_error_message() ) . '</p>';
0 ignored issues
show
Bug introduced by
The method get_error_message() does not seem to exist on object<WP_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
81
	}
82
83
	return render_player( $player_data, $attributes );
84
}
85
86
/**
87
 * Renders the HTML for the Podcast player and tracklist.
88
 *
89
 * @param array $player_data The player data details.
90
 * @param array $attributes Array containing the Podcast Player block attributes.
91
 * @return string The HTML for the podcast player.
92
 */
93
function render_player( $player_data, $attributes ) {
94
	// If there are no tracks (it is possible) then display appropriate user facing error message.
95
	if ( empty( $player_data['tracks'] ) ) {
96
		return '<p>' . esc_html__( 'No tracks available to play.', 'jetpack' ) . '</p>';
97
	}
98
99
	// Only use the amount of tracks requested.
100
	$player_data['tracks'] = array_slice(
101
		$player_data['tracks'],
102
		0,
103
		absint( $attributes['itemsToShow'] )
104
	);
105
106
	// Generate a unique id for the block instance.
107
	$instance_id             = wp_unique_id( 'jetpack-podcast-player-block-' );
108
	$player_data['playerId'] = $instance_id;
109
110
	// Generate object to be used as props for PodcastPlayer.
111
	$player_props = array_merge(
112
		// Add all attributes.
113
		array( 'attributes' => $attributes ),
114
		// Add all player data.
115
		$player_data
116
	);
117
118
	$secondary_colors  = get_colors( 'secondary', $attributes, 'color' );
119
	$background_colors = get_colors( 'background', $attributes, 'background-color' );
120
121
	$player_classes_name = trim( "{$secondary_colors['class']} {$background_colors['class']}" );
122
	$player_inline_style = trim( "{$secondary_colors['style']} ${background_colors['style']}" );
123
124
	$block_classname = Jetpack_Gutenberg::block_classes( FEATURE_NAME, $attributes, array( 'is-default' ) );
125
	$is_amp          = ( class_exists( 'Jetpack_AMP_Support' ) && Jetpack_AMP_Support::is_amp_request() );
126
127
	ob_start();
128
	?>
129
	<div class="<?php echo esc_attr( $block_classname ); ?>" id="<?php echo esc_attr( $instance_id ); ?>">
130
		<section
131
			class="<?php echo esc_attr( $player_classes_name ); ?>"
132
			style="<?php echo esc_attr( $player_inline_style ); ?>"
133
		>
134
			<?php render( 'podcast-header', $player_props ); ?>
135
			<ol class="jetpack-podcast-player__tracks">
136
				<?php foreach ( $player_data['tracks'] as $attachment ) : ?>
137
				<li
138
					class="jetpack-podcast-player__track <?php echo esc_attr( $secondary_colors['class'] ); ?>"
139
					style="<?php echo esc_attr( $secondary_colors['style'] ); ?>"
140
				>
141
					<a
142
						class="jetpack-podcast-player__track-link"
143
						href="<?php echo esc_url( $attachment['link'] ); ?>"
144
						role="button"
145
						aria-pressed="false"
146
					>
147
						<span class="jetpack-podcast-player__track-status-icon"></span>
148
						<span class="jetpack-podcast-player__track-title"><?php echo esc_html( $attachment['title'] ); ?></span>
149
						<time class="jetpack-podcast-player__track-duration"><?php echo ( ! empty( $attachment['duration'] ) ? esc_html( $attachment['duration'] ) : '' ); ?></time>
150
					</a>
151
				</li>
152
				<?php endforeach; ?>
153
			</ol>
154
		</section>
155
		<?php if ( ! $is_amp ) : ?>
156
		<script type="application/json"><?php echo wp_json_encode( $player_props ); ?></script>
157
		<?php endif; ?>
158
	</div>
159
	<?php if ( ! $is_amp ) : ?>
160
	<script>
161
		( function( instanceId ) {
162
			document.getElementById( instanceId ).classList.remove( 'is-default' );
163
			window.jetpackPodcastPlayers=(window.jetpackPodcastPlayers||[]);
164
			window.jetpackPodcastPlayers.push( instanceId );
165
		} )( <?php echo wp_json_encode( $instance_id ); ?> );
166
	</script>
167
	<?php endif; ?>
168
	<?php
169
	/**
170
	 * Enqueue necessary scripts and styles.
171
	 */
172
	if ( ! $is_amp ) {
173
		wp_enqueue_style( 'wp-mediaelement' );
174
	}
175
	Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'mediaelement' ) );
176
177
	return ob_get_clean();
178
}
179
180
/**
181
 * Given the color name, block attributes and the CSS property,
182
 * the function will return an array with the `class` and `style`
183
 * HTML attributes to be used straight in the markup.
184
 *
185
 * @example
186
 * $color = get_colors( 'secondary', $attributes, 'border-color'
187
 *  => array( 'class' => 'has-secondary', 'style' => 'border-color: #333' )
188
 *
189
 * @param string $name     Color attribute name, for instance `primary`, `secondary`, ...
190
 * @param array  $attrs    Block attributes.
191
 * @param string $property Color CSS property, fo instance `color`, `background-color`, ...
192
 * @return array           Colors array.
193
 */
194
function get_colors( $name, $attrs, $property ) {
195
	$attr_color  = "{$name}Color";
196
	$attr_custom = 'custom' . ucfirst( $attr_color );
197
198
	$color        = isset( $attrs[ $attr_color ] ) ? $attrs[ $attr_color ] : null;
199
	$custom_color = isset( $attrs[ $attr_custom ] ) ? $attrs[ $attr_custom ] : null;
200
201
	$colors = array(
202
		'class' => '',
203
		'style' => '',
204
	);
205
206
	if ( $color || $custom_color ) {
207
		$colors['class'] .= "has-{$name}";
208
209
		if ( $color ) {
210
			$colors['class'] .= " has-{$color}-{$property}";
211
		} elseif ( $custom_color ) {
212
			$colors['style'] .= "{$property}: {$custom_color};";
213
		}
214
	}
215
216
	return $colors;
217
}
218
219
/**
220
 * Render the given podcast template.
221
 *
222
 * @param string $name  Template name, available in `./templates` folder.
223
 * @param array  $data   Template data. Optional.
224
 * @param bool   $print   Render template. True as default.
225
 * @return false|string HTML markup or false.
226
 */
227
function render( $name, $data = array(), $print = true ) {
228
	if ( ! strpos( $name, '.php' ) ) {
229
		$name = $name . '.php';
230
	}
231
232
	$template_path = dirname( __FILE__ ) . '/templates/' . $name;
233
	if ( ! file_exists( $template_path ) ) {
234
		return '';
235
	}
236
237
	ob_start();
238
	include $template_path;
239
	$markup = ob_get_contents();
240
	ob_end_clean();
241
242
	if ( $print ) {
243
		echo $markup;
244
	}
245
	return $markup;
246
}
247