Proyectos de Subversion LeadersLinked - Services

Rev

Rev 822 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
283 www 1
<?php
546 ariadna 2
 
283 www 3
namespace LeadersLinked\Library;
4
 
5
use LeadersLinked\Model\User;
6
use LeadersLinked\Model\UserProfile;
7
use LeadersLinked\Model\Company;
8
use LeadersLinked\Model\Group;
9
 
345 www 10
class Storage
283 www 11
{
345 www 12
 
13
    const FILE_TYPE_IMAGE = 'image';
14
 
15
    const FILE_TYPE_VIDEO = 'video';
16
 
17
    const FILE_TYPE_DOCUMENT = 'document';
18
 
19
    const TYPE_DEFAULT = 'default';
20
 
21
    const TYPE_CHAT = 'chat';
22
 
23
    const TYPE_GROUP = 'group';
24
 
25
    const TYPE_USER = 'user';
26
 
27
    const TYPE_IMAGE = 'image';
28
 
29
    const TYPE_JOB = 'job';
30
 
31
    const TYPE_MEDIA = 'media';
32
 
33
    const TYPE_COMPANY = 'company';
34
 
35
    const TYPE_FEED = 'feed';
36
 
37
    const TYPE_POST = 'post';
38
 
39
    const TYPE_MICROLEARNING_TOPIC = 'topic';
40
 
41
    const TYPE_MICROLEARNING_CAPSULE = 'capsule';
42
 
43
    const TYPE_MICROLEARNING_SLIDE = 'slide';
44
 
45
    const TYPE_JOB_DESCRIPTION = 'jobdesc';
46
 
47
    const TYPE_SELF_EVALUATION = 'selfval';
48
 
49
    const TYPE_PERFORMANCE_EVALUATION = 'perfeva';
50
 
51
    const TYPE_RECRUITMENT_SELECTION = 'recrsel';
52
 
53
    const TYPE_PLANNING_OBJECTIVES_AND_GOALS = 'plannig';
54
 
55
    const TYPE_MESSAGE = 'message';
56
 
57
    const TYPE_SURVEY = 'survey';
58
 
59
    const TYPE_NETWORK = 'network';
60
 
61
    const TYPE_DAILY_PULSE = 'dailpuls';
62
 
63
    const TYPE_ENGAGEMENT_REWARD = 'engarewr';
64
 
65
    const TYPE_KNOWLEDGE_AREA = 'knowarea';
66
 
67
    const TYPE_MY_COACH = 'mycoach';
68
 
69
    const TYPE_HABIT_EMOJI = 'habit-emoji';
70
 
71
    const TYPE_HABIT_CONTENT = 'habit-content';
72
 
283 www 73
    /**
345 www 74
     *
75
     * @var\LeadersLinked\Library\Storage
283 www 76
     */
77
    private static $_instance;
345 www 78
 
283 www 79
    /**
345 www 80
     *
283 www 81
     * @var array
82
     */
83
    private $config;
345 www 84
 
283 www 85
    /**
345 www 86
     *
87
     * @var \Laminas\Db\Adapter\AdapterInterface
283 www 88
     */
333 www 89
    private $adapter;
345 www 90
 
91
    /**
92
     *
93
     * @var string
94
     */
95
    private $tempPath;
96
 
97
    /**
98
     *
99
     * @var string
100
     */
101
    private $storagePath;
102
 
103
    /**
104
     *
823 stevensc 105
     * @var string
106
     */
107
    private $fullStoragePath;
108
 
109
    /**
110
     *
345 www 111
     * @var array
112
     */
823 stevensc 113
    private $storageConfig;
114
 
115
    /**
116
     *
117
     * @var array
118
     */
345 www 119
    private $currentFile;
546 ariadna 120
 
121
 
345 www 122
    /**
123
     *
124
     * @var array
125
     */
126
    private $files;
333 www 127
 
283 www 128
    /**
345 www 129
     *
283 www 130
     * @param array $config
333 www 131
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
283 www 132
     */
345 www 133
    private function __construct($config, $adapter)
283 www 134
    {
345 www 135
        $this->config = $config;
136
        $this->adapter = $adapter;
137
        $this->currentFile = [];
138
 
823 stevensc 139
        // Cargar configuración desde storage.ini
140
        $this->loadStorageConfig();
141
 
142
        // Ruta relativa para BD
143
        $this->storagePath = str_replace('\\', '/', $this->storageConfig['base_path']);
144
 
145
        // Ruta completa para operaciones de archivo
146
        $this->fullStoragePath = str_replace('\\', '/', $this->storageConfig['full_path']);
147
 
148
        if (!file_exists($this->fullStoragePath)) {
149
            mkdir($this->fullStoragePath, 0775, true);
345 www 150
        }
151
 
823 stevensc 152
        $this->tempPath = str_replace('\\', '/', $this->storageConfig['temp_path']);
345 www 153
 
816 stevensc 154
        if (! file_exists($this->tempPath)) {
549 stevensc 155
            mkdir($this->tempPath, 0775, true);
345 www 156
        }
283 www 157
    }
345 www 158
 
283 www 159
    /**
345 www 160
     *
283 www 161
     * @param array $config
333 www 162
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
283 www 163
     * @return \LeadersLinked\Library\Storage
164
     */
333 www 165
    public static function getInstance($config, $adapter)
283 www 166
    {
345 www 167
        if (self::$_instance == null) {
333 www 168
            self::$_instance = new Storage($config, $adapter);
283 www 169
        }
345 www 170
 
283 www 171
        return self::$_instance;
172
    }
345 www 173
 
174
    /**
175
     *
176
     * @return string
177
     */
178
    public function getFullPathImageDefault()
179
    {
823 stevensc 180
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image.jpg';
345 www 181
    }
182
 
183
    /**
184
     *
185
     * @return string
186
     */
187
    public function getFullPathImageUserDefault()
188
    {
823 stevensc 189
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-user.jpg';
345 www 190
    }
191
 
192
    /**
193
     *
194
     * @return string
195
     */
196
    public function getFullPathImageUserPofileDefault()
197
    {
823 stevensc 198
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-user-profile.png';
345 www 199
    }
200
 
201
    /**
202
     *
203
     * @return string
204
     */
205
    public function getFullPathImageUserCoverDefault()
206
    {
823 stevensc 207
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-cover.jpg';
345 www 208
    }
209
 
210
    /**
211
     *
212
     * @return string
213
     */
214
    public function getFullPathImageCompanyDefault()
215
    {
823 stevensc 216
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-company.jpg';
345 www 217
    }
218
 
219
    /**
220
     *
221
     * @return string
222
     */
223
    public function getFullPathImageCompanyCoverDefault()
224
    {
823 stevensc 225
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-cover.jpg';
345 www 226
    }
227
 
228
    /**
229
     *
230
     * @return string
231
     */
232
    public function getFullPathImageGroupDefault()
233
    {
823 stevensc 234
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-group.jpg';
345 www 235
    }
236
 
237
    /**
238
     *
239
     * @return string
240
     */
241
    public function getFullPathImageGroupCoverDefault()
242
    {
823 stevensc 243
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'no-image-cover.jpg';
345 www 244
    }
245
 
246
    /**
247
     *
248
     * @return string
249
     */
250
    public function getFullPathImageCompanyHeaderPdfDefault()
251
    {
823 stevensc 252
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'default' . DIRECTORY_SEPARATOR . 'company-header.png';
345 www 253
    }
254
 
255
    /**
256
     *
257
     * @return string
258
     */
259
    public function getFullPathImageCompanyFooterPdfDefault()
260
    {
823 stevensc 261
        return $this->fullStoragePath . DIRECTORY_SEPARATOR . 'default' . DIRECTORY_SEPARATOR . 'company-footer.png';
345 www 262
    }
263
 
264
    /**
823 stevensc 265
     * Carga la configuración desde el archivo storage.ini
266
     */
267
    private function loadStorageConfig()
268
    {
269
        $iniPath = 'config' . DIRECTORY_SEPARATOR . 'storage.ini';
270
        if (file_exists($iniPath)) {
271
            $ini = parse_ini_file($iniPath, true);
272
            $this->storageConfig = [
273
                'base_path' => $ini['storage']['base_path'] ?? 'data/storage',
274
                'full_path' => $ini['storage']['full_path'] ?? 'data/storage',
275
                'base_url' => $ini['storage']['base_url'] ?? '',
276
                'temp_path' => $ini['temp']['temp_path'] ?? 'data/storage/tmp'
277
            ];
278
        } else {
279
            // Configuración por defecto si no existe el archivo .ini
280
            $this->storageConfig = [
281
                'base_path' => 'data/storage',
282
                'full_path' => 'data/storage',
283
                'base_url' => '',
284
                'temp_path' => 'data/storage/tmp'
285
            ];
286
        }
287
    }
288
 
289
    /**
290
     * Convierte una ruta relativa a ruta completa para operaciones de archivo
291
     * @param string $relativePath
292
     * @return string
293
     */
294
    private function getFullPathFromRelative($relativePath)
295
    {
296
        // Si la ruta ya es absoluta, la devolvemos tal como está
297
        if (strpos($relativePath, $this->fullStoragePath) === 0) {
298
            return $relativePath;
299
        }
300
 
301
        // Reemplazar la ruta base relativa con la ruta completa
302
        return str_replace($this->storagePath, $this->fullStoragePath, $relativePath);
303
    }
304
 
305
    /**
306
     * Convierte una ruta completa a ruta relativa para almacenar en BD
307
     * @param string $fullPath
308
     * @return string
309
     */
310
    private function getRelativePathFromFull($fullPath)
311
    {
312
        // Si ya es una ruta relativa, la devolvemos tal como está
313
        if (strpos($fullPath, $this->fullStoragePath) !== 0) {
314
            return $fullPath;
315
        }
316
 
317
        // Reemplazar la ruta completa con la ruta relativa
318
        return str_replace($this->fullStoragePath, $this->storagePath, $fullPath);
319
    }
320
 
321
    /**
345 www 322
     *
323
     * @return string
324
     */
325
    public function getStoagePath()
326
    {
327
        return $this->storagePath;
328
    }
329
 
330
    /**
823 stevensc 331
     * Obtiene la ruta completa para operaciones de archivo
332
     * @return string
333
     */
334
    public function getFullStoragePath()
335
    {
336
        return $this->fullStoragePath;
337
    }
338
 
339
    /**
345 www 340
     *
341
     * @return string
342
     */
343
    public function getTempPath()
344
    {
345
        return $this->tempPath;
346
    }
347
 
348
    /**
349
     *
350
     * @return array
351
     */
352
    public function getCurrentFile()
353
    {
354
        return $this->currentFile;
355
    }
356
 
357
    /**
358
     *
359
     * @param array $currentFile
360
     */
361
    public function setCurrentFile($currentFile)
362
    {
363
        $this->currentFile = $currentFile;
364
    }
365
 
366
    /**
367
     *
368
     * @param array $filename
369
     */
370
    public function setCurrentFilename($filename)
371
    {
546 ariadna 372
        if (empty($this->files)) {
345 www 373
            if (isset($_FILES[$filename]) && empty($_FILES[$filename]['error'])) {
374
                $this->currentFile = $_FILES[$filename];
375
            } else {
376
                $this->currentFile = [];
377
            }
378
        } else {
379
            if (isset($this->files[$filename]) && empty($this->files[$filename]['error'])) {
380
                $this->currentFile = $this->files[$filename];
381
            } else {
382
                $this->currentFile = [];
383
            }
384
        }
546 ariadna 385
 
345 www 386
        return !empty($this->currentFile);
387
    }
546 ariadna 388
 
283 www 389
    /**
390
     *
345 www 391
     * @return boolean
392
     */
393
    public function hasFile()
394
    {
395
        return !empty($this->currentFile);
396
    }
546 ariadna 397
 
345 www 398
    /**
399
     *
400
     * @param array $files
401
     */
402
    public function setFiles($files)
403
    {
404
        $this->files = $files;
405
    }
406
 
407
    /**
408
     *
409
     * @param string $type
410
     * @param string $code
411
     * @param string $filename
412
     * @return string
413
     */
414
    public function composePathToFilename($type, $code, $filename)
415
    {
416
        $path = $this->getPathByType($type);
417
        $path = $path . DIRECTORY_SEPARATOR . $code;
823 stevensc 418
        if (!file_exists($path)) {
419
            mkdir($path, 0775, true);
345 www 420
        }
421
        return $path . DIRECTORY_SEPARATOR . $filename;
422
    }
423
 
424
    /**
425
     *
426
     * @param string $type
427
     * @param string $code
428
     * @return string
429
     */
430
    public function composePathToDirectory($type, $code)
431
    {
432
        $path = $this->getPathByType($type);
433
        $path = $path . DIRECTORY_SEPARATOR . $code;
434
        if (! file_exists($path)) {
553 stevensc 435
            mkdir($path, 0775, true);
345 www 436
        }
437
        return $path;
438
    }
439
 
440
    /**
553 stevensc 441
     * Private helper to get a presigned URL for an entity's image/cover or its default.
345 www 442
     *
553 stevensc 443
     * @param string $entityType The type of the entity (e.g., self::TYPE_USER).
444
     * @param string $entityUuid The UUID of the entity.
445
     * @param string|null $imageFilename The filename of the image/cover, if it exists.
446
     * @param string $defaultImageMethodName The name of the method in this class to get the full path to the default image.
447
     * @return string The presigned URL.
283 www 448
     */
553 stevensc 449
    private function _getProcessedImageOrCoverUrl($entityType, $entityUuid, $imageFilename, $defaultImageMethodName)
283 www 450
    {
553 stevensc 451
        if ($imageFilename) {
452
            $remoto = $this->composePathToFilename($entityType, $entityUuid, $imageFilename);
345 www 453
            if (file_exists($remoto)) {
333 www 454
                return $this->getPresignedUrl($remoto);
283 www 455
            }
456
        }
553 stevensc 457
        // If imageFilename is null/empty, or the specific file doesn't exist, use the default.
458
        $defaultFullPath = $this->$defaultImageMethodName();
459
        return $this->getPresignedUrl($defaultFullPath);
460
    }
345 www 461
 
553 stevensc 462
    /**
463
     *
464
     * @param User $user
465
     * @return string
466
     */
467
    public function getUserImage($user)
468
    {
469
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $user->uuid, $user->image, 'getFullPathImageUserDefault');
283 www 470
    }
