Completed
Push — master ( 64c9c6...973681 )
by Michael
02:15
created

Image_Transform_Driver_Imagick3   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 375
Duplicated Lines 24 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
dl 90
loc 375
rs 8.3999
c 0
b 0
f 0
wmc 46
lcom 1
cbo 2

15 Methods

Rating   Name   Duplication   Size   Complexity  
A Image_Transform_Driver_Imagick3() 0 4 1
A __construct() 0 8 2
A load() 0 20 3
A _resize() 0 15 3
A rotate() 0 21 4
B addText() 5 29 5
C save() 29 29 8
C display() 27 27 7
A gamma() 0 8 2
A crop() 19 19 3
A greyscale() 0 11 1
A mirror() 0 10 2
A flip() 0 10 2
A free() 0 7 2
A raiseError() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Image_Transform_Driver_Imagick3 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Image_Transform_Driver_Imagick3, and based on these observations, apply Extract Interface, too.

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 46 and the first side effect is on line 26.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

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

Loading history...
2
3
/* vim: set expandtab tabstop=4 shiftwidth=4: */
4
5
/**
6
 * imagick PECL extension implementation for Image_Transform package
7
 *
8
 * PHP version 5
9
 *
10
 * LICENSE: This source file is subject to version 3.0 of the PHP license
11
 * that is available through the world-wide-web at the following URI:
12
 * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
13
 * the PHP License and are unable to obtain it through the web, please
14
 * send a note to [email protected] so we can mail you a copy immediately.
15
 *
16
 * @category   Image
17
 * @package    Image_Transform
18
 * @subpackage Image_Transform_Driver_Imagick3
19
 * @author     Philippe Jausions <[email protected]>
20
 * @copyright  2007 The PHP Group
21
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
22
 * @version    CVS: $Id: Imagick3.php 266908 2008-10-01 21:11:07Z dufuz $
23
 * @link       http://pear.php.net/package/Image_Transform
24
 */
25
26
require_once 'Image/Transform.php';
27
28
/**
29
 * imagick PECL extension implementation for Image_Transform package
30
 *
31
 * For use of version 2+ of the extension. For version 0.9.* use Imagick2 driver
32
 * instead
33
 *
34
 * @category   Image
35
 * @package    Image_Transform
36
 * @subpackage Image_Transform_Driver_Imagick3
37
 * @author     Philippe Jausions <[email protected]>
38
 * @copyright  2007 The PHP Group
39
 * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
40
 * @version    Release: @package_version@
41
 * @link       http://pear.php.net/package/Image_Transform
42
 * @since      0.9.2
43
 * @since      PHP 5.1.3
44
 * @since      PECL Imagick 2.0.0a1
45
 */
46
class Image_Transform_Driver_Imagick3 extends Image_Transform
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
47
{
48
    /**
49
     * Instance of imagick
50
     * @var Imagick
51
     */
52
    public $imagick = null;
53
54
    /**
55
     * Handler of the image resource before
56
     * the last transformation
57
     * @var array
58
     */
59
    public $oldImage;
60
61
    /**
62
     * @see __construct()
63
     */
64
    public function Image_Transform_Driver_Imagick3()
65
    {
66
        $this->__construct();
67
    }
68
69
    /**
70
     * @see http://www.imagemagick.org/www/formats.html
71
     */
72
    public function __construct()
73
    {
74
        if (PEAR::loadExtension('imagick')) {
75
            include 'Image/Transform/Driver/Imagick/ImageTypes.php';
76
        } else {
77
            $this->isError(PEAR::raiseError('Could not find the imagick extension.', IMAGE_TRANSFORM_ERROR_UNSUPPORTED));
0 ignored issues
show
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
78
        }
79
    }
80
81
    /**
82
     * Loads an image
83
     *
84
     * @param string $image filename
85
     *
86
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
87
     * @access public
88
     */
89
    public function load($image)
90
    {
91
        $this->free();
92
        $this->imagick = new Imagick();
93
        try {
94
            $this->imagick->readImage($image);
95
        } catch (ImagickException $e) {
96
            $this->free();
97
98
            return $this->raiseError('Could not load image:' . $e->getMessage(), IMAGE_TRANSFORM_ERROR_IO);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...GE_TRANSFORM_ERROR_IO); (PEAR) is incompatible with the return type documented by Image_Transform_Driver_Imagick3::load of type boolean|PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
99
        }
100
101
        $this->image = $image;
102
        $result      = $this->_get_image_details($image);
103
        if (PEAR::isError($result)) {
104
            return $result;
105
        }
106
107
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type of the parent method Image_Transform::load of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
108
    }
