ImageCommand   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 88.89%

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 6
dl 0
loc 126
ccs 56
cts 63
cp 0.8889
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A setReturnType() 0 4 1
A getToken() 0 4 1
B execute() 0 40 6
A filterIntOrNullArgument() 0 9 2
A parseDimension() 0 16 4
B returnImage() 0 25 6
1
<?php declare(strict_types=1);
2
3
namespace Bigwhoop\Trumpet\Commands;
4
5
use Intervention\Image\Constraint;
6
use Intervention\Image\Image;
7
use Intervention\Image\ImageManager;
8
9
class ImageCommand implements Command
10
{
11
    const RETURN_TYPE_URL      = 'url';
12
    const RETURN_TYPE_PATH     = 'path';
13
    const RETURN_TYPE_DATA_URL = 'data-url';
14
    const RETURN_TYPE_DATA     = 'data';
15
16
    /** @var ImageManager */
17
    private $imageManager;
18
19
    /** @var CommandExecutionContext */
20
    private $executionContext;
21
22
    /** @var string */
23
    private $returnType = self::RETURN_TYPE_URL;
24
25 1
    public function __construct(ImageManager $manager, CommandExecutionContext $context)
26
    {
27 1
        $this->imageManager     = $manager;
28 1
        $this->executionContext = $context;
29 1
    }
30
    
31 5
    public function setReturnType(string $type)
32
    {
33 5
        $this->returnType = $type;
34 5
    }
35
36 2
    public function getToken(): string
37
    {
38 2
        return 'image';
39
    }
40
    
41 5
    public function execute(CommandParams $params, CommandExecutionContext $executionContext): string
42
    {
43 5
        $fileName = $params->getFirstArgument();
44
45 5
        if (!$executionContext->hasFileInWorkingDirectory($fileName)) {
46
            throw new ExecutionFailedException("File '$fileName' does not exist.");
47
        }
48
49 5
        $img = $this->imageManager->make($executionContext->getPathOfFileInWorkingDirectory($fileName));
50
51 5
        if (!$params->hasSecondArgument()) {
52 1
            return $this->returnImage($img, $params);
53
        }
54
55 4
        list($width, $height) = $this->parseDimension($params->getSecondArgument());
56
57 4
        switch ($params->getThirdArgument()) {
58 4
            case 'stretch':
59 1
                $img->resize($width, $height);
60 1
                break;
61
62 3
            case 'fit':
63 1
                $img->fit($width, $height);
64 1
                break;
65
66 2
            case 'crop':
67 1
                $x = $this->filterIntOrNullArgument($params->getArgument(3));
68 1
                $y = $this->filterIntOrNullArgument($params->getArgument(4));
69 1
                $img->crop($width, $height, $x, $y);
70 1
                break;
71
72
            default:
73 1
                $img->resize($width, $height, function (Constraint $constraint) {
74 1
                    $constraint->aspectRatio();
75 1
                });
76 1
                break;
77
        }
78
79 4
        return $this->returnImage($img, $params);
80
    }
81
82 4
    private function filterIntOrNullArgument(string $value): ?int
83
    {
84 4
        $int = (int) $value;
85 4
        if ($int < 1) {
86
            $int = null;
87
        }
88
89 4
        return $int;
90
    }
91
    
92 4
    private function parseDimension(string $dimension): array
93
    {
94 4
        $matches = [];
95 4
        if (!preg_match('#(\d+)x(\d+)#', $dimension, $matches)) {
96
            throw new ExecutionFailedException("Dimension argument be in format WIDTHxHEIGHT. For example 100x50, 0x50 or 100x0, but not 0x0.");
97
        }
98
99 4
        $width  = $this->filterIntOrNullArgument($matches[1]);
100 4
        $height = $this->filterIntOrNullArgument($matches[2]);
101
102 4
        if ($width === null && $height === null) {
103
            throw new ExecutionFailedException("Either the width or the height must be greater than zero.");
104
        }
105
106 4
        return [$width, $height];
107
    }
108
    
109 5
    private function returnImage(Image $img, CommandParams $params): string
110
    {
111 5
        switch ($this->returnType) {
112 5
            case self::RETURN_TYPE_URL:
113 5
                case self::RETURN_TYPE_PATH:
114 5
                $tmpDir = $this->executionContext->ensureTempDirectory();
115 5
                $tmpFile = $tmpDir.'/'.md5(join("\n", $params->getArguments())).'.png';
116 5
                $img->encode('png')->save($tmpFile);
117
118 5
                if ($this->returnType === self::RETURN_TYPE_PATH) {
119 5
                    return $tmpFile;
120
                }
121
122
                return '<img src="/_tmp/'.basename($tmpFile).'">';
123
124 5
            case self::RETURN_TYPE_DATA_URL:
125
                return '![Image]('.$img->encode('data-url')->getEncoded().')';
126
127 5
            case self::RETURN_TYPE_DATA:
128 5
                return $img->encode('png')->getEncoded();
129
130
            default:
131
                throw new ExecutionFailedException("Invalid return type '{$this->returnType}' detected.");
132
        }
133
    }
134
}
135