345 www 471
 
283 www 472
    /**
473
     *
474
     * @param User $user
475
     * @return string
476
     */
477
    public function getUserImageForCodeAndFilename($code, $filename)
478
    {
553 stevensc 479
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $code, $filename, 'getFullPathImageUserDefault');
283 www 480
    }
345 www 481
 
283 www 482
    /**
483
     *
484
     * @param User $user
485
     * @param UserProfile $userProfile
486
     * @return string
487
     */
488
    public function getUserProfileImage($user, $userProfile)
489
    {
553 stevensc 490
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $user->uuid, $userProfile->image, 'getFullPathImageUserPofileDefault');
283 www 491
    }
345 www 492
 
283 www 493
    /**
494
     *
495
     * @param User $user
496
     * @param UserProfile $userProfile
497
     * @return string
498
     */
499
    public function getUserProfileCover($user, $userProfile)
500
    {
553 stevensc 501
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_USER, $user->uuid, $userProfile->cover, 'getFullPathImageUserCoverDefault');
283 www 502
    }
345 www 503
 
283 www 504
    /**
505
     *
506
     * @param Company $company
507
     * @return string
508
     */
509
    public function getCompanyImage($company)
510
    {
553 stevensc 511
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $company->uuid, $company->image, 'getFullPathImageCompanyDefault');
283 www 512
    }
