Completed
Push — master ( a3587c...b04bc5 )
by Luis Ramón
02:12
created

FolderController   F

Complexity

Total Complexity 81

Size/Duplication

Total Lines 535
Duplicated Lines 7.48 %

Coupling/Cohesion

Components 1
Dependencies 23

Importance

Changes 0
Metric Value
wmc 81
lcom 1
cbo 23
dl 40
loc 535
rs 1.5492
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
C folderFormAction() 0 55 11
C setFolderRolesInForm() 0 33 7
C updateFolderRolesFromForm() 0 41 8
B entryOperationAction() 0 24 6
A folderOperationAction() 0 12 3
A doOperation() 0 16 4
B browseAction() 0 27 3
A getRootFolder() 10 10 1
A getFolder() 10 10 1
B getFolderEntriesPager() 0 32 3
B generateBreadcrumb() 20 20 5
A getOrganizationTree() 0 16 3
C processChildren() 0 33 8
B uploadFormAction() 0 35 6
C processFileUpload() 0 65 7
B getUploadStatus() 0 12 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like FolderController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FolderController, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
  ÁTICA - Aplicación web para la gestión documental de centros educativos
4
5
  Copyright (C) 2015-2017: Luis Ramón López López
6
7
  This program is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU Affero General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
11
12
  This program is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU Affero General Public License for more details.
16
17
  You should have received a copy of the GNU Affero General Public License
