Completed
Push — master ( e5ab12...9197f0 )
by Konstantinos
09:09
created

AvatarModel::getAvatarPath()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0263
Metric Value
dl 0
loc 14
ccs 6
cts 7
cp 0.8571
rs 9.4286
cc 3
eloc 7
nc 4
nop 3
crap 3.0263
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 39
    protected function getIdenticon($idData)
37
    {
38 39
        Service::getContainer()->get('logger')
39 39
            ->info('Generating new identicon for "' . $this->getName() . '" in ' . $this->getAvatarPath());
40
41 39
        $identicon = new Identicon();
42 39
        $imageData = $identicon->getImageData($idData, 250);
43
44 39
        $path = $this->getAvatarPath($imageData);
45
46 39
        file_put_contents(DOC_ROOT . $path, $imageData);
47
48 38
        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 self
56
     */
57
    public function setAvatarFile($file)
58
    {
59
        if ($file) {
60
            $openFile = $file->openFile('r');
61
            $content = $openFile->fread($openFile->getSize());
62
63
            $path = $this->getAvatarPath(null, false, false);
64
            $filename = $this->getAvatarFileName($content);
65
66
            $file->move(DOC_ROOT . $path, $filename);
67
68
            $this->setAvatar($path . $filename);
69
        }
70
71
        return $this;
72
    }
73
74
    /**
75
     * Get the path for the image used as the object's avatar
76
     *
77
     * @param  bool $url Whether to return an absolute URL
78
     * @return string  The path for the avatar
79
     */
80
    public function getAvatar($url = false)
81
    {
82
        if (empty($this->avatar) && $this->avatar !== null) {
83
            $this->resetAvatar();
84
        }
85
86
        if ($url) {
87
            return Service::getRequest()->getBaseUrl() . $this->avatar;
88
        }
89
90
        return $this->avatar;
91
    }
92
93
    /**
94
     * Change the avatar of the object
95
     *
96
     * @param  string $avatar The file name of the avatar
97
     * @return self
98
     */
99
    public function setAvatar($avatar)
100
    {
101
        if (!empty($this->avatar)) {
102
            // Remove the old avatar
103
            unlink(DOC_ROOT . $this->avatar);
104
        }
105
106
        // Clear the thumbnail cache
107
        $imagine = Service::getContainer()->get('liip_imagine.cache.manager');
108
        $imagine->remove($this->avatar);
109
110
        return $this->updateProperty($this->avatar, 'avatar', $avatar, 's');
111
    }
112
113
    /**
114
     * Reset the object's avatar to an identicon
115
     *
116
     * @return self
117
     */
118
    public function resetAvatar()
119
    {
120
        $path = $this->getIdenticon($this->getName());
121
122
        return $this->setAvatar($path);
123
    }
124
125
    /**
126
     * Get the path to the avatar
127
     *
128
     * @param string|null $content The avatar data
129
     * @param bool $full Whether to return the full absolute path
130
     * @param bool $file Whether to include the name of the file
131
     * @return string The path to the avatar
132
     */
133 39
    private function getAvatarPath($content = null, $full = false, $file = true)
134
    {
135 39
        $path = static::AVATAR_LOCATION . $this->id . '/';
136
137 39
        if ($full) {
138
            $path = DOC_ROOT . $path;
139
        }
140
141 39
        if ($file) {
142 39
            $path .= $this->getAvatarFileName($content);
143
        }
144
145 39
        return $path;
146
    }
147
148
    /**
149
     * Get the filename for the avatar, creating its directory if it doesn't
150
     * exist
151
     *
152
     * @param  string|null $content The avatar data
153
     * @return string The file name of the avatar
154
     */
155 39
    private function getAvatarFileName(&$content = null)
156
    {
157
        // Calculate the avatar contents' hash, which is used to force the
158
        // browser to reload an image stored in the cache whenever it changes
159
        // (cache busting)
160
        //
161
        // MD5 is used because it's fast and we don't require a
162
        // cryptographically secure hashing function
163 39
        if ($content !== null) {
164 39
            $hash = substr(md5($content), 0, 7);
165
        } else {
166 39
            $hash = 'avatar';
167
        }
168
169 39
        return "$hash.png";
170
    }
171
}
172