Completed
Push — add/feature-rollout ( 16c199...2484fa )
by
unknown
10:53
created

Jetpack_Brightcove_Shortcode   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 242
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 242
rs 9.8
c 0
b 0
f 0
wmc 31
lcom 1
cbo 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A convert() 0 11 3
A normalize_attributes() 0 12 2
A has_legacy_atts() 0 4 4
B convert_to_new_studio() 0 26 1
F convert_to_legacy_studio() 0 129 21
1
<?php
2
3
/**
4
 * Brightcove shortcode.
5
 *
6
 * Brighcove had renovated their video player embedding code since they introduced their "new studio".
7
 * See https://support.brightcove.com/en/video-cloud/docs.
8
 * The new code is not 100% backward compatible, as long as a customized player is used.
9
 * By the time I wrote this, there were about 150000+ posts embedded legacy players, so it would be a bad
10
 * idea either to introduce a new brightcove shortcode, or to break those posts completely.
11
 *
12
 * That's why we introduce a less aggressive way: leaving the old embedding code untouched, and
13
 * introduce a new set of shortcode parameters which are translated to the latest Brightcove embedding code.
14
 *
15
 * e.g.
16
 * [brightcove video_id="12345" account_id="99999"] will be translated to the latest embedding code.
17
 * [brightcove exp=627045696&vid=1415670151] or [brightcove exp=1463233149&vref=1601200825] will be translated
18
 * to the legacy code.
19
 *
20
 */