345 www 513
 
283 www 514
    /**
515
     *
516
     * @param string $code
517
     * @param string $filename
518
     * @return string
519
     */
520
    public function getCompanyImageForCodeAndFilename($code, $filename)
521
    {
553 stevensc 522
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $code, $filename, 'getFullPathImageCompanyDefault');
283 www 523
    }
345 www 524
 
283 www 525
    /**
526
     *
527
     * @param Company $company
528
     * @return string
529
     */
530
    public function getCompanyCover($company)
531
    {
553 stevensc 532
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $company->uuid, $company->cover, 'getFullPathImageCompanyCoverDefault');
283 www 533
    }
345 www 534
 
283 www 535
    /**
536
     *
537
     * @param Group $group
538
     * @return string
539
     */
540
    public function getGroupImage($group)
541
    {
553 stevensc 542
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_GROUP, $group->uuid, $group->image, 'getFullPathImageGroupDefault');
283 www 543
    }
345 www 544
 
283 www 545
    /**
546
     *
547
     * @param string $code
548
     * @param string $filename
549
     * @return string
550
     */
551
    public function getGroupImageForCodeAndFilename($code, $filename)
552
    {
672 ariadna 553
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_GROUP, $code, $filename, 'getFullPathImageGroupDefault');
283 www 554
    }
345 www 555
 
668 ariadna 556
 
283 www 557
    /**
558
     *
559
     * @param Group $group
560
     * @return string
561
     */
562
    public function getGroupCover($group)
563
    {
672 ariadna 564
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_GROUP, $group->uuid, $group->cover, 'getFullPathImageGroupCoverDefault');
283 www 565
    }
345 www 566
 
668 ariadna 567
    public function getGroupCoverForCodeAndFilename($code, $filename)
568
    {
569
        return $this->_getProcessedImageOrCoverUrl(self::TYPE_COMPANY, $code, $filename, 'getFullPathCoverGroupDefault');
570
    }
571
 
283 www 572
    /**
573
     *
574
     * @param Group $group
575
     * @return string
576
     */
577
    public function getGenericImage($path, $code, $filename)
578
    {
345 www 579
        $remoto = $path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . $filename;
580
 
581
        if (file_exists($remoto)) {
333 www 582
            return $this->getPresignedUrl($remoto);
283 www 583
        }
345 www 584
 
755 stevensc 585
        $remoto = $path . DIRECTORY_SEPARATOR . $filename;
586
 
587
        if (file_exists($remoto)) {
588
            return $this->getPresignedUrl($remoto);
589
        }
590
 
345 www 591
        $remoto = $this->getFullPathImageDefault();
592
        return $this->getPresignedUrl($remoto);
283 www 593
    }
334 www 594
 
595
    /**
596
     *
597
     * @param string $path
598
     * @param string $code,
599
     * @param string $filename
600
     * @return string
601
     */
345 www 602
    public function getGenericFile($path, $code, $filename)