18
  along with this program.  If not, see [http://www.gnu.org/licenses/].
19
*/
20
21
namespace AppBundle\Controller\Documentation;
22
23
use AppBundle\Entity\Documentation\Entry;
24
use AppBundle\Entity\Documentation\Folder;
25
use AppBundle\Entity\Documentation\FolderPermission;
26
use AppBundle\Entity\Documentation\FolderRepository;
27
use AppBundle\Entity\Documentation\History;
28
use AppBundle\Entity\Documentation\Version;
29
use AppBundle\Entity\ElementRepository;
30
use AppBundle\Entity\Organization;
31
use AppBundle\Form\Model\DocumentUpload;
32
use AppBundle\Form\Type\Documentation\FolderType;
33
use AppBundle\Form\Type\Documentation\UploadType;
34
use AppBundle\Security\FolderVoter;
35
use AppBundle\Security\OrganizationVoter;
36
use Doctrine\Common\Collections\ArrayCollection;
37
use Doctrine\ORM\EntityManager;
38
use Doctrine\ORM\QueryBuilder;
39
use Gedmo\Sortable\Entity\Repository\SortableRepository;
40
use Pagerfanta\Adapter\DoctrineORMAdapter;
41
use Pagerfanta\Pagerfanta;
42
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
43
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
44
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
45
use Symfony\Component\Form\Form;
46
use Symfony\Component\HttpFoundation\File\UploadedFile;
47
use Symfony\Component\HttpFoundation\Request;
48
49
/**
50
 * @Route("/documentos")
51
 */
52
class FolderController extends Controller
53
{
54
    /**
55
     * @Route("/carpeta/{id}/nueva", name="documentation_folder_new", methods={"GET", "POST"})
56
     * @Route("/carpeta/{id}", name="documentation_folder_form", requirements={"id" = "\d+"}, methods={"GET", "POST"})
57
     * @Security("is_granted('FOLDER_MANAGE', folder)")
58
     */
59
    public function folderFormAction(Folder $folder = null, Request $request)
60
    {
61
        $organization = $this->get('AppBundle\Service\UserExtensionService')->getCurrentOrganization();
62
        $this->denyAccessUnlessGranted(OrganizationVoter::MANAGE, $organization);
63
64
        $em = $this->getDoctrine()->getManager();
65
        $new = $request->get('_route') === 'documentation_folder_new';
66
67
        $sourceFolder = $folder;
68
69
        if ($new) {
70
            $newFolder = new Folder();
71
            $newFolder
72
                ->setOrganization($organization)
73
                ->setParent($folder);
74
            $folder = $newFolder;
75
            $em->persist($folder);
76
        } else {
77
            if (null === $sourceFolder->getParent()) {
78
                throw $this->createAccessDeniedException();
79
            }
80
        }
81
        $breadcrumb = $sourceFolder->getParent() ? $this->generateBreadcrumb($sourceFolder, false) : [];
82
83
        if ($request->request->get('folder')) {
84
            $folder->setType($request->request->get('folder')['type']);
1 ignored issue
show
Bug introduced by
It seems like $folder is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
85
        }
86
        $form = $this->createForm(FolderType::class, $folder, [
87
            'new' => $new,
88
            'allow_extra_fields' => !$request->request->has('submit')
89
        ]);
90
91
        $this->setFolderRolesInForm($folder, $form);
92
        $form->handleRequest($request);
93
        $breadcrumb[] = ['fixed' => $this->get('translator')->trans($new ? 'title.folder.new' : 'title.folder.edit', [], 'documentation')];
94
95
        if ($form->isSubmitted() && $form->isValid() && $request->request->has('submit')) {
96
            try {
97
                $this->updateFolderRolesFromForm($folder, $em, $form);
1 ignored issue
show
Bug introduced by
It seems like $folder defined by parameter $folder on line 59 can be null; however, AppBundle\Controller\Doc...teFolderRolesFromForm() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
98
                $em->flush();
99
                $this->addFlash('success', $this->get('translator')->trans('message.folder.saved', [], 'documentation'));
100
                return $this->redirectToRoute('documentation', ['id' => $sourceFolder->getId()]);
101
            } catch (\Exception $e) {
102
                $this->addFlash('error', $this->get('translator')->trans('message.folder.save_error', [], 'documentation'));
103
            }
104
        }
105
106
        return $this->render('documentation/folder_form.html.twig', [
107
            'menu_path' => 'documentation',
108
            'breadcrumb' => $breadcrumb,
109
            'title' => $this->get('translator')->trans($new ? 'title.folder.new' : 'title.folder.edit', [], 'documentation'),
110
            'form' => $form->createView(),
111
            'folder' => $folder
112
        ]);
113
    }
114
115
    /**
116
     * @param Folder $folder
117
     * @param Form $form
118
     */
119
    private function setFolderRolesInForm(Folder $folder = null, Form $form)
120
    {
121
        if (null === $folder) {
122
            return;
123
        }
124
125
        $permissions = $folder->getPermissions();
126
127
        $permissionTypes = [
128
            'access' => FolderPermission::PERMISSION_VISIBLE,
129
            'manager' => FolderPermission::PERMISSION_MANAGE,
130
            'upload' => FolderPermission::PERMISSION_UPLOAD,
131
            'review' => FolderPermission::PERMISSION_REVIEW,
132
            'approve' => FolderPermission::PERMISSION_APPROVE
133
        ];
134
135
        foreach ($permissionTypes as $name => $type) {
136
            if ($form->has('profiles_'.$name)) {
137
                $data = [];
138
139
                /** @var FolderPermission $permission */
140
                foreach ($permissions as $permission) {
141
                    if ($permission->getPermission() === $type) {
142
                        $data[] = $permission->getElement();
143
                    }
144
                }
145
146
                if (!empty($data)) {
147
                    $form->get('profiles_' . $name)->setData($data);
148
                }
149
            }
150
        }
151
    }
152
153
    /**
154
     * @param Folder $folder
155
     * @param EntityManager $em
156
     * @param Form $form
157
     */
158
    private function updateFolderRolesFromForm($folder, EntityManager $em, $form)
159
    {
160
        $oldPermissions = $folder->getPermissions();
161
162
        $permissionTypes = [
163
            'access' => FolderPermission::PERMISSION_VISIBLE,
164
            'manager' => FolderPermission::PERMISSION_MANAGE,
165
            'upload' => FolderPermission::PERMISSION_UPLOAD,
166
            'review' => FolderPermission::PERMISSION_REVIEW,
167
            'approve' => FolderPermission::PERMISSION_APPROVE
168
        ];
169
170
        foreach ($permissionTypes as $name => $type) {
171
172
            $data = $form->has('profiles_' . $name) ? $form->get('profiles_' . $name)->getData() : [];
173
            if (!$data instanceof ArrayCollection) {
174
                $data = new ArrayCollection($data);
175
            }
176
177
            /** @var FolderPermission $permission */
178
            foreach ($oldPermissions as $permission) {
179
                if ($permission->getPermission() === $type) {
180
                    if (!$data->contains($permission->getElement())) {
181
                        $em->remove($permission);
182
                    } else {
183
                        $data->removeElement($permission->getElement());
184
                    }
185
                }
186
            }
187
188
            foreach ($data as $datum) {
189
                $permission = new FolderPermission();
190
                $permission
191
                    ->setFolder($folder)
192
                    ->setPermission($type)
193
                    ->setElement($datum);
194
                $em->persist($permission);
195
            }
196
        }
197
        $em->flush();
198
    }
199
200
    /**
201
     * @Route("/operacion/entrada/{id}", name="documentation_entry_operation", requirements={"id" = "\d+"}, methods={"POST"})
202
     * @Security("is_granted('FOLDER_MANAGE', folder)")
203
     */
204
    public function entryOperationAction(Request $request, Folder $folder)
205
    {
206
        $ok = false;
207
208
        $em = $this->getDoctrine()->getManager();
209
        foreach (['up' => -1, 'down' => 1] as $op => $step) {
210
            if ($request->get($op)) {
211
                /** @var SortableRepository $repository */
212
                $repository = $em->getRepository('AppBundle:Documentation\Entry');
213
214
                $entry = $repository->find($request->get($op));
215
216
                if ($entry && $entry->getFolder() === $folder) {
217
                    $entry->setPosition(max($entry->getPosition() + $step, 0));
218
                    $ok = true;
219
                }
220
            }
221
        }
222
        if ($ok) {
223
            $em->flush();
224
        }
225
226
        return $this->redirectToRoute('documentation', ['id' => $folder->getId()]);
227
    }
228
229
    /**
230
     * @Route("/operacion/{id}", name="documentation_folder_operation", requirements={"id" = "\d+"}, methods={"POST"})
231
     * @Security("is_granted('FOLDER_MANAGE', folder)")
232
     */
233
    public function folderOperationAction($id, Request $request)
234
    {
235
        $organization = $this->get('AppBundle\Service\UserExtensionService')->getCurrentOrganization();
236
237
        $folder = $this->getFolder($organization, $id);
238
239
        if (null === $folder || $folder->getOrganization() !== $organization) {
240
            throw $this->createNotFoundException();
241
        }
242
        $this->doOperation($request, $folder);
243
        return $this->redirectToRoute('documentation', ['id' => $folder->getId()]);
244
    }
245
246
247
    /**
248
     * @param Request $request
249
     * @param $item
250
     */
251
    private function doOperation(Request $request, $item)
252
    {
253
        $ok = false;
254
255
        $em = $this->getDoctrine()->getManager();
256
        foreach (['up', 'down'] as $op) {
257
            if ($request->get($op)) {
258
                $method = 'move' . ucfirst($op);
259
                $em->getRepository(get_class($item))->$method($item);
260
                $ok = true;
261
            }
262
        }
263
        if ($ok) {
264
            $em->flush();
265
        }
266
    }
267
268
    /**
269
     * @Route("/{id}/{page}", name="documentation", requirements={"page" = "\d+", "id" = "\d+"}, defaults={"page" = "1", "folder" = null}, methods={"GET"})
270
     */
271
    public function browseAction($page, $id = null, Request $request)
272
    {
273
        $organization = $this->get('AppBundle\Service\UserExtensionService')->getCurrentOrganization();
274
275
        $q = $request->get('q', null);
276
277
        $folder = (null === $id) ? $this->getRootFolder($organization) : $this->getFolder($organization, $id);
278
279
        if (null === $folder) {
280
            throw $this->createNotFoundException();
281
        }
282
        $this->denyAccessUnlessGranted('FOLDER_ACCESS', $folder);
283
284
        $pager = $this->getFolderEntriesPager($page, $folder, $q);
285
286
        $breadcrumb = $this->generateBreadcrumb($folder);
287
288
        return $this->render('documentation/list.html.twig', [
289
            'breadcrumb' => $breadcrumb,
290
            'pager' => $pager,
291
            'current' => $folder,
292
            'permissions' => ['is_folder_manager' => $this->isGranted('FOLDER_MANAGE', $folder), 'is_organization_manager' => $this->isGranted('ORGANIZATION_MANAGE', $organization)],
293
            'tree' => $this->getOrganizationTree($this->getRootFolder($organization), $folder),
294
            'q' => $q,
295
            'domain' => 'element'
296
        ]);
297
    }
298
299
    /**
300
     * @param Organization $organization
301
     * @return Folder
302
     */
303 View Code Duplication
    private function getRootFolder($organization)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
304
    {
305
        /** @var FolderRepository $folderRepository */
306
        $folderRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Documentation\Folder');
307
308
        /** @var Folder|null $folder */
309
        $folder = $folderRepository->findOneBy(['organization' => $organization, 'parent' => null]);
310
311
        return $folder;
312
    }
313
314
    /**
315
     * @param Organization $organization
316
     * @param int $id
317
     * @return Folder
318
     */
319 View Code Duplication
    private function getFolder($organization, $id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
320
    {
321
        /** @var FolderRepository $folderRepository */
322
        $folderRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Documentation\Folder');
323
324
        /** @var Folder|null $folder */
325
        $folder = $folderRepository->findOneBy(['organization' => $organization, 'id' => $id]);
326
327
        return $folder;
328
    }
329
330
    /**
331
     * @param $page
332
     * @param Folder|null $folder
333
     * @param $q
334
     * @return Pagerfanta
335
     */
336
    private function getFolderEntriesPager($page, Folder $folder = null, $q)
337
    {
338
        /** @var ElementRepository $entriesRepository */
339
        $entriesRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Documentation\Entry');
340
341
        // obtener las carpetas
342
        $folders = $this->getDoctrine()->getManager()->getRepository('AppBundle:Documentation\Folder')->getChildren($folder, false, false, 'ASC', true);
343
344
        /** @var QueryBuilder $queryBuilder */
345
        $queryBuilder = $entriesRepository->createQueryBuilder('e')
346
            ->andWhere('e.folder IN (:folders)')
347
            ->setParameter('folders', $folders)
348
            ->join('e.folder', 'f')
349
            ->addOrderBy('f.left')
350
            ->addOrderBy('e.position')
351
            ->addSelect('v')
352
            ->leftJoin('e.currentVersion', 'v');
353
354
        if ($q) {
355
            $queryBuilder
356
                ->andWhere('e.name LIKE :tq')
357
                ->setParameter('tq', '%'.$q.'%');
358
        }
359
360
        $adapter = new DoctrineORMAdapter($queryBuilder, false);
361
        $pager = new Pagerfanta($adapter);
362
        $pager
363
            ->setMaxPerPage($this->getParameter('page.size'))
364
            ->setCurrentPage($q ? 1 : $page);
365
366
        return $pager;
367
    }
368
369
    /**
370
     * Returns breadcrumb that matches the folder (ignores root element)
371
     * @param Folder $folder
372
     * @param bool $ignoreLast
373
     * @return array
374
     */
375 View Code Duplication
    private function generateBreadcrumb(Folder $folder = null, $ignoreLast = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
376
    {
377
        $breadcrumb = [];
378
379
        if (null === $folder) {
380
            return null;
381
        }
382
383
        $item = $folder;
384
        while ($item->getParent()) {
385
            $entry = ['fixed' => $item->getName()];
386
            if ($item !== $folder || !$ignoreLast) {
387
                $entry['routeName'] = 'documentation';
388
                $entry['routeParams'] = ['id' => $item->getId()];
389
            }
390
            array_unshift($breadcrumb, $entry);
391
            $item = $item->getParent();
392
        }
393
        return $breadcrumb;
394
    }
395
396
    /**
397
     * Returns folder tree
398
     *
399
     * @param Folder $folder
400
     * @param Folder $current
401
     *
402
     * @return array
403
     */
404
    private function getOrganizationTree(Folder $folder, Folder $current = null)
405
    {
406
        /** @var FolderRepository $folderRepository */
407
        $folderRepository = $this->getDoctrine()->getManager()->getRepository('AppBundle:Documentation\Folder');
408
409
        $children = $folderRepository->childrenHierarchy($folder);
410
411
        $organization = $folder->getOrganization();
412
        $disabled = $this->isGranted('ORGANIZATION_MANAGE', $organization) ? [] : array_map(function (Folder $f) {
413
            return $f->getId();
414
        }, $folderRepository->getAccessDeniedFoldersForUserAndOrganizationArray($this->getUser(), $organization));
415
416
        list($tree) = $this->processChildren($children, $current ? $current->getId() : null, $disabled);
1 ignored issue
show
Bug introduced by
It seems like $children can also be of type string; however, AppBundle\Controller\Doc...ller::processChildren() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
417
418
        return $tree;
419
    }
420
421
    /**
422
     * Convert children array into a treeview array
423
     *
424
     * @param array $children
425
     * @param integer $currentId
426
     * @param array $disabledId
427
     * @return mixed
428
     */
429
    private function processChildren(array $children, $currentId = null, $disabledId = [])
430
    {
431
        $result = [];
432
        $selected = false;
433
        foreach ($children as $child) {
434
            $item = [];
435
            $item['text'] = $child['name'];
436
437
            $disabled = in_array($child['id'], $disabledId,false);
438
            if ($disabled) {
439
                $item['state'] = ['disabled' => true];
440
            }
441
            if ($currentId === $child['id']) {
442
                $item['state'] = ['selected' => true, 'expanded' => true];
443
                $selected = true;
444
            }
445
            if (!$disabled && count($child['__children']) > 0) {
446
                list($item['nodes'], $selected) = $this->processChildren($child['__children'], $currentId, $disabledId);
447
            } else {
448
                $item['icon'] = 'fa fa-folder';
449
            }
450
            if ($selected) {
451
                if (!isset($item['state'])) {
452
                    $item['state'] = [];
453
                }
454
                $item['state']['expanded'] = true;
455
            }
456
            $item['href'] = $this->generateUrl('documentation', ['id' => $child['id']]);
457
            $result[] = $item;
458
        }
459
460
        return [$result, $selected];
461
    }
462
463
    /**
464
     * @Route("/carpeta/{id}/subir", name="documentation_folder_upload", methods={"GET", "POST"})
465
     * @Security("is_granted('FOLDER_UPLOAD', folder) and folder.getType() != constant('AppBundle\\Entity\\Documentation\\Folder::TYPE_TASKS')")
466
     */
467
    public function uploadFormAction(Request $request, Folder $folder)
468
    {
469
        $breadcrumb = $this->generateBreadcrumb($folder, false);
470
471
        $title = $this->get('translator')->trans('title.entry.new', [], 'documentation');
472
        $breadcrumb[] = ['fixed' => $title];
473
474
        $upload = new DocumentUpload();
475
476
        if ($this->isGranted(FolderVoter::MANAGE, $folder)) {
477
            $profiles = $this->getDoctrine()->getManager()->getRepository('AppBundle:Element')->findAllProfilesByFolderPermission($folder, FolderPermission::PERMISSION_UPLOAD, true);
478
        } else {
479
            $profiles = $this->getDoctrine()->getManager()->getRepository('AppBundle:Element')->findAllProfilesByFolderPermissionAndUser($folder, FolderPermission::PERMISSION_UPLOAD, $this->getUser(), true);
480
        }
481
        $form = $this->createForm(UploadType::class, $upload, ['upload_profiles' => $profiles]);
482
483
        $form->handleRequest($request);
484
485
        if ($form->isSubmitted() && $form->isValid()) {
486
            $state = $this->getUploadStatus($request, $folder);
487
            if (null !== $state && $this->processFileUpload($folder, $upload, $state, $state)) {
488
                $this->addFlash('success', $this->get('translator')->trans('message.upload.save_ok', [], 'upload'));
489
                return $this->redirectToRoute('documentation', ['id' => $folder->getId()]);
490
            }
491
            $this->addFlash('error', $this->get('translator')->trans('message.upload.save_error', [], 'upload'));
492
        }
493
494
        return $this->render('documentation/folder_upload.html.twig', [
495
            'menu_path' => 'documentation',
496
            'title' => $title,
497
            'breadcrumb' => $breadcrumb,
498
            'folder' => $folder,
499
            'form' => $form->createView()
500
        ]);
501
    }
502
503
    private function processFileUpload(Folder $folder, DocumentUpload $upload, $versionState = Version::STATUS_APPROVED, $entryState = Entry::STATUS_APPROVED)
504
    {
505
        $em = $this->getDoctrine()->getManager();
506
        $processedFileName = null;
507
        $filesystem = $this->get('entries_filesystem');
508
        try {
509
            /** @var UploadedFile $file */
510
            $file = $upload->getFile();
511
            $fileName = hash_file('sha256', $file->getRealPath());
512
            $fileName = substr($fileName, 0, 2).'/'.substr($fileName, 2, 2).'/'.$fileName;
513
            if (!$filesystem->has($fileName)) {
514
                $filesystem->write($fileName, file_get_contents($file->getRealPath()));
515
            }
516
            $processedFileName = $fileName;
517
518
            $entry = new Entry();
519
            $entry
520
                ->setName($upload->getTitle() ?: $file->getClientOriginalName())
521
                ->setFolder($folder)
522
                ->setState($entryState)
523
                ->setElement($upload->getUploadProfile())
524
                ->setDescription($upload->getDescription());
525
526
            if ($upload->getCreateDate()) {
527
                $entry->setCreatedAt($upload->getCreateDate());
528
            }
529
530
            $em->persist($entry);
531
532
            $version = new Version();
533
            $version
534
                ->setEntry($entry)
535
                ->setFile($fileName)
536
                ->setState($versionState)
537
                ->setVersionNr($upload->getVersion());
538
539
            $entry->setCurrentVersion($version);
540
541
            $em->persist($version);
542
543
            $history = new History();
544
            $history
545
                ->setEntry($entry)
546
                ->setVersion($upload->getVersion())
547
                ->setCreatedBy($this->getUser())
548
                ->setEvent(History::LOG_CREATE);
549
550
            $em->persist($history);
551
552
            $em->flush();
553
554
            return true;
555
        } catch (\Exception $e) {
556
            // seguir la ejecución si ha ocurrido una excepción por el camino
557
        }
558
559
        if (null !== $processedFileName) {
560
            // ha ocurrido un error pero el fichero se había almacenado, borrarlo si no se estaba usando
561
            if (0 == (int) $em->getRepository('AppBundle:Documentation\Version')->countByFile($processedFileName)) {
562
                $filesystem->delete($processedFileName);
563
            }
564
        }
565
566
        return false;
567
    }
568
569
    /**
570
     * @param Request $request
571
     * @param Folder $folder
572
     * @return int|null
573
     */
574
    private function getUploadStatus(Request $request, Folder $folder)
575
    {
576
        $state = null;
577
        switch ($folder->getType()) {
578
            case Folder::TYPE_NORMAL:
579
                $state = Version::STATUS_APPROVED;
580
                break;
581
            case Folder::TYPE_WORKFLOW:
582
                $state = ($request->request->has('approve') && $this->isGranted(FolderVoter::APPROVE, $folder)) ? Version::STATUS_APPROVED : Version::STATUS_DRAFT;
583
        }
584
        return $state;
585
    }
586
}
587