Completed
Push — master-stable ( d71fc2...2e33eb )
by
unknown
08:15
created

modules/videopress/class.videopress-video.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * VideoPress video object retrieved from VideoPress servers and parsed.
4
 * @since 1.3
5
 */
6
class VideoPress_Video {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The type VideoPress_Video has been defined more than once; this definition is ignored, only the first definition in modules/videopress-v2/class.videopress-video.php (L6-344) is considered.

This check looks for classes that have been defined more than once.

If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface.

This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.

Loading history...
7
	public $version = 3;
8
9
	/**
10
	 * Manifest version returned by remote service.
11
	 *
12
	 * @var string
13
	 * @since 1.3
14
	 */
15
	const manifest_version = '1.5';
16
17
	/**
18
	 * Expiration of the video expressed in Unix time
19
	 *
20
	 * @var int
21
	 * @since 1.3
22
	 */
23
	public $expires;
24
25
	/**
26
	 * VideoPress unique identifier
27
	 *
28
	 * @var string
29
	 * @since 1.3
30
	 */
31
	public $guid;
32
33
	/**
34
	 * WordPress.com blog identifier
35
	 *
36
	 * @var int
37
	 * @since 1.5
38
	 */
39
	public $blog_id;
40
41
	/**
42
	 * Remote blog attachment identifier
43
	 *
44
	 * @var int
45
	 * @since 1.5
46
	 */
47
	public $post_id;
48
49
	/**
50
	 * Maximum desired width.
51
	 *
52
	 * @var int
53
	 * @since 1.3
54
	 */
55
	public $maxwidth;
56
57
	/**
58
	 * Video width calculated based on original video dimensions and the requested maxwidth
59
	 *
60
	 * @var int
61
	 * @since 1.3
62
	 */
63
	public $calculated_width;
64
65
	/**
66
	 * Video height calculated based on original video dimensions and the requested maxwidth
67
	 *
68
	 * @var int
69
	 * @since 1.3
70
	 */
71
	public $calculated_height;
72
73
	/**
74
	 * Video title
75
	 *
76
	 * @var string
77
	 * @since 1.3
78
	 */
79
	public $title;
80
81
	/**
82
	 * Directionality of title text. ltr or rtl
83
	 *
84
	 * @var string
85
	 * @since 1.3
86
	 */
87
	public $text_direction;
88
89
	/**
90
	 * Text and audio language as ISO 639-2 language code
91
	 *
92
	 * @var string
93
	 * @since 1.3
94
	 */
95
	public $language;
96
97
	/**
98
	 * Video duration in whole seconds
99
	 *
100
	 * @var int
101
	 * @since 1.3
102
	 */
103
	public $duration;
104
105
	/**
106
	 * Recommended minimum age of the viewer.
107
	 *
108
	 * @var int
109
	 * @since 1.3
110
	 */
111
	public $age_rating;
112
113
	/**
114
	 * Video author has restricted video embedding or sharing
115
	 *
116
	 * @var bool
117
	 * @since 1.3
118
	 */
119
	public $restricted_embed;
120
121
	/**
122
	 * Poster frame image URI for the given video guid and calculated dimensions.
123
	 *
124
	 * @var string
125
	 * @since 1.3
126
	 */
127
	public $poster_frame_uri;
128
129
	/**
130
	 * Video files associated with the given guid for the calculated dimensions.
131
	 *
132
	 * @var stdClass
133
	 * @since 1.3
134
	 */
135
	public $videos;
136
137
	/**
138
	 * Video player information
139
	 *
140
	 * @var stdClass
141
	 * @since 1.3
142
	 */
143
	public $players;
144
145
	/**
146
	 * Video player skinning preferences including background color and watermark
147
	 *
148
	 * @var array
149
	 * @since 1.5
150
	 */
151
	public $skin;
152
153
	/**
154
	 * Closed captions if available for the given video. Associative array of ISO 639-2 language code and a WebVTT URI
155
	 *
156
	 * @var array
157
	 * @since 1.5
158
	 */
159
	public $captions;
160
161
	/**
162
	 * Setup the object.
163
	 * Request video information from VideoPress servers and process the response.
164
	 *
165
	 * @since 1.3
166
	 * @var string $guid VideoPress unique identifier
167
	 * @var int $maxwidth maximum requested video width. final width and height are calculated on VideoPress servers based on the aspect ratio of the original video upload.
168
	 */
169
	public function __construct( $guid, $maxwidth = 640 ) {
170
		$this->guid = $guid;
171
172
		$maxwidth = absint( $maxwidth );
173
		if ( $maxwidth > 0 )
174
			$this->maxwidth = $maxwidth;
175
176
		$data = $this->get_data();
177 View Code Duplication
		if ( is_wp_error( $data ) || empty( $data ) ) {
178
			/** This filter is documented in modules/videopress/class.videopress-player.php */
179
			if ( ! apply_filters( 'jetpack_videopress_use_legacy_player', false ) ) {
180
				// Unlike the Flash player, the new player does it's own error checking, age gate, etc.
181
				$data = (object) array( 'guid' => $guid, 'width' => $maxwidth, 'height' => $maxwidth / 16 * 9 );
182
			} else {
183
				$this->error = $data;
184
				return;
185
			}
186
		}
187
188
		if ( isset( $data->blog_id ) )
189
			$this->blog_id = absint( $data->blog_id );
190
191
		if ( isset( $data->post_id ) )
192
			$this->post_id = absint( $data->post_id );
193
194 View Code Duplication
		if ( isset( $data->title ) && $data->title !== '' )
195
			$this->title = trim( str_replace( '&nbsp;', ' ', $data->title ) );
196
197 View Code Duplication
		if ( isset( $data->text_direction ) && $data->text_direction === 'rtl' )
198
			$this->text_direction = 'rtl';
199
		else
200
			$this->text_direction = 'ltr';
201
202
		if ( isset( $data->language ) )
203
			$this->language = $data->language;
204
205 View Code Duplication
		if ( isset( $data->duration ) && $data->duration > 0 )
206
			$this->duration = absint( $data->duration );
207
208 View Code Duplication
		if ( isset( $data->width ) && $data->width > 0 )
209
			$this->calculated_width = absint( $data->width );
210
211 View Code Duplication
		if ( isset( $data->height ) && $data->height > 0 )
212
			$this->calculated_height = absint( $data->height );
213
214
		if ( isset( $data->age_rating ) )
215
			$this->age_rating = absint( $this->age_rating );
216
217 View Code Duplication
		if ( isset( $data->restricted_embed ) && $data->restricted_embed === true )
218
			$this->restricted_embed = true;
219
		else
220
			$this->restricted_embed = false;
221
222 View Code Duplication
		if ( isset( $data->posterframe ) && $data->posterframe !== '' )
223
			$this->poster_frame_uri = esc_url_raw( $data->posterframe, array( 'http', 'https' ) );
224
225 View Code Duplication
		if ( isset( $data->mp4 ) || isset( $data->ogv ) ) {
226
			$this->videos = new stdClass();
227
			if ( isset( $data->mp4 ) )
228
				$this->videos->mp4 = $data->mp4;
229
			if ( isset( $data->ogv ) )
230
				$this->videos->ogv = $data->ogv;
231
		}
232
233 View Code Duplication
		if ( isset( $data->swf ) ) {
234
			if ( ! isset( $this->players ) )
235
				$this->players = new stdClass();
236
			$this->players->swf = $data->swf;
237
		}
238
239
		if ( isset( $data->skin ) )
240
			$this->skin = $data->skin;
241
242
		if ( isset( $data->captions ) )
243
			$this->captions = (array) $data->captions;
244
	}
245
246
	/**
247
	 * Convert an Expires HTTP header value into Unix time for use in WP Cache
248
	 *
249
	 * @since 1.3
250
	 * @var string $expires_header
251
	 * @return int|bool Unix time or false
252
	 */
253 View Code Duplication
	public static function calculate_expiration( $expires_header ) {
254
		if ( empty( $expires_header ) || ! is_string( $expires_header ) )
255
			return false;
256
257
		if (
258
			class_exists( 'DateTimeZone' )
259
			&& method_exists( 'DateTime', 'createFromFormat' )
260
		) {
261
			$expires_date = DateTime::createFromFormat( 'D, d M Y H:i:s T', $expires_header, new DateTimeZone( 'UTC' ) );
262
			if ( $expires_date instanceOf DateTime )
263
				return date_format( $expires_date, 'U' );
264
		} else {
265
			$expires_array = strptime( $expires_header, '%a, %d %b %Y %H:%M:%S %Z' );
266
			if ( is_array( $expires_array ) && isset( $expires_array['tm_hour'] ) && isset( $expires_array['tm_min'] ) && isset( $expires_array['tm_sec'] ) && isset( $expires_array['tm_mon'] ) && isset( $expires_array['tm_mday'] ) && isset( $expires_array['tm_year'] ) )
267
				return gmmktime( $expires_array['tm_hour'], $expires_array['tm_min'], $expires_array['tm_sec'], 1 + $expires_array['tm_mon'], $expires_array['tm_mday'], 1900 + $expires_array['tm_year'] );
268
		}
269
		return false;
270
	}
271
272
	/**
273
	 * Extract the site's host domain for statistics and comparison against an allowed site list in the case of restricted embeds.
274
	 *
275
	 * @since 1.2
276
	 * @param string $url absolute URL
277
	 * @return bool|string host component of the URL, or false if none found
278
	 */
279
	public static function hostname( $url ) {
280
		return parse_url( esc_url_raw( $url ), PHP_URL_HOST );
281
	}
282
283
284
	/**
285
	 * Request data from WordPress.com for the given guid, maxwidth, and calculated blog hostname.
286
	 *
287
	 * @since 1.3
288
	 * @return stdClass|WP_Error parsed JSON response or WP_Error if request unsuccessful
289
	 */
290 View Code Duplication
	private function get_data() {
291
		global $wp_version;
292
293
		$domain = self::hostname( home_url() );
294
		$request_params = array( 'guid' => $this->guid, 'domain' => $domain );
295
		if ( isset( $this->maxwidth ) && $this->maxwidth > 0 )
296
			$request_params['maxwidth'] = $this->maxwidth;
297
298
		$url = 'http://videopress.com/data/wordpress.json';
299
		if ( is_ssl() )
300
			$url = 'https://v.wordpress.com/data/wordpress.json';
301
302
		$response = wp_remote_get( add_query_arg( $request_params, $url ), array(
303
			'redirection' => 1,
304
			'user-agent' => 'VideoPress plugin ' . $this->version . '; WordPress ' . $wp_version . ' (' . home_url('/') . ')',
305
		) );
306
307
		unset( $request_params );
308
		unset( $url );
309
		$response_body = wp_remote_retrieve_body( $response );
310
		$response_code = absint( wp_remote_retrieve_response_code( $response ) );
311
312
		if ( is_wp_error( $response ) ) {
313
			return $response;
314
		} elseif ( $response_code === 400 ) {
315
			return new WP_Error( 'bad_config', __( 'The VideoPress plugin could not communicate with the VideoPress servers. This error is most likely caused by a misconfigured plugin. Please reinstall or upgrade.', 'jetpack' ) );
316
		} elseif ( $response_code === 403 ) {
317
			return new WP_Error( 'http_forbidden', '<p>' . sprintf( __( '<strong>%s</strong> is not an allowed embed site.' , 'jetpack' ), esc_html( $domain ) ) . '</p><p>' . __( 'Publisher limits playback of video embeds.', 'jetpack' ) . '</p>' );
318
		} elseif ( $response_code === 404 ) {
319
			return new WP_Error( 'http_not_found', '<p>' . sprintf( __( 'No data found for VideoPress identifier: <strong>%s</strong>.', 'jetpack' ), $this->guid ) . '</p>' );
320
		} elseif ( $response_code !== 200 || empty( $response_body ) ) {
321
			return;
322
		} else {
323
			$expires_header = wp_remote_retrieve_header( $response, 'Expires' );
324
			if ( ! empty( $expires_header ) ) {
325
				$expires = self::calculate_expiration( $expires_header );
326
				if ( ! empty( $expires ) )
327
					$this->expires = $expires;
328
329
			}
330
			return json_decode( $response_body );
331
		}
332
	}
333
}
334