334 www 603
    {
345 www 604
        $remoto = $path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . $filename;
546 ariadna 605
 
345 www 606
        if (file_exists($remoto)) {
546 ariadna 607
            if ($code == 'd8e6c5de-52a6-4c28-bdce-4ba2823ba841') {
608
 
345 www 609
                error_log('getGenericFile = ' . $remoto);
610
            }
546 ariadna 611
 
612
 
333 www 613
            return $this->getPresignedUrl($remoto);
614
        }
760 stevensc 615
 
616
        $remoto = $path . DIRECTORY_SEPARATOR . $filename;
617
 
618
        if (file_exists($remoto)) {
619
            return $this->getPresignedUrl($remoto);
620
        }
621
 
622
        $remoto = $this->getFullPathImageDefault();
623
        return $this->getPresignedUrl($remoto);
333 www 624
    }
546 ariadna 625
 
345 www 626
    public function getPathDefault()
333 www 627
    {
345 www 628
        return $this->getPathByType(self::TYPE_DEFAULT);
333 www 629
    }
546 ariadna 630
 
345 www 631
    public function getPathChat()
320 www 632
    {
345 www 633
        return $this->getPathByType(self::TYPE_CHAT);
320 www 634
    }
546 ariadna 635
 
283 www 636
    public function getPathGroup()
637
    {
345 www 638
        return $this->getPathByType(self::TYPE_GROUP);
283 www 639
    }
546 ariadna 640
 
283 www 641
    public function getPathUser()
642
    {
345 www 643
        return $this->getPathByType(self::TYPE_USER);
283 www 644
    }
546 ariadna 645
 
283 www 646
    public function getPathImage()
647
    {
345 www 648
        return $this->getPathByType(self::TYPE_IMAGE);
283 www 649
    }
546 ariadna 650
 
283 www 651
    public function getPathJob()
652
    {
345 www 653
        return $this->getPathByType(self::TYPE_JOB);
283 www 654
    }
546 ariadna 655
 
283 www 656
    public function getPathCompany()
657
    {
345 www 658
        return $this->getPathByType(self::TYPE_COMPANY);
283 www 659
    }
546 ariadna 660
 
661
 
283 www 662
    public function getPathFeed()
663
    {
345 www 664
        return $this->getPathByType(self::TYPE_FEED);
283 www 665
    }
546 ariadna 666
 
345 www 667
    public function getPathMedia()
295 www 668
    {
345 www 669
        return $this->getPathByType(self::TYPE_MEDIA);
295 www 670
    }
546 ariadna 671
 
283 www 672
    public function getPathPost()
673
    {
345 www 674
        return $this->getPathByType(self::TYPE_POST);
283 www 675
    }
546 ariadna 676
 
677
 
283 www 678
    public function getPathMicrolearningTopic()
679
    {
345 www 680
        return $this->getPathByType(self::TYPE_MICROLEARNING_TOPIC);
283 www 681
    }
546 ariadna 682
 
283 www 683
    public function getPathMicrolearningCapsule()
684
    {
345 www 685
        return $this->getPathByType(self::TYPE_MICROLEARNING_CAPSULE);
283 www 686
    }
546 ariadna 687
 
283 www 688
    public function getPathMicrolearningSlide()
689
    {
345 www 690
        return $this->getPathByType(self::TYPE_MICROLEARNING_SLIDE);
283 www 691
    }
546 ariadna 692
 
283 www 693
    public function getPathJobDescription()
694
    {
345 www 695
        return $this->getPathByType(self::TYPE_JOB_DESCRIPTION);
283 www 696
    }
546 ariadna 697
 
295 www 698
    public function getPathSelfEvaluation()
283 www 699
    {
345 www 700
        return $this->getPathByType(self::TYPE_SELF_EVALUATION);
283 www 701
    }
546 ariadna 702
 
345 www 703
    public function getPathPerformanceEvaluation()
704
    {
705
        return $this->getPathByType(self::TYPE_PERFORMANCE_EVALUATION);
706
    }
546 ariadna 707
 
708
 
283 www 709
    public function getPathRecruitmentSelection()
710
    {
345 www 711
        return $this->getPathByType(self::TYPE_RECRUITMENT_SELECTION);
283 www 712
    }
546 ariadna 713
 
714
 
345 www 715
    public function getPathPlanningObjectivesAndGoals()
283 www 716
    {
345 www 717
        return $this->getPathByType(self::TYPE_PLANNING_OBJECTIVES_AND_GOALS);
283 www 718
    }
546 ariadna 719
 
345 www 720
    public function getPathMessage()
283 www 721
    {
345 www 722
        return $this->getPathByType(self::TYPE_MESSAGE);
283 www 723
    }
546 ariadna 724
 
725
 
283 www 726
    public function getPathSurvey()
727
    {
345 www 728
        return $this->getPathByType(self::TYPE_SURVEY);
283 www 729
    }
546 ariadna 730
 
731
 
283 www 732
    public function getPathNetwork()
733
    {
345 www 734
        return $this->getPathByType(self::TYPE_NETWORK);
283 www 735
    }
546 ariadna 736
 
737
 
345 www 738
    public function getPathDailyPulse()
283 www 739
    {
345 www 740
        return $this->getPathByType(self::TYPE_DAILY_PULSE);
283 www 741
    }
345 www 742
 
546 ariadna 743
 
345 www 744
    public function getPathEngagementReward()
283 www 745
    {
345 www 746
        return $this->getPathByType(self::TYPE_ENGAGEMENT_REWARD);
283 www 747
    }
546 ariadna 748
 
283 www 749
    public function getPathKnowledgeArea()
750
    {
345 www 751
        return $this->getPathByType(self::TYPE_KNOWLEDGE_AREA);
283 www 752
    }
546 ariadna 753
 
283 www 754
    public function getPathMyCoach()
755
    {
345 www 756
        return $this->getPathByType(self::TYPE_MY_COACH);
283 www 757
    }
546 ariadna 758
 
345 www 759
    public function getPathHabitEmoji()
283 www 760
    {
345 www 761
        return $this->getPathByType(self::TYPE_HABIT_EMOJI);
283 www 762
    }
345 www 763
 
764
    public function getPathHabitContent()
283 www 765
    {
345 www 766
        return $this->getPathByType(self::TYPE_HABIT_CONTENT);
767
    }
768
 
769
 
770
    public function getPathByType($type)
