AvatarFilenameListener   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 33
dl 0
loc 108
rs 10
c 1
b 0
f 0
wmc 12

5 Methods

Rating   Name   Duplication   Size   Complexity  
A implementedEvents() 0 5 1
A change() 0 35 5
A __construct() 0 3 1
A onModelAfterSaveCommit() 0 9 3
A deleteExistingFilesForUser() 0 8 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * Saito - The Threaded Web Forum
7
 *
8
 * @copyright Copyright (c) the Saito Project Developers
9
 * @link https://github.com/Schlaefer/Saito
10
 * @license http://opensource.org/licenses/MIT
11
 */
12
13
namespace Saito\User\Upload;
14
15
use App\Model\Entity\User;
16
use Cake\Core\Configure;
17
use Cake\Event\Event;
18
use Cake\Event\EventListenerInterface;
19
use Cake\Filesystem\Folder;
20
use Cake\ORM\Entity;
21
use Cake\Utility\Text;
22
use Proffer\Lib\ProfferPath;
23
24
/**
25
 * Handles files for Avatars-Images
26
 */
27
class AvatarFilenameListener implements EventListenerInterface
28
{
29
    /**
30
     * Upload root directory
31
     *
32
     * @var string
33
     */
34
    private $rootDirectory;
35
36
    /**
37
     * Constructor
38
     *
39
     * @param string $rootDirectory the upload root
40
     */
41
    public function __construct(string $rootDirectory)
42
    {
43
        $this->rootDirectory = $rootDirectory;
44
    }
45
46
    /**
47
     * {@inheritDoc}
48
     */
49
    public function implementedEvents()
50
    {
51
        return [
52
            'Proffer.afterPath' => 'change',
53
            'Model.afterSaveCommit' => 'onModelAfterSaveCommit',
54
        ];
55
    }
56
57
    /**
58
     * Rename a file and change it's upload folder before it's processed
59
     *
60
     * @param Event $event The event class with a subject of the entity
61
     * @param ProfferPath $path path
62
     * @return ProfferPath $path
63
     */
64
    public function change(Event $event, ProfferPath $path)
65
    {
66
        /** @var User $user */
67
        $user = $event->getSubject();
68
69
        if ($user->isDirty('avatar')) {
70
            $this->deleteExistingFilesForUser($user);
71
        }
72
73
        // Detect and select the right file extension
74
        switch ($user->get('avatar')['type']) {
75
            default:
76
            case "image/jpeg":
77
                $ext = '.jpg';
78
                break;
79
            case "image/png":
80
                $ext = '.png';
81
                break;
82
        }
83
84
        // `webroot/files/<table>/<field>/<seed>/<file>`
85
86
        $newFilename = Text::uuid() . $ext;
87
88
        // $path->setTable('avatars');
89
90
        $imgDir = $user->get('avatar_dir') ?: $user->get('id');
91
        $path->setSeed($imgDir);
92
93
        // Change the filename in both the path to be saved, and in the entity data for saving to the db
94
        $path->setFilename($newFilename);
95
        $user['avatar']['name'] = $newFilename;
96
97
        // Must return the modified path instance, so that things are saved in the right place
98
        return $path;
99
    }
100
101
    /**
102
     * Handle delete files if avatar is unset in DB
103
     *
104
     * Proffer only handles deleting an image when DB row is deleting, but
105
     * we don't delete the user, only set the avatar image null.
106
     *
107
     * @param Event $event event
108
     * @return void
109
     */
110
    public function onModelAfterSaveCommit(Event $event): void
111
    {
112
        /** @var User $user */
113
        $user = $event->getData('entity');
114
        $avatar = $user->get('avatar');
115
        if (!$user->isDirty('avatar') || !empty($avatar)) {
116
            return;
117
        }
118
        $this->deleteExistingFilesForUser($user);
119
    }
120
121
    /**
122
     * Delete existing avatar images for a user
123
     *
124
     * @param User $user user
125
     * @return void
126
     */
127
    private function deleteExistingFilesForUser(User $user): void
128
    {
129
        $dir = $user->get('id');
130
        if (!empty($dir)) {
131
            $folder = new Folder(
132
                $this->rootDirectory . '/users/avatar/' . $dir
133
            );
134
            $folder->delete();
135
        }
136
    }
137
}
138