WatermarkFactory   A
last analyzed

Complexity

Total Complexity 25

Size/Duplication

Total Lines 257
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 77
dl 0
loc 257
rs 10
c 1
b 0
f 0
wmc 25

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getPath() 0 13 2
A openUrl() 0 5 1
A right() 0 6 1
A get() 0 19 4
A bottom() 0 6 1
A horizontalAlignment() 0 15 4
A open() 0 5 1
A top() 0 6 1
A left() 0 6 1
A image() 0 7 2
A fromDisk() 0 5 1
A verticalAlignment() 0 15 4
A __construct() 0 3 1
A __call() 0 5 1
1
<?php
2
3
namespace ProtoneMedia\LaravelFFMpeg\Filters;
4
5
use Illuminate\Support\Traits\ForwardsCalls;
6
use ProtoneMedia\LaravelFFMpeg\Filesystem\Disk;
7
use ProtoneMedia\LaravelFFMpeg\Filesystem\Media;
8
use ProtoneMedia\LaravelFFMpeg\Filesystem\MediaOnNetwork;
9
use Spatie\Image\Image;
10
11
/**
12
 * Partly based on this PR:
13
 * https://github.com/PHP-FFMpeg/PHP-FFMpeg/pull/754/files
14
 */
15
class WatermarkFactory
16
{
17
    use ForwardsCalls;
18
19
    /** position constants */
20
    const LEFT   = 'left';
21
    const RIGHT  = 'right';
22
    const CENTER = 'center';
23
    const TOP    = 'top';
24
    const BOTTOM = 'bottom';
25
26
    /**
27
     * @var \ProtoneMedia\LaravelFFMpeg\Filesystem\Disk
28
     */
29
    private $disk;
30
31
    /**
32
     * @var \ProtoneMedia\LaravelFFMpeg\Filesystem\Media
33
     */
34
    private $media;
35
36
    /**
37
     * Offset values.
38
     */
39
    private $top;
40
    private $right;
41
    private $bottom;
42
    private $left;
43
44
    /**
45
     * @var \Spatie\Image\Image
46
     */
47
    private $image;
48
49
    /**
50
     * Array with the horizontal (x) and verical (y) alignment.
51
     *
52
     * @var array
53
     */
54
    private $alignments = [];
55
56
    /**
57
     * Uses the 'filesystems.default' disk as default.
58
     */
59
    public function __construct()
60
    {
61
        $this->disk = Disk::make(config('filesystems.default'));
62
    }
63
64
    /**
65
     * Set the disk to open files from.
66
     */
67
    public function fromDisk($disk): self
68
    {
69
        $this->disk = Disk::make($disk);
70
71
        return $this;
72
    }
73
74
    /**
75
     * Instantiates a Media object for the given path.
76
     */
77
    public function open(string $path): self
78
    {
79
        $this->media = Media::make($this->disk, $path);
80
81
        return $this;
82
    }
83
84
    /**
85
     * Instantiates a MediaOnNetwork object for the given url and transforms
86
     * it into a Media object.
87
     *
88
     * @param string $path
89
     * @param array $headers
90
     * @param callable $withCurl
91
     * @return self
92
     */
93
    public function openUrl(string $path, array $headers = [], callable $withCurl = null): self
94
    {
95
        $this->media = MediaOnNetwork::make($path, $headers)->toMedia($withCurl);
96
97
        return $this;
98
    }
99
100
    /**
101
     * Sets the offset from to top.
102
     *
103
     * @param integer $offset
104
     * @return self
105
     */
106
    public function top($offset = 0): self
107
    {
108
        $this->top    = $offset;
109
        $this->bottom = null;
110
111
        return $this;
112
    }
113
114
    /**
115
     * Sets the offset from the right.
116
     *
117
     * @param integer $offset
118
     * @return self
119
     */
120
    public function right($offset = 0): self
121
    {
122
        $this->right = $offset;
123
        $this->left  = null;
124
125
        return $this;
126
    }
127
128
    /**
129
     * Sets the offset from the bottom.
130
     *
131
     * @param integer $offset
132
     * @return self
133
     */
134
    public function bottom($offset = 0): self
135
    {
136
        $this->bottom = $offset;
137
        $this->top    = null;
138
139
        return $this;
140
    }
141
142
    /**
143
     * Sets the offset from the left.
144
     *
145
     * @param integer $offset
146
     * @return self
147
     */
148
    public function left($offset = 0): self
149
    {
150
        $this->left  = $offset;
151
        $this->right = null;
152
153
        return $this;
154
    }
155
156
    /**
157
     * Setter for the horizontal alignment with an optional offset.
158
     *
159
     * @param string $alignment
160
     * @param integer $offset
161
     * @return self
162
     */
163
    public function horizontalAlignment(string $alignment, $offset = 0): self
164
    {
165
        switch ($alignment) {
166
            case self::LEFT:
167
                $this->alignments['x'] = $offset;
168
                break;
169
            case self::CENTER:
170
                $this->alignments['x'] = "(W-w)/2+{$offset}";
171
                break;
172
            case self::RIGHT:
173
                $this->alignments['x'] = "W-w+{$offset}";
174
                break;
175
        }
176
177
        return $this;
178
    }
179
180
    /**
181
     * Setter for the vertical alignment with an optional offset.
182
     *
183
     * @param string $alignment
184
     * @param integer $offset
185
     * @return self
186
     */
187
    public function verticalAlignment(string $alignment, $offset = 0): self
188
    {
189
        switch ($alignment) {
190
            case self::TOP:
191
                $this->alignments['y'] = $offset;
192
                break;
193
            case self::CENTER:
194
                $this->alignments['y'] = "(H-h)/2+{$offset}";
195
                break;
196
            case self::BOTTOM:
197
                $this->alignments['y'] = "H-h+{$offset}";
198
                break;
199
        }
200
201
        return $this;
202
    }
203
204
    /**
205
     * Returns the full path to the watermark file.
206
     *
207
     * @return string
208
     */
209
    public function getPath(): string
210
    {
211
        if (!$this->image) {
212
            return $this->media->getLocalPath();
213
        }
214
215
        $path = Disk::makeTemporaryDisk()
216
            ->makeMedia($this->media->getFilename())
217
            ->getLocalPath();
218
219
        $this->image->save($path);
220
221
        return $path;
222
    }
223
224
    /**
225
     * Returns a new instance of the WatermarkFilter.
226
     *
227
     * @return \FFMpeg\Filters\Video\WatermarkFilter
228
     */
229
    public function get(): WatermarkFilter
230
    {
231
        $path = $this->getPath();
232
233
        if (!empty($this->alignments)) {
234
            return new WatermarkFilter($path, $this->alignments);
235
        }
236
237
        $coordinates = ['position' => 'relative'];
238
239
        foreach (['top', 'right', 'bottom', 'left'] as $attribute) {
240
            if (is_null($this->$attribute)) {
241
                continue;
242
            }
243
244
            $coordinates[$attribute] = $this->$attribute;
245
        }
246
247
        return new WatermarkFilter($path, $coordinates);
248
    }
249
250
    /**
251
     * Returns an instance of Image.
252
     *
253
     * @return \Spatie\Image\Image
254
     */
255
    private function image(): Image
256
    {
257
        if (!$this->image) {
258
            $this->image = Image::load($this->media->getLocalPath());
259
        }
260
261
        return $this->image;
262
    }
263
264
    /**
265
     * Forwards calls to the Image manipulation class.
266
     */
267
    public function __call($method, $arguments)
268
    {
269
        $this->forwardCallTo($this->image(), $method, $arguments);
270
271
        return $this;
272
    }
273
}
274