GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Manipulations   F
last analyzed

Complexity

Total Complexity 89

Size/Duplication

Total Lines 699
Duplicated Lines 16.88 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 89
lcom 1
cbo 3
dl 118
loc 699
rs 1.901
c 0
b 0
f 0

45 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 3
A orientation() 12 12 2
A flip() 12 12 2
A crop() 15 15 2
A focalCrop() 0 7 1
A manualCrop() 0 12 3
A width() 0 8 2
A height() 0 8 2
A fit() 15 15 2
A devicePixelRatio() 0 8 3
A brightness() 0 8 3
A gamma() 0 8 3
A contrast() 0 8 3
A sharpen() 0 8 3
A blur() 8 8 3
A pixelate() 0 8 3
A greyscale() 0 4 1
A sepia() 0 4 1
A background() 0 4 1
A border() 0 16 3
A quality() 8 8 3
A format() 12 12 2
A filter() 12 12 2
A watermark() 0 10 2
A watermarkWidth() 0 6 2
A watermarkHeight() 0 6 2
A watermarkFit() 12 12 2
A watermarkPadding() 0 12 3
A watermarkPosition() 12 12 2
A watermarkOpacity() 0 8 3
A optimize() 0 4 1
A apply() 0 6 1
A create() 0 4 1
A toArray() 0 4 1
A hasMultipleConversions() 0 10 4
A removeManipulation() 0 4 1
A hasManipulation() 0 4 1
A getManipulationArgument() 0 8 3
A addManipulation() 0 6 1
A mergeManipulations() 0 6 1
A getManipulationSequence() 0 4 1
A validateManipulation() 0 4 1
A getValidManipulationOptions() 0 8 1
A isEmpty() 0 4 1
A getFirstManipulationArgument() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

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

Common duplication problems, and corresponding solutions are:

Complex Class

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

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

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

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

