Completed
Push — master ( 6eaf7d...374325 )
by Vladimir
02:54
created

AvatarModel::hasAvatar()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
ccs 2
cts 2
cp 1
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
/**
3
 * This file contains functionality relating to database objects that have avatars and identicons such as teams and players
4
 *
5
 * @package    BZiON\Models
6
 * @license    https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3
7
 */
8
9
use Identicon\Identicon;
10
use Symfony\Component\HttpFoundation\File\File;
11
12
/**
13
 * A Model that has a URL, an alias, and an avatar
14
 * @package    BZiON\Models
15
 */
16
abstract class AvatarModel extends AliasModel implements NamedModel
17
{
18
    /**
19
     * The url of the object's profile avatar
20
     * @var string
21
     */
22
    protected $avatar;
23
24
    /**
25
     * The location where avatars will be stored
26
     */
27
    const AVATAR_LOCATION = "";
28
29
    /**
30
     * Get the identicon for a model. This function will overwrite the previous avatar
31
     *
32
     * @param string $idData The data (name or id) that will be used to generate an identicon
33
     *
34
     * @return string The path to the generated identicon
35
     */
36 76
    protected function getIdenticon($idData)
37
    {
38 76
        Service::getContainer()->get('logger')
39 76
            ->info('Generating new identicon for "' . $this->getName() . '" in ' . $this->getAvatarPath());
40
41 76
        $identicon = new Identicon();
42 76
        $imageData = $identicon->getImageData($idData, 250);
43
44 76
        $path = $this->getAvatarPath($imageData);
45
46 76
        file_put_contents(DOC_ROOT . $path, $imageData);
47
48 76
        return $path;
49
    }
50
51
    /**
52
     * Set the avatar of the object to be a specific file
53
     *
54
     * @param  File|null $file The avatar file
55
     * @return static
56
     */
57
    public function setAvatarFile($file)
58
    {
59
        if ($file) {
60
            // We don't use File's fread() because it's unavailable in less
61
            // recent PHP versions
62
            $path = $file->getPath() . '/' . $file->getFilename();
63
            $content = file_get_contents($path);
64
65
            $path = $this->getAvatarPath(null, false, false);
66
            $filename = $this->getAvatarFileName($content);
67
68
            $file->move(DOC_ROOT . $path, $filename);
69
70
            $this->setAvatar($path . $filename);
71
        }
72
73
        return $this;
74
    }
75
76
    /**
77
     * Get the path for the image used as the object's avatar
78
     *
79
     * @param  bool $url Whether to return an absolute URL
80
     * @return string  The path for the avatar
81
     */
82 1
    public function getAvatar($url = false)
83
    {
84 1
        if (empty($this->avatar) && $this->avatar !== null) {
85 1
            $this->resetAvatar();
86
        }
87
88 1
        if ($url) {
89
            return Service::getRequest()->getBaseUrl() . $this->avatar;
90
        }
91
92 1
        return $this->avatar;
93
    }
94
95
    /**
96
     * Check whether this model has a non-null avatar
97
     *
98
     * @return bool
99
     */
100
    public function hasAvatar()
101 1
    {
102
       return ($this->avatar === null);
103 1
    }
104
105 1
    /**
106
     * Change the avatar of the object
107
     *
108
     * @param  string $avatar The file name of the avatar
109
     * @return static
110
     */
111 1
    public function setAvatar($avatar)
112 1
    {
113
        $currentAvatar = DOC_ROOT . $this->avatar;
114 1
115
        if (!empty($this->avatar) && $avatar != $this->avatar && file_exists($currentAvatar)) {
116
            // Remove the old avatar
117
            unlink($currentAvatar);
118
        }
119
120
        // Clear the thumbnail cache
121
        $imagine = Service::getContainer()->get('liip_imagine.cache.manager');
122 1
        $imagine->remove($this->avatar);
123
124 1
        return $this->updateProperty($this->avatar, 'avatar', $avatar);
125
    }
126 1
127
    /**
128
     * Reset the object's avatar to an identicon
129
     *
130
     * @return self
131
     */
132
    public function resetAvatar()
133
    {
134
        $path = $this->getIdenticon($this->getName());
135
136
        return $this->setAvatar($path);
137 76
    }
138
139 76
    /**
140
     * Get the path to the avatar, creating its directory if it doesn't exist
141 76
     *
142 76
     * @param string|null $content The avatar data
143
     * @param bool $full Whether to return the full absolute path
144
     * @param bool $file Whether to include the name of the file
145 76
     * @return string The path to the avatar
146
     */
147
    private function getAvatarPath($content = null, $full = false, $file = true)
148
    {
149 76
        $path = static::AVATAR_LOCATION . $this->id . '/';
150 76
151
        if (!@file_exists(DOC_ROOT . $path)) {
152
            mkdir(DOC_ROOT . $path);
153 76
        }
154
155
        if ($full) {
156
            $path = DOC_ROOT . $path;
157
        }
158
159
        if ($file) {
160
            $path .= $this->getAvatarFileName($content);
161
        }
162 76
163
        return $path;
164
    }
165
166
    /**
167
     * Get the filename for the avatar
168
     *
169
     * @param  string|null $content The avatar data
170 76
     * @return string The file name of the avatar
171 76
     */
172
    private function getAvatarFileName(&$content = null)
173 76
    {
174
        // Calculate the avatar contents' hash, which is used to force the
175
        // browser to reload an image stored in the cache whenever it changes
176 76
        // (cache busting)
177
        //
178
        // MD5 is used because it's fast and we don't require a
179
        // cryptographically secure hashing function
180
        if ($content !== null) {
181
            $hash = substr(md5($content), 0, 7);
182 1
        } else {
183
            $hash = 'avatar';
184 1
        }
185
186
        return "$hash.png";
187 1
    }
188 1
189
    /**
190
     * {@inheritdoc}
191
     */
192
    public function delete()
193
    {
194
        parent::delete();
195
196
        // Reset the avatar to an Identicon when this object is deleted
197
        $this->resetAvatar();
198
    }
199
}
200