Proyectos de Subversion LeadersLinked - Backend

Rev

Ir a la última revisión | | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
17002 efrain 1
<?php
2
declare(strict_types=1);
3
 
4
namespace LeadersLinked\Controller;
5
 
6
use Laminas\Db\Adapter\AdapterInterface;
7
 
8
use Laminas\Mvc\Controller\AbstractActionController;
9
use Laminas\Log\LoggerInterface;
10
use Laminas\View\Model\ViewModel;
11
use Laminas\View\Model\JsonModel;
12
use LeadersLinked\Library\Functions;
13
use LeadersLinked\Hydrator\ObjectPropertyHydrator;
14
use LeadersLinked\Library\Image;
15
use LeadersLinked\Mapper\MediaFileMapper;
16
use LeadersLinked\Model\MediaFile;
17
use LeadersLinked\Library\Storage;
18
use LeadersLinked\Form\Media\FileForm;
19
use LeadersLinked\Mapper\MediaCategoryMapper;
20
use LeadersLinked\Model\VideoConvert;
21
use LeadersLinked\Mapper\VideoConvertMapper;
22
 
23
 
24
class MediaFileController extends AbstractActionController
25
{
26
    /**
27
     *
28
     * @var \Laminas\Db\Adapter\AdapterInterface
29
     */
30
    private $adapter;
31
 
32
    /**
33
     *
34
     * @var \LeadersLinked\Cache\CacheInterface
35
     */
36
    private $cache;
37
 
38
 
39
    /**
40
     *
41
     * @var \Laminas\Log\LoggerInterface
42
     */
43
    private $logger;
44
 
45
    /**
46
     *
47
     * @var array
48
     */
49
    private $config;
50
 
51
 
52
    /**
53
     *
54
     * @var \Laminas\Mvc\I18n\Translator
55
     */
56
    private $translator;
57
 
58
 
59
    /**
60
     *
61
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
62
     * @param \LeadersLinked\Cache\CacheInterface $cache
63
     * @param \Laminas\Log\LoggerInterface LoggerInterface $logger
64
     * @param array $config
65
     * @param \Laminas\Mvc\I18n\Translator $translator
66
     */
67
    public function __construct($adapter, $cache, $logger, $config, $translator)
68
    {
69
        $this->adapter      = $adapter;
70
        $this->cache        = $cache;
71
        $this->logger       = $logger;
72
        $this->config       = $config;
73
        $this->translator   = $translator;
74
    }
75
 
76
    /**
77
     *
78
     * Generación del listado de perfiles
79
     * {@inheritDoc}
80
     * @see \Laminas\Mvc\Controller\AbstractActionController::indexAction()
81
     */
82
    public function indexAction()
83
    {
84
        $request = $this->getRequest();
85
        $currentUserPlugin = $this->plugin('currentUserPlugin');
86
        $currentCompany = $currentUserPlugin->getCompany();
87
        $currentUser    = $currentUserPlugin->getUser();
88
 
89
 
90
        $request = $this->getRequest();
91
        if($request->isGet()) {
92
 
93
 
94
            $headers  = $request->getHeaders();
95
 
96
            $isJson = false;
97
            if($headers->has('Accept')) {
98
                $accept = $headers->get('Accept');
99
 
100
                $prioritized = $accept->getPrioritized();
101
 
102
                foreach($prioritized as $key => $value) {
103
                    $raw = trim($value->getRaw());
104
 
105
                    if(!$isJson) {
106
                        $isJson = strpos($raw, 'json');
107
                    }
108
 
109
                }
110
            }
111
 
112
           // $isJson = true;
113
            if($isJson) {
114
                $category = null;
115
                $uuid = \LeadersLinked\Library\Functions::sanitizeFilterString($this->params()->fromQuery('category'));
116
                if($uuid) {
117
                    $categoryMapper = \LeadersLinked\Mapper\MediaCategoryMapper::getInstance($this->adapter);
118
                    $category = $categoryMapper->fetchOneByUuid($uuid);
119
                    if(!$category) {
120
 
121
                        if(!$category) {
122
                            return new JsonModel([
123
                                'success'   => false,
124
                                'data'   => 'ERROR_MEDIA_CATEGORY_NOT_FOUND'
125
                            ]);
126
                        }
127
 
128
                        if($category->company_id != $currentCompany->id) {
129
                            return new JsonModel([
130
                                'success'   => false,
131
                                'data'   => 'ERROR_UNAUTHORIZED'
132
                            ]);
133
                        }
134
 
135
 
136
                    }
137
 
138
 
139
                }
140
 
141
                if(!$category) {
142
                    return new JsonModel([
143
                        'success' => true,
144
                        'data' => [
145
                            'items' => [],
146
                            'total' => 0,
147
                        ]
148
                    ]);
149
                }
150
 
151
                $search = $this->params()->fromQuery('search', []);
152
                $search = empty($search['value']) ? '' :  Functions::sanitizeFilterString($search['value']);
153
 
154
                $records_x_page     = intval($this->params()->fromQuery('length', 10), 10);
155
                $page               = (intval($this->params()->fromQuery('start', 1), 10)/$records_x_page)+1;
156
                $order =  $this->params()->fromQuery('order', []);
157
                $order_field        = empty($order[0]['column']) ? 99 :  intval($order[0]['column'], 10);
158
                $order_direction    = empty($order[0]['dir']) ? 'ASC' : strtoupper(Functions::sanitizeFilterString($order[0]['dir']));
159
 
160
                $fields =  ['name'];
161
                $order_field = isset($fields[$order_field]) ? $fields[$order_field] : 'name';
162
 
163
                if(!in_array($order_direction, ['ASC', 'DESC'])) {
164
                    $order_direction = 'ASC';
165
                }
166
 
167
 
168
                $storage = Storage::getInstance($this->config);
169
                $target_path = $storage->getPathMedia();
170
 
171
 
172
                $acl = $this->getEvent()->getViewModel()->getVariable('acl');
173
                $allowDelete = $acl->isAllowed($currentUser->usertype_id, 'media/files/delete');
174
 
175
 
176
                $mediaFileMapper = MediaFileMapper::getInstance($this->adapter);
177
 
178
                $paginator = $mediaFileMapper->fetchAllDataTableByCategoryId($category->id, $search, $page, $records_x_page, $order_field, $order_direction);
179
 
180
 
181
 
182
                $records = $paginator->getCurrentItems();
183
 
184
                $items = [];
185
                foreach($records as $record)
186
                {
187
 
188
 
189
                    if($record->type == MediaFile::TYPE_IMAGE) {
190
 
191
                        $urlFile = $storage->getGenericImage($target_path, $record->uuid, $record->file);
192
                    } else {
193
                        $urlFile = $storage->getGenericFile($target_path, $record->uuid, $record->file);
194
                    }
195
 
196
                    if($record->preview) {
197
                        $urlPreview = $storage->getGenericImage($target_path, $record->uuid, $record->preview);
198
                    } else {
199
                        $urlPreview = '';
200
                    }
201
 
202
 
203
                    $item = [
204
 
205
                        'name' => $record->name,
206
                        'file' => [
207
                           'filename'   => $record->file,
208
                           'url'        => $urlFile,
209
                            'type'      => $record->type,
210
                        ],
211
                        'preview'       => [
212
                            'filename'   => $record->preview,
213
                            'url'        => $urlPreview,
214
                        ],
215
                        'actions' => [
216
                            'link_delete' => $allowDelete ? $this->url()->fromRoute('media/files/delete', ['id' => $record->uuid ]) : '',
217
                        ]
218
 
219
 
220
                    ];
221
 
222
 
223
                    array_push($items, $item);
224
                }
225
 
226
 
227
 
228
                return new JsonModel([
229
                    'success' => true,
230
                    'data' => [
231
                        'items' => $items,
232
                        'total' => $paginator->getTotalItemCount(),
233
                    ]
234
                ]);
235
 
236
 
237
 
238
            } else {
239
 
240
                $categories = [];
241
 
242
                $categoryMapper = MediaCategoryMapper::getInstance($this->adapter);
243
                $records = $categoryMapper->fetchAllByCompanyId($currentCompany->id);
244
                foreach($records as $record)
245
                {
246
                    $categories[  $record->uuid ] = $record->name;
247
                }
248
 
249
 
250
                $form = new FileForm();
251
                $this->layout()->setTemplate('layout/layout-backend.phtml');
252
                $viewModel = new ViewModel();
253
                $viewModel->setTemplate('leaders-linked/media/files.phtml');
254
                $viewModel->setVariables([
255
                   'categories' => $categories,
256
                   'form' => $form,
257
 
258
 
259
                ]);
260
                return $viewModel ;
261
            }
262
 
263
        } else {
264
            return new JsonModel([
265
                'success' => false,
266
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
267
            ]);
268
        }
269
    }
270
 
271
    public function uploadAction()
272
    {
273
        $currentUserPlugin  = $this->plugin('currentUserPlugin');
274
        $currentCompany     = $currentUserPlugin->getCompany();
275
        $currentUser        = $currentUserPlugin->getUser();
276
 
277
        $request    = $this->getRequest();
278
 
279
        if($request->isPost()) {
280
 
281
            $category = null;
282
            $uuid = \LeadersLinked\Library\Functions::sanitizeFilterString($this->params()->fromPost('category'));
283
            if($uuid) {
284
                $categoryMapper = \LeadersLinked\Mapper\MediaCategoryMapper::getInstance($this->adapter);
285
                $category = $categoryMapper->fetchOneByUuid($uuid);
286
                if(!$category) {
287
 
288
                    if(!$category) {
289
                        return new JsonModel([
290
                            'success'   => false,
291
                            'data'   => 'ERROR_MEDIA_CATEGORY_NOT_FOUND'
292
                        ]);
293
                    }
294
 
295
                    if($category->company_id != $currentCompany->id) {
296
                        return new JsonModel([
297
                            'success'   => false,
298
                            'data'   => 'ERROR_UNAUTHORIZED'
299
                        ]);
300
                    }
301
 
302
 
303
                }
304
 
305
 
306
            }
307
 
308
            if(!$category) {
309
                return new JsonModel([
310
                    'success'   => false,
311
                    'data'   => 'ERROR_MEDIA_CATEGORY_NOT_FOUND'
312
                ]);
313
            }
314
 
315
 
316
            $form = new FileForm();
317
            $dataPost = array_merge($request->getPost()->toArray(), $request->getFiles()->toArray());
318
 
319
            $form->setData($dataPost);
320
 
321
            if($form->isValid()) {
322
                $dataPost = (array) $form->getData();
323
 
324
                $hydrator = new ObjectPropertyHydrator();
325
                $mediaFile = new MediaFile();
326
                $hydrator->hydrate($dataPost, $mediaFile);
327
 
328
                $mediaFile->category_id = $category->id;
329
                $mediaFile->company_id  = $category->company_id;
330
                $mediaFile->file        = 'tmp';
331
                $mediaFile->type        = 'tmp';
332
 
333
                $files = $this->getRequest()->getFiles()->toArray();
334
                $media_type = '';
335
                $media_tmp_filename = '';
336
                $media_filename = '';
337
 
338
                if (isset($files['file']) && empty($files['file']['error'])) {
339
                    $media_tmp_filename  = $files['file']['tmp_name'];
340
                    $media_filename      = $this->normalizeString($files['file']['name']);
341
 
342
                    $mime_type = mime_content_type($media_tmp_filename);
343
 
344
 
345
                    if ($mime_type == 'image/jpg' || $mime_type == 'image/jpeg' || $mime_type == 'image/png') {
346
                        $media_type = MediaFile::TYPE_IMAGE;
347
                    } else if ($mime_type ==  'video/quicktime' ||  $mime_type == 'video/webm' || $mime_type == 'video/mpeg' || $mime_type == 'video/mpg' || $mime_type == 'video/mp4') {
348
                        $media_type = MediaFile::TYPE_VIDEO;
349
                    } else if ($mime_type == 'audio/wav' || $mime_type == 'audio/mpeg') {
350
                        $media_type =  MediaFile::TYPE_AUDIO;
351
                    }
352
                }
353
 
354
 
355
 
356
 
357
                if(empty($media_type)) {
358
                   return new JsonModel([
359
                        'success'   => false,
360
                        'data'   => 'ERROR_MEDIA_CATEGORY_NOT_FOUND'
361
                    ]);
362
 
363
                }
364
 
365
 
366
 
367
                $fileMapper = MediaFileMapper::getInstance($this->adapter);
368
                if($fileMapper->insert($mediaFile)) {
369
                    $mediaFile = $fileMapper->fetchOne($mediaFile->id);
370
 
371
                    $storage = Storage::getInstance($this->config);
372
                    $target_path = $storage->getPathMedia();
373
                    $interal_path = 'data' . DIRECTORY_SEPARATOR . 'storage' . DIRECTORY_SEPARATOR . 'tmp';
374
                    if(!file_exists($interal_path)) {
375
                        mkdir($interal_path, 0775);
376
                    }
377
 
378
                    if ($media_type == MediaFile::TYPE_AUDIO) {
379
                        if($storage->moveAndPutFile($target_path, $mediaFile->uuid, $media_tmp_filename, $media_filename)) {
380
 
381
                            $mediaFile->type    = $media_type;
382
                            $mediaFile->file    = $media_filename;
383
 
384
                            $fileMapper->update($mediaFile);
385
                        }
386
 
387
                    } else if ($media_type == MediaFile::TYPE_IMAGE) {
388
                        $image = Image::getInstance($this->config);
389
 
390
                        $generate_media_filename = substr($media_filename, 0, strrpos($media_filename, '.')).  '.png';
391
                        $unlink_source = true;
392
 
393
                        if($image->uploadImageRaw($media_tmp_filename, $target_path, $mediaFile->uuid, $generate_media_filename, $unlink_source)) {
394
 
395
                            $mediaFile->type    = $media_type;
396
                            $mediaFile->file    = $media_filename;
397
 
398
 
399
                            $fileMapper->update($mediaFile);
400
                        }
401
                    } else if ($media_type == MediaFile::TYPE_VIDEO) {
402
                        try {
403
                            $full_filename          = $interal_path . DIRECTORY_SEPARATOR. $media_filename;
404
                            $poster_filename        = substr($media_filename, 0, strrpos($media_filename, '.')).  '.jpg';
405
                            $poster_full_filename   = $interal_path . DIRECTORY_SEPARATOR . $poster_filename;
406
 
407
                            move_uploaded_file($media_tmp_filename, $full_filename);
408
 
409
                            $cmd        = "/usr/bin/ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width,duration  $full_filename";
410
                            $response   = trim(shell_exec($cmd));
411
 
412
                            $source_duration = 0;
413
                            $lines = explode("\n", $response);
414
                            foreach ($lines as $line) {
415
                                $line = trim(strtolower($line));
416
                                if (strpos($line, 'duration') !== false) {
417
                                    $values = explode('=', $line);
418
                                    $source_duration = intval(str_replace($values[1], '#', ''), 10);
419
                                }
420
                            }
421
 
422
 
423
                            if ($source_duration == 0) {
424
                                $second_extract = '00:00:02';
425
                            } else {
426
                                if ($source_duration > 10) {
427
                                    $second_extract = '00:00:10';
428
                                } else {
429
                                    $second_extract = '00:00:02';
430
                                }
431
                            }
432
 
433
                            //$imageSize = $this->config['leaderslinked.image_sizes.feed_image_size'];
434
 
435
                            //$cmd = "/usr/bin/ffmpeg -y -i $full_filename  -pix_fmt yuvj422p -deinterlace -an -ss $second_extract -f mjpeg -t 1 -r 1 -y -s $imageSize $generateFile";
436
                            // $cmd = "/usr/bin/ffmpeg -y -i $full_filename  -pix_fmt yuvj422p -an -ss $second_extract -f mjpeg -t 1 -r 1 -y -s $imageSize $generateFile";
437
                            $cmd = "/usr/bin/ffmpeg -y -i $full_filename  -pix_fmt yuvj422p -an -ss $second_extract -f mjpeg -t 1 -r 1 -y  $poster_full_filename";
438
                            exec($cmd);
439
 
440
 
441
                            $ok = $storage->putFile($target_path, $mediaFile->uuid, $poster_full_filename);
442
                            $ok = $ok && $storage->putFile($target_path, $mediaFile->uuid, $full_filename);
443
 
444
                            if( $ok ) {
445
 
446
 
447
                                $mediaFile->type    = $media_type;
448
                                $mediaFile->file    = basename($media_filename);
449
                                $mediaFile->preview = basename($poster_filename);
450
 
451
                                if($fileMapper->update($mediaFile)) {
452
 
453
                                    $videoConvert = new VideoConvert();
454
                                    $videoConvert->uuid     = $mediaFile->uuid;
455
                                    $videoConvert->filename = basename($media_filename);
456
                                    $videoConvert->type     = VideoConvert::TYPE_MEDIA;
457
 
458
                                    $videoConvertMapper = VideoConvertMapper::getInstance($this->adapter);
459
                                    $videoConvertMapper->insert($videoConvert);
460
                                }
461
                            }
462
 
463
                           // @unlink($full_filename);
464
                            //@unlink($generate_full_filename);
465
 
466
 
467
 
468
                        } catch (\Throwable $e) {
469
 
470
                            $fileMapper->delete($mediaFile);
471
 
472
 
473
                            return new JsonModel([
474
                                'success'   => false,
475
                                'data'   => 'ERROR_UPLOAD_FILE'
476
                            ]);
477
 
478
                        }
479
                    }
480
 
481
                    $this->logger->info('Se agrego el archivo a la media library ' . $mediaFile->name, ['user_id' => $currentUser->id, 'ip' => Functions::getUserIP()]);
482
 
483
                    return new JsonModel([
484
                        'success'   => true,
485
                        'data'   => 'LABEL_RECORD_ADDED'
486
                    ]);
487
 
488
 
489
 
490
                } else {
491
                    $data = [
492
                        'success'   => false,
493
                        'data'      => $fileMapper->getError()
494
                    ];
495
 
496
                }
497
 
498
                return new JsonModel($data);
499
 
500
            } else {
501
                $messages = [];
502
                $form_messages = (array) $form->getMessages();
503
                foreach($form_messages  as $fieldname => $field_messages)
504
                {
505
 
506
                    $messages[$fieldname] = array_values($field_messages);
507
                }
508
 
509
                return new JsonModel([
510
                    'success'   => false,
511
                    'data'   => $messages
512
                ]);
513
            }
514
 
515
        } else {
516
            $data = [
517
                'success' => false,
518
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
519
            ];
520
 
521
            return new JsonModel($data);
522
        }
523
 
524
        return new JsonModel($data);
525
    }
526
 
527
    /**
528
     *
529
     * Borrar un perfil excepto el público
530
     * @return \Laminas\View\Model\JsonModel
531
     */
532
    public function deleteAction()
533
    {
534
        $currentUserPlugin  = $this->plugin('currentUserPlugin');
535
        $currentCompany     = $currentUserPlugin->getCompany();
536
        $currentUser        = $currentUserPlugin->getUser();
537
 
538
        $request    = $this->getRequest();
539
        $id   = $this->params()->fromRoute('id');
540
 
541
 
542
        $fileMapper = MediaFileMapper::getInstance($this->adapter);
543
        $file = $fileMapper->fetchOneByUuid($id);
544
        if(!$file) {
545
            return new JsonModel([
546
                'success'   => false,
547
                'data'   => 'ERROR_MEDIA_FILE_NOT_FOUND'
548
            ]);
549
        }
550
 
551
        if($file->company_id != $currentCompany->id) {
552
            return new JsonModel([
553
                'success'   => false,
554
                'data'   => 'ERROR_UNAUTHORIZED'
555
            ]);
556
        }
557
 
558
 
559
 
560
        if($request->isPost()) {
561
 
562
 
563
 
564
            $result = $fileMapper->delete($file);
565
            if($result) {
566
                $this->logger->info('Se borro el el archivo de la media query : ' .  $file->name, ['user_id' => $currentUser->id, 'ip' => Functions::getUserIP()]);
567
 
568
                $storage = Storage::getInstance($this->config);
569
                $target_path = $storage->getPathMedia();
570
 
571
                $storage->deleteFile($target_path, $file->uuid, $file->file);
572
 
573
 
574
                if($file->type == MediaFile::TYPE_VIDEO) {
575
                    $videoConvertMapper = VideoConvertMapper::getInstance($this->adapter);
576
                    $videoConvertMapper->deleteByUuidAndType($file->uuid, $file->type);
577
                }
578
 
579
 
580
                $data = [
581
                    'success' => true,
582
                    'data' => 'LABEL_RECORD_DELETED'
583
                ];
584
            } else {
585
 
586
                $data = [
587
                    'success'   => false,
588
                    'data'      => $fileMapper->getError()
589
                ];
590
 
591
                return new JsonModel($data);
592
            }
593
 
594
        } else {
595
            $data = [
596
                'success' => false,
597
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
598
            ];
599
 
600
            return new JsonModel($data);
601
        }
602
 
603
        return new JsonModel($data);
604
    }
605
 
606
    /**
607
     *
608
     * @param string $str
609
     * @return string
610
     */
611
    private function normalizeString($str = '')
612
    {
613
        $basename  = substr($str, 0, strrpos($str, '.'));
614
        $basename  = str_replace('.', '-', $basename);
615
 
616
        $extension  = substr($str, strrpos($str, '.'));
617
 
618
        $str = $basename . $extension;
619
 
620
        $str = strip_tags($str);
621
        $str = preg_replace('/[\r\n\t ]+/', ' ', $str);
622
        $str = preg_replace('/[\"\*\/\:\<\>\?\'\|\,]+/', ' ', $str);
623
        $str = strtolower($str);
624
        $str = html_entity_decode($str, ENT_QUOTES, "utf-8");
625
        $str = htmlentities($str, ENT_QUOTES, "utf-8");
626
        $str = preg_replace("/(&)([a-z])([a-z]+;)/i", '$2', $str);
627
        $str = str_replace(' ', '-', $str);
628
        $str = rawurlencode($str);
629
        $str = str_replace('%', '-', $str);
630
 
631
 
632
        return trim(strtolower($str));
633
    }
634
 
635
 
636
}