1
<?php
2
3
namespace Spatie\Image;
4
5
use League\Flysystem\FileNotFoundException;
6
use ReflectionClass;
7
use Spatie\Image\Exceptions\InvalidManipulation;
8
9
class Manipulations
10
{
11
    const CROP_TOP_LEFT = 'crop-top-left';
12
    const CROP_TOP = 'crop-top';
13
    const CROP_TOP_RIGHT = 'crop-top-right';
14
    const CROP_LEFT = 'crop-left';
15
    const CROP_CENTER = 'crop-center';
16
    const CROP_RIGHT = 'crop-right';
17
    const CROP_BOTTOM_LEFT = 'crop-bottom-left';
18
    const CROP_BOTTOM = 'crop-bottom';
19
    const CROP_BOTTOM_RIGHT = 'crop-bottom-right';
20
21
    const ORIENTATION_AUTO = 'auto';
22
    const ORIENTATION_90 = 90;
23
    const ORIENTATION_180 = 180;
24
    const ORIENTATION_270 = 270;
25
26
    const FLIP_HORIZONTALLY = 'h';
27
    const FLIP_VERTICALLY = 'v';
28
    const FLIP_BOTH = 'both';
29
30
    const FIT_CONTAIN = 'contain';
31
    const FIT_MAX = 'max';
32
    const FIT_FILL = 'fill';
33
    const FIT_STRETCH = 'stretch';
34
    const FIT_CROP = 'crop';
35
36
    const BORDER_OVERLAY = 'overlay';
37
    const BORDER_SHRINK = 'shrink';
38
    const BORDER_EXPAND = 'expand';
39
40
    const FORMAT_JPG = 'jpg';
41
    const FORMAT_PJPG = 'pjpg';
42
    const FORMAT_PNG = 'png';
43
    const FORMAT_GIF = 'gif';
44
    const FORMAT_WEBP = 'webp';
45
46
    const FILTER_GREYSCALE = 'greyscale';
47
    const FILTER_SEPIA = 'sepia';
48
49
    const UNIT_PIXELS = 'px';
50
    const UNIT_PERCENT = '%';
51
52
    const POSITION_TOP_LEFT = 'top-left';
53
    const POSITION_TOP = 'top';
54
    const POSITION_TOP_RIGHT = 'top-right';
55
    const POSITION_LEFT = 'left';
56
    const POSITION_CENTER = 'center';
57
    const POSITION_RIGHT = 'right';
58
    const POSITION_BOTTOM_LEFT = 'bottom-left';
59
    const POSITION_BOTTOM = 'bottom';
60
    const POSITION_BOTTOM_RIGHT = 'bottom-right';
61
62
    /** @var \Spatie\Image\ManipulationSequence */
63
    protected $manipulationSequence;
64
65
    public function __construct(array $manipulations = [])
66
    {
67
        if (! $this->hasMultipleConversions($manipulations)) {
68
            $manipulations = [$manipulations];
69
        }
70
71
        foreach ($manipulations as $manipulation) {
72
            $this->manipulationSequence = new ManipulationSequence($manipulation);
73
        }
74
    }
75
76
    /**
77
     * @param string $orientation
78
     *
79
     * @return $this
80
     *
81
     * @throws InvalidManipulation
82
     */
83 View Code Duplication
    public function orientation(string $orientation)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
84
    {
85
        if (! $this->validateManipulation($orientation, 'orientation')) {
86
            throw InvalidManipulation::invalidParameter(
87
                'orientation',
88
                $orientation,
89
                $this->getValidManipulationOptions('orientation')
90
            );
91
        }
92
93
        return $this->addManipulation('orientation', $orientation);
94
    }
95
96
    /**
97
     * @param string $orientation
98
     *
99
     * @return $this
100
     *
101
     * @throws InvalidManipulation
102
     */
103 View Code Duplication
    public function flip(string $orientation)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
104
    {
105
        if (! $this->validateManipulation($orientation, 'flip')) {
106
            throw InvalidManipulation::invalidParameter(
107
                'flip',
108
                $orientation,
109
                $this->getValidManipulationOptions('flip')
110
            );
111
        }
112
113
        return $this->addManipulation('flip', $orientation);
114
    }
115
116
    /**
117
     * @param string $cropMethod
118
     * @param int $width
119
     * @param int $height
120
     *
121
     * @return $this
122
     *
123
     * @throws InvalidManipulation
124
     */
125 View Code Duplication
    public function crop(string $cropMethod, int $width, int $height)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
126
    {
127
        if (! $this->validateManipulation($cropMethod, 'crop')) {
128
            throw InvalidManipulation::invalidParameter(
129
                'cropmethod',
130
                $cropMethod,
131
                $this->getValidManipulationOptions('crop')
132
            );
133
        }
134
135
        $this->width($width);
136
        $this->height($height);
137
138
        return $this->addManipulation('crop', $cropMethod);
139
    }
140
141
    /**
142
     * @param int $width
143
     * @param int $height
144
     * @param int $focalX Crop center X in percent
145
     * @param int $focalY Crop center Y in percent
146
     *
147
     * @return $this
148
     */
149
    public function focalCrop(int $width, int $height, int $focalX, int $focalY)
150
    {
151
        $this->width($width);
152
        $this->height($height);
153
154
        return $this->addManipulation('crop', "crop-{$focalX}-{$focalY}");
155
    }
156
157
    /**
158
     * @param int $width
159
     * @param int $height
160
     * @param int $x
161
     * @param int $y
162
     *
163
     * @return $this
164
     *
165
     * @throws InvalidManipulation
166
     */
167
    public function manualCrop(int $width, int $height, int $x, int $y)
168
    {
169
        if ($width < 0) {
170
            throw InvalidManipulation::invalidWidth($width);
171
        }
172
173
        if ($height < 0) {
174
            throw InvalidManipulation::invalidWidth($height);
175
        }
176
177
        return $this->addManipulation('manualCrop', "{$width},{$height},{$x},{$y}");
178
    }
179
180
    /**
181
     * @param int $width
182
     *
183
     * @return $this
184
     *
185
     * @throws InvalidManipulation
186
     */
187
    public function width(int $width)
188
    {
189
        if ($width < 0) {
190
            throw InvalidManipulation::invalidWidth($width);
191
        }
192
193
        return $this->addManipulation('width', $width);
194
    }
195
196
    /**
197
     * @param int $height
198
     *
199
     * @return $this
200
     *
201
     * @throws InvalidManipulation
202
     */
203
    public function height(int $height)
204
    {
205
        if ($height < 0) {
206
            throw InvalidManipulation::invalidHeight($height);
207
        }
208
209
        return $this->addManipulation('height', $height);
210
    }
211
212
    /**
213
     * @param string $fitMethod
214
     * @param int $width
215
     * @param int $height
216
     *
217
     * @return $this
218
     *
219
     * @throws InvalidManipulation
220
     */
221 View Code Duplication
    public function fit(string $fitMethod, int $width, int $height)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
222
    {
223
        if (! $this->validateManipulation($fitMethod, 'fit')) {
224
            throw InvalidManipulation::invalidParameter(
225
                'fit',
226
                $fitMethod,
227
                $this->getValidManipulationOptions('fit')
228
            );
229
        }
230
231
        $this->width($width);
232
        $this->height($height);
233
234
        return $this->addManipulation('fit', $fitMethod);
235
    }
236
237
    /**
238
     * @param int $ratio A value between 1 and 8
239
     *
240
     * @return $this
241
     *
242
     * @throws InvalidManipulation
243
     */
244
    public function devicePixelRatio(int $ratio)
245
    {
246
        if ($ratio < 1 || $ratio > 8) {
247
            throw InvalidManipulation::valueNotInRange('ratio', $ratio, 1, 8);
248
        }
249
250
        return $this->addManipulation('devicePixelRatio', $ratio);
251
    }
252
253
    /**
254
     * @param int $brightness A value between -100 and 100
255
     *
256
     * @return $this
257
     *
258
     * @throws InvalidManipulation
259
     */
260
    public function brightness(int $brightness)
261
    {
262
        if ($brightness < -100 || $brightness > 100) {
263
            throw InvalidManipulation::valueNotInRange('brightness', $brightness, -100, 100);
264
        }
265
266
        return $this->addManipulation('brightness', $brightness);
267
    }
268
269
    /**
270
     * @param float $gamma A value between 0.01 and 9.99
271
     *
272
     * @return $this
273
     *
274
     * @throws InvalidManipulation
275
     */
276
    public function gamma(float $gamma)
277
    {
278
        if ($gamma < 0.01 || $gamma > 9.99) {
279
            throw InvalidManipulation::valueNotInRange('gamma', $gamma, 0.01, 9.00);
280
        }
281
282
        return $this->addManipulation('gamma', $gamma);
283
    }
284
285
    /**
286
     * @param int $contrast A value between -100 and 100
287
     *
288
     * @return $this
289
     *
290
     * @throws InvalidManipulation
291
     */
292
    public function contrast(int $contrast)
293
    {
294
        if ($contrast < -100 || $contrast > 100) {
295
            throw InvalidManipulation::valueNotInRange('contrast', $contrast, -100, 100);
296
        }
297
298
        return $this->addManipulation('contrast', $contrast);
299
    }
300
301
    /**
302
     * @param int $sharpen A value between 0 and 100
303
     *
304
     * @return $this
305
     *
306
     * @throws InvalidManipulation
307
     */
308
    public function sharpen(int $sharpen)
309
    {
310
        if ($sharpen < 0 || $sharpen > 100) {
311
            throw InvalidManipulation::valueNotInRange('sharpen', $sharpen, 0, 100);
312
        }
313
314
        return $this->addManipulation('sharpen', $sharpen);
315
    }
316
317
    /**
318
     * @param int $blur A value between 0 and 100
319
     *
320
     * @return $this
321
     *
322
     * @throws InvalidManipulation
323
     */
324 View Code Duplication
    public function blur(int $blur)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
325
    {
326
        if ($blur < 0 || $blur > 100) {
327
            throw InvalidManipulation::valueNotInRange('blur', $blur, 0, 100);
328
        }
329
330
        return $this->addManipulation('blur', $blur);
331
    }
332
333
    /**
334
     * @param int $pixelate A value between 0 and 1000
335
     *
336
     * @return $this
337
     *
338
     * @throws InvalidManipulation
339
     */
340
    public function pixelate(int $pixelate)
341
    {
342
        if ($pixelate < 0 || $pixelate > 1000) {
343
            throw InvalidManipulation::valueNotInRange('pixelate', $pixelate, 0, 1000);
344
        }
345
346
        return $this->addManipulation('pixelate', $pixelate);
347
    }
348
349
    /**
350
     * @return $this
351
     */
352
    public function greyscale()
353
    {
354
        return $this->filter('greyscale');
355
    }
356
357
    /**
358
     * @return $this
359
     */
360
    public function sepia()
361
    {
362
        return $this->filter('sepia');
363
    }
364
365
    /**
366
     * @param string $colorName
367
     *
368
     * @return $this
369
     */
370
    public function background(string $colorName)
371
    {
372
        return $this->addManipulation('background', $colorName);
373
    }
374
375
    /**
376
     * @param int $width
377
     * @param string $color
378
     * @param string $borderType
379
     *
380
     * @return $this
381
     *
382
     * @throws InvalidManipulation
383
     */
384
    public function border(int $width, string $color, string $borderType = 'overlay')
385
    {
386
        if ($width < 0) {
387
            throw InvalidManipulation::invalidWidth($width);
388
        }
389
390
        if (! $this->validateManipulation($borderType, 'border')) {
391
            throw InvalidManipulation::invalidParameter(
392
                'border',
393
                $borderType,
394
                $this->getValidManipulationOptions('border')
395
            );
396
        }
397
398
        return $this->addManipulation('border', "{$width},{$color},{$borderType}");
399
    }
400
401
    /**
402
     * @param int $quality
403
     *
404
     * @return $this
405
     *
406
     * @throws InvalidManipulation
407
     */
408 View Code Duplication
    public function quality(int $quality)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
409
    {
410
        if ($quality < 0 || $quality > 100) {
411
            throw InvalidManipulation::valueNotInRange('quality', $quality, 0, 100);
412
        }
413
414
        return $this->addManipulation('quality', $quality);
415
    }
416
417
    /**
418
     * @param string $format
419
     *
420
     * @return $this
421
     *
422
     * @throws InvalidManipulation
423
     */
424 View Code Duplication
    public function format(string $format)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
425
    {
426
        if (! $this->validateManipulation($format, 'format')) {
427
            throw InvalidManipulation::invalidParameter(
428
                'format',
429
                $format,
430
                $this->getValidManipulationOptions('format')
431
            );
432
        }
433
434
        return $this->addManipulation('format', $format);
435
    }
436
437
    /**
438
     * @param string $filterName
439
     *
440
     * @return $this
441
     *
442
     * @throws InvalidManipulation
443
     */
444 View Code Duplication
    protected function filter(string $filterName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
445
    {
446
        if (! $this->validateManipulation($filterName, 'filter')) {
447
            throw InvalidManipulation::invalidParameter(
448
                'filter',
449
                $filterName,
450
                $this->getValidManipulationOptions('filter')
451
            );
452
        }
453
454
        return $this->addManipulation('filter', $filterName);
455
    }
456
457
    /**
458
     * @param string $filePath
459
     *
460
     * @return $this
461
     *
462
     * @throws FileNotFoundException
463
     */
464
    public function watermark(string $filePath)
465
    {
466
        if (! file_exists($filePath)) {
467
            throw new FileNotFoundException($filePath);
468
        }
469
470
        $this->addManipulation('watermark', $filePath);
471
472
        return $this;
473
    }
474
475
    /**
476
     * @param int    $width The width of the watermark in pixels (default) or percent.
477
     * @param string $unit  The unit of the `$width` parameter. Use `Manipulations::UNIT_PERCENT` or `Manipulations::UNIT_PIXELS`.
478
     *
479
     * @return $this
480
     */
481
    public function watermarkWidth(int $width, string $unit = 'px')
482
    {
483
        $width = ($unit == static::UNIT_PERCENT ? $width.'w' : $width);
484
485
        return $this->addManipulation('watermarkWidth', $width);
486
    }
487
488
    /**
489
     * @param int    $height The height of the watermark in pixels (default) or percent.
490
     * @param string $unit   The unit of the `$height` parameter. Use `Manipulations::UNIT_PERCENT` or `Manipulations::UNIT_PIXELS`.
491
     *
492
     * @return $this
493
     */
494
    public function watermarkHeight(int $height, string $unit = 'px')
495
    {
496
        $height = ($unit == static::UNIT_PERCENT ? $height.'h' : $height);
497
498
        return $this->addManipulation('watermarkHeight', $height);
499
    }
500
501
    /**
502
     * @param string $fitMethod How is the watermark fitted into the watermarkWidth and watermarkHeight properties.
503
     *
504
     * @return $this
505
     *
506
     * @throws InvalidManipulation
507
     */
508 View Code Duplication
    public function watermarkFit(string $fitMethod)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
509
    {
510
        if (! $this->validateManipulation($fitMethod, 'fit')) {
511
            throw InvalidManipulation::invalidParameter(
512
                'watermarkFit',
513
                $fitMethod,
514
                $this->getValidManipulationOptions('fit')
515
            );
516
        }
517
518
        return $this->addManipulation('watermarkFit', $fitMethod);
519
    }
520
521
    /**
522
     * @param int $xPadding         How far is the watermark placed from the left and right edges of the image.
523
     * @param int|null $yPadding    How far is the watermark placed from the top and bottom edges of the image.
524
     * @param string $unit          Unit of the padding values. Use `Manipulations::UNIT_PERCENT` or `Manipulations::UNIT_PIXELS`.
525
     *
526
     * @return $this
527
     */
528
    public function watermarkPadding(int $xPadding, int $yPadding = null, string $unit = 'px')
529
    {
530
        $yPadding = $yPadding ?? $xPadding;
531
532
        $xPadding = ($unit == static::UNIT_PERCENT ? $xPadding.'w' : $xPadding);
533
        $yPadding = ($unit == static::UNIT_PERCENT ? $yPadding.'h' : $yPadding);
534
535
        $this->addManipulation('watermarkPaddingX', $xPadding);
536
        $this->addManipulation('watermarkPaddingY', $yPadding);
537
538
        return $this;
539
    }
540
541
    /**
542
     * @param string $position
543
     *
544
     * @return $this
545
     *
546
     * @throws InvalidManipulation
547
     */
548 View Code Duplication
    public function watermarkPosition(string $position)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
549
    {
550
        if (! $this->validateManipulation($position, 'position')) {
551
            throw InvalidManipulation::invalidParameter(
552
                'watermarkPosition',
553
                $position,
554
                $this->getValidManipulationOptions('position')
555
            );
556
        }
557
558
        return $this->addManipulation('watermarkPosition', $position);
559
    }
560
561
    /**
562
     * Sets the opacity of the watermark. Only works with the `imagick` driver.
563
     *
564
     * @param int $opacity A value between 0 and 100.
565
     *
566
     * @return $this
567
     *
568
     * @throws InvalidManipulation
569
     */
570
    public function watermarkOpacity(int $opacity)
571
    {
572
        if ($opacity < 0 || $opacity > 100) {
573
            throw InvalidManipulation::valueNotInRange('opacity', $opacity, 0, 100);
574
        }
575
576
        return $this->addManipulation('watermarkOpacity', $opacity);
577
    }
578
579
    /**
580
     * Shave off some kilobytes by optimizing the image.
581
     *
582
     * @param array $optimizationOptions
583
     *
584
     * @return $this
585
     */
586
    public function optimize(array $optimizationOptions = [])
587
    {
588
        return $this->addManipulation('optimize', json_encode($optimizationOptions));
589
    }
590
591
    /**
592
     * @return $this
593
     */
594
    public function apply()
595
    {
596
        $this->manipulationSequence->startNewGroup();
597
598
        return $this;
599
    }
600
601
    /**
602
     * Create new manipulations class.
603
     *
604
     * @param array $manipulations
605
     *
606
     * @return self
607
     */
608
    public static function create(array $manipulations = [])
609
    {
610
        return new self($manipulations);
611
    }
612
613
    public function toArray(): array
614
    {
615
        return $this->manipulationSequence->toArray();
616
    }
617
618
    /**
619
     * Checks if the given manipulations has arrays inside or not.
620
     *
621
     * @param  array $manipulations
622
     *
623
     * @return bool
624
     */
625
    private function hasMultipleConversions(array $manipulations): bool
626
    {
627
        foreach ($manipulations as $manipulation) {
628
            if (isset($manipulation[0]) && is_array($manipulation[0])) {
629
                return true;
630
            }
631
        }
632
633
        return false;
634
    }
635
636
    public function removeManipulation(string $name)
637
    {
638
        $this->manipulationSequence->removeManipulation($name);
639
    }
640
641
    public function hasManipulation(string $manipulationName): bool
642
    {
643
        return ! is_null($this->getManipulationArgument($manipulationName));
644
    }
645
646
    /**
647
     * @param string $manipulationName
648
     *
649
     * @return string|null
650
     */
651
    public function getManipulationArgument(string $manipulationName)
652
    {
653
        foreach ($this->manipulationSequence->getGroups() as $manipulationSet) {
654
            if (array_key_exists($manipulationName, $manipulationSet)) {
655
                return $manipulationSet[$manipulationName];
656
            }
657
        }
658
    }
659
660
    protected function addManipulation(string $manipulationName, string $manipulationArgument)
661
    {
662
        $this->manipulationSequence->addManipulation($manipulationName, $manipulationArgument);
663
664
        return $this;
665
    }
666
667
    public function mergeManipulations(self $manipulations)
668
    {
669
        $this->manipulationSequence->merge($manipulations->manipulationSequence);
670
671
        return $this;
672
    }
673
674
    public function getManipulationSequence(): ManipulationSequence
675
    {
676
        return $this->manipulationSequence;
677
    }
678
679
    protected function validateManipulation(string $value, string $constantNamePrefix): bool
680
    {
681
        return in_array($value, $this->getValidManipulationOptions($constantNamePrefix));
682
    }
683
684
    protected function getValidManipulationOptions(string $manipulation): array
685
    {
686
        $options = (new ReflectionClass(static::class))->getConstants();
687
688
        return array_filter($options, function ($value, $name) use ($manipulation) {
689
            return strpos($name, mb_strtoupper($manipulation)) === 0;
690
        }, ARRAY_FILTER_USE_BOTH);
691
    }
692
693
    public function isEmpty(): bool
694
    {
695
        return $this->manipulationSequence->isEmpty();
696
    }
697
698
    /*
699
     * Get the first manipultion with the given name.
700
     *
701
     * @return mixed
702
     */
703
    public function getFirstManipulationArgument(string $manipulationName)
704
    {
705
        return $this->manipulationSequence->getFirstManipulationArgument($manipulationName);
706
    }
707
}
708