Completed
Push — try/fix-old-videopress-embeds ( a61d1a )
by
unknown
06:44
created

VideoPress_Shortcode::reverse_old_embeds()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 1
nop 1
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * VideoPress Shortcode Handler
5
 *
6
 * This file may or may not be included from the Jetpack VideoPress module.
7
 */
8
9
class VideoPress_Shortcode {
10
	/** @var VideoPress_Shortcode */
11
	protected static $instance;
12
13
	protected function __construct() {
14
15
		// By explicitly declaring the provider here, we can speed things up by not relying on oEmbed discovery.
16
		wp_oembed_add_provider( '#^https?://videopress.com/v/.*#', 'https://public-api.wordpress.com/oembed/1.0/', true );
17
18
		add_shortcode( 'videopress', array( $this, 'shortcode_callback' ) );
19
		add_shortcode( 'wpvideo', array( $this, 'shortcode_callback' ) );
20
21
		add_filter( 'wp_video_shortcode_override', array( $this, 'video_shortcode_override' ), 10, 4 );
22
23
		add_filter( 'oembed_fetch_url', array( $this, 'add_oembed_for_parameter' ) );
24
25
		add_filter( 'the_content', array( $this, 'reverse_old_embeds' ) );
26
27
		$this->add_video_embed_hander();
28
	}
29
30
	/**
31
	 * @return VideoPress_Shortcode
32
	 */
33
	public static function initialize() {
34
		if ( ! isset( self::$instance ) ) {
35
			self::$instance = new self();
36
		}
37
38
		return self::$instance;
39
	}
40
41
	/**
42
	 * Filters old <embed> codes out of the content
43
	 *
44
	 * @param string $content the content.
45
	 * @return string filtered content
46
	 */
47
	public function reverse_old_embeds( $content ) {
48
		$regex   = '%<embed[^>]*+>(?:\s*</embed>)?%i';
49
		$content = preg_replace_callback(
50
			$regex,
51
			function( $matches, $orig_html = null ) {
52
				$embed_code  = $matches[0];
53
				$url_matches = array();
54
55
				// get src="http://v.wordpress.com/KllQxFVq" attribute.
56
				$url_matched = preg_match( '/src="http:\/\/v.wordpress.com\/([^"]+)"/', $embed_code, $url_matches );
57
58
				if ( $url_matched ) {
59
					$video_id = $url_matches[1];
60
					return "[videopress $video_id]";
61
				}
62
			},
63
			$content
64
		);
65
		return $content;
66
	}
67
68
	/**
69
	 * Translate a 'videopress' or 'wpvideo' shortcode and arguments into a video player display.
70
	 *
71
	 * Expected input formats:
72
	 *
73
	 * [videopress OcobLTqC]
74
	 * [wpvideo OcobLTqC]
75
	 *
76
	 * @link https://codex.wordpress.org/Shortcode_API Shortcode API
77
	 * @param array $attr shortcode attributes
78
	 * @return string HTML markup or blank string on fail
79
	 */
80
	public function shortcode_callback( $attr ) {
81
		global $content_width;
82
83
		/**
84
		 * We only accept GUIDs as a first unnamed argument.
85
		 */
86
		$guid = isset( $attr[0] ) ? $attr[0] : null;
87
88
		if ( isset( $attr['postid'] ) ) {
89
			$guid = get_post_meta( $attr['postid'], 'videopress_guid', true );
90
		}
91
92
		/**
93
		 * Make sure the GUID passed in matches how actual GUIDs are formatted.
94
		 */
95
		if ( ! videopress_is_valid_guid( $guid ) ) {
96
			return '';
97
		}
98
99
		/**
100
		 * Set the defaults
101
		 */
102
		$defaults = array(
103
			'w'               => 0,     // Width of the video player, in pixels
104
			'at'              => 0,     // How many seconds in to initially seek to
105
			'hd'              => true,  // Whether to display a high definition version
106
			'loop'            => false, // Whether to loop the video repeatedly
107
			'freedom'         => false, // Whether to use only free/libre codecs
108
			'autoplay'        => false, // Whether to autoplay the video on load
109
			'permalink'       => true,  // Whether to display the permalink to the video
110
			'flashonly'       => false, // Whether to support the Flash player exclusively
111
			'defaultlangcode' => false, // Default language code
112
		);
113
114
		$attr = shortcode_atts( $defaults, $attr, 'videopress' );
115
116
		/**
117
		 * Cast the attributes, post-input.
118
		 */
119
		$attr['width']   = absint( $attr['w'] );
120
		$attr['hd']      = (bool) $attr['hd'];
121
		$attr['freedom'] = (bool) $attr['freedom'];
122
123
		/**
124
		 * If the provided width is less than the minimum allowed
125
		 * width, or greater than `$content_width` ignore.
126
		 */
127
		if ( $attr['width'] < VIDEOPRESS_MIN_WIDTH ) {
128
			$attr['width'] = 0;
129 View Code Duplication
		} elseif ( isset( $content_width ) && $content_width > VIDEOPRESS_MIN_WIDTH && $attr['width'] > $content_width ) {
130
			$attr['width'] = 0;
131
		}
132
133
		/**
134
		 * If there was an invalid or unspecified width, set the width equal to the theme's `$content_width`.
135
		 */
136 View Code Duplication
		if ( 0 === $attr['width'] && isset( $content_width ) && $content_width >= VIDEOPRESS_MIN_WIDTH ) {
137
			$attr['width'] = $content_width;
138
		}
139
140
		/**
141
		 * If the width isn't an even number, reduce it by one (making it even).
142
		 */
143
		if ( 1 === ( $attr['width'] % 2 ) ) {
144
			$attr['width'] --;
145
		}
146
147
		/**
148
		 * Filter the default VideoPress shortcode options.
149
		 *
150
		 * @module videopress
151
		 *
152
		 * @since 2.5.0
153
		 *
154
		 * @param array $args Array of VideoPress shortcode options.
155
		 */
156
		$options = apply_filters(
157
			'videopress_shortcode_options',
158
			array(
159
				'at'              => (int) $attr['at'],
160
				'hd'              => $attr['hd'],
161
				'loop'            => $attr['loop'],
162
				'freedom'         => $attr['freedom'],
163
				'autoplay'        => $attr['autoplay'],
164
				'permalink'       => $attr['permalink'],
165
				'force_flash'     => (bool) $attr['flashonly'],
166
				'defaultlangcode' => $attr['defaultlangcode'],
167
				'forcestatic'     => false, // This used to be a displayed option, but now is only
168
			// accessible via the `videopress_shortcode_options` filter.
169
			)
170
		);
171
172
		// Register VideoPress scripts
173
		wp_register_script( 'videopress', 'https://v0.wordpress.com/js/videopress.js', array( 'jquery', 'swfobject' ), '1.09' );
174
175
		require_once dirname( __FILE__ ) . '/class.videopress-video.php';
176
		require_once dirname( __FILE__ ) . '/class.videopress-player.php';
177
178
		$player = new VideoPress_Player( $guid, $attr['width'], $options );
179
180
		if ( is_feed() ) {
181
			return $player->asXML();
182
		} else {
183
			return $player->asHTML();
184
		}
185
	}
186
187
	/**
188
	 * Override the standard video short tag to also process videopress files as well.
189
	 *
190
	 * This will, parse the src given, and if it is a videopress file, it will parse as the
191
	 * VideoPress shortcode instead.
192
	 *
193
	 * @param string $html     Empty variable to be replaced with shortcode markup.
194
	 * @param array  $attr     Attributes of the video shortcode.
195
	 * @param string $content  Video shortcode content.
196
	 * @param int    $instance Unique numeric ID of this video shortcode instance.
197
	 *
198
	 * @return string
199
	 */
200
	public function video_shortcode_override( $html, $attr, $content, $instance ) {
201
202
		$videopress_guid = null;
203
204
		if ( isset( $attr['videopress_guid'] ) ) {
205
			$videopress_guid = $attr['videopress_guid'];
206
207
		} else {
208
			// Handle the different possible url attributes
209
			$url_keys = array( 'src', 'mp4' );
210
211
			foreach ( $url_keys as $key ) {
212
				if ( isset( $attr[ $key ] ) ) {
213
					$url = $attr[ $key ];
214
					// phpcs:ignore WordPress.WP.CapitalPDangit
215
					if ( preg_match( '@videos.(videopress\.com|files\.wordpress\.com)/([a-z0-9]{8})/@i', $url, $matches ) ) {
216
						$videopress_guid = $matches[2];
217
					}
218
219
					// Also test for videopress oembed url, which is used by the Video Media Widget.
220
					if ( ! $videopress_guid && preg_match( '@https://videopress.com/v/([a-z0-9]{8})@i', $url, $matches ) ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $videopress_guid of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
221
						$videopress_guid = $matches[1];
222
					}
223
224
					break;
225
				}
226
			}
227
		}
228
229
		if ( $videopress_guid ) {
230
			$videopress_attr = array( $videopress_guid );
231
			if ( isset( $attr['width'] ) ) {
232
				$videopress_attr['w'] = (int) $attr['width'];
233
			}
234
			if ( isset( $attr['autoplay'] ) ) {
235
				$videopress_attr['autoplay'] = $attr['autoplay'];
236
			}
237
			if ( isset( $attr['loop'] ) ) {
238
				$videopress_attr['loop'] = $attr['loop'];
239
			}
240
241
			// Then display the VideoPress version of the stored GUID!
242
			return $this->shortcode_callback( $videopress_attr );
243
		}
244
245
		return '';
246
	}
247
248
	/**
249
	 * Adds a `for` query parameter to the oembed provider request URL.
250
	 *
251
	 * @param String $oembed_provider
252
	 * @return String $ehnanced_oembed_provider
253
	 */
254
	public function add_oembed_for_parameter( $oembed_provider ) {
255
		if ( false === stripos( $oembed_provider, 'videopress.com' ) ) {
256
			return $oembed_provider;
257
		}
258
		return add_query_arg( 'for', wp_parse_url( home_url(), PHP_URL_HOST ), $oembed_provider );
259
	}
260
261
	/**
262
	 * Register a VideoPress handler for direct links to .mov files (and potential other non-handled types later).
263
	 */
264
	public function add_video_embed_hander() {
265
		// These are the video extensions that VideoPress can transcode and considers video as well (even if core does not).
266
		$extensions          = array( 'mov' );
267
		$override_extensions = implode( '|', $extensions );
268
269
		$regex = "#^https?://videos.(videopress.com|files.wordpress.com)/.+?.($override_extensions)$#i";
270
271
		/** This filter is already documented in core/wp-includes/embed.php */
272
		$filter = apply_filters( 'wp_video_embed_handler', 'wp_embed_handler_video' );
273
		wp_embed_register_handler( 'video', $regex, $filter, 10 );
274
	}
275
}
276
277
VideoPress_Shortcode::initialize();
278