Completed
Push — 12.x ( c2e9d6 )
by Tim
03:58
created

FileUploadTrait::imageHasNotBeenMapped()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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
     * Set's the flag to copy the images or not.
65
     *
66
     * @param boolean $copyImages The flag
67
     *
68
     * @return void
69
     */
70 1
    public function setCopyImages($copyImages)
71
    {
72 1
        $this->copyImages = $copyImages;
73 1
    }
74
75
    /**
76
     * Return's the flag to copy images or not.
77
     *
78
     * @return boolean The flag
79
     */
80 1
    public function hasCopyImages()
81
    {
82 1
        return $this->copyImages;
83
    }
84
85
    /**
86
     * Set's directory with the Magento media files => target directory for images.
87
     *
88
     * @param string $mediaDir The directory with the Magento media files => target directory for images
89
     *
90
     * @return void
91
     */
92 3
    public function setMediaDir($mediaDir)
93
    {
94 3
        $this->mediaDir = $mediaDir;
95 3
    }
96
97
    /**
98
     * Return's the directory with the Magento media files => target directory for images.
99
     *
100
     * @return string The directory with the Magento media files => target directory for images
101
     */
102 3
    public function getMediaDir()
103
    {
104 3
        return $this->mediaDir;
105
    }
106
107
    /**
108
     * Set's directory with the images that have to be imported.
109
     *
110
     * @param string $imagesFileDir The directory with the images that have to be imported
111
     *
112
     * @return void
113
     */
114 3
    public function setImagesFileDir($imagesFileDir)
115
    {
116 3
        $this->imagesFileDir = $imagesFileDir;
117 3
    }
118
119
    /**
120
     * Return's the directory with the images that have to be imported.
121
     *
122
     * @return string The directory with the images that have to be imported
123
     */
124 3
    public function getImagesFileDir()
125
    {
126 3
        return $this->imagesFileDir;
127
    }
128
129
    /**
130
     * Adds the mapping from the filename => new filename.
131
     *
132
     * @param string $filename    The filename
133
     * @param string $newFilename The new filename
134
     *
135
     * @return void
136
     */
137 1
    public function addImageMapping($filename, $newFilename)
138
    {
139 1
        $this->imageMappings[$filename] = $newFilename;
140 1
    }
141
142
    /**
143
     * Returns the mapped filename (which is the new filename).
144
     *
145
     * @param string $filename The filename to map
146
     *
147
     * @return string The mapped filename
148
     */
149 1
    public function getImageMapping($filename)
150
    {
151
152
        // query whether or not a mapping is available, if yes return the mapped name
153 1
        if (isset($this->imageMappings[$filename])) {
154 1
            return $this->imageMappings[$filename];
155
        }
156
157
        // return the passed filename otherwise
158
        return $filename;
159
    }
160
161
    /**
162
     * Returns TRUE, if the passed filename has already been mapped.
163
     *
164
     * @param string $filename The filename to query for
165
     *
166
     * @return boolean TRUE if the filename has already been mapped, else FALSE
167
     */
168
    public function imageHasBeenMapped($filename)
169
    {
170
        return isset($this->imageMappings[$filename]);
171
    }
172
173
    /**
174
     * Returns TRUE, if the passed filename has NOT been mapped yet.
175
     *
176
     * @param string $filename The filename to query for
177
     *
178
     * @return boolean TRUE if the filename has NOT been mapped yet, else FALSE
179
     */
180 1
    public function imageHasNotBeenMapped($filename)
181
    {
182 1
        return !isset($this->imageMappings[$filename]);
183
    }
184
185
    /**
186
     * Returns the original filename for passed one (which is the new filename).
187
     *
188
     * @param string $newFilename The new filename to return the original one for
189
     *
190
     * @return string The original filename
191
     */
192
    public function getInversedImageMapping($newFilename)
193
    {
194
195
        // try to load the original filename
196
        if ($filename = array_search($newFilename, $this->imageMappings)) {
197
            return $filename;
198
        }
199
200
        // return the new one otherwise
201
        return $newFilename;
202
    }