771
    {
772
        switch ($type) {
773
            case self::TYPE_DEFAULT:
823 stevensc 774
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'default';
345 www 775
                break;
776
 
777
            case self::TYPE_CHAT:
823 stevensc 778
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'chat';
345 www 779
                break;
780
 
781
            case self::TYPE_GROUP:
823 stevensc 782
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'group';
345 www 783
                break;
784
 
785
            case self::TYPE_USER:
823 stevensc 786
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'user';
345 www 787
                break;
788
 
789
            case self::TYPE_IMAGE:
823 stevensc 790
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'image';
345 www 791
                break;
792
 
793
            case self::TYPE_JOB:
823 stevensc 794
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'job';
345 www 795
                break;
796
 
797
            case self::TYPE_COMPANY:
823 stevensc 798
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'company';
345 www 799
                break;
800
 
801
            case self::TYPE_FEED:
823 stevensc 802
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'feed';
345 www 803
                break;
804
 
805
            case self::TYPE_MEDIA:
823 stevensc 806
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'media';
345 www 807
                break;
808
 
809
            case self::TYPE_POST:
823 stevensc 810
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'post';
345 www 811
                break;
812
 
813
            case self::TYPE_MICROLEARNING_TOPIC:
823 stevensc 814
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'microlearning' . DIRECTORY_SEPARATOR . 'topic';
345 www 815
                break;
816
 
817
            case self::TYPE_MICROLEARNING_CAPSULE:
823 stevensc 818
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'microlearning' . DIRECTORY_SEPARATOR . 'capsule';
345 www 819
                break;
820
 
821
            case self::TYPE_MICROLEARNING_SLIDE:
823 stevensc 822
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'microlearning' . DIRECTORY_SEPARATOR . 'slide';
345 www 823
                break;
824
 
825
            case self::TYPE_JOB_DESCRIPTION:
823 stevensc 826
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'job-description';
345 www 827
                break;
828
 
829
            case self::TYPE_SELF_EVALUATION:
823 stevensc 830
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'self-evaluation';
345 www 831
                break;
832
 
833
            case self::TYPE_PERFORMANCE_EVALUATION:
823 stevensc 834
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'performance-evaluation';
345 www 835
                break;
836
 
837
            case self::TYPE_RECRUITMENT_SELECTION:
823 stevensc 838
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'recruitment-selection';
345 www 839
                break;
840
 
841
            case self::TYPE_PLANNING_OBJECTIVES_AND_GOALS:
823 stevensc 842
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'planning-objectives-and-goals';
345 www 843
                break;
844
 
845
            case self::TYPE_MESSAGE:
823 stevensc 846
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'message';
345 www 847
                break;
848
 
849
            case self::TYPE_SURVEY:
823 stevensc 850
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'survey';
345 www 851
                break;
852
 
853
            case self::TYPE_NETWORK:
823 stevensc 854
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'network';
345 www 855
                break;
856
 
857
            case self::TYPE_DAILY_PULSE:
823 stevensc 858
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'daily-pulse';
345 www 859
                break;
860
 
861
            case self::TYPE_ENGAGEMENT_REWARD:
823 stevensc 862
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'engagement-reward';
345 www 863
                break;
864
 
865
            case self::TYPE_KNOWLEDGE_AREA:
823 stevensc 866
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'knowledge-area';
345 www 867
                break;
868
 
869
            case self::TYPE_MY_COACH:
823 stevensc 870
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'my-coach';
345 www 871
                break;
872
 
873
            case self::TYPE_HABIT_EMOJI:
823 stevensc 874
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'habit' . DIRECTORY_SEPARATOR . 'emoji';
345 www 875
                break;
876
 
877
            case self::TYPE_HABIT_CONTENT:
823 stevensc 878
                $path = $this->fullStoragePath . DIRECTORY_SEPARATOR . 'habit' . DIRECTORY_SEPARATOR . 'content';
345 www 879
                break;
880
 
881
            default:
823 stevensc 882
                $path = $this->fullStoragePath;
345 www 883
                break;
334 www 884
        }
345 www 885
 
886
        if (! file_exists($path)) {
887
            mkdir($path, 0775, true);
888
        }
889
 
890
        return $path;
283 www 891
    }
345 www 892
 
283 www 893
    /**
894
     *
895
     * @param string $path
896
     * @param string $code
897
     * @param string $filename
345 www 898
     * @return string
283 www 899
     */
900
    public function deleteFile($path, $code, $filename)
901
    {
345 www 902
        $remoto = $path . DIRECTORY_SEPARATOR . $code . DIRECTORY_SEPARATOR . $filename;
553 stevensc 903
        if (file_exists($remoto)) {
904
            return unlink($remoto);
283 www 905
        } else {
906
            return true;
907
        }
908
    }
345 www 909
 
295 www 910
    /**
911
     *
549 stevensc 912
     * @param string $type
295 www 913
     * @param string $code
914
     * @return boolean
915
     */
549 stevensc 916
    public function deleteDirectory($type, $code)
295 www 917
    {
549 stevensc 918
        $path = $this->getPathByType($type);
919
        $remoto = $path . DIRECTORY_SEPARATOR . $code;
345 www 920
        if (file_exists($remoto)) {
334 www 921
            $this->deleteDirectoryRecursive($remoto);
922
            return true;
295 www 923
        } else {
924
            return true;
925
        }
926
    }
345 www 927
 
334 www 928
    /**
929
     *
930
     * @param string $dir
931
     */
345 www 932
    private function deleteDirectoryRecursive($dir)
933
    {
334 www 934
        if (is_dir($dir)) {
935
            $objects = scandir($dir);
936
            foreach ($objects as $object) {
345 www 937
                if ($object != '.' && $object != '..') {
938
                    $s = $dir . DIRECTORY_SEPARATOR . $object;
939
                    if (is_dir($s) && ! is_link($s)) {
549 stevensc 940
                        $this->deleteDirectoryRecursive($s);
345 www 941
                    } else {
553 stevensc 942
                        unlink($s);
334 www 943
                    }
944
                }
945
            }
553 stevensc 946
            rmdir($dir);
334 www 947
        }
948
    }
283 www 949
 
950
    /**
951
     *
952
     * @param string $path
953
     * @param string $code
290 www 954
     * @param string $local_filename
283 www 955
     * @return boolean
956
     */
345 www 957
    public function putFile($source_file, $target_file)
283 www 958
    {
553 stevensc 959
        return rename($source_file, $target_file);
345 www 960
    }
961
 
962
    /**
963
     *
964
     * @param string $tempfile
965
     * @param string $path
966
     * @param string $code
967
     * @param string $filename
968
     * @return boolean
969
     */
