Completed
Branch master (44f723)
by Michael
11:35 queued 08:26
created

Zebra_Image::flip_both()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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 6 and the first side effect is on line 19.

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
/**
4
 *  Methods used with the {@link resize()} method.
5
 */
6
define('ZEBRA_IMAGE_BOXED', 0);
7
define('ZEBRA_IMAGE_NOT_BOXED', 1);
8
define('ZEBRA_IMAGE_CROP_TOPLEFT', 2);
9
define('ZEBRA_IMAGE_CROP_TOPCENTER', 3);
10
define('ZEBRA_IMAGE_CROP_TOPRIGHT', 4);
11
define('ZEBRA_IMAGE_CROP_MIDDLELEFT', 5);
12
define('ZEBRA_IMAGE_CROP_CENTER', 6);
13
define('ZEBRA_IMAGE_CROP_MIDDLERIGHT', 7);
14
define('ZEBRA_IMAGE_CROP_BOTTOMLEFT', 8);
15
define('ZEBRA_IMAGE_CROP_BOTTOMCENTER', 9);
16
define('ZEBRA_IMAGE_CROP_BOTTOMRIGHT', 10);
17
18
// this enables handling of partially broken JPEG files without warnings/errors
19
ini_set('gd.jpeg_ignore_warning', true);
20
21
/**
22
 *  A compact, lightweight, object-oriented image manipulation library written in and for PHP, that provides methods
23
 *  for performing several types of image manipulation operations. It doesn't require any external libraries other than
24
 *  the GD2 extension (with which PHP usually comes precompiled with).
25
 *
26
 *  The code is heavily commented and generates no warnings/errors/notices when PHP's error reporting level is set to
27
 *  E_ALL.
28
 *
29
 *  With this library you can rescale, flip, rotate and crop images. It supports loading and saving images in the GIF,
30
 *  JPEG and PNG formats and preserves transparency for GIF, PNG and PNG24.
31
 *
32
 *  The cool thing about it is that it can resize images to exact given width and height and still maintain aspect
33
 *  ratio.
34
 *
35
 *  Visit {@link http://stefangabos.ro/php-libraries/zebra-image/} for more information.
36
 *
37
 *  For more resources visit {@link http://stefangabos.ro/}
38
 *
39
 * @author         Stefan Gabos <[email protected]>
40
 * @version        2.2.3 (last revision: July 14, 2013)
41
 * @copyright  (c) 2006 - 2013 Stefan Gabos
42
 * @license        http://www.gnu.org/licenses/lgpl-3.0.txt GNU LESSER GENERAL PUBLIC LICENSE
43
 * @package        Zebra_Image
44
 */