21
class Jetpack_Brightcove_Shortcode {
22
    static $shortcode = 'brightcove';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $shortcode.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
23
24
	/**
25
	 * Parse shortcode arguments and render its output.
26
	 *
27
	 * @since 4.5.0
28
	 *
29
	 * @param array $atts Shortcode parameters.
30
	 *
31
	 * @return string
32
	 */
33
	static public function convert( $atts ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
34
		$normalized_atts = self::normalize_attributes( $atts );
35
36
		if ( empty( $atts ) ) {
37
			return '<!-- Missing Brightcove parameters -->';
38
		}
39
40
		return self::has_legacy_atts( $normalized_atts )
0 ignored issues
show
Bug introduced by
It seems like $normalized_atts defined by self::normalize_attributes($atts) on line 34 can also be of type null; however, Jetpack_Brightcove_Shortcode::has_legacy_atts() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
41
			? self::convert_to_legacy_studio( $normalized_atts )
0 ignored issues
show
Bug introduced by
It seems like $normalized_atts defined by self::normalize_attributes($atts) on line 34 can also be of type null; however, Jetpack_Brightcove_Short...vert_to_legacy_studio() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
42
			: self::convert_to_new_studio( $normalized_atts );
0 ignored issues
show
Bug introduced by
It seems like $normalized_atts defined by self::normalize_attributes($atts) on line 34 can also be of type null; however, Jetpack_Brightcove_Short...convert_to_new_studio() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
43
	}
44
45
	/**
46
	 * We need to take care of two kinds of shortcode format here.
47
	 * The latest: [shortcode a=1 b=2] and the legacy: [shortcode a=1&b=2]
48
	 * For an old shortcode: [shortcode a=1&b=2&c=3], it would be parsed into array( 'a' => 1&b=2&c=3' ), which is useless.
49
	 * However, since we want to determine whether to call convert_to_legacy_studio() or convert_to_new_studio() via passed parameters, we still need to parse the two properly.
50
	 * See http://jetpack.wp-a2z.org/oik_api/shortcode_new_to_old_params/
51
	 *
52
	 * @since 4.5.0
53
	 *
54
	 * @param array $atts Shortcode parameters.
55
	 *
56
	 * @return array
57
	 */
58
	static public function normalize_attributes( $atts ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
59
		if ( 1 == count( $atts ) ) { // this is the case we need to take care of.
60
			$parsed_atts = array();
61
			$params = shortcode_new_to_old_params( $atts );
62
			$params = apply_filters( 'brightcove_dimensions', $params );
63
			parse_str( $params, $parsed_atts );
64
65
			return $parsed_atts;
66
		} else {
67
			return $atts;
68
		}
69
	}
70
71
	/**
72
	 * Check that it has legacy attributes.
73
	 *
74
	 * @since 4.5.0
75
	 *
76
	 * @param array $atts Shortcode parameters.
77
	 *
78
	 * @return bool
79
	 */
80
	static public function has_legacy_atts( $atts ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
81
		return ( isset( $atts[ 'vid' ] ) || isset( $atts[ 'vref' ] ) )
82
			&& ( isset( $atts[ 'exp' ] ) || isset( $atts[ 'exp3' ] ) );
83
	}
84
85
	/**
86
	 * Convert to latest player format.
87
	 *
88
	 * @since 4.5.0
89
	 *
90
	 * @param array $atts Shortcode parameters.
91
	 *
92
	 * @return string
93
	 */
94
	static public function convert_to_new_studio( $atts ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
95
		$defaults = array(
96
			'account_id' => '',
97
			'video_id'   => '',
98
			'player_id'  => 'default',
99
			'width'      => '100%',
100
			'height'     => '100%',
101
		);
102
103
		$atts_applied = shortcode_atts( $defaults, $atts, self::$shortcode );
104
105
		$player_url = sprintf(
106
			'//players.brightcove.net/%s/%s_default/index.html?videoId=%s',
107
			esc_attr( $atts_applied['account_id'] ),
108
			esc_attr( $atts_applied['player_id'] ),
109
			esc_attr( $atts_applied['video_id'] )
110
		);
111
112
		$output_html = sprintf(
113
			'<iframe src="' . esc_url( $player_url ) . '" allowfullscreen webkitallowfullscreen mozallowfullscreen style="width: %spx; height: %spx;"></iframe>',
114
			esc_attr( $atts_applied['width'] ),
115
			esc_attr( $atts_applied['height'] )
116
		);
117
118
		return $output_html;
119
	}
120
121
	/**
122
	 * Convert to legacy player format.
123
	 *
124
	 * [brightcove exp=627045696&vid=1415670151] for the older player and backward compatibility
125
	 * [brightcove exp=1463233149&vref=1601200825] for the new player
126
	 *
127
	 * @since 4.5.0
128
	 *
129
	 * @param array $atts Shortcode parameters.
130
	 *
131
	 * @return string
132
	 */
133
	static public function convert_to_legacy_studio( $atts ) {
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
134
		$attr = shortcode_atts( array(
135
			'bg'    => '',
136
			'exp'   => '',
137
			'exp3'  => '',
138
			'h'     => '',
139
			'lbu'   => '',
140
			'pk'    => '',
141
			'pubid' => '',
142
			's'     => '',
143
			'surl'  => '',
144
			'vid'   => '',
145
			'vref'  => '',
146
			'w'     => '',
147
		), $atts );
148
149
		if ( isset( $attr['pk'] ) ) {
150
			$attr['pk'] = rawurlencode( preg_replace( '/[^a-zA-Z0-9!*\'();:@&=+$,\/?#\[\]\-_.~ ]/', '', $attr['pk'] ) );
151
		}
152
153
		if ( isset( $attr['bg'] ) ) {
154
			$attr['bg'] = preg_replace( '![^-a-zA-Z0-9#]!', '', $attr['bg'] );
155
		}
156
157
		$fv = array(
158
			'viewerSecureGatewayURL' => 'https://services.brightcove.com/services/amfgateway',
159
			'servicesURL'            => 'http://services.brightcove.com/services',
160
			'cdnURL'                 => 'http://admin.brightcove.com',
161
			'autoStart'              => 'false',
162
		);
163
164
		$js_tld = 'com';
165
		$src    = '';
0 ignored issues
show
Unused Code introduced by
$src is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
166
		$name   = 'flashObj';
167
		$html5  = false;
168
169
		if ( isset( $attr['exp3'] ) ) {
170
			if ( isset( $attr['surl'] ) && strpos( $attr['surl'], 'brightcove.co.jp' ) ) {
171
				$js_tld = 'co.jp';
172
			}
173
			if ( ! isset( $attr['surl'] ) || ! preg_match( '#^https?://(?:[a-z\d-]+\.)*brightcove\.(?:com|co\.jp)/#', $attr['surl'] ) ) {
174
				$attr['surl'] = 'http://c.brightcove.com/services';
175
			}
176
177
			$attr['exp3']  = intval( $attr['exp3'] );
178
			$attr['pubid'] = intval( $attr['pubid'] );
179
			$attr['vid']   = intval( $attr['vid'] );
180
181
			$fv['servicesURL'] = $attr['surl'];
182
			$fv['playerID']    = $attr['exp3'];
183
			$fv['domain']      = 'embed';
184
			$fv['videoID']     = intval( $attr['vid'] );
185
186
			$src   = sprintf( '%s/viewer/federated_f9/%s?isVid=1&amp;isUI=1&amp;publisherID=%s',
187
				$attr['surl'],
188
				$attr['exp3'],
189
				$attr['pubid']
190
			);
191
			$html5 = true;
192
		} elseif ( isset( $attr['exp'] ) ) {
193
			$attr['exp'] = intval( $attr['exp'] );
194
			$src         = 'http://services.brightcove.com/services/viewer/federated_f8/' . $attr['exp'];
195
			if ( $attr['vid'] ) {
196
				$fv['videoId'] = $attr['vid'];
197
			} else if ( $attr['vref'] ) {
198
				$fv['videoRef'] = $attr['vref'];
199
			}
200
201
			$fv['playerId'] = $attr['exp'];
202
			$fv['domain']   = 'embed';
203
		} else {
204
			return '<small>brightcove error: missing required parameter exp or exp3</small>';
205
		}
206
207
		if ( ! empty( $attr['lbu'] ) ) {
208
			$fv['linkBaseURL'] = $attr['lbu'];
209
		}
210
211
		$flashvars = trim( add_query_arg( array_map( 'urlencode', $fv ), '' ), '?' );
212
213
		$width = $height = null;
214
		if ( ! empty( $attr['w'] ) && ! empty( $attr['h'] ) ) {
215
			$w = abs( (int) $attr['w'] );
216
			$h = abs( (int) $attr['h'] );
217
			if ( $w && $h ) {
218
				$width  = $w;
219
				$height = $h;
220
			}
221
		} elseif ( empty( $attr['s'] ) || 'l' === $attr['s'] ) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of 'l' (string) and $attr['s'] (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
222
			$width  = '480';
223
			$height = '360';
224
		}
225
226
		if ( empty( $width ) || empty( $height ) ) {
227
			$width  = '280';
228
			$height = '210';
229
		}
230
231
		if ( $html5 ) {
232
			wp_enqueue_script( 'brightcove-loader', plugins_url( 'js/brightcove.js', __FILE__ ), array( 'jquery' ), 20121127, false );
233
			wp_localize_script( 'brightcove-loader', 'brightcoveData', array(
234
				'tld' => esc_js( $js_tld )
235
			) );
236
237
			return '
238
				<object id="myExperience" class="BrightcoveExperience">
239
					<param name="bgcolor" value="' . esc_attr( $attr['bg'] ) . '" />
240
					<param name="width" value="' . esc_attr( $width ) . '" />
241
					<param name="height" value="' . esc_attr( $height ) . '" />
242
					<param name="playerID" value="' . esc_attr( $attr['exp3'] ) . '" />
243
					<param name="@videoPlayer" value="' . esc_attr( $attr['vid'] ) . '" />
244
					<param name="playerKey" value="' . esc_attr( $attr['pk'] ) . '" />
245
					<param name="isVid" value="1" />
246
					<param name="isUI" value="1" />
247
					<param name="dynamicStreaming" value="true" />
248
					<param name="autoStart" value="false" />
249
					<param name="secureConnections" value="true" />
250
					<param name="secureHTMLConnections" value="true" />
251
				</object>';
252
		}
253
254
		return sprintf( '<embed src="%s" bgcolor="#FFFFFF" flashvars="%s" base="http://admin.brightcove.com" name="%s" width="%s" height="%s" allowFullScreen="true" seamlesstabbing="false" type="application/x-shockwave-flash" swLiveConnect="true" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" />',
255
			esc_url( $src ),
256
			$flashvars,
257
			esc_attr( $name ),
258
			esc_attr( $width ),
259
			esc_attr( $height )
260
		);
261
	}
262
}
263
264
add_shortcode( Jetpack_Brightcove_Shortcode::$shortcode, array( 'Jetpack_Brightcove_Shortcode', 'convert' ) );
0 ignored issues
show
Bug introduced by
The property shortcode cannot be accessed from this context as it is declared private in class Jetpack_Brightcove_Shortcode.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
265