970
    public function moveUploadedFile($source_file, $target_file)
971
    {
553 stevensc 972
        return move_uploaded_file($source_file, $target_file);
345 www 973
    }
974
 
975
    /**
976
     *
346 www 977
     * @param string $tempfile
978
     * @param string $path
979
     * @param string $code
980
     * @param string $filename
981
     * @return boolean
982
     */
983
    public function copyFile($source_file, $target_file)
984
    {
553 stevensc 985
        return copy($source_file, $target_file);
346 www 986
    }
546 ariadna 987
 
988
 
346 www 989
    /**
990
     *
345 www 991
     * @param string $url
992
     * @return string
993
     */
994
    public function getPresignedUrl($url)
995
    {
823 stevensc 996
        // Convertir la ruta completa a ruta relativa para almacenar en BD
997
        $relativePath = $this->getRelativePathFromFull($url);
345 www 998
        $code = hash('sha256', $url);
546 ariadna 999
 
345 www 1000
        $storageFileMapper = \LeadersLinked\Mapper\StorageFileMapper::getInstance($this->adapter);
1001
        $storageFile = $storageFileMapper->fetchOneByCode($code);
1002
        if (! $storageFile) {
1003
            $storageFile = new \LeadersLinked\Model\StorageFile();
1004
            $storageFile->code = $code;
823 stevensc 1005
            // Guardar la ruta relativa en la base de datos
1006
            $storageFile->path = $relativePath;
345 www 1007
            $storageFile->salt = \LeadersLinked\Library\Functions::generatePassword(8);
1008
 
1009
            $storageFileMapper->insert($storageFile);
334 www 1010
        }
345 www 1011
 
1012
        $url = 'https://' . $_SERVER['SERVER_NAME'] . '/storage/' . $code;
668 ariadna 1013
 
345 www 1014
        return $url;
1015
    }
290 www 1016
 
345 www 1017
    /**
823 stevensc 1018
     * Obtiene la ruta completa del archivo basado en el código almacenado
1019
     * @param string $code
1020
     * @return string|null
1021
     */
1022
    public function getFilePathByCode($code)
1023
    {
1024
        $storageFileMapper = \LeadersLinked\Mapper\StorageFileMapper::getInstance($this->adapter);
1025
        $storageFile = $storageFileMapper->fetchOneByCode($code);
1026
 
1027
        if ($storageFile && $storageFile->path) {
1028
            // Convertir la ruta relativa almacenada en BD a ruta completa
1029
            return $this->getFullPathFromRelative($storageFile->path);
1030
        }
1031
 
1032
        return null;
1033
    }
1034
 
1035
    /**
1036
     * Verifica si un archivo existe usando el código almacenado
1037
     * @param string $code
1038
     * @return bool
1039
     */
1040
    public function fileExistsByCode($code)
1041
    {
1042
        $filePath = $this->getFilePathByCode($code);
1043
        return $filePath && file_exists($filePath);
1044
    }
1045
 
1046
    /**
345 www 1047
     *
1048
     * @return @return void|string
1049
     */
1050
    public function getFilenamePNG()
1051
    {
1052
        if ($this->currentFile) {
1053
            $filename = $this->normalizeStringFilename($this->currentFile['name']);
1054
            $path_parts = pathinfo($filename);
1055
            return $path_parts['filename'] . '.png';
1056
        } else {
1057
            return;
1058
        }
1059
    }
333 www 1060
 
345 www 1061
    /**
1062
     *
1063
     * @return @return void|string
1064
     */
1065
    public function getTmpFilename()
1066
    {
1067
        if ($this->currentFile) {
1068
            return $this->currentFile['tmp_name'];
1069
        } else {
1070
            return;
1071
        }
283 www 1072
    }
345 www 1073
 
283 www 1074
    /**
1075
     *
345 www 1076
     * @return @return void|string
283 www 1077
     */
345 www 1078
    public function getFilename()
283 www 1079
    {
345 www 1080
        if ($this->currentFile) {
1081
            return $this->normalizeStringFilename($this->currentFile['name']);
283 www 1082
        } else {
345 www 1083
            return;
283 www 1084
        }
345 www 1085
    }
334 www 1086
 
345 www 1087
    /**
1088
     *
1089
     * @return void|string
1090
     */
1091
    public function getFileType()
1092
    {
1093
        if ($this->currentFile) {
1094
            $tmp_name = $this->currentFile['tmp_name'];
1095
            $mime_type = mime_content_type($tmp_name);
1096
            if ($mime_type == 'image/jpg' || $mime_type == 'image/jpeg' || $mime_type == 'image/png') {
1097
                return self::FILE_TYPE_IMAGE;
1098
            } else if ($mime_type == 'video/quicktime' || $mime_type == 'video/webm' || $mime_type == 'video/mpeg' || $mime_type == 'video/mpg' || $mime_type == 'video/mp4') {
1099
                return self::FILE_TYPE_VIDEO;
1100
            } else if ($mime_type == 'application/pdf') {
1101
                return self::FILE_TYPE_DOCUMENT;
1102
            } else {
1103
                return;
1104
            }
1105
        } else {
1106
            return;
334 www 1107
        }
283 www 1108
    }
345 www 1109
 
1110
    /**
1111
     *
1112
     * @return void|string
1113
     */
1114
    public function getExtension()
1115
    {
1116
        if ($this->currentFile) {
1117
            $path_parts = pathinfo($this->currentFile['name']);
1118
            $ext = $path_parts['extension'];
1119
            return $ext;
1120
        } else {
1121
            return;
1122
        }
1123
    }
546 ariadna 1124
 
283 www 1125
    /**
553 stevensc 1126
     * Creates a new GD image resource with transparency settings for PNG.
1127
     * @param int $width The width of the new image.
1128
     * @param int $height The height of the new image.
1129
     * @return \GdImage|false The image resource or false on failure.
1130
     */
1131
    private function _createImageCanvas($width, $height)