203
204
    /**
205
     * Get new file name, if a filename with the same name already exists.
206
     *
207
     * @param string $targetFilename The name of target file
208
     *
209
     * @return string The new filename
210
     */
211 3
    public function getNewFileName($targetFilename)
212
    {
213
214
        // load the file information
215 3
        $fileInfo = pathinfo($targetFilename);
216
217
        // query whether or not, the file exists
218 3
        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...
219
            // initialize the index and the basename
220 1
            $index = 1;
221 1
            $baseName = $fileInfo['filename'] . '.' . $fileInfo['extension'];
222
223
            // prepare the new filename by raising the index
224 1
            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...
225 1
                $baseName = $fileInfo['filename'] . '_' . $index . '.' . $fileInfo['extension'];
226 1
                $index++;
227
            }
228
229
            // set the new filename
230 1
            $targetFilename = $baseName;
231
        } else {
232
            // if not, simply return the filename
233 2
            return $fileInfo['basename'];
234
        }
235
236
        // return the new filename
237 1
        return $targetFilename;
238
    }
239
240
    /**
241
     * Upload's the file with the passed name to the Magento
242
     * media directory. If the file already exists, the will
243
     * be given a new name that will be returned.
244
     *
245
     * @param string $filename The name of the file to be uploaded
246
     *
247
     * @return string The name of the uploaded file
248
     * @throws \Exception Is thrown, if the file with the passed name is not available
249
     */
250 2
    public function uploadFile($filename)
251
    {
252
253
        // trim the leading /, if available
254 2
        $trimmedFilename = ltrim($filename, '/');
255 2
        $mediaDir = ltrim($this->getMediaDir(), '/');
256 2
        $imagesFileDir = ltrim($this->getImagesFileDir(), '/');
257
258
        // prepare source/target filename
259 2
        $sourceFilename = sprintf('%s/%s', $imagesFileDir, $trimmedFilename);
260 2
        $targetFilename = sprintf('%s/%s', $mediaDir, $trimmedFilename);
261
262
        // query whether or not the image file to be imported is available
263 2
        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...
264 1
            throw new \Exception(sprintf('Media file "%s" is not available', $sourceFilename));
265
        }
266
267
        // query whether or not, the file has already been processed
268 1
        if ($this->imageHasNotBeenMapped($filename)) {
269
            // load the new filename, e. g. if a file with the same name already exists
270 1
            $newTargetFilename =  $this->getNewFileName($targetFilename);
271
            // replace the old filename with the new one
272 1
            $targetFilename = str_replace(basename($targetFilename), $newTargetFilename, $targetFilename);
273
274
            // make sure, the target directory exists
275 1
            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...
276 1
                $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...
277
            }
278
279
            // copy the image to the target directory
280 1
            $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...
281
282
            // add the mapping and return the mapped filename
283 1
            $this->addImageMapping($filename, str_replace($mediaDir, '', $targetFilename));
284
        }
285
286
        // simply return the mapped filename
287 1
        return $this->getImageMapping($filename);
288
    }
289
290
    /**
291
     * Delete the file with the passed name.
292
     *
293
     * @param string $filename The name of the file to be deleted
294
     *
295
     * @return boolean TRUE on success, else FALSE
296
     */
297
    public function deleteFile($filename)
298
    {
299
300
        // trim the leading /, if available
301
        $trimmedFilename = ltrim($filename, '/');
302
        $mediaDir = ltrim($this->getMediaDir(), '/');
303
304
        // prepare source/target filename
305
        $targetFilename = sprintf('%s/%s', $mediaDir, $trimmedFilename);
306
307
        // query whether or not the image file to be deleted is available
308
        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...
309
            throw new \Exception(sprintf('Media file "%s" is not available', $targetFilename));
310
        }
311
312
        // delte the image from the target directory
313
        $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...
314
    }
315
}
316