Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 17350 | | Comparar con el anterior | Ultima modificación | Ver Log |

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