Completed
Push — update/podcast-player-colors-s... ( ba652b...1e20b3 )
by
unknown
108:12 queued 101:42
created

podcast-player.php ➔ render_player()   B

Complexity

Conditions 8
Paths 33

Size

Total Lines 85

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 33
nop 2
dl 0
loc 85
rs 7.0828
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
			<ol class="jetpack-podcast-player__episodes">
135
				<?php foreach ( $player_data['tracks'] as $attachment ) : ?>
136
				<li
137
					class="jetpack-podcast-player__episode <?php echo esc_attr( $secondary_colors['class'] ); ?>"
138
					style="<?php echo esc_attr( $secondary_colors['style'] ); ?>"
139
				>
140
					<a
141
						class="jetpack-podcast-player__episode-link"
142
						href="<?php echo esc_url( $attachment['link'] ); ?>"
143
						role="button"
144
						aria-pressed="false"
145
					>
146
						<span class="jetpack-podcast-player__episode-status-icon"></span>
147
						<span class="jetpack-podcast-player__episode-title"><?php echo esc_html( $attachment['title'] ); ?></span>
148
						<time class="jetpack-podcast-player__episode-duration"><?php echo ( ! empty( $attachment['duration'] ) ? esc_html( $attachment['duration'] ) : '' ); ?></time>
149
					</a>
150
				</li>
151
				<?php endforeach; ?>
152
			</ol>
153
		</section>
154
		<?php if ( ! $is_amp ) : ?>
155
		<script type="application/json"><?php echo wp_json_encode( $player_props ); ?></script>
156
		<?php endif; ?>
157
	</div>
158
	<?php if ( ! $is_amp ) : ?>
159
	<script>
160
		( function( instanceId ) {
161
			document.getElementById( instanceId ).classList.remove( 'is-default' );
162
			window.jetpackPodcastPlayers=(window.jetpackPodcastPlayers||[]);
163
			window.jetpackPodcastPlayers.push( instanceId );
164
		} )( <?php echo wp_json_encode( $instance_id ); ?> );
165
	</script>
166
	<?php endif; ?>
167
	<?php
168
	/**
169
	 * Enqueue necessary scripts and styles.
170
	 */
171
	if ( ! $is_amp ) {
172
		wp_enqueue_style( 'mediaelement' );
173
	}
174
	Jetpack_Gutenberg::load_assets_as_required( FEATURE_NAME, array( 'mediaelement' ) );
175
176
	return ob_get_clean();
177
}
178
179
/**
180
 * Returns a CSS class based on the context a color is being used and its slug.
181
 *
182
 * @param string $color_context_name Context/place where color is being used e.g: background, text etc...
183
 * @param string $color_slug         Slug of the color.
184
 *
185
 * @return string String with the class corresponding to the color in the provided context.
186
 */
187
function get_color_class_name( $color_context_name, $color_slug ) {
188
	if ( ! isset( $color_context_name ) || ! isset( $color_slug ) ) {
189
		return null;
190
	}
191
192
	return "has-{$color_slug}-{$color_context_name}";
193
}
194
195
/**
196
 * Given the color name, bock 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
	// `secondary` color.
217
	$colors = array(
218
		'class' => '',
219
		'style' => '',
220
	);
221
222
	if ( $color || $custom_color ) {
223
		$colors['class'] .= " has-{$name}";
224
225
		if ( $color ) {
226
			$colors['class'] .= ' ' . get_color_class_name( $property, $color );
227
		} elseif ( $custom_color ) {
228
			$colors['style'] .= "{$property}: {$custom_color};";
229
		}
230
	}
231
232
	$colors['class'] = trim( $colors['class'] );
233
	return $colors;
234
}
235