Completed
Push — add/react-videopress-settings ( 1a2dcb...a2519f )
by
unknown
275:56 queued 263:52
created

Tonesque::contrast()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/*
3
Plugin Name: Tonesque
4
Plugin URI: http://automattic.com/
5
Description: Grab an average color representation from an image.
6
Version: 1.0
7
Author: Automattic, Matias Ventura
8
Author URI: http://automattic.com/
9
License: GNU General Public License v2 or later
10
License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
*/
12
13
class Tonesque {
14
15
	private $image_url = '';
16
	private $image_obj = NULL;
17
	private $color = '';
18
19
	function __construct( $image_url ) {
20
		if ( ! class_exists( 'Jetpack_Color' ) ) {
21
			jetpack_require_lib( 'class.color' );
22
		}
23
24
		$this->image_url = esc_url_raw( $image_url );
25
		$this->image_url = trim( $this->image_url );
26
		/**
27
		 * Allows any image URL to be passed in for $this->image_url.
28
		 *
29
		 * @module theme-tools
30
		 *
31
		 * @since 2.5.0
32
		 *
33
		 * @param string $image_url The URL to any image
34
		 */
35
		$this->image_url = apply_filters( 'tonesque_image_url', $this->image_url );
36
37
		$this->image_obj = self::imagecreatefromurl( $this->image_url );
38
	}
39
40
	public static function imagecreatefromurl( $image_url ) {
41
		$data = null;
42
43
		// If it's a URL:
44
		if ( preg_match( '#^https?://#i', $image_url ) ) {
45
			// If it's a url pointing to a local media library url:
46
			$content_url = content_url();
47
			$_image_url  = set_url_scheme( $image_url );
48
			if ( wp_startswith( $_image_url, $content_url ) ) {
49
				$_image_path = str_replace( $content_url, ABSPATH . 'wp-content', $_image_url );
50 View Code Duplication
				if ( file_exists( $_image_path ) ) {
51
					$filetype = wp_check_filetype( $_image_path );
52
					$ext = $filetype['ext'];
0 ignored issues
show
Unused Code introduced by
$ext 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...
53
					$type = $filetype['type'];
54
55
					if ( wp_startswith( $type, 'image/' ) ) {
56
						$data = file_get_contents( $_image_path );
57
					}
58
				}
59
			}
60
61
			if ( empty( $data ) ) {
62
				$response = wp_remote_get( $image_url );
63
				if ( is_wp_error( $response ) ) {
64
					return $response;
65
				}
66
				$data = wp_remote_retrieve_body( $response );
67
			}
68
		}
69
70
		// If it's a local path in our WordPress install:
71 View Code Duplication
		if ( file_exists( $image_url ) ) {
72
			$filetype = wp_check_filetype( $image_url );
73
			$ext = $filetype['ext'];
0 ignored issues
show
Unused Code introduced by
$ext 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...
74
			$type = $filetype['type'];
75
76
			if ( wp_startswith( $type, 'image/' ) ) {
77
				$data = file_get_contents( $image_url );
78
			}
79
		}
80
81
		// Now turn it into an image and return it.
82
		return imagecreatefromstring( $data );
83
	}
84
85
	/**
86
	 *
87
	 * Construct object from image.
88
	 *
89
	 * @param optional $type (hex, rgb, hsl)
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be string|optional?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
90
	 * @return color as a string formatted as $type
91
	 *
92
 	 */
93
	function color( $type = 'hex' ) {
94
		// Bail if there is no image to work with
95
	 	if ( ! $this->image_obj )
96
			return false;
97
98
		// Finds dominant color
99
		$color = self::grab_color();
100
		// Passes value to Color class
101
		$color = self::get_color( $color, $type );
102
		return $color;
103
	}
104
105
	/**
106
	 *
107
	 * Grabs the color index for each of five sample points of the image
108
	 *
109
	 * @param $image
110
	 * @param $type can be 'index' or 'hex'
111
	 * @return array() with color indices
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
112
	 *
113
 	 */
114
	function grab_points( $type = 'index' ) {
115
		$img = $this->image_obj;
116
		if ( ! $img )
117
			return false;
118
119
		$height = imagesy( $img );
120
		$width  = imagesx( $img );
121
122
		// Sample five points in the image
123
		// Based on rule of thirds and center
124
		$topy    = round( $height / 3 );
125
		$bottomy = round( ( $height / 3 ) * 2 );
126
		$leftx   = round( $width / 3 );
127
		$rightx  = round( ( $width / 3 ) * 2 );
128
		$centery = round( $height / 2 );
129
		$centerx = round( $width / 2 );
130
131
		// Cast those colors into an array
132
		$points = array(
133
			imagecolorat( $img, $leftx, $topy ),
134
			imagecolorat( $img, $rightx, $topy ),
135
			imagecolorat( $img, $leftx, $bottomy ),
136
			imagecolorat( $img, $rightx, $bottomy ),
137
			imagecolorat( $img, $centerx, $centery ),
138
		);
139
140
		if ( 'hex' == $type ) {
141
			foreach ( $points as $i => $p ) {
142
				$c = imagecolorsforindex( $img, $p );
143
				$points[ $i ] = self::get_color( array(
144
					'r' => $c['red'],
145
					'g' => $c['green'],
146
					'b' => $c['blue'],
147
				), 'hex' );
148
			}
149
		}
150
151
		return $points;
152
	}
153
154
	/**
155
	 *
156
	 * Finds the average color of the image based on five sample points
157
	 *
158
	 * @param $image
159
	 * @return array() with rgb color
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
160
	 *
161
 	 */
162
	function grab_color() {
163
		$img = $this->image_obj;
164
		if ( ! $img )
165
			return false;
166
167
		$rgb = self::grab_points();
168
169
		// Process the color points
170
		// Find the average representation
171
		foreach ( $rgb as $color ) {
0 ignored issues
show
Bug introduced by
The expression $rgb of type false|array<integer,integer|string> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
172
			$index = imagecolorsforindex( $img, $color );
173
			$r[] = $index['red'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$r was never initialized. Although not strictly required by PHP, it is generally a good practice to add $r = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
174
			$g[] = $index['green'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$g was never initialized. Although not strictly required by PHP, it is generally a good practice to add $g = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
175
			$b[] = $index['blue'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$b was never initialized. Although not strictly required by PHP, it is generally a good practice to add $b = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
176
177
			$red = round( array_sum( $r ) / 5 );
0 ignored issues
show
Bug introduced by
The variable $r 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...
178
			$green = round( array_sum( $g ) / 5 );
0 ignored issues
show
Bug introduced by
The variable $g 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...
179
			$blue = round( array_sum( $b ) / 5 );
0 ignored issues
show
Bug introduced by
The variable $b 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...
180
		}
181
182
		// The average color of the image as rgb array
183
		$color = array(
184
			'r' => $red,
0 ignored issues
show
Bug introduced by
The variable $red 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...
185
			'g' => $green,
0 ignored issues
show
Bug introduced by
The variable $green 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...
186
			'b' => $blue,
0 ignored issues
show
Bug introduced by
The variable $blue 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...
187
		);
188
189
		return $color;
190
	}
191
192
	/**
193
	 *
194
	 * Get a Color object using /lib class.color
195
	 * Convert to appropriate type
196
	 *
197
	 * @return string
198
	 *
199
	 */
200
	function get_color( $color, $type ) {
201
		$c = new Jetpack_Color( $color, 'rgb' );
202
		$this->color = $c;
0 ignored issues
show
Documentation Bug introduced by
It seems like $c of type object<Jetpack_Color> is incompatible with the declared type string of property $color.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
203
204
		switch ( $type ) {
205
			case 'rgb' :
206
				$color = implode( $c->toRgbInt(), ',' );
207
				break;
208
			case 'hex' :
209
				$color = $c->toHex();
210
				break;
211
			case 'hsv' :
212
				$color = implode( $c->toHsvInt(), ',' );
213
				break;
214
			default:
215
				return $color = $c->toHex();
0 ignored issues
show
Unused Code introduced by
$color 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...
216
		}
217
218
		return $color;
219
	}
220
221
	/**
222
	 *
223
	 * Checks contrast against main color
224
	 * Gives either black or white for using with opacity
225
	 *
226
	 * @return string
227
	 *
228
 	 */
229
	function contrast() {
230
	 	if ( ! $this->color )
231
			return false;
232
233
		$c = $this->color->getMaxContrastColor();
0 ignored issues
show
Bug introduced by
The method getMaxContrastColor cannot be called on $this->color (of type string).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
234
		return implode( $c->toRgbInt(), ',' );
235
	}
236
237
};
238