1132
    {
1133
        $new_image = imageCreateTrueColor($width, $height);
1134
        if ($new_image === false) {
1135
            error_log("_createImageCanvas: imageCreateTrueColor failed for dimensions {$width}x{$height}.");
1136
            return false;
1137
        }
1138
        imageAlphaBlending($new_image, False);
1139
        imageSaveAlpha($new_image, True);
1140
        $transparent = imageColorAllocateAlpha($new_image, 0, 0, 0, 127);
1141
        if ($transparent === false) {
1142
            error_log("_createImageCanvas: imageColorAllocateAlpha failed.");
1143
            imagedestroy($new_image);
1144
            return false;
1145
        }
1146
        imagefill($new_image, 0, 0, $transparent);
1147
        return $new_image;
1148
    }
1149
 
1150
    /**
1151
     * Saves a GD image resource as PNG, unlinks source, and cleans up image resource.
1152
     * @param \GdImage $imageResource The GD image resource to save.
1153
     * @param string $targetFilename The path to save the PNG file to.
1154
     * @param string $sourceFilenameToUnlink The path to the source file to unlink.
1155
     * @return bool True on success, false on failure.
1156
     */
1157
    private function _savePngAndCleanup($imageResource, $targetFilename, $sourceFilenameToUnlink)
1158
    {
823 stevensc 1159
        $save_success = imagepng($imageResource, $targetFilename);
553 stevensc 1160
        imagedestroy($imageResource); // Clean up the image resource
1161
 
1162
        if ($save_success) {
1163
            if ($sourceFilenameToUnlink && file_exists($sourceFilenameToUnlink)) {
1164
                unlink($sourceFilenameToUnlink);
1165
            }
1166
            return true;
1167
        } else {
823 stevensc 1168
            error_log("_savePngAndCleanup: imagepng failed to save image to {$targetFilename}.");
553 stevensc 1169
            return false;
1170
        }
1171
    }
1172
 
1173
    /**
784 stevensc 1174
     * Redimensiona una imagen manteniendo su proporción original.
1175
     * La imagen resultante tendrá las dimensiones que mejor se ajusten
1176
     * dentro de los límites especificados sin recortar contenido.
283 www 1177
     *
784 stevensc 1178
     * @param string $source_filename Ruta del archivo de imagen fuente
1179
     * @param string $target_filename Ruta donde guardar la imagen redimensionada
1180
     * @param int $target_width Ancho máximo deseado
1181
     * @param int $target_height Alto máximo deseado
1182
     * @return boolean True si se redimensionó correctamente, false en caso de error
283 www 1183
     */
345 www 1184
    public function uploadImageResize($source_filename, $target_filename, $target_width, $target_height)
283 www 1185
    {
345 www 1186
        try {
1187
            $data = file_get_contents($source_filename);
1188
            $img = imagecreatefromstring($data);
546 ariadna 1189
 
1190
            if ($img) {
345 www 1191
                list($source_width, $source_height) = getimagesize($source_filename);
546 ariadna 1192
 
345 www 1193
                $width_ratio = $target_width / $source_width;
1194
                $height_ratio = $target_height / $source_height;
546 ariadna 1195
 
1196
                if ($width_ratio > $height_ratio) {
345 www 1197
                    $resized_width = $target_width;
1198
                    $resized_height = $source_height * $width_ratio;
1199
                } else {
1200
                    $resized_height = $target_height;
1201
                    $resized_width = $source_width * $height_ratio;
1202
                }
546 ariadna 1203
 
345 www 1204
                $resized_width = round($resized_width);
1205
                $resized_height = round($resized_height);
546 ariadna 1206
 
784 stevensc 1207
                $new_image = $this->_createImageCanvas($resized_width, $resized_height);
553 stevensc 1208
                if ($new_image === false) {
1209
                    imagedestroy($img);
1210
                    unlink($source_filename);
1211
                    return false;
1212
                }
1213
 
546 ariadna 1214
                imageCopyResampled($new_image, $img, 0, 0, 0, 0, $resized_width, $resized_height, $source_width, $source_height);
553 stevensc 1215
                imagedestroy($img); // Source image resource can be destroyed after resampling
546 ariadna 1216
 
553 stevensc 1217
                return $this->_savePngAndCleanup($new_image, $target_filename, $source_filename);
345 www 1218
            }
546 ariadna 1219
 
553 stevensc 1220
            unlink($source_filename);
345 www 1221
            return false;
1222
        } catch (\Throwable $e) {
546 ariadna 1223
            error_log($e->getTraceAsString());
553 stevensc 1224
            if (isset($img) && ($img instanceof \GdImage || is_resource($img))) {
1225
                imagedestroy($img);
1226
            }
1227
            if (isset($new_image) && ($new_image instanceof \GdImage || is_resource($new_image))) {
1228
                imagedestroy($new_image);
668 ariadna 1229
            }
553 stevensc 1230
            if (isset($source_filename) && file_exists($source_filename)) {
668 ariadna 1231
                unlink($source_filename);
553 stevensc 1232
            }
345 www 1233
            return false;
1234
        }
546 ariadna 1235
    }
345 www 1236
 
546 ariadna 1237
 
333 www 1238
    /**
345 www 1239
     *
1240
     * @param string $source
1241
     * @param string $target_filename
1242
     * @param number $target_width
1243
     * @param number $target_height
1244
 
1245
     * @return boolean
334 www 1246
     */
345 www 1247
    public function uploadImageCrop($source_filename, $target_filename, $target_width, $target_height)
1248
    {
1249
        try {
1250
            $data = file_get_contents($source_filename);
1251
            $img = imagecreatefromstring($data);
546 ariadna 1252
 
1253
            if ($img) {
345 www 1254
                list($source_width, $source_height) = getimagesize($source_filename);
546 ariadna 1255
 
345 www 1256
                $width_ratio = $target_width / $source_width;
1257
                $height_ratio = $target_height / $source_height;
546 ariadna 1258
                if ($width_ratio > $height_ratio) {
345 www 1259
                    $resized_width = $target_width;
1260
                    $resized_height = $source_height * $width_ratio;
1261
                } else {
1262
                    $resized_height = $target_height;
1263
                    $resized_width = $source_width * $height_ratio;
1264
                }
546 ariadna 1265
 
345 www 1266
                $resized_width = round($resized_width);
1267
                $resized_height = round($resized_height);
546 ariadna 1268
 
345 www 1269
                $offset_width = round(($target_width - $resized_width) / 2);
1270
                $offset_height = round(($target_height - $resized_height) / 2);
546 ariadna 1271
 
553 stevensc 1272
                $new_image = $this->_createImageCanvas($target_width, $target_height);
1273
                if ($new_image === false) {
1274
                    imagedestroy($img);
1275
                    unlink($source_filename);
1276
                    return false;
1277
                }
546 ariadna 1278
 
1279
                imageCopyResampled($new_image, $img, $offset_width, $offset_height, 0, 0, $resized_width, $resized_height, $source_width, $source_height);
553 stevensc 1280
                imagedestroy($img);
546 ariadna 1281
 
553 stevensc 1282
                return $this->_savePngAndCleanup($new_image, $target_filename, $source_filename);
546 ariadna 1283
            }
1284
 
553 stevensc 1285
            unlink($source_filename);
345 www 1286
            return false;
546 ariadna 1287
        } catch (\Throwable $e) {
1288
            error_log($e->getTraceAsString());
553 stevensc 1289
            if (isset($img) && ($img instanceof \GdImage || is_resource($img))) {
1290
                imagedestroy($img);
1291
            }
1292
            if (isset($new_image) && ($new_image instanceof \GdImage || is_resource($new_image))) {
1293
                imagedestroy($new_image);
1294
            }
1295
            if (isset($source_filename) && file_exists($source_filename)) {
1296
                unlink($source_filename);
1297
            }
345 www 1298
            return false;
1299
        }
334 www 1300
    }