109
110
    /**
111
     * Resizes the image
112
     *
113
     * @param integer $new_x   New width
114
     * @param integer $new_y   New height
115
     * @param mixed   $options Optional parameters
116
     *                         <ul>
117
     *                         <li>'scaleMethod': "pixel" or "smooth"</li>
118
     *                         </ul>
119
     *
120
     * @return bool|PEAR_Error TRUE or PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be PEAR|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
121
     * @access protected
122
     */
123
    public function _resize($new_x, $new_y, $options = null)
124
    {
125
        try {
126
            $scaleMethod = $this->_getOption('scaleMethod', $options, 'smooth');
127
            $blur        = ($scaleMethod == 'pixel') ? 0 : 1;
128
            $this->imagick->resizeImage($new_x, $new_y, imagick::FILTER_UNDEFINED, $blur);
129
        } catch (ImagickException $e) {
130
            return $this->raiseError('Could not resize image.', IMAGE_TRANSFORM_ERROR_FAILED);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...RANSFORM_ERROR_FAILED); (PEAR) is incompatible with the return type of the parent method Image_Transform::_resize of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
131
        }
132
133
        $this->new_x = $new_x;
134
        $this->new_y = $new_y;
135
136
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type of the parent method Image_Transform::_resize of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
137
    } // End resize
138
139
    /**
140
     * Rotates the current image
141
     *
142
     * @param float $angle   Rotation angle in degree
143
     * @param array $options Supported options:
0 ignored issues
show
Documentation introduced by
Should the type for parameter $options not be array|null?

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...
144
     *                       <ul>
145
     *                       <li>'canvasColor' : array(r ,g, b), named color or #rrggbb</li>
146
     *                       </ul>
147
     *
148
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|PEAR?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
149
     * @access public
150
     */
151
    public function rotate($angle, $options = null)
152
    {
153
        if (($angle % 360) == 0) {
154
            return true;
155
        }
156
        $color = $this->_getColor('canvasColor', $options, array(255, 255, 255));
0 ignored issues
show
Bug introduced by
It seems like $options defined by parameter $options on line 151 can also be of type null; however, Image_Transform::_getColor() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
157
        if (is_array($color)) {
158
            $color = $this->colorarray2colorhex($color);
159
        }
160
        $pixel = new ImagickPixel($color);
161
        try {
162
            $this->imagick->rotateImage($pixel, $angle);
163
        } catch (ImagickException $e) {
164
            return $this->raiseError('Cannot create a new imagick image for the rotation: ' . $e->getMessage(), IMAGE_TRANSFORM_ERROR_FAILED);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...RANSFORM_ERROR_FAILED); (PEAR) is incompatible with the return type of the parent method Image_Transform::rotate of type boolean|PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
165
        }
166
        $info        = $this->imagick->getImageGeometry();
167
        $this->new_x = $info['width'];
168
        $this->new_y = $info['height'];
169
170
        return true;
171
    } // End rotate
172
173
    /**
174
     * Adds text to the image
175
     *
176
     * @param   array $params Array contains options:
177
     *                        <ul>
178
     *                        <li>'text' (string) The string to draw</li>
179
     *                        <li>'x'    (integer) Horizontal position</li>
180
     *                        <li>'y'    (integer) Vertical Position</li>
181
     *                        <li>'Color' (mixed) Font color</li>
182
     *                        <li>'font' (string) Font to be used</li>
183
     *                        <li>'size' (integer) Size of the fonts in pixel</li>
184
     *                        </ul>
185
     *
186
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be PEAR|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
187
     * @access public
188
     */
189
    public function addText($params)