45
class Zebra_Image
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...
46
{
47
48
    /**
49
     *  Indicates the file system permissions to be set for newly created images.
50
     *
51
     *  Better is to leave this setting as it is.
52
     *
53
     *  If you know what you are doing, here is how you can calculate the permission levels:
54
     *
55
     *  - 400 Owner Read
56
     *  - 200 Owner Write
57
     *  - 100 Owner Execute
58
     *  - 40 Group Read
59
     *  - 20 Group Write
60
     *  - 10 Group Execute
61
     *  - 4 Global Read
62
     *  - 2 Global Write
63
     *  - 1 Global Execute
64
     *
65
     *  Default is 0755
66
     *
67
     * @var integer
68
     */
69
    public $chmod_value;
70
71
    /**
72
     *  If set to FALSE, images having both width and height smaller than the required width and height, will be left
73
     *  untouched ({@link jpeg_quality} and {@link png_compression} will still apply).
74
     *
75
     *  Available only for the {@link resize()} method
76
     *
77
     *  Default is TRUE
78
     *
79
     * @var boolean
80
     */
81
    public $enlarge_smaller_images;
82
83
    /**
84
     *  In case of an error read this property's value to see the error's code.
85
     *
86
     *  Possible error codes are:
87
     *
88
     *  - 1:  source file could not be found
89
     *  - 2:  source file is not readable
90
     *  - 3:  could not write target file
91
     *  - 4:  unsupported source file format
92
     *  - 5:  unsupported target file format
93
     *  - 6:  GD library version does not support target file format
94
     *  - 7:  GD library is not installed!
95
     *  - 8:  "chmod" command is disabled via configuration
96
     *
97
     *  Default is 0 (no error).
98
     *
99
     * @var integer
100
     */
101
    public $error;
102
103
    /**
104
     *  Indicates the quality of the output image (better quality means bigger file size).
105
     *
106
     *  Used only if the file at {@link target_path} is a JPG/JPEG image.
107
     *
108
     *  Range is 0 - 100
109
     *
110
     *  Default is 85
111
     *
112
     * @var integer
113
     */
114
    public $jpeg_quality;
115
116
    /**
117
     *  Indicates the compression level of the output image (lower compression means bigger file size).
118
     *
119
     *  Available only if PHP version is 5.1.2+, and only if the file at {@link target_path} is a PNG image. It will be
120
     *  ignored otherwise.
121
     *
122
     *  Range is 0 - 9
123
     *
124
     *  Default is 9
125
     *
126
     * @since 2.2
127
     *
128
     * @var integer
129
     */
130
    public $png_compression;
131
132
    /**
133
     *  Specifies whether, upon resizing, images should preserve their aspect ratio.
134
     *
135
     *  Available only for the {@link resize()} method
136
     *
137
     *  Default is TRUE
138
     *
139
     * @var boolean
140
     */
141
    public $preserve_aspect_ratio;
142
143
    /**
144
     *  Indicates whether a target files should preserve the source file's date/time.
145
     *
146
     *  Default is TRUE
147
     *
148
     * @since 1.0.4
149
     *
150
     * @var boolean
151
     */
152
    public $preserve_time;
153
154
    /**
155
     *  Indicates whether the target image should have a "sharpen" filter applied to it.
156
     *
157
     *  Can be very useful when creating thumbnails and should be used only when creating thumbnails.
158
     *
159
     *  <i>The sharpen filter relies on the "imageconvolution" PHP function which is available only for PHP version
160
     *  5.1.0+, and will leave the images unaltered for older versions!</i>
161
     *
162
     *  Default is FALSE
163
     *
164
     * @since 2.2
165
     *
166
     * @var boolean
167
     */
168
    public $sharpen_images;
169
170
    /**
171
     *  Path to an image file to apply the transformations to.
172
     *
173
     *  Supported file types are <b>GIF</b>, <b>PNG</b> and <b>JPEG</b>.
174
     *
175
     * @var string
176
     */
177
    public $source_path;
178
179
    /**
180
     *  Path (including file name) to where to save the transformed image.
181
     *
182
     *  <i>Can be a different than {@link source_path} - the type of the transformed image will be as indicated by the
183
     *  file's extension (supported file types are GIF, PNG and JPEG)</i>.
184
     *
185
     * @var string
186
     */
187
    public $target_path;
188
189
    /**
190
     *  Constructor of the class.
191
     *
192
     *  Initializes the class and the default properties
193
     *
194
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
195
     */
196
    public function __construct()
197
    {
198
199
        // set default values for properties
200
        $this->chmod_value = 0755;
201
202
        $this->error = 0;
203
204
        $this->jpeg_quality = 85;
205
206
        $this->png_compression = 9;
207
208
        $this->preserve_aspect_ratio = $this->preserve_time = $this->enlarge_smaller_images = true;
209
210
        $this->sharpen_images = false;
211
212
        $this->source_path = $this->target_path = '';
213
    }
214
215
    /**
216
     *  Applies one or more filters to the image given as {@link source_path} and outputs it as the file specified as
217
     *  {@link target_path}.
218
     *
219
     *  <samp>This method is available only if the {@link http://php.net/manual/en/function.imagefilter.php imagefilter}
220
     *  function is available (available from PHP 5+), and will leave images unaltered otherwise.</samp>
221
     *
222
     *  <code>
223
     *  // include the Zebra_Image library
224
     *  require 'path/to/Zebra_Image.php';
225
     *
226
     *  // instantiate the class
227
     *  $img = new Zebra_Image();
228
     *
229
     *  // a source image
230
     *  $img->source_path = 'path/to/source.ext';
231
     *
232
     *  // path to where should the resulting image be saved
233
     *  // note that by simply setting a different extension to the file will
234
     *  // instruct the script to create an image of that particular type
235
     *  $img->target_path = 'path/to/target.ext';
236
     *
237
     *  // apply the "grayscale" filter
238
     *  $img->apply_filter('grayscale');
239
     *
240
     *  // apply the "contrast" filter
241
     *  $img->apply_filter('contrast', -20);
242
     *  </code>
243
     *
244
     *  You can also apply multiple filters at once. In this case, the method requires a single argument, an array of
245
     *  arrays, containing the filters and associated arguments, where applicable:
246
     *
247
     *  <code>
248
     *  // create a sepia effect
249
     *  // note how we're applying multiple filters at once
250
     *  // each filter is in its own array
251
     *  $img->apply_filter(array(
252
     *
253
     *      // first we apply the "grayscale" filter
254
     *      array('grayscale'),
255
     *
256
     *      // then we apply the "colorize" filter with 90, 60, 40 as
257
     *      // the values for red, green and blue
258
     *      array('colorize', 90, 60, 40),
259
     *
260
     *  ));
261
     *  </code>
262
     *
263
     * @param string $filter The (case-insensitive) name of the filter to apply. Can be one of the following:
264
     *
265
     *                              -   <b>brightness</b>       -   changes the brightness of the image; use <b>arg1</b>
266
     *                                                              to set the level of brightness; the range of brightness
267
     *                                                              is -255 to 255;
268
     *                              -   <b>colorize</b>         -   adds (subtracts) specified RGB values to each pixel;
269
     *                                                              use <b>arg1</b>, <b>arg2</b> and <b>arg3</b> in the
270
     *                                                              form of red, green, blue and <b>arg4</b> for the alpha
271
     *                                                              channel. the range for each color is -255 to 255 and
272
     *                                                              0 to 127 for alpha; <i>alpha support is available only
273
     *                                                              for PHP 5.2.5+</i>;
274
     *                              -   <b>contrast</b>         -   changes the contrast of the image; use <b>arg1</b>
275
     *                                                              to set the level of contrast; the range of contrast
276
     *                                                              is -100 to 100;
277
     *                              -   <b>gausian_blur</b>     -   blurs the image using the Gaussian method;
278
     *                              -   <b>grayscale</b>        -   converts the image into grayscale;
279
     *                              -   <b>edgedetect</b>       -   uses edge detection to highlight the edges in the image;
280
     *                              -   <b>emboss</b>           -   embosses the image;
281
     *                              -   <b>mean_removal</b>     -   uses mean removal to achieve a "sketchy" effect;
282
     *                              -   <b>negate</b>           -   reverses all the colors of the image;
283
     *                              -   <b>pixelate</b>         -   applies pixelation effect to the image, use <b>arg1</b>
284
     *                                                              to set the block size and <b>arg2</b> to set the
285
     *                                                              pixelation effect mode; <i>this filter is available
286
     *                                                              only for PHP 5.3.0+</i>;
287
     *                              -   <b>selective_blur</b>   -   blurs the image;
288
     *                              -   <b>smooth</b>           -   makes the image smoother. Use <b>arg1</b> to set the
289
     *                                                              level of smoothness. applies a 9-cell convolution matrix
290
     *                                                              where center pixel has the weight of <b>arg1</b> and
291
     *                                                              others weight of 1.0. the result is normalized by dividing
292
     *                                                              the sum with <b>arg1</b> + 8.0 (sum of the matrix).
293
     *                                                              any float is accepted;
294
     *
295
     * @param mixed  $arg1   Used by the following filters:
296
     *                       -   <b>brightness</b>       -   sets the brightness level (-255 to 255)
297
     *                       -   <b>contrast</b>         -   sets the contrast level (-100 to 100)
298
     *                       -   <b>colorize</b>         -   sets the value of the red component (-255 to 255)
299
     *                       -   <b>smooth</b>           -   sets the smoothness level
300
     *                       -   <b>pixelate</b>         -   sets the block size, in pixels
301
     *
302
     * @param mixed  $arg2   Used by the following filters:
303
     *                       -   <b>colorize</b>         -   sets the value of the green component (-255 to 255)
304
     *                       -   <b>pixelate</b>         -   whether to use advanced pixelation effect or not (defaults to FALSE).
305
     *
306
     * @param mixed  $arg3   Used by the following filters:
307
     *                       -   <b>colorize</b>         -   sets the value of the blue component (-255 to 255)
308
     *
309
     * @param mixed  $arg4   Used by the following filters:
310
     *                       -   <b>colorize</b>         -   alpha channel; a value between 0 and 127. 0 indicates
311
     *                       completely opaque while 127 indicates completely
312
     *                       transparent.
313
     *
314
     * @since 2.2.2
315
     *
316
     * @return boolean Returns TRUE on success or FALSE on error.
317
     *
318
     *                              If {@link http://php.net/manual/en/function.imagefilter.php imagefilter} is not
319
     *                              available the method will return FALSE without setting an {@link error} code.
320
     *
321
     *                              If the requested filter doesn't exist, or invalid arguments are passed, the method
322
     *                              will trigger a warning.
323
     *
324
     *                              If FALSE is returned and you are sure that
325
     *                              {@link http://php.net/manual/en/function.imagefilter.php imagefilter} exists and that
326
     *                              the requested filter is valid, check the {@link error} property to see the error code.
327
     */
328
    public function apply_filter($filter, $arg1 = '', $arg2 = '', $arg3 = '', $arg4 = '')
0 ignored issues
show
Unused Code introduced by
The parameter $arg1 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $arg2 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $arg3 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $arg4 is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
329
    {
330
331
        // if "imagefilter" function exists and the requested filter exists
332
        if (function_exists('imagefilter')) { // if image resource was successfully created
333
            if ($this->_create_from_source()) {
334
335
                // prepare the target image
336
                $target_identifier = $this->_prepare_image($this->source_width, $this->source_height, -1);
0 ignored issues
show
Bug introduced by
The property source_width does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property source_height does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
337
338
                // copy the original image
339
                imagecopyresampled(
340
341
                    $target_identifier, $this->source_identifier, 0, 0, 0, 0, $this->source_width, $this->source_height, $this->source_width, $this->source_height
0 ignored issues
show
Bug introduced by
The property source_identifier does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
342
343
                );
344
345
                // if multiple filters are to be applied at once
346
                if (is_array($filter)) {
347
348
                    // iterate through the filters
349
                    foreach ($filter as $arguments) { // if filter exists
350
                        if (defined('IMG_FILTER_' . strtoupper($arguments[0]))) {
351
352
                            // try to apply the filter...
353 View Code Duplication
                            if (!@call_user_func_array('imagefilter', array_merge(array($target_identifier, constant('IMG_FILTER_' . strtoupper($arguments[0]))), array_slice($arguments, 1)))) {
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...
354
                                // ...and trigger an error if the filter could not be applied
355
356
                                trigger_error('Invalid arguments used for "' . strtoupper($arguments[0]) . '" filter', E_USER_WARNING);
357
                            }
358
359
                            // if filter doesn't exists, trigger an error
360
                        } else {
361
                            trigger_error('Filter "' . strtoupper($arguments[0]) . '" is not available', E_USER_WARNING);
362
                        }
363
                    }
364
365
                    // if a single filter is to be applied and it is available
366
                } elseif (defined('IMG_FILTER_' . strtoupper($filter))) {
367
368
                    // get all the arguments passed to the method
369
                    $arguments = func_get_args();
370
371
                    // try to apply the filter...
372 View Code Duplication
                    if (!@call_user_func_array('imagefilter', array_merge(array($target_identifier, constant('IMG_FILTER_' . strtoupper($filter))), array_slice($arguments, 1)))) {
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...
373
                        // ...and trigger an error if the filter could not be applied
374
375
                        trigger_error('Invalid arguments used for "' . strtoupper($arguments[0]) . '" filter', E_USER_WARNING);
376
                    }
377
378
                    // if filter doesn't exists, trigger an error
379
                } else {
380
                    trigger_error('Filter "' . strtoupper($arguments[0]) . '" is not available', E_USER_WARNING);
0 ignored issues
show
Bug introduced by
The variable $arguments seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
381
                }
382
383
                // write image
384
                return $this->_write_image($target_identifier);
385
            }
386
        }
387
388
        // if script gets this far, return false
389
        // note that we do not set the error level as it has been already set
390
        // by the _create_from_source() method earlier, if the case
391
        return false;
392
    }
393
394
    /**
395
     *  Crops a portion of the image given as {@link source_path} and outputs it as the file specified as {@link target_path}.
396
     *
397
     *  <code>
398
     *  // include the Zebra_Image library
399
     *  require 'path/to/Zebra_Image.php';
400
     *
401
     *  // instantiate the class
402
     *  $img = new Zebra_Image();
403
     *
404
     *  // a source image
405
     *  $img->source_path = 'path/to/source.ext';
406
     *
407
     *  // path to where should the resulting image be saved
408
     *  // note that by simply setting a different extension to the file will
409
     *  // instruct the script to create an image of that particular type
410
     *  $img->target_path = 'path/to/target.ext';
411
     *
412
     *  // crop a rectangle of 100x100 pixels, starting from the top-left corner
413
     *  $img->crop(0, 0, 100, 100);
414
     *  </code>
415
     *
416
     * @param integer $start_x x coordinate to start cropping from
417
     *
418
     * @param integer $start_y y coordinate to start cropping from
419
     *
420
     * @param integer $end_x   x coordinate where to end the cropping
421
     *
422
     * @param integer $end_y   y coordinate where to end the cropping
423
     *
424
     * @since  1.0.4
425
     *
426
     * @return boolean Returns TRUE on success or FALSE on error.
427
     *
428
     *                      If FALSE is returned, check the {@link error} property to see the error code.
429
     */
430
    public function crop($start_x, $start_y, $end_x, $end_y)
431
    {
432
433
        // this method might be also called internally
434
        // in this case, there's a fifth argument that points to an already existing image identifier
435
        $args = func_get_args();
436
437
        // if fifth argument exists
438
        if (isset($args[4]) && is_resource($args[4])) {
439
440
            // that it is the image identifier that we'll be using further on
441
            $this->source_identifier = $args[4];
442
443
            // set this to true so that the script will continue to execute at the next IF
444
            $result = true;
445
446
            // if method is called as usually
447
            // try to create an image resource from source path
448
        } else {
449
            $result = $this->_create_from_source();
450
        }
451
452
        // if image resource was successfully created
453
        if ($result !== false) {
454
455
            // prepare the target image
456
            $target_identifier = $this->_prepare_image($end_x - $start_x, $end_y - $start_y, -1);
457
458
            // crop the image
459
            imagecopyresampled(
460
461
                $target_identifier, $this->source_identifier, 0, 0, $start_x, $start_y, $end_x - $start_x, $end_y - $start_y, $end_x - $start_x, $end_y - $start_y
462
463
            );
464
465
            // write image
466
            return $this->_write_image($target_identifier);
467
        }
468
469
        // if script gets this far, return false
470
        // note that we do not set the error level as it has been already set
471
        // by the _create_from_source() method earlier
472
        return false;
473
    }
474
475
    /**
476
     *  Flips both horizontally and vertically the image given as {@link source_path} and outputs the resulted image as
477
     *  {@link target_path}
478
     *
479
     *  <code>
480
     *  // include the Zebra_Image library
481
     *  require 'path/to/Zebra_Image.php';
482
     *
483
     *  // instantiate the class
484
     *  $img = new Zebra_Image();
485
     *
486
     *  // a source image
487
     *  $img->source_path = 'path/to/source.ext';
488
     *
489
     *  // path to where should the resulting image be saved
490
     *  // note that by simply setting a different extension to the file will
491
     *  // instruct the script to create an image of that particular type
492
     *  $img->target_path = 'path/to/target.ext';
493
     *
494
     *  // flip the image both horizontally and vertically
495
     *  $img->flip_both();
496
     *  </code>
497
     *
498
     * @since 2.1
499
     *
500
     * @return boolean Returns TRUE on success or FALSE on error.
501
     *
502
     *                      If FALSE is returned, check the {@link error} property to see the error code.
503
     */
504
    public function flip_both()
505
    {
506
        return $this->_flip('both');
507
    }
508
509
    /**
510
     *  Flips horizontally the image given as {@link source_path} and outputs the resulted image as {@link target_path}
511
     *
512
     *  <code>
513
     *  // include the Zebra_Image library
514
     *  require 'path/to/Zebra_Image.php';
515
     *
516
     *  // instantiate the class
517
     *  $img = new Zebra_Image();
518
     *
519
     *  // a source image
520
     *  $img->source_path = 'path/to/source.ext';
521
     *
522
     *  // path to where should the resulting image be saved
523
     *  // note that by simply setting a different extension to the file will
524
     *  // instruct the script to create an image of that particular type
525
     *  $img->target_path = 'path/to/target.ext';
526
     *
527
     *  // flip the image horizontally
528
     *  $img->flip_horizontal();
529
     *  </code>
530
     *
531
     * @return boolean Returns TRUE on success or FALSE on error.
532
     *
533
     *                      If FALSE is returned, check the {@link error} property to see the error code.
534
     */
535
    public function flip_horizontal()
536
    {
537
        return $this->_flip('horizontal');
538
    }
539
540
    /**
541
     *  Flips vertically the image given as {@link source_path} and outputs the resulted image as {@link target_path}
542
     *
543
     *  <code>
544
     *  // include the Zebra_Image library
545
     *  require 'path/to/Zebra_Image.php';
546
     *
547
     *  // instantiate the class
548
     *  $img = new Zebra_Image();
549
     *
550
     *  // a source image
551
     *  $img->source_path = 'path/to/source.ext';
552
     *
553
     *  // path to where should the resulting image be saved
554
     *  // note that by simply setting a different extension to the file will
555
     *  // instruct the script to create an image of that particular type
556
     *  $img->target_path = 'path/to/target.ext';
557
     *
558
     *  // flip the image vertically
559
     *  $img->flip_vertical();
560
     *  </code>
561
     *
562
     * @return boolean Returns TRUE on success or FALSE on error.
563
     *
564
     *                      If FALSE is returned, check the {@link error} property to see the error code.
565
     */
566
    public function flip_vertical()
567
    {
568
        return $this->_flip('vertical');
569
    }
570
571
    /**
572
     *  Resizes the image given as {@link source_path} and outputs the resulted image as {@link target_path}.
573
     *
574
     *  <code>
575
     *  // include the Zebra_Image library
576
     *  require 'path/to/Zebra_Image.php';
577
     *
578
     *  // instantiate the class
579
     *  $img = new Zebra_Image();
580
     *
581
     *  // a source image
582
     *  $img->source_path = 'path/to/source.ext';
583
     *
584
     *  // path to where should the resulting image be saved
585
     *  // note that by simply setting a different extension to the file will
586
     *  // instruct the script to create an image of that particular type
587
     *  $img->target_path = 'path/to/target.ext';
588
     *
589
     *  // apply a "sharpen" filter to the resulting images
590
     *  $img->sharpen_images = true;
591
     *
592
     *  // resize the image to exactly 150x150 pixels, without altering aspect ratio, by using the CROP_CENTER method
593
     *  $img->resize(150, 150, ZEBRA_IMAGE_CROP_CENTER);
594
     *  </code>
595
     *
596
     * @param integer             $width            The width to resize the image to.
597
     *
598
     *                                          If set to <b>0</b>, the width will be automatically adjusted, depending
599
     *                                          on the value of the <b>height</b> argument so that the image preserves
600
     *                                          its aspect ratio.
601
     *
602
     *                                          If {@link preserve_aspect_ratio} is set to TRUE and both this and the
603
     *                                          <b>height</b> arguments are values greater than <b>0</b>, the image will
604
     *                                          be resized to the exact required width and height and the aspect ratio
605
     *                                          will be preserved - (also see the description for the <b>method</b>
606
     *                                          argument below on how can this be done).
607
     *
608
     *                                          If {@link preserve_aspect_ratio} is set to FALSE, the image will be
609
     *                                          resized to the required width and the aspect ratio will be ignored.
610
     *
611
     *                                          If both <b>width</b> and <b>height</b> are set to <b>0</b>, a copy of
612
     *                                          the source image will be created ({@link jpeg_quality} and
613
     *                                          {@link png_compression} will still apply).
614
     *
615
     *                                          If either <b>width</b> or <b>height</b> are set to <b>0</b>, the script
616
     *                                          will consider the value of the {@link preserve_aspect_ratio} to bet set
617
     *                                          to TRUE regardless of its actual value!
618
     *
619
     * @param integer             $height           The height to resize the image to.
620
     *
621
     *                                          If set to <b>0</b>, the height will be automatically adjusted, depending
622
     *                                          on the value of the <b>width</b> argument so that the image preserves
623
     *                                          its aspect ratio.
624
     *
625
     *                                          If {@link preserve_aspect_ratio} is set to TRUE and both this and the
626
     *                                          <b>width</b> arguments are values greater than <b>0</b>, the image will
627
     *                                          be resized to the exact required width and height and the aspect ratio
628
     *                                          will be preserved - (also see the description for the <b>method</b>
629
     *                                          argument below on how can this be done).
630
     *
631
     *                                          If {@link preserve_aspect_ratio} is set to FALSE, the image will be
632
     *                                          resized to the required height and the aspect ratio will be ignored.
633
     *
634
     *                                          If both <b>width</b> and <b>height</b> are set to <b>0</b>, a copy of
635
     *                                          the source image will be created ({@link jpeg_quality} and
636
     *                                          {@link png_compression} will still apply).
637
     *
638
     *                                          If either <b>height</b> or <b>width</b> are set to <b>0</b>, the script
639
     *                                          will consider the value of the {@link preserve_aspect_ratio} to bet set
640
     *                                          to TRUE regardless of its actual value!
641
     *
642
     * @param int                 $method           (Optional) Method to use when resizing images to exact width and height
643
     *                                              while preserving aspect ratio.
644
     *
645
     *                                          If the {@link preserve_aspect_ratio} property is set to TRUE and both the
646
     *                                          <b>width</b> and <b>height</b> arguments are values greater than <b>0</b>,
647
     *                                          the image will be resized to the exact given width and height and the
648
     *                                          aspect ratio will be preserved by using on of the following methods:
649
     *
650
     *                                          -   <b>ZEBRA_IMAGE_BOXED</b> - the image will be scalled so that it will
651
     *                                              fit in a box with the given width and height (both width/height will
652
     *                                              be smaller or equal to the required width/height) and then it will
653
     *                                              be centered both horizontally and vertically. The blank area will be
654
     *                                              filled with the color specified by the <b>bgcolor</b> argument. (the
655
     *                                              blank area will be filled only if the image is not transparent!)
656
     *
657
     *                                          -   <b>ZEBRA_IMAGE_NOT_BOXED</b> - the image will be scalled so that it
658
     *                                              <i>could</i> fit in a box with the given width and height but will
659
     *                                              not be enclosed in a box with given width and height. The new width/
660
     *                                              height will be both smaller or equal to the required width/height
661
     *
662
     *                                          -   <b>ZEBRA_IMAGE_CROP_TOPLEFT</b>
663
     *                                          -   <b>ZEBRA_IMAGE_CROP_TOPCENTER</b>
664
     *                                          -   <b>ZEBRA_IMAGE_CROP_TOPRIGHT</b>
665
     *                                          -   <b>ZEBRA_IMAGE_CROP_MIDDLELEFT</b>
666
     *                                          -   <b>ZEBRA_IMAGE_CROP_CENTER</b>
667
     *                                          -   <b>ZEBRA_IMAGE_CROP_MIDDLERIGHT</b>
668
     *                                          -   <b>ZEBRA_IMAGE_CROP_BOTTOMLEFT</b>
669
     *                                          -   <b>ZEBRA_IMAGE_CROP_BOTTOMCENTER</b>
670
     *                                          -   <b>ZEBRA_IMAGE_CROP_BOTTOMRIGHT</b>
671
     *
672
     *                                          For the methods involving crop, first the image is scaled so that both
673
     *                                          its sides are equal or greater than the respective sizes of the bounding
674
     *                                          box; next, a region of required width and height will be cropped from
675
     *                                          indicated region of the resulted image.
676
     *
677
     *                                          Default is ZEBRA_IMAGE_CROP_CENTER
678
     *
679
     * @param \hexadecimal|string $background_color (Optional) The hexadecimal color (like "#FFFFFF" or "#FFF") of the
680
     *                                              blank area. See the <b>method</b> argument.
681
     *
682
     *                                          When set to -1 the script will preserve transparency for transparent GIF
683
     *                                          and PNG images. For non-transparent images the background will be white
684
     *                                          in this case.
685
     *
686
     *                                          Default is #FFFFFF.
687
     *
688
     * @return boolean Returns TRUE on success or FALSE on error.
689
     *
690
     *                                          If FALSE is returned, check the {@link error} property to see what went
691
     *                                          wrong
692
     */
693
    public function resize($width = 0, $height = 0, $method = ZEBRA_IMAGE_CROP_CENTER, $background_color = '#FFFFFF')
694
    {
695
696
        // if image resource was successfully created
697
        if ($this->_create_from_source()) {
698
699
            // if either width or height is to be adjusted automatically
700
            // set a flag telling the script that, even if $preserve_aspect_ratio is set to false
701
            // treat everything as if it was set to true
702
            if ($width == 0 || $height == 0) {
703
                $auto_preserve_aspect_ratio = true;
704
            }
705
706
            // if aspect ratio needs to be preserved
707
            if ($this->preserve_aspect_ratio || isset($auto_preserve_aspect_ratio)) {
708
709
                // if height is given and width is to be computed accordingly
710
                if ($width == 0 && $height > 0) {
711
712
                    // get the original image's aspect ratio
713
                    $aspect_ratio = $this->source_width / $this->source_height;
714
715
                    // the target image's height is as given as argument to the method
716
                    $target_height = $height;
717
718
                    // compute the target image's width, preserving the aspect ratio
719
                    $target_width = round($height * $aspect_ratio);
720
721
                    // if width is given and height is to be computed accordingly
722
                } elseif ($width > 0 && $height == 0) {
723
724
                    // get the original image's aspect ratio
725
                    $aspect_ratio = $this->source_height / $this->source_width;
726
727
                    // the target image's width is as given as argument to the method
728
                    $target_width = $width;
729
730
                    // compute the target image's height, preserving the aspect ratio
731
                    $target_height = round($width * $aspect_ratio);
732
733
                    // if both width and height are given and ZEBRA_IMAGE_BOXED or ZEBRA_IMAGE_NOT_BOXED methods are to be used
734
                } elseif ($width > 0 && $height > 0 && ($method == 0 || $method == 1)) {
735
736
                    // compute the horizontal and vertical aspect ratios
737
                    $vertical_aspect_ratio   = $height / $this->source_height;
738
                    $horizontal_aspect_ratio = $width / $this->source_width;
739
740
                    // if the image's newly computed height would be inside the bounding box
741
                    if (round($horizontal_aspect_ratio * $this->source_height < $height)) {
742
743
                        // the target image's width is as given as argument to the method
744
                        $target_width = $width;
745
746
                        // compute the target image's height so that the image will stay inside the bounding box
747
                        $target_height = round($horizontal_aspect_ratio * $this->source_height);
748
749
                        // otherwise
750
                    } else {
751
752
                        // the target image's height is as given as argument to the method
753
                        $target_height = $height;
754
755
                        // compute the target image's width so that the image will stay inside the bounding box
756
                        $target_width = round($vertical_aspect_ratio * $this->source_width);
757
                    }
758
759
                    // if both width and height are given and image is to be cropped in order to get to the required size
760
                } elseif ($width > 0 && $height > 0 && $method > 1 && $method < 11) {
761
762
                    // compute the horizontal and vertical aspect ratios
763
                    $vertical_aspect_ratio   = $this->source_height / $height;
764
                    $horizontal_aspect_ratio = $this->source_width / $width;
765
766
                    // we'll use one of the two
767
                    $aspect_ratio = $vertical_aspect_ratio < $horizontal_aspect_ratio ?
768
769
                        $vertical_aspect_ratio :
770
771
                        $horizontal_aspect_ratio;
772
773
                    // compute the target image's width, preserving the aspect ratio
774
                    $target_width = round($this->source_width / $aspect_ratio);
775
776
                    // compute the target image's height, preserving the aspect ratio
777
                    $target_height = round($this->source_height / $aspect_ratio);
778
779
                    // for any other case
780
                } else {
781
782
                    // we will create a copy of the source image
783
                    $target_width  = $this->source_width;
784
                    $target_height = $this->source_height;
785
                }
786
787
                // if aspect ratio does not need to be preserved
788
            } else {
789
790
                // compute the target image's width
791
                $target_width = ($width > 0 ? $width : $this->source_width);
792
793
                // compute the target image's height
794
                $target_height = ($height > 0 ? $height : $this->source_height);
795
            }
796
797
            // if
798
            if (
799
800
                // all images are to be resized - including images that are smaller than the given width/height
801
                $this->enlarge_smaller_images || // smaller images than the given width/height are to be left untouched
802
                // but current image has at leas one side that is larger than the required width/height
803
                ($width > 0 && $height > 0 ?
804
805
                    ($this->source_width > $width || $this->source_height > $height) :
806
807
                    ($this->source_width > $target_width || $this->source_height > $target_height)
808
809
                )
810
811
            ) {
812
813
                // if
814
                if (
815
816
                    // aspect ratio needs to be preserved AND
817
                    ($this->preserve_aspect_ratio || isset($auto_preserve_aspect_ratio)) && // both width and height are given
818
                    ($width > 0 && $height > 0) && // images are to be cropped
819
                    ($method > 1 && $method < 11)
820
821
                ) {
822
823
                    // prepare the target image
824
                    $target_identifier = $this->_prepare_image($target_width, $target_height, $background_color);
825
826
                    imagecopyresampled(
827
828
                        $target_identifier, $this->source_identifier, 0, 0, 0, 0, $target_width, $target_height, $this->source_width, $this->source_height
829
830
                    );
831
832
                    // do the crop according to the required method
833
                    switch ($method) {
834
835
                        // if image needs to be cropped from the top-left corner
836
                        case ZEBRA_IMAGE_CROP_TOPLEFT:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
837
838
                            // crop accordingly
839
                            return $this->crop(0, 0, $width, $height, $target_identifier // crop this resource instead
840
                            );
841
842
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
843
844
                        // if image needs to be cropped from the top-center
845 View Code Duplication
                        case ZEBRA_IMAGE_CROP_TOPCENTER:
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
846
847
                            // crop accordingly
848
                            return $this->crop(floor(($target_width - $width) / 2), 0, floor(($target_width - $width) / 2) + $width, $height, $target_identifier // crop this resource instead
849
                            );
850
851
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
852
853
                        // if image needs to be cropped from the top-right corner
854
                        case ZEBRA_IMAGE_CROP_TOPRIGHT:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
855
856
                            // crop accordingly
857
                            return $this->crop($target_width - $width, 0, $target_width, $height, $target_identifier // crop this resource instead
858
                            );
859
860
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
861
862
                        // if image needs to be cropped from the middle-left
863 View Code Duplication
                        case ZEBRA_IMAGE_CROP_MIDDLELEFT:
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
864
865
                            // crop accordingly
866
                            return $this->crop(
867
868
                                0, floor(($target_height - $height) / 2), $width, floor(($target_height - $height) / 2) + $height, $target_identifier // crop this resource instead
869
870
                            );
871
872
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
873
874
                        // if image needs to be cropped from the center of the image
875
                        case ZEBRA_IMAGE_CROP_CENTER:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
876
877
                            // crop accordingly
878
                            return $this->crop(
879
880
                                floor(($target_width - $width) / 2), floor(($target_height - $height) / 2), floor(($target_width - $width) / 2) + $width, floor(($target_height - $height) / 2) + $height, $target_identifier // crop this resource instead
881
882
                            );
883
884
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
885
886
                        // if image needs to be cropped from the middle-right
887 View Code Duplication
                        case ZEBRA_IMAGE_CROP_MIDDLERIGHT:
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
888
889
                            // crop accordingly
890
                            return $this->crop(
891
892
                                $target_width - $width, floor(($target_height - $height) / 2), $target_width, floor(($target_height - $height) / 2) + $height, $target_identifier // crop this resource instead
893
894
                            );
895
896
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
897
898
                        // if image needs to be cropped from the bottom-left corner
899
                        case ZEBRA_IMAGE_CROP_BOTTOMLEFT:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
900
901
                            // crop accordingly
902
                            return $this->crop(
903
904
                                0, $target_height - $height, $width, $target_height, $target_identifier // crop this resource instead
905
906
                            );
907
908
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
909
910
                        // if image needs to be cropped from the bottom-center
911 View Code Duplication
                        case ZEBRA_IMAGE_CROP_BOTTOMCENTER:
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
912
913
                            // crop accordingly
914
                            return $this->crop(
915
916
                                floor(($target_width - $width) / 2), $target_height - $height, floor(($target_width - $width) / 2) + $width, $target_height, $target_identifier // crop this resource instead
917
918
                            );
919
920
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
921
922
                        // if image needs to be cropped from the bottom-right corner
923
                        case ZEBRA_IMAGE_CROP_BOTTOMRIGHT:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
924
925
                            // crop accordingly
926
                            return $this->crop(
927
928
                                $target_width - $width, $target_height - $height, $target_width, $target_height, $target_identifier // crop this resource instead
929
930
                            );
931
932
                            break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
933
934
                    }
935
936
                    // if aspect ratio doesn't need to be preserved or
937
                    // it needs to be preserved and method is ZEBRA_IMAGE_BOXED or ZEBRA_IMAGE_NOT_BOXED
938
                } else {
939
940
                    // prepare the target image
941
                    $target_identifier = $this->_prepare_image(($width > 0 && $height > 0 && $method != ZEBRA_IMAGE_NOT_BOXED ? $width : $target_width), ($width > 0 && $height > 0 && $method != ZEBRA_IMAGE_NOT_BOXED ? $height : $target_height), $background_color);
942
943
                    imagecopyresampled(
944
945
                        $target_identifier, $this->source_identifier, ($width > 0 && $height > 0 && $method != ZEBRA_IMAGE_NOT_BOXED ? ($width - $target_width) / 2 : 0), ($width > 0 && $height > 0 && $method != ZEBRA_IMAGE_NOT_BOXED ? ($height - $target_height) / 2 : 0), 0, 0, $target_width, $target_height, $this->source_width, $this->source_height
946
947
                    );
948
949
                    // if script gets this far, write the image to disk
950
                    return $this->_write_image($target_identifier);
951
                }
952
953
                // if we get here it means that
954
                // smaller images than the given width/height are to be left untouched
955
                // therefore, we save the image as it is
956
            } else {
957
                return $this->_write_image($this->source_identifier);
958
            }
959
        }
960
961
        // if script gets this far return false
962
        // note that we do not set the error level as it has been already set
963
        // by the _create_from_source() method earlier
964
        return false;
965
    }
966
967
    /**
968
     *  Rotates the image given as {@link source_path} and outputs the resulted image as {@link target_path}.
969
     *
970
     *  <code>
971
     *  // include the Zebra_Image library
972
     *  require 'path/to/Zebra_Image.php';
973
     *
974
     *  // instantiate the class
975
     *  $img = new Zebra_Image();
976
     *
977
     *  // a source image
978
     *  $img->source_path = 'path/to/source.ext';
979
     *
980
     *  // path to where should the resulting image be saved
981
     *  // note that by simply setting a different extension to the file will
982
     *  // instruct the script to create an image of that particular type
983
     *  $img->target_path = 'path/to/target.ext';
984
     *
985
     *  // rotate the image 45 degrees, clockwise
986
     *  $img->rotate(45);
987
     *  </code>
988
     *
989
     * @param double $angle            Angle by which to rotate the image clockwise.
990
     *
991
     *                                          Between 0 and 360.
992
     *
993
     * @param mixed  $background_color (Optional) The hexadecimal color (like "#FFFFFF" or "#FFF") of the
994
     *                                 uncovered zone after the rotation.
995
     *
996
     *                                          When set to -1 the script will preserve transparency for transparent GIF
997
     *                                          and PNG images. For non-transparent images the background will be white
998
     *                                          in this case.
999
     *
1000
     *                                          Default is -1.
1001
     *
1002
     * @return boolean Returns TRUE on success or FALSE on error.
1003
     *
1004
     *                                          If FALSE is returned, check the {@link error} property to see the error
1005
     *                                          code.
1006
     */
1007
    public function rotate($angle, $background_color = -1)
1008
    {
1009
1010
        // if image resource was successfully created
1011
        if ($this->_create_from_source()) {
1012
1013
            // angles are given clockwise but imagerotate works counterclockwise so we need to negate our value
1014
            $angle = -$angle;
1015
1016
            // if source image is PNG
1017
            if ($this->source_type == IMAGETYPE_PNG && $background_color == -1) {
1018
1019
                // rotate the image
1020
                // but if using -1 as background color didn't work (as is the case for PNG8)
1021
                if (!($target_identifier = imagerotate($this->source_identifier, $angle, -1))) {
1022
1023
                    // we will be using #FFF as the color to fill the uncovered zone after the rotation
1024
                    $background_color = imagefilledarc($this->source_identifier, 255, 255, 255);
1025
1026
                    // rotate the image
1027
                    $target_identifier = imagerotate($this->source_identifier, $angle, $background_color);
1028
                }
1029
1030
                // if source image is a transparent GIF
1031
            } elseif ($this->source_type == IMAGETYPE_GIF && $this->source_transparent_color_index >= 0) {
0 ignored issues
show
Bug introduced by
The property source_type does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property source_transparent_color_index does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1032
1033
                // convert the background color to RGB values
1034
                $background_color = $this->_hex2rgb($background_color);
1035
1036
                // allocate the color to the image identifier
1037
                $background_color = imagefilledarc(
1038
1039
                    $this->source_identifier, $background_color['r'], $background_color['g'], $background_color['b']
1040
1041
                );
1042
1043
                // rotate the image
1044
                $this->source_identifier = imagerotate($this->source_identifier, $angle, $background_color);
1045
1046
                // get the width of rotated image
1047
                $width = imagesx($this->source_identifier);
1048
1049
                // get the height of rotated image
1050
                $height = imagesy($this->source_identifier);
1051
1052
                // create a blank image with the new width and height
1053
                // (this intermediary step is for preserving transparency)
1054
                $target_identifier = $this->_prepare_image($width, $height, -1);
1055
1056
                // copy the rotated image on to the new one
1057
                imagecopyresampled($target_identifier, $this->source_identifier, 0, 0, 0, 0, $width, $height, $width, $height);
1058
1059
                // for the other cases
1060
            } else {
1061
1062
                // convert the color to RGB values
1063
                $background_color = $this->_hex2rgb($background_color);
1064
1065
                // allocate the color to the image identifier
1066
                $background_color = imagefilledarc(
1067
1068
                    $this->source_identifier, $background_color['r'], $background_color['g'], $background_color['b']
1069
1070
                );
1071
1072
                // rotate the image
1073
                $target_identifier = imagerotate($this->source_identifier, $angle, $background_color);
1074
            }
1075
1076
            // write image
1077
            $this->_write_image($target_identifier);
1078
        }
1079
1080
        // if script gets this far return false
1081
        // note that we do not set the error level as it has been already set
1082
        // by the _create_from_source() method earlier
1083
        return false;
1084
    }
1085
1086
    /**
1087
     *  Returns an array containing the image identifier representing the image obtained from {@link $source_path}, the
1088
     *  image's width and height and the image's type
1089
     *
1090
     * @access private
1091
     */
1092
    public function _create_from_source()
1093
    {
1094
1095
        // perform some error checking first
1096
        // if the GD library is not installed
1097
        if (!function_exists('gd_info')) {
1098
1099
            // save the error level and stop the execution of the script
1100
            $this->error = 7;
1101
1102
            return false;
1103
1104
            // if source file does not exist
1105
        } elseif (!is_file($this->source_path)) {
1106
1107
            // save the error level and stop the execution of the script
1108
            $this->error = 1;
1109
1110
            return false;
1111
1112
            // if source file is not readable
1113
        } elseif (!is_readable($this->source_path)) {
1114
1115
            // save the error level and stop the execution of the script
1116
            $this->error = 2;
1117
1118
            return false;
1119
1120
            // if target file is same as source file and source file is not writable
1121
        } elseif ($this->target_path == $this->source_path && !is_writable($this->source_path)) {
1122
1123
            // save the error level and stop the execution of the script
1124
            $this->error = 3;
1125
1126
            return false;
1127
1128
            // try to get source file width, height and type
1129
            // and if it founds an unsupported file type
1130
        } elseif (!list($this->source_width, $this->source_height, $this->source_type) = @getimagesize($this->source_path)) {
1131
1132
            // save the error level and stop the execution of the script
1133
            $this->error = 4;
1134
1135
            return false;
1136
1137
            // if no errors so far
1138
        } else {
1139
1140
            // get target file's type based on the file extension
1141
            $this->target_type = strtolower(substr($this->target_path, strrpos($this->target_path, '.') + 1));
0 ignored issues
show
Bug introduced by
The property target_type does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1142
1143
            // create an image from file using extension dependant function
1144
            // checks for file extension
1145
            switch ($this->source_type) {
1146
1147
                // if GIF
1148
                case IMAGETYPE_GIF:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1149
1150
                    // create an image from file
1151
                    $identifier = imagecreatefromgif($this->source_path);
1152
1153
                    // get the index of the transparent color (if any)
1154
                    if (($this->source_transparent_color_index = imagecolortransparent($identifier)) >= 0) {
1155
                        // get the transparent color's RGB values
1156
                        // we have to mute errors because there are GIF images which *are* transparent and everything
1157
                        // works as expected, but imagecolortransparent() returns a color that is outside the range of
1158
                        // colors in the image's pallette...
1159
1160
                        $this->source_transparent_color = @imagecolorsforindex($identifier, $this->source_transparent_color_index);
0 ignored issues
show
Bug introduced by
The property source_transparent_color does not seem to exist. Did you mean source_transparent_color_index?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1161
                    }
1162
1163
                    break;
1164
1165
                // if JPEG
1166
                case IMAGETYPE_JPEG:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1167
1168
                    // create an image from file
1169
                    $identifier = imagecreatefromjpeg($this->source_path);
1170
1171
                    break;
1172
1173
                // if PNG
1174
                case IMAGETYPE_PNG:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1175
1176
                    // create an image from file
1177
                    $identifier = imagecreatefrompng($this->source_path);
1178
1179
                    // disable blending
1180
                    imagealphablending($identifier, false);
1181
1182
                    break;
1183
1184
                default:
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1185
1186
                    // if unsupported file type
1187
                    // note that we call this if the file is not GIF, JPG or PNG even though the getimagesize function
1188
                    // handles more image types
1189
                    $this->error = 4;
1190
1191
                    return false;
1192
1193
            }
1194
        }
1195
1196
        // if target file has to have the same timestamp as the source image
1197
        // save it as a global property of the class
1198
        if ($this->preserve_time) {
1199
            $this->source_image_time = filemtime($this->source_path);
0 ignored issues
show
Bug introduced by
The property source_image_time does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1200
        }
1201
1202
        // make available the source image's identifier
1203
        $this->source_identifier = $identifier;
1204
1205
        return true;
1206
    }
1207
1208
    /**
1209
     *  Converts a hexadecimal representation of a color (i.e. #123456 or #AAA) to a RGB representation.
1210
     *
1211
     *  The RGB values will be a value between 0 and 255 each.
1212
     *
1213
     * @param string $color            Hexadecimal representation of a color (i.e. #123456 or #AAA).
1214
     *
1215
     * @param string $default_on_error Hexadecimal representation of a color to be used in case $color is not
1216
     *                                 recognized as a hexadecimal color.
1217
     *
1218
     * @return array Returns an associative array with the values of (R)ed, (G)reen and (B)lue
1219
     *
1220
     * @access private
1221
     */
1222
    public function _hex2rgb($color, $default_on_error = '#FFFFFF')
1223
    {
1224
1225
        // if color is not formatted correctly
1226
        // use the default color
1227
        if (preg_match('/^#?([a-f]|[0-9]){3}(([a-f]|[0-9]){3})?$/i', $color) == 0) {
1228
            $color = $default_on_error;
1229
        }
1230
1231
        // trim off the "#" prefix from $background_color
1232
        $color = ltrim($color, '#');
1233
1234
        // if color is given using the shorthand (i.e. "FFF" instead of "FFFFFF")
1235
        if (strlen($color) == 3) {
1236
            $tmp = '';
1237
1238
            // take each value
1239
            // and duplicate it
1240
            for ($i = 0; $i < 3; ++$i) {
1241
                $tmp .= str_repeat($color[$i], 2);
1242
            }
1243
1244
            // the color in it's full, 6 characters length notation
1245
            $color = $tmp;
1246
        }
1247
1248
        // decimal representation of the color
1249
        $int = hexdec($color);
1250
1251
        // extract and return the RGB values
1252
        return array(
1253
1254
            'r' => 0xFF & ($int >> 0x10),
1255
            'g' => 0xFF & ($int >> 0x8),
1256
            'b' => 0xFF & $int
1257
1258
        );
1259
    }
1260
1261
    /**
1262
     *  Flips horizontally or vertically or both ways the image given as {@link source_path}.
1263
     *
1264
     * @since  2.1
1265
     *
1266
     * @access private
1267
     *
1268
     * @param $orientation
1269
     *
1270
     * @return boolean Returns TRUE on success or FALSE on error.
1271
     *
1272
     *                      If FALSE is returned, check the {@link error} property to see the error code.
1273
     */
1274
    public function _flip($orientation)
1275
    {
1276
1277
        // if image resource was successfully created
1278
        if ($this->_create_from_source()) {
1279
1280
            // prepare the target image
1281
            $target_identifier = $this->_prepare_image($this->source_width, $this->source_height, -1);
1282
1283
            // flip according to $orientation
1284
            switch ($orientation) {
1285
1286 View Code Duplication
                case 'horizontal':
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1287
1288
                    imagecopyresampled(
1289
1290
                        $target_identifier, $this->source_identifier, 0, 0, $this->source_width - 1, 0, $this->source_width, $this->source_height, -$this->source_width, $this->source_height
1291
1292
                    );
1293
1294
                    break;
1295
1296 View Code Duplication
                case 'vertical':
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1297
1298
                    imagecopyresampled(
1299
1300
                        $target_identifier, $this->source_identifier, 0, 0, 0, $this->source_height - 1, $this->source_width, $this->source_height, $this->source_width, -$this->source_height
1301
1302
                    );
1303
1304
                    break;
1305
1306 View Code Duplication
                case 'both':
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1307
1308
                    imagecopyresampled(
1309
1310
                        $target_identifier, $this->source_identifier, 0, 0, $this->source_width - 1, $this->source_height - 1, $this->source_width, $this->source_height, -$this->source_width, -$this->source_height
1311
1312
                    );
1313
1314
                    break;
1315
1316
            }
1317
1318
            // write image
1319
            return $this->_write_image($target_identifier);
1320
        }
1321
1322
        // if script gets this far, return false
1323
        // note that we do not set the error level as it has been already set
1324
        // by the _create_from_source() method earlier
1325
        return false;
1326
    }
1327
1328
    /**
1329
     *  Creates a blank image of given width, height and background color.
1330
     *
1331
     * @param integer $width            Width of the new image.
1332
     *
1333
     * @param integer $height           Height of the new image.
1334
     *
1335
     * @param string  $background_color (Optional) The hexadecimal color of the background.
1336
     *
1337
     *                                          Can also be -1 case in which the script will try to create a transparent
1338
     *                                          image, if possible.
1339
     *
1340
     *                                          Default is "#FFFFFF".
1341
     *
1342
     * @return Returns the identifier of the newly created image.
0 ignored issues
show
Documentation introduced by
Should the return type not be resource?

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...
1343
     *
1344
     * @access private
1345
     */
1346
    public function _prepare_image($width, $height, $background_color = '#FFFFFF')
1347
    {
1348
1349
        // create a blank image
1350
        $identifier = imagecreatetruecolor((int)$width <= 0 ? 1 : (int)$width, (int)$height <= 0 ? 1 : (int)$height);
1351
1352
        // if we are creating a PNG image
1353
        if ($this->target_type === 'png' && $background_color == -1) {
1354
1355
            // disable blending
1356
            imagealphablending($identifier, false);
1357
1358
            // allocate a transparent color
1359
            $transparent_color = imagecolorallocatealpha($identifier, 0, 0, 0, 127);
1360
1361
            // fill the image with the transparent color
1362
            imagefill($identifier, 0, 0, $transparent_color);
1363
1364
            //save full alpha channel information
1365
            imagesavealpha($identifier, true);
1366
1367
            // if source image is a transparent GIF
1368
        } elseif ($this->target_type === 'gif' && $background_color == -1 && $this->source_transparent_color_index >= 0) {
1369
1370
            // allocate the source image's transparent color also to the new image resource
1371
            $transparent_color = imagefilledarc($identifier, $this->source_transparent_color['red'], $this->source_transparent_color['green'], $this->source_transparent_color['blue']);
0 ignored issues
show
Bug introduced by
The property source_transparent_color does not seem to exist. Did you mean source_transparent_color_index?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1372
1373
            // fill the background of the new image with transparent color
1374
            imagefill($identifier, 0, 0, $transparent_color);
1375
1376
            // from now on, every pixel having the same RGB as the transparent color will be transparent
1377
            imagecolortransparent($identifier, $transparent_color);
1378
1379
            // for other image types
1380
        } else {
1381
1382
            // if transparent background color specified, revert to white
1383
            if ($background_color == -1) {
1384
                $background_color = '#FFFFFF';
1385
            }
1386
1387
            // convert hex color to rgb
1388
            $background_color = $this->_hex2rgb($background_color);
1389
1390
            // prepare the background color
1391
            $background_color = imagefilledarc($identifier, $background_color['r'], $background_color['g'], $background_color['b']);
1392
1393
            // fill the image with the background color
1394
            imagefill($identifier, 0, 0, $background_color);
1395
        }
1396
1397
        // return the image's identifier
1398
        return $identifier;
1399
    }
1400
1401
    /**
1402
     *  Sharpens images. Useful when creating thumbnails.
1403
     *
1404
     *  Code taken from the comments at {@link http://docs.php.net/imageconvolution}.
1405
     *
1406
     *  <i>This function will yield a result only for PHP version 5.1.0+ and will leave the image unaltered for older
1407
     *  versions!</i>
1408
     *
1409
     * @param $image
1410
     *
1411
     * @return
1412
     * @internal param \identifier $identifier An image identifier
1413
     *
1414
     * @access   private
1415
     */
1416
    public function _sharpen_image($image)
1417
    {
1418
1419
        // if the "sharpen_images" is set to true and we're running an appropriate version of PHP
1420
        // (the "imageconvolution" is available only for PHP 5.1.0+)
1421
        if ($this->sharpen_images && version_compare(PHP_VERSION, '5.1.0') >= 0) {
1422
1423
            // the convolution matrix as an array of three arrays of three floats
1424
            $matrix = array(
1425
                array(-1.2, -1, -1.2),
1426
                array(-1, 20, -1),
1427
                array(-1.2, -1, -1.2),
1428
            );
1429
1430
            // the divisor of the matrix
1431
            $divisor = array_sum(array_map('array_sum', $matrix));
1432
1433
            // color offset
1434
            $offset = 0;
1435
1436
            // sharpen image
1437
            imageconvolution($image, $matrix, $divisor, $offset);
1438
        }
1439
1440
        // return the image's identifier
1441
        return $image;
1442
    }
1443
1444
    /**
1445
     *  Creates a new image from given image identifier having the extension as specified by {@link target_path}.
1446
     *
1447
     * @param  $identifier identifier  An image identifier
1448
     *
1449
     * @return boolean Returns TRUE on success or FALSE on error.
1450
     *
1451
     *                                  If FALSE is returned, check the {@link error} property to see the error code.
1452
     *
1453
     * @access private
1454
     */
1455
    public function _write_image($identifier)
1456
    {
1457
1458
        // sharpen image if it's required
1459
        $this->_sharpen_image($identifier);
1460
1461
        // image saving process goes according to required extension
1462
        switch ($this->target_type) {
1463
1464
            // if GIF
1465
            case 'gif':
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1466
1467
                // if GD support for this file type is not available
1468
                // in version 1.6 of GD the support for GIF files was dropped see
1469
                // http://php.net/manual/en/function.imagegif.php#function.imagegif.notes
1470
                if (!function_exists('imagegif')) {
1471
1472
                    // save the error level and stop the execution of the script
1473
                    $this->error = 6;
1474
1475
                    return false;
1476
1477
                    // if, for some reason, file could not be created
1478
                } elseif (@!imagegif($identifier, $this->target_path)) {
1479
1480
                    // save the error level and stop the execution of the script
1481
                    $this->error = 3;
1482
1483
                    return false;
1484
                }
1485
1486
                break;
1487
1488
            // if JPEG
1489
            case 'jpg':
1490 View Code Duplication
            case 'jpeg':
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1491
1492
                // if GD support for this file type is not available
1493
                if (!function_exists('imagejpeg')) {
1494
1495
                    // save the error level and stop the execution of the script
1496
                    $this->error = 6;
1497
1498
                    return false;
1499
1500
                    // if, for some reason, file could not be created
1501
                } elseif (@!imagejpeg($identifier, $this->target_path, $this->jpeg_quality)) {
1502
1503
                    // save the error level and stop the execution of the script
1504
                    $this->error = 3;
1505
1506
                    return false;
1507
                }
1508
1509
                break;
1510
1511
            // if PNG
1512 View Code Duplication
            case 'png':
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...
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1513
1514
                // save full alpha channel information
1515
                imagesavealpha($identifier, true);
1516
1517
                // if GD support for this file type is not available
1518
                if (!function_exists('imagepng')) {
1519
1520
                    // save the error level and stop the execution of the script
1521
                    $this->error = 6;
1522
1523
                    return false;
1524
1525
                    // if, for some reason, file could not be created
1526
                } elseif (@!imagepng($identifier, $this->target_path, $this->png_compression)) {
1527
1528
                    // save the error level and stop the execution of the script
1529
                    $this->error = 3;
1530
1531
                    return false;
1532
                }
1533
1534
                break;
1535
1536
            // if not a supported file extension
1537
            default:
0 ignored issues
show
Coding Style introduced by
The default body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a default statement must start on the line immediately following the statement.

switch ($expr) {
    default:
        doSomething(); //right
        break;
}


switch ($expr) {
    default:

        doSomething(); //wrong
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
1538
1539
                // save the error level and stop the execution of the script
1540
                $this->error = 5;
1541
1542
                return false;
1543
1544
        }
1545
1546
        // get a list of functions disabled via configuration
1547
        $disabled_functions = @ini_get('disable_functions');
1548
1549
        // if the 'chmod' function is not disabled via configuration
1550
        if ($disabled_functions == '' || strpos('chmod', $disabled_functions) === false) {
1551
1552
            // chmod the file
1553
            chmod($this->target_path, (int)$this->chmod_value, 8);
1554
1555
            // save the error level
1556
        } else {
1557
            $this->error = 8;
1558
        }
1559
1560
        // if target file has to have the same timestamp as the source image
1561
        if ($this->preserve_time && isset($this->source_image_time)) {
1562
1563
            // touch the newly created file
1564
            @touch($this->target_path, $this->source_image_time);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
1565
        }
1566
1567
        // return true
1568
        return true;
1569
    }
1570
}
1571