Completed
Pull Request — master (#129)
by jelmer
03:24
created

AbstractFile::remove()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 2
nop 0
1
<?php
2
3
namespace SumoCoders\FrameworkCoreBundle\ValueObject;
4
5
use Doctrine\ORM\Mapping as ORM;
6
use Symfony\Component\HttpFoundation\File\UploadedFile;
7
8
/**
9
 * The following things are mandatory to use this class.
10
 *
11
 * You need to implement the method getUploadDir.
12
 * When using this class in an entity certain life cycle callbacks should be called
13
 * prepareToUpload for @ORM\PrePersist() and @ORM\PreUpdate()
14
 * upload for @ORM\PostPersist() and @ORM\PostUpdate()
15
 * remove for @ORM\PostRemove()
16
 */
17
abstract class AbstractFile
18
{
19
    /**
20
     * @var string
21
     * @ORM\Column(type="string", length=255, nullable=true)
22
     */
23
    protected $fileName = null;
24
25
    /**
26
     * @var UploadedFile
27
     */
28
    protected $file;
29
30
    /**
31
     * @var string
32
     */
33
    protected $oldFileName;
34
35
    /**
36
     * @param string $fileName
37
     */
38
    protected function __construct($fileName)
39
    {
40
        $this->fileName = $fileName;
41
    }
42
43
    /**
44
     * @return string
45
     */
46
    public function getFileName()
47
    {
48
        return $this->fileName;
49
    }
50
51
    /**
52
     * @return string|null
53
     */
54
    public function getAbsolutePath()
55
    {
56
        return $this->fileName === null ? null : $this->getUploadRootDir() . '/' . $this->fileName;
57
    }
58
59
    /**
60
     * @return string
61
     */
62
    public function getWebPath()
63
    {
64
        $file = $this->getAbsolutePath();
65
        if (is_file($file) && file_exists($file)) {
66
            return '/' . $this->getUploadDir() . '/' . $this->fileName;
67
        }
68
69
        return '';
70
    }
71
72
    /**
73
     * @return string
74
     */
75
    protected function getUploadRootDir()
76
    {
77
        // the absolute directory path where uploaded documents should be saved
78
        return __DIR__ . '/../../../../web/' . $this->getTrimmedUploadDir();
79
    }
80
81
    /**
82
     * @return string
83
     */
84
    protected function getTrimmedUploadDir()
85
    {
86
        return trim($this->getUploadDir(), '/\\');
87
    }
88
89
    /**
90
     * The dir in the web folder where the file needs to be uploaded.
91
     * The base directory is always the src/Frontend/Files/ directory
92
     *
93
     * @return string
94
     */
95
    abstract protected function getUploadDir();
96
97
    /**
98
     * Sets file.
99
     *
100
     * @param UploadedFile $file
101
     *
102
     * @return static
103
     */
104
    public function setFile(UploadedFile $file = null)
105
    {
106
        $this->file = $file;
107
        // check if we have an old image path
108
        if ($this->fileName === null) {
109
            return $this;
110
        }
111
112
        // store the old name to delete after the update
113
        $this->oldFileName = $this->fileName;
114
        $this->fileName = null;
115
116
        return clone $this;
117
    }
118
119
    /**
120
     * @param UploadedFile|null $uploadedFile
121
     *
122
     * @return static
123
     */
124
    public static function fromUploadedFile(UploadedFile $uploadedFile = null)
125
    {
126
        $file = new static(null);
127
        $file->setFile($uploadedFile);
128
129
        return $file;
130
    }
131
132
    /**
133
     * Get file.
134
     *
135
     * @return UploadedFile
136
     */
137
    public function getFile()
138
    {
139
        return $this->file;
140
    }
141
142
    /**
143
     * This function should be called for the life cycle events @ORM\PrePersist() and @ORM\PreUpdate()
144
     */
145
    public function prepareToUpload()
146
    {
147
        if ($this->getFile() === null) {
148
            return;
149
        }
150
151
        // do whatever you want to generate a unique name
152
        $filename = sha1(uniqid(mt_rand(), true));
153
        $this->fileName = $filename . '.' . $this->getFile()->guessExtension();
154
    }
155
156
    /**
157
     * This function should be called for the life cycle events @ORM\PostPersist() and @ORM\PostUpdate()
158
     */
159
    public function upload()
160
    {
161
        if ($this->getFile() === null) {
162
            return;
163
        }
164
165
        $this->writeFileToDisk();
166
167
        // check if we have an old image
168
        if ($this->oldFileName !== null) {
169
            // delete the old image
170
            $oldFile = $this->getUploadRootDir() . '/' . $this->oldFileName;
171
            if (is_file($oldFile) && file_exists($oldFile)) {
172
                unlink($oldFile);
173
            }
174
            // clear the $this->oldFileName image path
175
            $this->oldFileName = null;
176
        }
177
        $this->file = null;
178
    }
179
180
    /**
181
     * if there is an error when moving the file, an exception will
182
     * be automatically thrown by move(). This will properly prevent
183
     * the entity from being persisted to the database on error
184
     */
185
    protected function writeFileToDisk()
186
    {
187
        $this->getFile()->move($this->getUploadRootDir(), $this->fileName);
188
    }
189
190
    /**
191
     * This function should be called for the life cycle event @ORM\PostRemove()
192
     */
193
    public function remove()
194
    {
195
        $file = $this->getAbsolutePath();
196
        if (!is_file($file) || !file_exists($file)) {
197
            return;
198
        }
199
200
        unlink($file);
201
    }
202
203
    /**
204
     * Returns a string representation of the image.
205
     *
206
     * @return string
207
     */
208
    public function __toString()
209
    {
210
        return (string) $this->fileName;
211
    }
212
213
    /**
214
     * @param string $fileName
215
     *
216
     * @return static
217
     */
218
    public static function fromString($fileName)
219
    {
220
        return new static($fileName);
221
    }
222
223
    /**
224
     * {@inheritdoc}
225
     */
226
    public function jsonSerialize()
227
    {
228
        return (string) $this->getWebPath();
229
    }
230
}
231