190
    {
191
        $this->oldImage = clone $this->imagick;
0 ignored issues
show
Documentation Bug introduced by
It seems like clone $this->imagick of type object<Imagick> is incompatible with the declared type array of property $oldImage.

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...
192
        $params         = array_merge($this->_get_default_text_params(), $params);
193
194 View Code Duplication
        if (is_array($params['color'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
195
            $params['color'] = $this->colorarray2colorhex($params['color']);
196
        } else {
197
            $params['color'] = strtolower($params['color']);
198
        }
199
200
        static $cmds = array(
201
            'setFillColor' => 'color',
202
            'setFontSize'  => 'size',
203
            'setFontFace'  => 'font'
204
        );
205
        $this->imagick->beginDraw();
206
207
        foreach ($cmds as $cmd => $v) {
208
            if (!$this->imagick->$cmd($params[$v])) {
209
                return $this->raiseError("Problem with adding Text::{$v} = {$params[$v]}", IMAGE_TRANSFORM_ERROR_FAILED);
210
            }
211
        }
212
        if (!$this->imagick->drawAnnotation($params['x'], $params['y'], $params['text'])) {
213
            return $this->raiseError('Problem with adding Text', IMAGE_TRANSFORM_ERROR_FAILED);
214
        }
215
216
        return true;
217
    } // End addText
218
219
    /**
220
     * Saves the image to a file
221
     *
222
     * @param $filename string the name of the file to write to
223
     *
224
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be PEAR|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
225
     * @access public
226
     */
227 View Code Duplication
    public function save($filename, $type = '', $quality = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
    {
229
        $options = (is_array($quality)) ? $quality : array();
230
        if (is_numeric($quality)) {
231
            $options['quality'] = $quality;
232
        }
233
        $quality = $this->_getOption('quality', $options, 75);
234
        $this->imagick->setImageCompression($quality);
235
236
        if ($type && strcasecmp($type, $this->type)) {
237
            try {
238
                $this->imagick->setImageFormat($type);
239
            } catch (ImagickException $e) {
240
                return $this->raiseError('Could not save image to file (conversion failed).', IMAGE_TRANSFORM_ERROR_FAILED);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...RANSFORM_ERROR_FAILED); (PEAR) is incompatible with the return type of the parent method Image_Transform::save of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
241
            }
242
        }
243
244
        try {
245
            $this->imagick->writeImage($filename);
246
        } catch (ImagickException $e) {
247
            return $this->raiseError('Could not save image to file: ' . $e->getMessage(), IMAGE_TRANSFORM_ERROR_IO);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...GE_TRANSFORM_ERROR_IO); (PEAR) is incompatible with the return type of the parent method Image_Transform::save of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
248
        }
249
250
        if (!$this->keep_settings_on_save) {
251
            $this->free();
252
        }
253
254
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type of the parent method Image_Transform::save of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
255
    } // End save
256
257
    /**
258
     * Displays image without saving and lose changes
259
     *
260
     * This method adds the Content-type HTTP header
261
     *
262
     * @param string type (JPG,PNG...);
263
     * @param int    quality 75
264
     *
265
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be PEAR|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
266
     * @access public
267
     */
268 View Code Duplication
    public function display($type = '', $quality = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269
    {
270
        $options = (is_array($quality)) ? $quality : array();
271
        if (is_numeric($quality)) {
272
            $options['quality'] = $quality;
273
        }
274
        $quality = $this->_getOption('quality', $options, 75);
275
        $this->imagick->setImageCompression($quality);
276
277
        if ($type && strcasecmp($type, $this->type)) {
278
            try {
279
                $this->imagick->setImageFormat($type);
280
            } catch (ImagickException $e) {
281
                return $this->raiseError('Could not save image to file (conversion failed).', IMAGE_TRANSFORM_ERROR_FAILED);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...RANSFORM_ERROR_FAILED); (PEAR) is incompatible with the return type of the parent method Image_Transform::display of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
282
            }
283
        }
284
        try {
285
            $image = $this->imagick->getImageBlob();
286
        } catch (ImagickException $e) {
287
            return $this->raiseError('Could not display image.', IMAGE_TRANSFORM_ERROR_IO);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...GE_TRANSFORM_ERROR_IO); (PEAR) is incompatible with the return type of the parent method Image_Transform::display of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
288
        }
289
        header('Content-type: ' . $this->getMimeType($type));
290
        echo $image;
291
        $this->free();
292
293
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type of the parent method Image_Transform::display of type PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
294
    }
295
296
    /**
297
     * Adjusts the image gamma
298
     *
299
     * @param float $outputgamma
300
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
301
     * @access public
302
     */
