Completed
Push — add/podcast-episodes-edit ( dbb851...a8f0e9 )
by
unknown
27:22 queued 20:34
created

podcast-player.php ➔ render_player()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 34
rs 9.376
c 0
b 0
f 0
1
<?php
2
/**
3
 * Podcast Player Block.
4
 *
5
 * @since 8.x
6
 *
7
 * @package Jetpack
8
 */
9
10
namespace Jetpack\Podcast_Episodes_Block;
11
12
use WP_Error;
13
use Jetpack_Gutenberg;
14
15
const FEATURE_NAME = 'podcast-player';
16
const BLOCK_NAME   = 'jetpack/' . FEATURE_NAME;
17
18
/**
19
 * Registers the block for use in Gutenberg
20
 * This is done via an action so that we can disable
21
 * registration if we need to.
22
 */
23
function register_block() {
24
	jetpack_register_block(
25
		BLOCK_NAME,
26
		array(
27
			'attributes'      => array(
28
				'url'         => array(
29
					'type' => 'url',
30
				),
31
				'itemsToShow' => array(
32
					'type'    => 'integer',
33
					'default' => 5,
34
				),
35
			),
36
			'render_callback' => __NAMESPACE__ . '\render_block',
37
		)
38
	);
39
}
40
add_action( 'init', __NAMESPACE__ . '\register_block' );
41
42
/**
43
 * Podcast Player block registration/dependency declaration.
44
 *
45
 * @param array  $attributes Array containing the Podcast Player block attributes.
46
 * @param string $content    String containing the Podcast Player block content.
47
 *
48
 * @return string
49
 */
50
function render_block( $attributes, $content ) {
51
	if ( empty( $attributes['url'] ) ) {
52
		return;
53
	}
54
55
	$track_list = get_track_list( $attributes['url'], $attributes['itemsToShow'] );
56
57
	if ( is_wp_error( $track_list ) ) {
58
		return '<p>' . $track_list->get_error_message() . '</p>';
59
	}
60
61
	return render_player( $track_list, $attributes );
62
}
63
64
/**
65
 * Renders the HTML for the Podcast player and tracklist.
66
 *
67
 * @param array $track_list the list of podcast tracks.
68
 * @param array $attributes Array containing the Podcast Player block attributes.
69
 * @return string the HTML for the podcast player.
70
 */
71
function render_player( $track_list, $attributes ) {
72
73
	$player_data = array(
74
		'type'         => 'audio',
75
		// Don't pass strings to JSON, will be truthy in JS.
76
		'tracklist'    => true,
77
		'tracknumbers' => true,
78
		'images'       => true,
79
		'artists'      => true,
80
		'tracks'       => $track_list,
81
	);
82
83
	$block_classname = Jetpack_Gutenberg::block_classes( FEATURE_NAME, $attributes );
84
85
	// If there are no tracks (it is possible) then display appropriate user facing error message.
86
	if ( empty( $track_list ) ) {
87
		return '<p>' . __( 'No tracks available to play.', 'jetpack' ) . '</p>';
88
	}
89
90
	ob_start();
91
92
	?>
93
	<div class="<?php echo esc_attr( $block_classname ); ?>">
94
		<?php // Placeholder: block markup is being handled in https://github.com/Automattic/jetpack/pull/14952. ?>
95
		<script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $player_data ); ?></script>
96
	</div>
97
	<?php
98
	/*
99
	* Enqueue necessary scripts and styles.
100
	*/
101
	Jetpack_Gutenberg::load_assets_as_required( 'podcast-player' );
102
103
	return ob_get_clean();
104
}
105
106
/**
107
 * Gets a list of tracks for the supplied RSS feed.
108
 *
109
 * @param string $feed the RSS feed to load and list tracks for.
110
 * @param int    $quantity the number of tracks to return.
111
 * @return array|WP_Error the feed's tracks or a error object.
112
 */
113
function get_track_list( $feed, $quantity = 5 ) {
114
	if ( empty( $feed ) ) {
115
		return new WP_Error( 'missing_feed', __( 'Podcast audio RSS feed missing.', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'missing_feed'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
116
	}
117
118
	$rss = fetch_feed( $feed );
119
	if ( is_wp_error( $rss ) ) {
120
		return new WP_Error( 'invalid_url', __( 'That RSS feed could not be found. Double check the URL you entered.', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_url'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
121
	}
122
123
	if ( ! $rss->get_item_quantity() ) {
124
		return new WP_Error( 'no_tracks', __( 'Podcast audio RSS feed has no tracks.', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'no_tracks'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
125
	}
126
127
	$episodes = $rss->get_items( 0, $quantity );
128
129
	$track_list = array_map(
130
		function( $episode ) {
131
132
			$url  = ! empty( $episode->data['child']['']['enclosure'][0]['attribs']['']['url'] ) ? $episode->data['child']['']['enclosure'][0]['attribs']['']['url'] : null;
133
			$type = ! empty( $episode->data['child']['']['enclosure'][0]['attribs']['']['type'] ) ? $episode->data['child']['']['enclosure'][0]['attribs']['']['type'] : null;
134
135
			// If there is no type return an empty array as the array entry. We will filter out later.
136
			if ( ! $url ) {
137
				return array();
138
			}
139
140
			// Build track data.
141
			$track = array(
142
				'link'        => esc_url( $episode->get_link() ),
143
				'src'         => $url,
144
				'type'        => $type,
145
				'caption'     => '',
146
				'description' => wp_kses_post( $episode->get_description() ),
147
				'meta'        => array(),
148
			);
149
150
			$track['title'] = esc_html( trim( wp_strip_all_tags( $episode->get_title() ) ) );
151
152
			if ( empty( $track['title'] ) ) {
153
				$track['title'] = __( '(no title)', 'jetpack' );
154
			}
155
156
			return $track;
157
		},
158
		$episodes
159
	);
160
161
	// Remove empty tracks.
162
	return \array_filter( $track_list );
163
}
164