546 ariadna 1301
 
334 www 1302
    /**
345 www 1303
     *
1304
     * @param string $source
1305
     * @param string $target_filename
1306
     * @return boolean
333 www 1307
     */
345 www 1308
    public function uploadImageWithOutChangeSize($source_filename, $target_filename)
333 www 1309
    {
345 www 1310
        try {
1311
            $data = file_get_contents($source_filename);
1312
            $img = imagecreatefromstring($data);
546 ariadna 1313
 
1314
            if ($img) {
345 www 1315
                list($source_width, $source_height) = getimagesize($source_filename);
546 ariadna 1316
 
553 stevensc 1317
                $new_image = $this->_createImageCanvas($source_width, $source_height);
1318
                if ($new_image === false) {
1319
                    imagedestroy($img);
1320
                    unlink($source_filename);
1321
                    return false;
1322
                }
668 ariadna 1323
 
546 ariadna 1324
                imageCopyResampled($new_image, $img, 0, 0, 0, 0, $source_width, $source_height, $source_width, $source_height);
553 stevensc 1325
                imagedestroy($img);
546 ariadna 1326
 
553 stevensc 1327
                return $this->_savePngAndCleanup($new_image, $target_filename, $source_filename);
546 ariadna 1328
            }
1329
 
553 stevensc 1330
            unlink($source_filename);
345 www 1331
            return false;
1332
        } catch (\Throwable $e) {
546 ariadna 1333
            error_log($e->getTraceAsString());
781 stevensc 1334
            error_log('Error al subir la imagen: ' . $e->getMessage());
553 stevensc 1335
            if (isset($img) && ($img instanceof \GdImage || is_resource($img))) {
1336
                imagedestroy($img);
1337
            }
1338
            if (isset($new_image) && ($new_image instanceof \GdImage || is_resource($new_image))) {
1339
                imagedestroy($new_image);
1340
            }
1341
            if (isset($source_filename) && file_exists($source_filename)) {
1342
                unlink($source_filename);
1343
            }
345 www 1344
            return false;
333 www 1345
        }
345 www 1346
    }
546 ariadna 1347
 
345 www 1348
    public static function extractPosterFromVideo($source_filename, $target_filename)
1349
    {
546 ariadna 1350
 
345 www 1351
        try {
1352
            $cmd        = "/usr/bin/ffprobe -v error -of flat=s=_ -select_streams v:0 -show_entries stream=height,width,duration  $source_filename";
1353
            $response   = trim(shell_exec($cmd));
546 ariadna 1354
 
345 www 1355
            $source_duration = 0;
1356
            $lines = explode("\n", $response);
1357
            foreach ($lines as $line) {
1358
                $line = trim(strtolower($line));
1359
                if (strpos($line, 'duration') !== false) {
1360
                    $values = explode('=', $line);
1361
                    $source_duration = intval(str_replace($values[1], '#', ''), 10);
1362
                }
1363
            }
546 ariadna 1364
 
1365
 
345 www 1366
            if ($source_duration == 0) {
1367
                $second_extract = '00:00:02';
1368
            } else {
1369
                if ($source_duration > 10) {
1370
                    $second_extract = '00:00:10';
1371
                } else {
1372
                    $second_extract = '00:00:02';
1373
                }
333 www 1374
            }
546 ariadna 1375
 
345 www 1376
            $cmd = "/usr/bin/ffmpeg -y -i $source_filename  -pix_fmt yuvj422p -an -ss $second_extract -f mjpeg -t 1 -r 1 -y  $target_filename";
1377
            exec($cmd);
546 ariadna 1378
 
345 www 1379
            return true;
546 ariadna 1380
        } catch (\Throwable $e) {
1381
            error_log($e->getTraceAsString());
1382
 
345 www 1383
            return false;
1384
        }
333 www 1385
    }
345 www 1386
 
1387
    /**
1388
     *
1389
     * @param string $str
1390
     * @return string
1391
     */
1392
    public function normalizeStringFilename($str = '')
1393
    {
1394
        $basename = substr($str, 0, strrpos($str, '.'));
1395
        $basename = str_replace('.', '-', $basename);
1396
 
1397
        $extension = substr($str, strrpos($str, '.'));
1398
 
1399
        $str = $basename . $extension;
1400
 
1401
        $str = strip_tags($str);
1402
        $str = preg_replace('/[\r\n\t ]+/', ' ', $str);
1403
        $str = preg_replace('/[\#\"\*\/\:\<\>\?\'\|\,]+/', ' ', $str);
1404
        $str = strtolower($str);
1405
        $str = html_entity_decode($str, ENT_QUOTES, "utf-8");
1406
        $str = htmlentities($str, ENT_QUOTES, "utf-8");
1407
        $str = preg_replace("/(&)([a-z])([a-z]+;)/i", '$2', $str);
1408
        $str = str_replace(' ', '-', $str);
1409
        $str = rawurlencode($str);
1410
        $str = str_replace('%', '-', $str);
1411
        $str = str_replace([
1412
            '-----',
1413
            '----',
1414
            '---',
1415
            '--'
1416
        ], '-', $str);
1417
        return trim(strtolower($str));
1418
    }
546 ariadna 1419
}