303
    public function gamma($outputgamma = 1.0)
304
    {
305
        if ($outputgamma != 1.0) {
306
            $this->imagick->setImageGamma($outputgamma);
307
        }
308
309
        return true;
310
    }
311
312
    /**
313
     * Crops the image
314
     *
315
     * @param integer $width  Cropped image width
316
     * @param integer $height Cropped image height
317
     * @param integer $x      X-coordinate to crop at
318
     * @param integer $y      Y-coordinate to crop at
319
     *
320
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
321
     * @access public
322
     */
323 View Code Duplication
    public function crop($width, $height, $x = 0, $y = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
324
    {
325
        // Sanity check
326
        if (!$this->intersects($width, $height, $x, $y)) {
327
            return PEAR::raiseError('Nothing to crop', IMAGE_TRANSFORM_ERROR_OUTOFBOUND);
0 ignored issues
show
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
328
        }
329
        try {
330
            $this->imagick->cropImage($width, $height, $x, $y);
331
        } catch (ImagickException $e) {
332
            return $this->raiseError('Could not crop image', IMAGE_TRANSFORM_ERROR_FAILED);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...RANSFORM_ERROR_FAILED); (PEAR) is incompatible with the return type documented by Image_Transform_Driver_Imagick3::crop of type boolean|PEAR_Error.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
333
        }
334
335
        // I think that setting img_x/y is wrong, but scaleByLength() & friends
336
        // mess up the aspect after a crop otherwise.
337
        $this->new_x = $width;
338
        $this->new_y = $height;
339
340
        return true;
341
    }
342
343
    /**
344
     * Converts the image to greyscale
345
     *
346
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
347
     * @access public
348
     */
349
    public function greyscale()
350
    {
351
        $this->imagick->setImageType(Imagick::IMGTYPE_GRAYSCALE);
352
353
        /*$this->imagick->setImageColorSpace(Imagick::COLORSPACE_GRAY);
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
354
        $this->imagick->setImageDepth(8);
355
        $this->imagick->separateImageChannel(Imagick::CHANNEL_GRAY);
356
        $this->imagick->setImageChannelDepth(Imagick::CHANNEL_GRAY, 8);*/
357
358
        return true;
359
    }
360
361
    /**
362
     * Horizontal mirroring
363
     *
364
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be PEAR|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
365
     * @access public
366
     */
367
    public function mirror()
368
    {
369
        try {
370
            $this->imagick->flopImage();
371
        } catch (ImagickException $e) {
372
            return $this->raiseError('Could not mirror the image.', IMAGE_TRANSFORM_ERROR_FAILED);
373
        }
374
375
        return true;
376
    }
377
378
    /**
379
     * Vertical mirroring
380
     *
381
     * @return bool|PEAR_Error TRUE or a PEAR_Error object on error
0 ignored issues
show
Documentation introduced by
Should the return type not be PEAR|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
382
     * @access public
383
     */
384
    public function flip()
385
    {
386
        try {
387
            $this->imagick->flipImage();
388
        } catch (ImagickException $e) {
389
            return $this->raiseError('Could not flip the image.', IMAGE_TRANSFORM_ERROR_FAILED);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->raiseError...RANSFORM_ERROR_FAILED); (PEAR) is incompatible with the return type of the parent method Image_Transform::flip of type TRUE.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
390
        }
391
392
        return true;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return true; (boolean) is incompatible with the return type of the parent method Image_Transform::flip of type TRUE.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
393
    }
394
395
    /**
396
     * Destroy image handle
397
     *
398
     * @access public
399
     */
400
    public function free()
401
    {
402
        if (isset($this->imagick)) {
403
            $this->imagick->destroy();
404
            $this->imagick = null;
405
        }
406
    }
407
408
    /**
409
     * RaiseError Method - shows imagick Raw errors.
410
     *
411
     * @param string $message message = prefixed message..
412
     * @param int    $code    error code
413
     * @return PEAR error object
414
     * @access protected
415
     */
416
    public function raiseError($message, $code = 0)
417
    {
418
        return PEAR::raiseError($message, $code);
0 ignored issues
show
Bug introduced by
The method raiseError() does not exist on PEAR. Did you maybe mean _raiseError()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
419
    }
420
}
421