Completed
Push — fix/gulp-env ( ec4107...cf0b47 )
by
unknown
133:51 queued 124:05
created

Tonesque::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 19
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
		$this->image_url = esc_url_raw( $image_url );
24
		$this->image_url = trim( $this->image_url );
25
		/**
26
		 * Allows any image URL to be passed in for $this->image_url.
27
		 *
28
		 * @module theme-tools
29
		 *
30
		 * @since 2.5.0
31
		 *
32
		 * @param string $image_url The URL to any image
33
		 */
34
		$this->image_url = apply_filters( 'tonesque_image_url', $this->image_url );
35
36
		$this->image_obj = self::imagecreatefromurl( $this->image_url );
37
	}
38
39
	public static function imagecreatefromurl( $image_url ) {
40
		return imagecreatefromstring( file_get_contents( $image_url ) );
41
	}
42
43
	/**
44
	 *
45
	 * Construct object from image.
46
	 *
47
	 * @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...
48
	 * @return color as a string formatted as $type
49
	 *
50
 	 */
51
	function color( $type = 'hex' ) {
52
		// Bail if there is no image to work with
53
	 	if ( ! $this->image_obj )
54
			return false;
55
56
		// Finds dominant color
57
		$color = self::grab_color();
58
		// Passes value to Color class
59
		$color = self::get_color( $color, $type );
60
		return $color;
61
	}
62
63
	/**
64
	 *
65
	 * Grabs the color index for each of five sample points of the image
66
	 *
67
	 * @param $image
68
	 * @param $type can be 'index' or 'hex'
69
	 * @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...
70
	 *
71
 	 */
72
	function grab_points( $type = 'index' ) {
73
		$img = $this->image_obj;
74
		if ( ! $img )
75
			return false;
76
77
		$height = imagesy( $img );
78
		$width  = imagesx( $img );
79
80
		// Sample five points in the image
81
		// Based on rule of thirds and center
82
		$topy    = round( $height / 3 );
83
		$bottomy = round( ( $height / 3 ) * 2 );
84
		$leftx   = round( $width / 3 );
85
		$rightx  = round( ( $width / 3 ) * 2 );
86
		$centery = round( $height / 2 );
87
		$centerx = round( $width / 2 );
88
89
		// Cast those colors into an array
90
		$points = array(
91
			imagecolorat( $img, $leftx, $topy ),
92
			imagecolorat( $img, $rightx, $topy ),
93
			imagecolorat( $img, $leftx, $bottomy ),
94
			imagecolorat( $img, $rightx, $bottomy ),
95
			imagecolorat( $img, $centerx, $centery ),
96
		);
97
98
		if ( 'hex' == $type ) {
99
			foreach ( $points as $i => $p ) {
100
				$c = imagecolorsforindex( $img, $p );
101
				$points[ $i ] = self::get_color( array(
102
					'r' => $c['red'],
103
					'g' => $c['green'],
104
					'b' => $c['blue'],
105
				), 'hex' );
106
			}
107
		}
108
109
		return $points;
110
	}
111
112
	/**
113
	 *
114
	 * Finds the average color of the image based on five sample points
115
	 *
116
	 * @param $image
117
	 * @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...
118
	 *
119
 	 */
120
	function grab_color() {
121
		$img = $this->image_obj;
122
		if ( ! $img )
123
			return false;
124
125
		$rgb = self::grab_points();
126
127
		// Process the color points
128
		// Find the average representation
129
		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...
130
			$index = imagecolorsforindex( $img, $color );
131
			$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...
132
			$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...
133
			$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...
134
135
			$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...
136
			$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...
137
			$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...
138
		}
139
140
		// The average color of the image as rgb array
141
		$color = array(
142
			'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...
143
			'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...
144
			'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...
145
		);
146
147
		return $color;
148
	}
149
150
	/**
151
	 *
152
	 * Get a Color object using /lib class.color
153
	 * Convert to appropriate type
154
	 *
155
	 * @return string
156
	 *
157
	 */
158
	function get_color( $color, $type ) {
159
		$c = new Jetpack_Color( $color, 'rgb' );
160
		$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...
161
162
		switch ( $type ) {
163
			case 'rgb' :
164
				$color = implode( $c->toRgbInt(), ',' );
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $color. This often makes code more readable.
Loading history...
165
				break;
166
			case 'hex' :
167
				$color = $c->toHex();
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $color. This often makes code more readable.
Loading history...
168
				break;
169
			case 'hsv' :
170
				$color = implode( $c->toHsvInt(), ',' );
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $color. This often makes code more readable.
Loading history...
171
				break;
172
			default:
173
				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...
Coding Style introduced by
Consider using a different name than the parameter $color. This often makes code more readable.
Loading history...
174
		}
175
176
		return $color;
177
	}
178
179
	/**
180
	 *
181
	 * Checks contrast against main color
182
	 * Gives either black or white for using with opacity
183
	 *
184
	 * @return string
185
	 *
186
 	 */
187
	function contrast() {
188
	 	if ( ! $this->color )
189
			return false;
190
191
		$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...
192
		return implode( $c->toRgbInt(), ',' );
193
	}
194
195
};
196