Completed
Push — pac-96--override-images-option ( 781536 )
by Marcus
02:03
created

FileUploadTrait::shouldOverride()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * TechDivision\Import\Subjects\FileUploadTrait
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Subjects;
22
23
/**
24
 * The trait implementation for the file upload functionality.
25
 *
26
 * @author    Tim Wagner <[email protected]>
27
 * @copyright 2016 TechDivision GmbH <[email protected]>
28
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
29
 * @link      https://github.com/techdivision/import
30
 * @link      http://www.techdivision.com
31
 */
32
trait FileUploadTrait
33
{
34
35
    /**
36
     * The directory with the Magento media files => target directory for images (relative to the root directory).
37
     *
38
     * @var string
39
     */
40
    protected $mediaDir;
41
42
    /**
43
     * The directory with the images that have to be imported (relative to the root directory).
44
     *
45
     * @var string
46
     */
47
    protected $imagesFileDir;
48
49
    /**
50
     * Contains the mappings for the image names that has been uploaded (old => new image name).
51
     *
52
     * @var array
53
     */
54
    protected $imageMappings = array();
55
56
    /**
57
     * The flag whether to copy the images or not.
58
     *
59
     * @var boolean
60
     */
61
    protected $copyImages = false;
62
63
    /**
64
     * Whether or not to override images with the same name.
65
     *
66
     * @var bool
67
     */
68
    protected $overrideImages = false;
69
70
    /**
71
     * Sets whether or not to override images with the same name.
72
     *
73
     * @param $overrideImages
74
     *
75
     * @return void
76
     */
77
    public function setOverrideImages($overrideImages)
78
    {
79
        $this->overrideImages = $overrideImages;
80
    }
81
82
    /**
83
     * Returns whether or not we should override images with the same name.
84
     *
85
     * @return bool
86
     */
87
    public function shouldOverride()
88
    {
89
        return $this->overrideImages;
90
    }
91
92
    /**
93
     * Set's the flag to copy the images or not.
94
     *
95
     * @param boolean $copyImages The flag
96
     *
97
     * @return void
98
     */
99
    public function setCopyImages($copyImages)
100
    {
101
        $this->copyImages = $copyImages;
102
    }
103
104
    /**
105
     * Return's the flag to copy images or not.
106
     *
107
     * @return boolean The flag
108
     */
109
    public function hasCopyImages()
110
    {
111
        return $this->copyImages;
112
    }
113
114
    /**
115
     * Set's directory with the Magento media files => target directory for images.
116
     *
117
     * @param string $mediaDir The directory with the Magento media files => target directory for images
118
     *
119
     * @return void
120
     */
121
    public function setMediaDir($mediaDir)
122
    {
123
        $this->mediaDir = $mediaDir;
124
    }
125
126
    /**
127
     * Return's the directory with the Magento media files => target directory for images.
128
     *
129
     * @return string The directory with the Magento media files => target directory for images
130
     */
131
    public function getMediaDir()
132
    {
133
        return $this->mediaDir;
134
    }
135
136
    /**
137
     * Set's directory with the images that have to be imported.
138
     *
139
     * @param string $imagesFileDir The directory with the images that have to be imported
140
     *
141
     * @return void
142
     */
143
    public function setImagesFileDir($imagesFileDir)
144
    {
145
        $this->imagesFileDir = $imagesFileDir;
146
    }
147
148
    /**
149
     * Return's the directory with the images that have to be imported.
150
     *
151
     * @return string The directory with the images that have to be imported
152
     */
153
    public function getImagesFileDir()
154
    {
155
        return $this->imagesFileDir;
156
    }
157
158
    /**
159
     * Adds the mapping from the filename => new filename.
160
     *
161
     * @param string $filename    The filename
162
     * @param string $newFilename The new filename
163
     *
164
     * @return void
165
     */
166
    public function addImageMapping($filename, $newFilename)
167
    {
168
        $this->imageMappings[$filename] = $newFilename;
169
    }
170
171
    /**
172
     * Returns the mapped filename (which is the new filename).
173
     *
174
     * @param string $filename The filename to map
175
     *
176
     * @return string The mapped filename
177
     */
178
    public function getImageMapping($filename)
179
    {
180
181
        // query whether or not a mapping is available, if yes return the mapped name
182
        if (isset($this->imageMappings[$filename])) {
183
            return $this->imageMappings[$filename];
184
        }
185
186
        // return the passed filename otherwise
187
        return $filename;
188
    }
189
190
    /**
191
     * Returns TRUE, if the passed filename has already been mapped.
192
     *
193
     * @param string $filename The filename to query for
194
     *
195
     * @return boolean TRUE if the filename has already been mapped, else FALSE
196
     */
197
    public function imageHasBeenMapped($filename)
198
    {
199
        return isset($this->imageMappings[$filename]);
200
    }
201
202
    /**
203
     * Returns TRUE, if the passed filename has NOT been mapped yet.
204
     *
205
     * @param string $filename The filename to query for
206
     *
207
     * @return boolean TRUE if the filename has NOT been mapped yet, else FALSE
208
     */
209
    public function imageHasNotBeenMapped($filename)
210
    {
211
        return !isset($this->imageMappings[$filename]);
212
    }
213
214
    /**
215
     * Returns the original filename for passed one (which is the new filename).
216
     *
217
     * @param string $newFilename The new filename to return the original one for
218
     *
219
     * @return string The original filename
220
     */
221
    public function getInversedImageMapping($newFilename)
222
    {
223
224
        // try to load the original filename
225
        if ($filename = array_search($newFilename, $this->imageMappings)) {
226
            return $filename;
227
        }
228
229
        // return the new one otherwise
230
        return $newFilename;
231
    }
232
233
    /**
234
     * Get new file name, if a filename with the same name already exists.
235
     *
236
     * @param string $targetFilename The name of target file
237
     *
238
     * @return string The new filename
239
     */
240
    public function getNewFileName($targetFilename)
241
    {
242
243
        // load the file information
244
        $fileInfo = pathinfo($targetFilename);
245
246
        // query whether or not the file exists and if we should override it
247
        if ($this->getFilesystemAdapter()->isFile($targetFilename) && $this->shouldOverride() === false) {
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
248
            // initialize the index and the basename
249
            $index = 1;
250
            $baseName = $fileInfo['filename'] . '.' . $fileInfo['extension'];
251
252
            // prepare the new filename by raising the index
253
            while ($this->getFilesystemAdapter()->isFile($fileInfo['dirname'] . '/' . $baseName)) {
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
254
                $baseName = $fileInfo['filename'] . '_' . $index . '.' . $fileInfo['extension'];
255
                $index++;
256
            }
257
258
            // set the new filename
259
            $targetFilename = $baseName;
260
        } else {
261
            // if not, simply return the filename
262
            return $fileInfo['basename'];
263
        }
264
265
        // return the new filename
266
        return $targetFilename;
267
    }
268
269
    /**
270
     * Upload's the file with the passed name to the Magento
271
     * media directory. If the file already exists, the will
272
     * be given a new name that will be returned.
273
     *
274
     * @param string $filename The name of the file to be uploaded
275
     *
276
     * @return string The name of the uploaded file
277
     * @throws \Exception Is thrown, if the file with the passed name is not available
278
     */
279
    public function uploadFile($filename)
280
    {
281
282
        // trim the leading /, if available
283
        $trimmedFilename = ltrim($filename, '/');
284
        $mediaDir = ltrim($this->getMediaDir(), '/');
285
        $imagesFileDir = ltrim($this->getImagesFileDir(), '/');
286
287
        // prepare source/target filename
288
        $sourceFilename = sprintf('%s/%s', $imagesFileDir, $trimmedFilename);
289
        $targetFilename = sprintf('%s/%s', $mediaDir, $trimmedFilename);
290
291
        // query whether or not the image file to be imported is available
292
        if (!$this->getFilesystemAdapter()->isFile($sourceFilename)) {
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
293
            throw new \Exception(sprintf('Media file "%s" is not available', $sourceFilename));
294
        }
295
296
        // query whether or not, the file has already been processed
297
        if ($this->imageHasNotBeenMapped($filename)) {
298
            // load the new filename, e. g. if a file with the same name already exists
299
            $newTargetFilename =  $this->getNewFileName($targetFilename);
300
            // replace the old filename with the new one
301
            $targetFilename = str_replace(basename($targetFilename), $newTargetFilename, $targetFilename);
302
303
            // make sure, the target directory exists
304
            if (!$this->getFilesystemAdapter()->isDir($targetDirectory = dirname($targetFilename))) {
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
305
                $this->getFilesystemAdapter()->mkdir($targetDirectory, 0755);
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
306
            }
307
308
            // copy the image to the target directory
309
            $this->getFilesystemAdapter()->copy($sourceFilename, $targetFilename);
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
310
311
            // add the mapping and return the mapped filename
312
            $this->addImageMapping($filename, str_replace($mediaDir, '', $targetFilename));
313
        }
314
315
        // simply return the mapped filename
316
        return $this->getImageMapping($filename);
317
    }
318
319
    /**
320
     * Delete the file with the passed name.
321
     *
322
     * @param string $filename The name of the file to be deleted
323
     *
324
     * @return boolean TRUE on success, else FALSE
325
     */
326
    public function deleteFile($filename)
327
    {
328
329
        // trim the leading /, if available
330
        $trimmedFilename = ltrim($filename, '/');
331
        $mediaDir = ltrim($this->getMediaDir(), '/');
332
333
        // prepare source/target filename
334
        $targetFilename = sprintf('%s/%s', $mediaDir, $trimmedFilename);
335
336
        // query whether or not the image file to be deleted is available
337
        if (!$this->getFilesystemAdapter()->isFile($targetFilename)) {
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
338
            throw new \Exception(sprintf('Media file "%s" is not available', $targetFilename));
339
        }
340
341
        // delte the image from the target directory
342
        $this->getFilesystemAdapter()->delete($targetFilename);
0 ignored issues
show
Bug introduced by
It seems like getFilesystemAdapter() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
343
    }
344
}
345