Completed
Push — master ( 207699...acf74c )
by Benjamin
10:45
created

MediaManager::setAllowedMimeTypes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
namespace Alpixel\Bundle\MediaBundle\Services;
4
5
use Alpixel\Bundle\MediaBundle\Entity\Media;
6
use Alpixel\Bundle\MediaBundle\Exception\InvalidMimeTypeException;
7
use Cocur\Slugify\Slugify;
8
use Doctrine\ORM\EntityManager;
9
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
10
use Symfony\Component\Filesystem\Exception\IOException;
11
use Symfony\Component\Filesystem\Filesystem;
12
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
13
use Symfony\Component\HttpFoundation\File\File;
14
use Symfony\Component\HttpFoundation\File\UploadedFile;
15
16
class MediaManager
17
{
18
    protected $entityManager;
19
    protected $uploadDir;
20
    protected $allowedMimetypes;
21
22
    use ContainerAwareTrait;
23
24
    const SIZE_OF_KIBIOCTET = 1024;
25
    const OCTET_IN_KO = 1;
26
    const OCTET_IN_MO = 2;
27
    const OCTET_IN_GO = 3;
28
    const OCTET_IN_TO = 4;
29
    const OCTET_IN_PO = 5;
30
31
    public function __construct(EntityManager $entityManager, $uploadDir, $allowedMimetypes)
32
    {
33
        $this->entityManager = $entityManager;
34
        if(substr($uploadDir, -1) !== '/') {
35
            $uploadDir = $uploadDir.'/';
36
        }
37
        $this->uploadDir = $uploadDir;
38
        $this->allowedMimetypes = $allowedMimetypes;
39
    }
40
41
  /**
42
   * $current_uri String actual uri of the file
43
   * $dest_folder String future uri of the file starting from web/upload folder
44
   * $lifetime DateTime lifetime of the file. If time goes over this limit, the file will be deleted.
45
   **/
46
  public function upload(File $file, $dest_folder = '', \DateTime $lifetime = null)
47
  {
48
    //preparing dir name
49
    $dest_folder = date('Ymd').'/'.date('G').'/'.$dest_folder;
50
51
    //checking mimetypes
52
    $mimeTypePassed = false;
53
    foreach ($this->allowedMimetypes as $mimeType) {
54
      if (preg_match('@'.$mimeType.'@', $file->getMimeType())) {
55
          $mimeTypePassed = true;
56
      }
57
    }
58
59
    if (!$mimeTypePassed) {
60
      throw new InvalidMimeTypeException('Only following filetypes are allowed : '.implode(', ', $this->allowedMimetypes));
61
    }
62
63
    $fs = new Filesystem();
64
    if (!$fs->exists($this->uploadDir.$dest_folder)) {
65
      $fs->mkdir($this->uploadDir.$dest_folder);
66
    }
67
68
    $em = $this->entityManager;
69
    $media = new Media();
70
    $media->setMime($file->getMimeType());
71
72
    // Sanitizing the filename
73
    $slugify = new Slugify();
74
    if($file instanceof UploadedFile) {
75
        $filename = $slugify->slugify($file->getClientOriginalName());
76
    } else {
77
        $filename = $slugify->slugify($file->getFilename());
78
    }
79
80
    // A media can have a lifetime and will be deleted with the cleanup function
81
    if (!empty($lifetime)) {
82
        $media->setLifetime($lifetime);
83
    }
84
85
    // Checking for a media with the same name
86
    $mediaExists = $this->entityManager->getRepository('AlpixelMediaBundle:Media')->findOneByUri($dest_folder.$filename);
87
    if (count($mediaExists) === 0) {
88
      $mediaExists = $fs->exists($this->uploadDir.$dest_folder.$filename);
89
    }
90
91
    // If there's one, we try to generate a new name
92
    $extension = $file->getExtension();
93
    if (empty($extension)) {
94
      $extension = $file->guessExtension();
95
    }
96
97
    if (count($mediaExists) > 0) {
98
      $filename = basename($filename, '.'.$extension);
99
100
      $i = 1;
101
      do {
102
          $media->setName($filename.'-'.$i++.'.'.$extension);
103
          $media->setUri($dest_folder.$media->getName());
104
          $mediaExists = $this->entityManager->getRepository('AlpixelMediaBundle:Media')->findOneByUri($media->getUri());
105
      } while (count($mediaExists) > 0);
106
    } else {
107
      $media->setName($filename.'.'.$extension);
108
      $media->setUri($dest_folder.$media->getName());
109
    }
110
111
    $file->move($this->uploadDir.$dest_folder, $media->getName());
112
    chmod($this->uploadDir.$dest_folder.$media->getName(), 0664);
113
114
    // Getting the salt defined in parameters.yml
115
    $secret = $this->container->getParameter('secret');
116
    $media->setSecretKey(hash('sha256', $secret.$media->getName().$media->getUri()));
117
118
    $em->persist($media);
119
    $em->flush();
120
121
    return $media;
122
  }
123
124
    public function cleanup()
125
    {
126
        $medias = $this->entityManager->getRepository('AlpixelMediaBundle:Media')->findExpiredMedias();
127
        foreach ($medias as $media) {
128
            $this->delete($media);
129
        }
130
    }
131
132
    public function delete(Media $media)
133
    {
134
        $em = $this->entityManager;
135
        $fs = new Filesystem();
136
137
        $file_path = $this->uploadDir.$media->getUri();
138
139
        try {
140
            $file = new File($file_path);
141
            if ($file->isFile() && $file->isWritable()) {
142
                $fs->remove($file_path);
143
            }
144
        } catch (FileNotFoundException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
145
        } catch (IOException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
146
        }
147
148
        $em->remove($media);
149
        $em->flush();
150
    }
151
152
    public function getUploadDir($filter = null)
153
    {
154
        if (!empty($filter)) {
155
            return $this->uploadDir.'filters/'.$filter.'/';
156
        }
157
158
        return $this->uploadDir;
159
    }
160
161
    public function getWebPath(Media $media)
162
    {
163
        $request = $this->container->get('request');
164
        $dir = $request->getSchemeAndHttpHost().$request->getBaseUrl().'/';
165
166
        return $dir.$media->getUri();
167
    }
168
169
    public function getAbsolutePath(Media $media, $filter = null)
170
    {
171
        $imgSrc = $this->uploadDir;
172
        if (!empty($filter)) {
173
            return $imgSrc.'filters/'.$filter.'/'.$media->getUri();
174
        } else {
175
            return $imgSrc.$media->getUri();
176
        }
177
    }
178
179
    public function generateUrl(Media $media, $options)
180
    {
181
        $defaultOptions = [
182
            'public'   => true,
183
            'action'   => 'show',
184
            'filter'   => null,
185
            'absolute' => false,
186
        ];
187
188
        $options = array_merge($defaultOptions, $options);
189
        $params = [];
190
191
        $routeName = 'media_';
192
        if ($options['action'] === 'download') {
193
            $routeName .= 'download_';
194
        } else {
195
            $routeName .= 'show_';
196
        }
197
198
        if ($options['public'] === true) {
199
            $routeName .= 'public';
200
            $params['id'] = $media->getId();
201
            $params['name'] = $media->getName();
202
        } else {
203
            $routeName .= 'private';
204
            $params['secretKey'] = $media->getSecretKey();
205
        }
206
207
        if ($options['filter'] !== null) {
208
            if ($options['public'] === true) {
209
                $routeName .= '_filters';
210
            }
211
            $params['filter'] = $options['filter'];
212
        }
213
214
        $container = $this->container;
215
216
        $router = $container->get('router');
217
218
        return $router->generate($routeName, $params, $options['absolute']);
219
    }
220
221
    public function findFromSecret($secret)
222
    {
223
        return $this->entityManager->getRepository('AlpixelMediaBundle:Media')->findOneBySecretKey($secret);
224
    }
225
226
    public function setAllowedMimeTypes(array $type)
227
    {
228
        if ($type !== null) {
229
            $this->allowedMimetypes = $type;
230
        }
231
232
        return $this;
233
    }
234
235
    public function getAllowedMimeTypes()
236
    {
237
        return $this->allowedMimetypes;
238
    }
239
240
    public function convertOctetIn($size, $convert)
241
    {
242
        if ($convert > 0) {
243
            $size = ($size / self::SIZE_OF_KIBIOCTET) * 1;
244
245
            return $this->convertOctetIn($size, $convert - 1);
246
        }
247
248
        return $size;
249
    }
250
}
251