Completed
Push — ignore/lazy-images-linting-pac... ( 3c044f...b5c515 )
by Jeremy
367:06 queued 352:42
created

bandcamp.php ➔ shortcode_handler_bandcamp()   F

Complexity

Conditions 46
Paths > 20000

Size

Total Lines 224

Duplication

Lines 23
Ratio 10.27 %

Importance

Changes 0
Metric Value
cc 46
nc 35831809
nop 1
dl 23
loc 224
rs 0
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
 * Shortcode handler for [bandcamp], which inserts a bandcamp.com
4
 * music player (iframe, html5)
5
 *
6
 * [bandcamp album=119385304]
7
 * [bandcamp album=3462839126  bgcol=FFFFFF linkcol=4285BB size=venti]
8
 * [bandcamp track=2446959313]
9
 *
10
 * @package Jetpack
11
 */
12
13
/**
14
 * Display the Bandcamp shortcode.
15
 *
16
 * @param array $atts Shortcode attributes.
17
 */
18
function shortcode_handler_bandcamp( $atts ) {
19
	// there are no default values, but specify here anyway to explicitly list supported atts.
20
	$attributes = shortcode_atts(
21
		array(
22
			'album'       => null,     // integer album id.
23
			'track'       => null,     // integer track id.
24
			'video'       => null,     // integer track id for video player.
25
			'size'        => 'venti',  // one of the supported sizes.
26
			'bgcol'       => 'FFFFFF', // hex, no '#' prefix.
27
			'linkcol'     => null,     // hex, no '#' prefix.
28
			'layout'      => null,     // encoded layout url.
29
			'width'       => null,     // integer with optional "%".
30
			'height'      => null,     // integer with optional "%".
31
			'notracklist' => null,     // may be string "true" (defaults false).
32
			'tracklist'   => null,     // may be string "false" (defaults true).
33
			'artwork'     => null,     // may be string "false" (alternately: "none") or "small" (default is large).
34
			'minimal'     => null,     // may be string "true" (defaults false).
35
			'theme'       => null,     // may be theme identifier string ("light"|"dark" so far).
36
			'package'     => null,     // integer package id.
37
			't'           => null,     // integer track number.
38
			'tracks'      => null,     // comma separated list of allowed tracks.
39
			'esig'        => null,      // hex, no '#' prefix.
40
		),
41
		$atts,
42
		'bandcamp'
43
	);
44
45
	$sizes = array(
46
		'venti'      => array(
47
			'width'  => 400,
48
			'height' => 100,
49
		),
50
		'grande'     => array(
51
			'width'  => 300,
52
			'height' => 100,
53
		),
54
		'grande2'    => array(
55
			'width'  => 300,
56
			'height' => 355,
57
		),
58
		'grande3'    => array(
59
			'width'  => 300,
60
			'height' => 415,
61
		),
62
		'tall_album' => array(
63
			'width'  => 150,
64
			'height' => 295,
65
		),
66
		'tall_track' => array(
67
			'width'  => 150,
68
			'height' => 270,
69
		),
70
		'tall2'      => array(
71
			'width'  => 150,
72
			'height' => 450,
73
		),
74
		'short'      => array(
75
			'width'  => 46,
76
			'height' => 23,
77
		),
78
		'large'      => array(
79
			'width'  => 350,
80
			'height' => 470,
81
		),
82
		'medium'     => array(
83
			'width'  => 450,
84
			'height' => 120,
85
		),
86
		'small'      => array(
87
			'width'  => 350,
88
			'height' => 42,
89
		),
90
	);
91
92
	$sizekey = $attributes['size'];
93
	$height  = null;
94
	$width   = null;
95
96
	$is_video = false;
97
98
	/*
99
	 * Build iframe url.  For audio players, args are appended as
100
	 * extra path segments for historical reasons having to
101
	 * do with an IE-only flash bug which required this URL
102
	 * to contain no querystring.  Delay the actual joining
103
	 * of args into a string until after we decide if it's
104
	 * a video player or an audio player
105
	 */
106
	$argparts = array();
107
108
	if ( ! isset( $attributes['album'] ) && ! isset( $attributes['track'] ) && ! isset( $attributes['video'] ) ) {
109
		return "[bandcamp: shortcode must include 'track', 'album', or 'video' param]";
110
	}
111
112
	if ( isset( $attributes['track'] ) && is_numeric( $attributes['track'] ) ) {
113
		$track = esc_attr( $attributes['track'] );
114
		array_push( $argparts, "track={$track}" );
115
	} elseif ( isset( $attributes['video'] ) && is_numeric( $attributes['video'] ) ) {
116
		$track    = esc_attr( $attributes['video'] ); // videos are referenced by track id.
117
		$url      = '//bandcamp.com/EmbeddedPlayer/v=2';
0 ignored issues
show
Unused Code introduced by
$url 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...
118
		$is_video = true;
119
		array_push( $argparts, "track={$track}" );
120
	}
121
	if ( isset( $attributes['album'] ) && is_numeric( $attributes['album'] ) ) {
122
		$album = esc_attr( $attributes['album'] );
123
		array_push( $argparts, "album={$album}" );
124
	}
125
126
	if ( 'tall' === $sizekey ) {
127
		if ( isset( $attributes['album'] ) ) {
128
			$sizekey .= '_album';
129
		} else {
130
			$sizekey .= '_track';
131
		}
132
	}
133
134
	// if size specified that we don't recognize, fall back on venti.
135
	if ( empty( $sizes[ $sizekey ] ) ) {
136
		$sizekey            = 'venti';
137
		$attributes['size'] = 'venti';
138
	}
139
140
	/*
141
	 * use strict regex for digits + optional % instead of absint for height/width
142
	 * 'width' and 'height' params in the iframe url get the exact string from the shortcode
143
	 * args, whereas the inline style attribute must have "px" added to it if it has no "%"
144
	 */
145 View Code Duplication
	if ( isset( $attributes['width'] ) && preg_match( '|^([0-9]+)(%)?$|', $attributes['width'], $matches ) ) {
146
		$width    = $attributes['width'];
147
		$csswidth = $attributes['width'];
148
		if ( count( $matches ) < 3 ) {
149
			$csswidth .= 'px';
150
		}
151
	}
152 View Code Duplication
	if ( isset( $attributes['height'] ) && preg_match( '|^([0-9]+)(%)?$|', $attributes['height'], $matches ) ) {
153
		$height    = $attributes['height'];
154
		$cssheight = $attributes['height'];
155
		if ( count( $matches ) < 3 ) {
156
			$cssheight .= 'px';
157
		}
158
	}
159
160
	if ( ! $height ) {
161
		$height    = $sizes[ $sizekey ]['height'];
162
		$cssheight = $height . 'px';
163
	}
164
165
	if ( ! $width ) {
166
		$width    = $sizes[ $sizekey ]['width'];
167
		$csswidth = $width . 'px';
168
	}
169
170 View Code Duplication
	if ( isset( $attributes['layout'] ) ) {
171
		array_push( $argparts, "layout={$attributes['layout']}" );
172
	} elseif ( isset( $attributes['size'] ) && preg_match( '|^[a-zA-Z0-9]+$|', $attributes['size'] ) ) {
173
		array_push( $argparts, "size={$attributes['size']}" );
174
	}
175
176
	if ( isset( $attributes['bgcol'] ) && preg_match( '|^[0-9A-Fa-f]+$|', $attributes['bgcol'] ) ) {
177
		array_push( $argparts, "bgcol={$attributes['bgcol']}" );
178
	}
179
180
	if ( isset( $attributes['linkcol'] ) && preg_match( '|^[0-9A-Fa-f]+$|', $attributes['linkcol'] ) ) {
181
		array_push( $argparts, "linkcol={$attributes['linkcol']}" );
182
	}
183
184
	if ( isset( $attributes['package'] ) && preg_match( '|^[0-9]+$|', $attributes['package'] ) ) {
185
		array_push( $argparts, "package={$attributes['package']}" );
186
	}
187
188
	if ( isset( $attributes['t'] ) && preg_match( '|^[0-9]+$|', $attributes['t'] ) ) {
189
		array_push( $argparts, "t={$attributes['t']}" );
190
	}
191
192
	if ( 'true' === $attributes['notracklist'] ) {
193
		array_push( $argparts, 'notracklist=true' );
194
	}
195
196
	// 'tracklist' arg deprecates 'notracklist=true' to be less weird.  note, behavior
197
	// if both are specified is undefined
198
	switch ( $attributes['tracklist'] ) {
199
		case 'false':
200
		case 'none':
201
			array_push( $argparts, 'tracklist=false' );
202
			break;
203
	}
204
205
	switch ( $attributes['artwork'] ) {
206
		case 'false':
207
		case 'none':
208
		case 'small':
209
			array_push( $argparts, 'artwork=' . $attributes['artwork'] );
210
			break;
211
	}
212
213
	if ( 'true' === $attributes['minimal'] ) {
214
		array_push( $argparts, 'minimal=true' );
215
	}
216
217
	if ( isset( $attributes['theme'] ) && preg_match( '|^[a-zA-Z_]+$|', $attributes['theme'] ) ) {
218
		array_push( $argparts, "theme={$attributes['theme']}" );
219
	}
220
221
	// param 'tracks' is signed digest param 'esig'.
222
	if ( isset( $attributes['tracks'] ) && preg_match( '|^[0-9\,]+$|', $attributes['tracks'] ) ) {
223 View Code Duplication
		if ( isset( $attributes['esig'] ) && preg_match( '|^[0-9A-Fa-f]+$|', $attributes['esig'] ) ) {
224
			array_push( $argparts, "tracks={$attributes['tracks']}" );
225
			array_push( $argparts, "esig={$attributes['esig']}" );
226
		}
227
	}
228
229
	if ( $is_video ) {
230
		$url         = '//bandcamp.com/VideoEmbed?' . join( '&', $argparts );
231
		$extra_attrs = " mozallowfullscreen='1' webkitallowfullscreen='1' allowfullscreen='1'";
232
	} else {
233
		$url         = '//bandcamp.com/EmbeddedPlayer/v=2/' . join( '/', $argparts ) . '/';
234
		$extra_attrs = '';
235
	}
236
237
	$iframe = '<iframe width="%s" height="%s" style="position: relative; display: block; width: %s; height: %s;" src="%s" allowtransparency="true" frameborder="0"%s></iframe>';
238
	$iframe = sprintf( $iframe, esc_attr( $width ), esc_attr( $height ), esc_attr( $csswidth ), esc_attr( $cssheight ), esc_url( $url ), $extra_attrs );
0 ignored issues
show
Bug introduced by
The variable $csswidth does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $cssheight does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
239
240
	return $iframe;
241
}
242
243
add_shortcode( 'bandcamp', 'shortcode_handler_bandcamp' );
244