Completed
Push — phpcbf/shortcodes ( 33156a...4c0aca )
by
unknown
118:01 queued 110:19
created

bandcamp.php ➔ shortcode_handler_bandcamp()   F

Complexity

Conditions 46
Paths > 20000

Size

Total Lines 219

Duplication

Lines 21
Ratio 9.59 %

Importance

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