Completed
Push — master ( 219f9c...015b0d )
by Benjamin
23:07 queued 20:27
created

MediaManager   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 11
Bugs 3 Features 0
Metric Value
wmc 34
c 11
b 3
f 0
lcom 1
cbo 8
dl 0
loc 229
rs 9.2

12 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
C upload() 0 74 10
A cleanup() 0 7 2
B delete() 0 19 5
A getUploadDir() 0 8 2
A getWebPath() 0 7 1
A getAbsolutePath() 0 9 2
B generateUrl() 0 41 5
A findFromSecret() 0 4 1
A setAllowedMimeTypes() 0 8 2
A getAllowedMimeTypes() 0 4 1
A convertOctetIn() 0 10 2
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)
0 ignored issues
show
Bug introduced by
You have injected the EntityManager via parameter $entityManager. This is generally not recommended as it might get closed and become unusable. Instead, it is recommended to inject the ManagerRegistry and retrieve the EntityManager via getManager() each time you need it.

The EntityManager might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:

function someFunction(ManagerRegistry $registry) {
    $em = $registry->getManager();
    $em->getConnection()->beginTransaction();
    try {
        // Do something.
        $em->getConnection()->commit();
    } catch (\Exception $ex) {
        $em->getConnection()->rollback();
        $em->close();

        throw $ex;
    }
}

If that code throws an exception and the EntityManager is closed. Any other code which depends on the same instance of the EntityManager during this request will fail.

On the other hand, if you instead inject the ManagerRegistry, the getManager() method guarantees that you will always get a usable manager instance.

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