Proyectos de Subversion LeadersLinked - Backend

Rev

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