]> BookStack Code Mirror - bookstack/blob - app/Uploads/UserAvatars.php
Merge branch 'master' of git://github.com/Swoy/BookStack into Swoy-master
[bookstack] / app / Uploads / UserAvatars.php
1 <?php namespace BookStack\Uploads;
2
3 use BookStack\Auth\User;
4 use BookStack\Exceptions\HttpFetchException;
5 use Exception;
6
7 class UserAvatars
8 {
9     protected $imageService;
10     protected $http;
11
12     public function __construct(ImageService $imageService, HttpFetcher $http)
13     {
14         $this->imageService = $imageService;
15         $this->http = $http;
16     }
17
18     /**
19      * Fetch and assign an avatar image to the given user.
20      */
21     public function fetchAndAssignToUser(User $user): void
22     {
23         if (!$this->avatarFetchEnabled()) {
24             return;
25         }
26
27         try {
28             $avatar = $this->saveAvatarImage($user);
29             $user->avatar()->associate($avatar);
30             $user->save();
31         } catch (Exception $e) {
32             Log::error('Failed to save user avatar image');
33         }
34     }
35
36     /**
37      * Save an avatar image from an external service.
38      * @throws Exception
39      */
40     protected function saveAvatarImage(User $user, int $size = 500): Image
41     {
42         $avatarUrl = $this->getAvatarUrl();
43         $email = strtolower(trim($user->email));
44
45         $replacements = [
46             '${hash}' => md5($email),
47             '${size}' => $size,
48             '${email}' => urlencode($email),
49         ];
50
51         $userAvatarUrl = strtr($avatarUrl, $replacements);
52         $imageName = str_replace(' ', '-', $user->id . '-avatar.png');
53         $imageData = $this->getAvatarImageData($userAvatarUrl);
54
55         $image = $this->imageService->saveNew($imageName, $imageData, 'user', $user->id);
56         $image->created_by = $user->id;
57         $image->updated_by = $user->id;
58         $image->save();
59
60         return $image;
61     }
62
63     /**
64      * Gets an image from url and returns it as a string of image data.
65      * @throws Exception
66      */
67     protected function getAvatarImageData(string $url): string
68     {
69         try {
70             $imageData = $this->http->fetch($url);
71         } catch (HttpFetchException $exception) {
72             throw new Exception(trans('errors.cannot_get_image_from_url', ['url' => $url]));
73         }
74         return $imageData;
75     }
76
77     /**
78      * Check if fetching external avatars is enabled.
79      */
80     protected function avatarFetchEnabled(): bool
81     {
82         $fetchUrl = $this->getAvatarUrl();
83         return is_string($fetchUrl) && strpos($fetchUrl, 'http') === 0;
84     }
85
86     /**
87      * Get the URL to fetch avatars from.
88      */
89     protected function getAvatarUrl(): string
90     {
91         $url = trim(config('services.avatar_url'));
92
93         if (empty($url) && !config('services.disable_services')) {
94             $url = 'https://www.gravatar.com/avatar/${hash}?s=${size}&d=identicon';
95         }
96
97         return $url;
98     }
99
100 }