Completed
Pull Request — master (#9197)
by John
30:51 queued 13:30
created
core/Controller/AvatarController.php 2 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -41,7 +41,6 @@
 block discarded – undo
41 41
 use OCP\IRequest;
42 42
 use OCP\IUserManager;
43 43
 use OCP\IUserSession;
44
-use OCP\AppFramework\Http\DataResponse;
45 44
 
46 45
 /**
47 46
  * Class AvatarController
Please login to merge, or discard this patch.
Indentation   +283 added lines, -283 removed lines patch added patch discarded remove patch
@@ -51,288 +51,288 @@
 block discarded – undo
51 51
  */
52 52
 class AvatarController extends Controller {
53 53
 
54
-	/** @var IAvatarManager */
55
-	protected $avatarManager;
56
-
57
-	/** @var ICache */
58
-	protected $cache;
59
-
60
-	/** @var IL10N */
61
-	protected $l;
62
-
63
-	/** @var IUserManager */
64
-	protected $userManager;
65
-
66
-	/** @var IUserSession */
67
-	protected $userSession;
68
-
69
-	/** @var IRootFolder */
70
-	protected $rootFolder;
71
-
72
-	/** @var ILogger */
73
-	protected $logger;
74
-
75
-	/** @var string */
76
-	protected $userId;
77
-
78
-	/** @var TimeFactory */
79
-	protected $timeFactory;
80
-
81
-	/**
82
-	 * @param string $appName
83
-	 * @param IRequest $request
84
-	 * @param IAvatarManager $avatarManager
85
-	 * @param ICache $cache
86
-	 * @param IL10N $l10n
87
-	 * @param IUserManager $userManager
88
-	 * @param IRootFolder $rootFolder
89
-	 * @param ILogger $logger
90
-	 * @param string $userId
91
-	 * @param TimeFactory $timeFactory
92
-	 */
93
-	public function __construct($appName,
94
-								IRequest $request,
95
-								IAvatarManager $avatarManager,
96
-								ICache $cache,
97
-								IL10N $l10n,
98
-								IUserManager $userManager,
99
-								IRootFolder $rootFolder,
100
-								ILogger $logger,
101
-								$userId,
102
-								TimeFactory $timeFactory) {
103
-		parent::__construct($appName, $request);
104
-
105
-		$this->avatarManager = $avatarManager;
106
-		$this->cache = $cache;
107
-		$this->l = $l10n;
108
-		$this->userManager = $userManager;
109
-		$this->rootFolder = $rootFolder;
110
-		$this->logger = $logger;
111
-		$this->userId = $userId;
112
-		$this->timeFactory = $timeFactory;
113
-	}
114
-
115
-
116
-	/**
117
-	 * @NoAdminRequired
118
-	 * @NoCSRFRequired
119
-	 * @NoSameSiteCookieRequired
120
-	 * @PublicPage
121
-	 *
122
-	 * @param string $userId
123
-	 * @param int $size
124
-	 * @return JSONResponse|FileDisplayResponse
125
-	 */
126
-	public function getAvatar($userId, $size) {
127
-		// min/max size
128
-		if ($size > 2048) {
129
-			$size = 2048;
130
-		} elseif ($size <= 0) {
131
-			$size = 64;
132
-		}
133
-
134
-		try {
135
-			$avatar = $this->avatarManager->getAvatar($userId)->getFile($size);
136
-			$resp = new FileDisplayResponse(
137
-				$avatar,
138
-				Http::STATUS_OK,
139
-				['Content-Type' => $avatar->getMimeType()
140
-			]);
141
-		} catch (\Exception $e) {
142
-			var_dump($e);
143
-			$resp = new Http\Response();
144
-			$resp->setStatus(Http::STATUS_NOT_FOUND);
145
-			return $resp;
146
-		}
147
-
148
-		// Cache for 30 minutes
149
-		$resp->cacheFor(1800);
150
-		return $resp;
151
-	}
152
-
153
-	/**
154
-	 * @NoAdminRequired
155
-	 *
156
-	 * @param string $path
157
-	 * @return JSONResponse
158
-	 */
159
-	public function postAvatar($path) {
160
-		$files = $this->request->getUploadedFile('files');
161
-
162
-		if (isset($path)) {
163
-			$path = stripslashes($path);
164
-			$userFolder = $this->rootFolder->getUserFolder($this->userId);
165
-			/** @var File $node */
166
-			$node = $userFolder->get($path);
167
-			if (!($node instanceof File)) {
168
-				return new JSONResponse(['data' => ['message' => $this->l->t('Please select a file.')]]);
169
-			}
170
-			if ($node->getSize() > 20*1024*1024) {
171
-				return new JSONResponse(
172
-					['data' => ['message' => $this->l->t('File is too big')]],
173
-					Http::STATUS_BAD_REQUEST
174
-				);
175
-			}
176
-
177
-			if ($node->getMimeType() !== 'image/jpeg' && $node->getMimeType() !== 'image/png') {
178
-				return new JSONResponse(
179
-					['data' => ['message' => $this->l->t('The selected file is not an image.')]],
180
-					Http::STATUS_BAD_REQUEST
181
-				);
182
-			}
183
-
184
-			try {
185
-				$content = $node->getContent();
186
-			} catch (\OCP\Files\NotPermittedException $e) {
187
-				return new JSONResponse(
188
-					['data' => ['message' => $this->l->t('The selected file cannot be read.')]],
189
-					Http::STATUS_BAD_REQUEST
190
-				);
191
-			}
192
-		} elseif (!is_null($files)) {
193
-			if (
194
-				$files['error'][0] === 0 &&
195
-				 is_uploaded_file($files['tmp_name'][0]) &&
196
-				!\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])
197
-			) {
198
-				if ($files['size'][0] > 20*1024*1024) {
199
-					return new JSONResponse(
200
-						['data' => ['message' => $this->l->t('File is too big')]],
201
-						Http::STATUS_BAD_REQUEST
202
-					);
203
-				}
204
-				$this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
205
-				$content = $this->cache->get('avatar_upload');
206
-				unlink($files['tmp_name'][0]);
207
-			} else {
208
-				return new JSONResponse(
209
-					['data' => ['message' => $this->l->t('Invalid file provided')]],
210
-					Http::STATUS_BAD_REQUEST
211
-				);
212
-			}
213
-		} else {
214
-			//Add imgfile
215
-			return new JSONResponse(
216
-				['data' => ['message' => $this->l->t('No image or file provided')]],
217
-				Http::STATUS_BAD_REQUEST
218
-			);
219
-		}
220
-
221
-		try {
222
-			$image = new \OC_Image();
223
-			$image->loadFromData($content);
224
-			$image->readExif($content);
225
-			$image->fixOrientation();
226
-
227
-			if ($image->valid()) {
228
-				$mimeType = $image->mimeType();
229
-				if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
230
-					return new JSONResponse(
231
-						['data' => ['message' => $this->l->t('Unknown filetype')]],
232
-						Http::STATUS_OK
233
-					);
234
-				}
235
-
236
-				$this->cache->set('tmpAvatar', $image->data(), 7200);
237
-				return new JSONResponse(
238
-					['data' => 'notsquare'],
239
-					Http::STATUS_OK
240
-				);
241
-			} else {
242
-				return new JSONResponse(
243
-					['data' => ['message' => $this->l->t('Invalid image')]],
244
-					Http::STATUS_OK
245
-				);
246
-			}
247
-		} catch (\Exception $e) {
248
-			$this->logger->logException($e, ['app' => 'core']);
249
-			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK);
250
-		}
251
-	}
252
-
253
-	/**
254
-	 * @NoAdminRequired
54
+    /** @var IAvatarManager */
55
+    protected $avatarManager;
56
+
57
+    /** @var ICache */
58
+    protected $cache;
59
+
60
+    /** @var IL10N */
61
+    protected $l;
62
+
63
+    /** @var IUserManager */
64
+    protected $userManager;
65
+
66
+    /** @var IUserSession */
67
+    protected $userSession;
68
+
69
+    /** @var IRootFolder */
70
+    protected $rootFolder;
71
+
72
+    /** @var ILogger */
73
+    protected $logger;
74
+
75
+    /** @var string */
76
+    protected $userId;
77
+
78
+    /** @var TimeFactory */
79
+    protected $timeFactory;
80
+
81
+    /**
82
+     * @param string $appName
83
+     * @param IRequest $request
84
+     * @param IAvatarManager $avatarManager
85
+     * @param ICache $cache
86
+     * @param IL10N $l10n
87
+     * @param IUserManager $userManager
88
+     * @param IRootFolder $rootFolder
89
+     * @param ILogger $logger
90
+     * @param string $userId
91
+     * @param TimeFactory $timeFactory
92
+     */
93
+    public function __construct($appName,
94
+                                IRequest $request,
95
+                                IAvatarManager $avatarManager,
96
+                                ICache $cache,
97
+                                IL10N $l10n,
98
+                                IUserManager $userManager,
99
+                                IRootFolder $rootFolder,
100
+                                ILogger $logger,
101
+                                $userId,
102
+                                TimeFactory $timeFactory) {
103
+        parent::__construct($appName, $request);
104
+
105
+        $this->avatarManager = $avatarManager;
106
+        $this->cache = $cache;
107
+        $this->l = $l10n;
108
+        $this->userManager = $userManager;
109
+        $this->rootFolder = $rootFolder;
110
+        $this->logger = $logger;
111
+        $this->userId = $userId;
112
+        $this->timeFactory = $timeFactory;
113
+    }
114
+
115
+
116
+    /**
117
+     * @NoAdminRequired
118
+     * @NoCSRFRequired
119
+     * @NoSameSiteCookieRequired
120
+     * @PublicPage
255 121
      *
256
-	 * @return JSONResponse
257
-	 */
258
-	public function deleteAvatar() {
259
-		try {
260
-			$avatar = $this->avatarManager->getAvatar($this->userId);
261
-			$avatar->remove();
262
-			return new JSONResponse();
263
-		} catch (\Exception $e) {
264
-			$this->logger->logException($e, ['app' => 'core']);
265
-			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
266
-		}
267
-	}
268
-
269
-	/**
270
-	 * @NoAdminRequired
271
-	 *
272
-	 * @return JSONResponse|DataDisplayResponse
273
-	 */
274
-	public function getTmpAvatar() {
275
-		$tmpAvatar = $this->cache->get('tmpAvatar');
276
-		if (is_null($tmpAvatar)) {
277
-			return new JSONResponse(['data' => [
278
-										'message' => $this->l->t("No temporary profile picture available, try again")
279
-									]],
280
-									Http::STATUS_NOT_FOUND);
281
-		}
282
-
283
-		$image = new \OC_Image();
284
-		$image->loadFromData($tmpAvatar);
285
-
286
-		$resp = new DataDisplayResponse($image->data(),
287
-				Http::STATUS_OK,
288
-				['Content-Type' => $image->mimeType()]);
289
-
290
-		$resp->setETag((string)crc32($image->data()));
291
-		$resp->cacheFor(0);
292
-		$resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
293
-		return $resp;
294
-	}
295
-
296
-	/**
297
-	 * @NoAdminRequired
298
-	 *
299
-	 * @param array $crop
300
-	 * @return JSONResponse
301
-	 */
302
-	public function postCroppedAvatar($crop) {
303
-		if (is_null($crop)) {
304
-			return new JSONResponse(['data' => ['message' => $this->l->t("No crop data provided")]],
305
-									Http::STATUS_BAD_REQUEST);
306
-		}
307
-
308
-		if (!isset($crop['x'], $crop['y'], $crop['w'], $crop['h'])) {
309
-			return new JSONResponse(['data' => ['message' => $this->l->t("No valid crop data provided")]],
310
-									Http::STATUS_BAD_REQUEST);
311
-		}
312
-
313
-		$tmpAvatar = $this->cache->get('tmpAvatar');
314
-		if (is_null($tmpAvatar)) {
315
-			return new JSONResponse(['data' => [
316
-										'message' => $this->l->t("No temporary profile picture available, try again")
317
-									]],
318
-									Http::STATUS_BAD_REQUEST);
319
-		}
320
-
321
-		$image = new \OC_Image();
322
-		$image->loadFromData($tmpAvatar);
323
-		$image->crop($crop['x'], $crop['y'], (int)round($crop['w']), (int)round($crop['h']));
324
-		try {
325
-			$avatar = $this->avatarManager->getAvatar($this->userId);
326
-			$avatar->set($image);
327
-			// Clean up
328
-			$this->cache->remove('tmpAvatar');
329
-			return new JSONResponse(['status' => 'success']);
330
-		} catch (\OC\NotSquareException $e) {
331
-			return new JSONResponse(['data' => ['message' => $this->l->t('Crop is not square')]],
332
-									Http::STATUS_BAD_REQUEST);
333
-		} catch (\Exception $e) {
334
-			$this->logger->logException($e, ['app' => 'core']);
335
-			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
336
-		}
337
-	}
122
+     * @param string $userId
123
+     * @param int $size
124
+     * @return JSONResponse|FileDisplayResponse
125
+     */
126
+    public function getAvatar($userId, $size) {
127
+        // min/max size
128
+        if ($size > 2048) {
129
+            $size = 2048;
130
+        } elseif ($size <= 0) {
131
+            $size = 64;
132
+        }
133
+
134
+        try {
135
+            $avatar = $this->avatarManager->getAvatar($userId)->getFile($size);
136
+            $resp = new FileDisplayResponse(
137
+                $avatar,
138
+                Http::STATUS_OK,
139
+                ['Content-Type' => $avatar->getMimeType()
140
+            ]);
141
+        } catch (\Exception $e) {
142
+            var_dump($e);
143
+            $resp = new Http\Response();
144
+            $resp->setStatus(Http::STATUS_NOT_FOUND);
145
+            return $resp;
146
+        }
147
+
148
+        // Cache for 30 minutes
149
+        $resp->cacheFor(1800);
150
+        return $resp;
151
+    }
152
+
153
+    /**
154
+     * @NoAdminRequired
155
+     *
156
+     * @param string $path
157
+     * @return JSONResponse
158
+     */
159
+    public function postAvatar($path) {
160
+        $files = $this->request->getUploadedFile('files');
161
+
162
+        if (isset($path)) {
163
+            $path = stripslashes($path);
164
+            $userFolder = $this->rootFolder->getUserFolder($this->userId);
165
+            /** @var File $node */
166
+            $node = $userFolder->get($path);
167
+            if (!($node instanceof File)) {
168
+                return new JSONResponse(['data' => ['message' => $this->l->t('Please select a file.')]]);
169
+            }
170
+            if ($node->getSize() > 20*1024*1024) {
171
+                return new JSONResponse(
172
+                    ['data' => ['message' => $this->l->t('File is too big')]],
173
+                    Http::STATUS_BAD_REQUEST
174
+                );
175
+            }
176
+
177
+            if ($node->getMimeType() !== 'image/jpeg' && $node->getMimeType() !== 'image/png') {
178
+                return new JSONResponse(
179
+                    ['data' => ['message' => $this->l->t('The selected file is not an image.')]],
180
+                    Http::STATUS_BAD_REQUEST
181
+                );
182
+            }
183
+
184
+            try {
185
+                $content = $node->getContent();
186
+            } catch (\OCP\Files\NotPermittedException $e) {
187
+                return new JSONResponse(
188
+                    ['data' => ['message' => $this->l->t('The selected file cannot be read.')]],
189
+                    Http::STATUS_BAD_REQUEST
190
+                );
191
+            }
192
+        } elseif (!is_null($files)) {
193
+            if (
194
+                $files['error'][0] === 0 &&
195
+                 is_uploaded_file($files['tmp_name'][0]) &&
196
+                !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])
197
+            ) {
198
+                if ($files['size'][0] > 20*1024*1024) {
199
+                    return new JSONResponse(
200
+                        ['data' => ['message' => $this->l->t('File is too big')]],
201
+                        Http::STATUS_BAD_REQUEST
202
+                    );
203
+                }
204
+                $this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
205
+                $content = $this->cache->get('avatar_upload');
206
+                unlink($files['tmp_name'][0]);
207
+            } else {
208
+                return new JSONResponse(
209
+                    ['data' => ['message' => $this->l->t('Invalid file provided')]],
210
+                    Http::STATUS_BAD_REQUEST
211
+                );
212
+            }
213
+        } else {
214
+            //Add imgfile
215
+            return new JSONResponse(
216
+                ['data' => ['message' => $this->l->t('No image or file provided')]],
217
+                Http::STATUS_BAD_REQUEST
218
+            );
219
+        }
220
+
221
+        try {
222
+            $image = new \OC_Image();
223
+            $image->loadFromData($content);
224
+            $image->readExif($content);
225
+            $image->fixOrientation();
226
+
227
+            if ($image->valid()) {
228
+                $mimeType = $image->mimeType();
229
+                if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
230
+                    return new JSONResponse(
231
+                        ['data' => ['message' => $this->l->t('Unknown filetype')]],
232
+                        Http::STATUS_OK
233
+                    );
234
+                }
235
+
236
+                $this->cache->set('tmpAvatar', $image->data(), 7200);
237
+                return new JSONResponse(
238
+                    ['data' => 'notsquare'],
239
+                    Http::STATUS_OK
240
+                );
241
+            } else {
242
+                return new JSONResponse(
243
+                    ['data' => ['message' => $this->l->t('Invalid image')]],
244
+                    Http::STATUS_OK
245
+                );
246
+            }
247
+        } catch (\Exception $e) {
248
+            $this->logger->logException($e, ['app' => 'core']);
249
+            return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK);
250
+        }
251
+    }
252
+
253
+    /**
254
+     * @NoAdminRequired
255
+     *
256
+     * @return JSONResponse
257
+     */
258
+    public function deleteAvatar() {
259
+        try {
260
+            $avatar = $this->avatarManager->getAvatar($this->userId);
261
+            $avatar->remove();
262
+            return new JSONResponse();
263
+        } catch (\Exception $e) {
264
+            $this->logger->logException($e, ['app' => 'core']);
265
+            return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
266
+        }
267
+    }
268
+
269
+    /**
270
+     * @NoAdminRequired
271
+     *
272
+     * @return JSONResponse|DataDisplayResponse
273
+     */
274
+    public function getTmpAvatar() {
275
+        $tmpAvatar = $this->cache->get('tmpAvatar');
276
+        if (is_null($tmpAvatar)) {
277
+            return new JSONResponse(['data' => [
278
+                                        'message' => $this->l->t("No temporary profile picture available, try again")
279
+                                    ]],
280
+                                    Http::STATUS_NOT_FOUND);
281
+        }
282
+
283
+        $image = new \OC_Image();
284
+        $image->loadFromData($tmpAvatar);
285
+
286
+        $resp = new DataDisplayResponse($image->data(),
287
+                Http::STATUS_OK,
288
+                ['Content-Type' => $image->mimeType()]);
289
+
290
+        $resp->setETag((string)crc32($image->data()));
291
+        $resp->cacheFor(0);
292
+        $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
293
+        return $resp;
294
+    }
295
+
296
+    /**
297
+     * @NoAdminRequired
298
+     *
299
+     * @param array $crop
300
+     * @return JSONResponse
301
+     */
302
+    public function postCroppedAvatar($crop) {
303
+        if (is_null($crop)) {
304
+            return new JSONResponse(['data' => ['message' => $this->l->t("No crop data provided")]],
305
+                                    Http::STATUS_BAD_REQUEST);
306
+        }
307
+
308
+        if (!isset($crop['x'], $crop['y'], $crop['w'], $crop['h'])) {
309
+            return new JSONResponse(['data' => ['message' => $this->l->t("No valid crop data provided")]],
310
+                                    Http::STATUS_BAD_REQUEST);
311
+        }
312
+
313
+        $tmpAvatar = $this->cache->get('tmpAvatar');
314
+        if (is_null($tmpAvatar)) {
315
+            return new JSONResponse(['data' => [
316
+                                        'message' => $this->l->t("No temporary profile picture available, try again")
317
+                                    ]],
318
+                                    Http::STATUS_BAD_REQUEST);
319
+        }
320
+
321
+        $image = new \OC_Image();
322
+        $image->loadFromData($tmpAvatar);
323
+        $image->crop($crop['x'], $crop['y'], (int)round($crop['w']), (int)round($crop['h']));
324
+        try {
325
+            $avatar = $this->avatarManager->getAvatar($this->userId);
326
+            $avatar->set($image);
327
+            // Clean up
328
+            $this->cache->remove('tmpAvatar');
329
+            return new JSONResponse(['status' => 'success']);
330
+        } catch (\OC\NotSquareException $e) {
331
+            return new JSONResponse(['data' => ['message' => $this->l->t('Crop is not square')]],
332
+                                    Http::STATUS_BAD_REQUEST);
333
+        } catch (\Exception $e) {
334
+            $this->logger->logException($e, ['app' => 'core']);
335
+            return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
336
+        }
337
+    }
338 338
 }
Please login to merge, or discard this patch.
lib/private/Avatar.php 3 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -169,7 +169,7 @@  discard block
 block discarded – undo
169 169
 		}
170 170
 
171 171
 		$this->remove();
172
-		$file = $this->folder->newFile('avatar.' . $type);
172
+		$file = $this->folder->newFile('avatar.'.$type);
173 173
 		$file->putContent($data);
174 174
 
175 175
 		try {
@@ -218,9 +218,9 @@  discard block
 block discarded – undo
218 218
 		}
219 219
 
220 220
 		if ($size === -1) {
221
-			$path = 'avatar.' . $ext;
221
+			$path = 'avatar.'.$ext;
222 222
 		} else {
223
-			$path = 'avatar.' . $size . '.' . $ext;
223
+			$path = 'avatar.'.$size.'.'.$ext;
224 224
 		}
225 225
 
226 226
 		try {
@@ -238,7 +238,7 @@  discard block
 block discarded – undo
238 238
 			} else {
239 239
 				$avatar = new OC_Image();
240 240
 				/** @var ISimpleFile $file */
241
-				$file = $this->folder->getFile('avatar.' . $ext);
241
+				$file = $this->folder->getFile('avatar.'.$ext);
242 242
 				$avatar->loadFromData($file->getContent());
243 243
 				$avatar->resize($size);
244 244
 				$data = $avatar->data();
@@ -248,7 +248,7 @@  discard block
 block discarded – undo
248 248
 				$file = $this->folder->newFile($path);
249 249
 				$file->putContent($data);
250 250
 			} catch (NotPermittedException $e) {
251
-				$this->logger->error('Failed to save avatar for ' . $this->user->getUID());
251
+				$this->logger->error('Failed to save avatar for '.$this->user->getUID());
252 252
 				throw new NotFoundException();
253 253
 			}
254 254
 
@@ -308,7 +308,7 @@  discard block
 block discarded – undo
308 308
 			return false;
309 309
 		}
310 310
 		try {
311
-			$font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf';
311
+			$font = __DIR__.'/../../core/fonts/OpenSans-Semibold.ttf';
312 312
 			$svg = $this->getAvatarVector($size);
313 313
 			$avatar = new Imagick();
314 314
 			$avatar->setFont($font);
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
 		$white = imagecolorallocate($im, 255, 255, 255);
339 339
 		imagefilledrectangle($im, 0, 0, $size, $size, $background);
340 340
 
341
-		$font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf';
341
+		$font = __DIR__.'/../../core/fonts/OpenSans-Semibold.ttf';
342 342
 
343 343
 		$fontSize = $size * 0.4;
344 344
 
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
 		$hash = strtolower($hash);
449 449
 		
450 450
 		// Already a md5 hash?
451
-		if( preg_match('/^([0-9a-f]{4}-?){8}$/', $hash, $matches) !== 1 ) {
451
+		if (preg_match('/^([0-9a-f]{4}-?){8}$/', $hash, $matches) !== 1) {
452 452
 			$hash = md5($hash);
453 453
 		}
454 454
 
Please login to merge, or discard this patch.
Doc Comments   +5 added lines, -3 removed lines patch added patch discarded remove patch
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
 	 * Generate png avatar from svg with Imagick
302 302
 	 * 
303 303
 	 * @param int $size
304
-	 * @return string|boolean
304
+	 * @return string
305 305
 	 */
306 306
 	private function generateAvatarFromSvg(int $size) {
307 307
 		if (!extension_loaded('imagick')) {
@@ -387,6 +387,7 @@  discard block
 block discarded – undo
387 387
 	 * Calculate steps between two Colors
388 388
 	 * @param object Color $steps start color
389 389
 	 * @param object Color $ends end color
390
+	 * @param integer $steps
390 391
 	 * @return array [r,g,b] steps for each color to go from $steps to $ends
391 392
 	 */
392 393
 	private function stepCalc($steps, $ends) {
@@ -399,8 +400,9 @@  discard block
 block discarded – undo
399 400
 
400 401
 	/**
401 402
 	 * Convert a string to an integer evenly
402
-	 * @param string $hash the text to parse
403
-	 * @param int $maximum the maximum range
403
+	 * @param integer $steps
404
+	 * @param Color $color1
405
+	 * @param Color $color2
404 406
 	 * @return int between 0 and $maximum
405 407
 	 */
406 408
 	private function mixPalette($steps, $color1, $color2) {
Please login to merge, or discard this patch.
Indentation   +419 added lines, -419 removed lines patch added patch discarded remove patch
@@ -49,441 +49,441 @@
 block discarded – undo
49 49
  */
50 50
 
51 51
 class Avatar implements IAvatar {
52
-	/** @var ISimpleFolder */
53
-	private $folder;
54
-	/** @var IL10N */
55
-	private $l;
56
-	/** @var User */
57
-	private $user;
58
-	/** @var ILogger  */
59
-	private $logger;
60
-	/** @var IConfig */
61
-	private $config;
62
-
63
-	/**
64
-	 * https://github.com/sebdesign/cap-height -- for 500px height
65
-	 * Open Sans cap-height is 0.72 and we want a 200px caps height size (0.4 letter-to-total-height ratio, 500*0.4=200). 200/0.72 = 278px.
66
-	 * Since we start from the baseline (text-anchor) we need to shift the y axis by 100px (half the caps height): 500/2+100=350
67
-	 * 
68
-	 * @var string 
69
-	 */
70
-	private $svgTemplate = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
52
+    /** @var ISimpleFolder */
53
+    private $folder;
54
+    /** @var IL10N */
55
+    private $l;
56
+    /** @var User */
57
+    private $user;
58
+    /** @var ILogger  */
59
+    private $logger;
60
+    /** @var IConfig */
61
+    private $config;
62
+
63
+    /**
64
+     * https://github.com/sebdesign/cap-height -- for 500px height
65
+     * Open Sans cap-height is 0.72 and we want a 200px caps height size (0.4 letter-to-total-height ratio, 500*0.4=200). 200/0.72 = 278px.
66
+     * Since we start from the baseline (text-anchor) we need to shift the y axis by 100px (half the caps height): 500/2+100=350
67
+     * 
68
+     * @var string 
69
+     */
70
+    private $svgTemplate = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
71 71
 		<svg width="{size}" height="{size}" version="1.1" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg">
72 72
 			<rect width="100%" height="100%" fill="#{fill}"></rect>
73 73
 			<text x="50%" y="350" style="font-weight:600;font-size:278px;font-family:\'Open Sans\';text-anchor:middle;fill:#fff">{letter}</text>
74 74
 		</svg>';
75 75
 
76
-	/**
77
-	 * constructor
78
-	 *
79
-	 * @param ISimpleFolder $folder The folder where the avatars are
80
-	 * @param IL10N $l
81
-	 * @param User $user
82
-	 * @param ILogger $logger
83
-	 * @param IConfig $config
84
-	 */
85
-	public function __construct(ISimpleFolder $folder,
86
-		IL10N $l,
87
-		$user,
88
-		ILogger $logger,
89
-		IConfig $config) {
90
-		$this->folder = $folder;
91
-		$this->l = $l;
92
-		$this->user = $user;
93
-		$this->logger = $logger;
94
-		$this->config = $config;
95
-	}
96
-
97
-	/**
98
-	 * @inheritdoc
99
-	 */
100
-	public function get($size = 64) {
101
-		try {
102
-			$file = $this->getFile($size);
103
-		} catch (NotFoundException $e) {
104
-			return false;
105
-		}
106
-
107
-		$avatar = new OC_Image();
108
-		$avatar->loadFromData($file->getContent());
109
-		return $avatar;
110
-	}
111
-
112
-	/**
113
-	 * Check if an avatar exists for the user
114
-	 *
115
-	 * @return bool
116
-	 */
117
-	public function exists() {
118
-
119
-		return $this->folder->fileExists('avatar.jpg') || $this->folder->fileExists('avatar.png');
120
-	}
121
-
122
-	/**
123
-	 * sets the users avatar
124
-	 * @param IImage|resource|string $data An image object, imagedata or path to set a new avatar
125
-	 * @throws \Exception if the provided file is not a jpg or png image
126
-	 * @throws \Exception if the provided image is not valid
127
-	 * @throws NotSquareException if the image is not square
128
-	 * @return void
129
-	 */
130
-	public function set($data) {
131
-
132
-		if ($data instanceof IImage) {
133
-			$img = $data;
134
-			$data = $img->data();
135
-		} else {
136
-			$img = new OC_Image();
137
-			if (is_resource($data) && get_resource_type($data) === "gd") {
138
-				$img->setResource($data);
139
-			} elseif (is_resource($data)) {
140
-				$img->loadFromFileHandle($data);
141
-			} else {
142
-				try {
143
-					// detect if it is a path or maybe the images as string
144
-					$result = @realpath($data);
145
-					if ($result === false || $result === null) {
146
-						$img->loadFromData($data);
147
-					} else {
148
-						$img->loadFromFile($data);
149
-					}
150
-				} catch (\Error $e) {
151
-					$img->loadFromData($data);
152
-				}
153
-			}
154
-		}
155
-		$type = substr($img->mimeType(), -3);
156
-		if ($type === 'peg') {
157
-			$type = 'jpg';
158
-		}
159
-		if ($type !== 'jpg' && $type !== 'png') {
160
-			throw new \Exception($this->l->t('Unknown filetype'));
161
-		}
162
-
163
-		if (!$img->valid()) {
164
-			throw new \Exception($this->l->t('Invalid image'));
165
-		}
166
-
167
-		if (!($img->height() === $img->width())) {
168
-			throw new NotSquareException($this->l->t('Avatar image is not square'));
169
-		}
170
-
171
-		$this->remove();
172
-		$file = $this->folder->newFile('avatar.' . $type);
173
-		$file->putContent($data);
174
-
175
-		try {
176
-			$generated = $this->folder->getFile('generated');
177
-			$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'false');
178
-			$generated->delete();
179
-		} catch (NotFoundException $e) {
180
-			//
181
-		}
182
-		$this->user->triggerChange('avatar', $file);
183
-	}	
184
-
185
-	/**
186
-	 * remove the users avatar
187
-	 * @return void
188
-	 */
189
-	public function remove() {
190
-		$avatars = $this->folder->getDirectoryListing();
191
-
192
-		$this->config->setUserValue($this->user->getUID(), 'avatar', 'version',
193
-			(int) $this->config->getUserValue($this->user->getUID(), 'avatar', 'version', 0) + 1);
194
-
195
-		foreach ($avatars as $avatar) {
196
-			$avatar->delete();
197
-		}
198
-		$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true');
199
-		$this->user->triggerChange('avatar', '');
200
-	}
201
-
202
-	/**
203
-	 * @inheritdoc
204
-	 */
205
-	public function getFile($size) {
206
-		try {
207
-			$ext = $this->getExtension();
208
-		} catch (NotFoundException $e) {
209
-			if (!$data = $this->generateAvatarFromSvg(1024)) {
210
-				$data = $this->generateAvatar($this->user->getDisplayName(), 1024);
211
-			}
212
-			$avatar = $this->folder->newFile('avatar.png');
213
-			$avatar->putContent($data);
214
-			$ext = 'png';
215
-
216
-			$this->folder->newFile('generated');
217
-			$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true');
218
-		}
219
-
220
-		if ($size === -1) {
221
-			$path = 'avatar.' . $ext;
222
-		} else {
223
-			$path = 'avatar.' . $size . '.' . $ext;
224
-		}
225
-
226
-		try {
227
-			$file = $this->folder->getFile($path);
228
-		} catch (NotFoundException $e) {
229
-			if ($size <= 0) {
230
-				throw new NotFoundException;
231
-			}
232
-
233
-			if ($this->folder->fileExists('generated')) {
234
-				if (!$data = $this->generateAvatarFromSvg($size)) {
235
-					$data = $this->generateAvatar($this->user->getDisplayName(), $size);
236
-				}
237
-
238
-			} else {
239
-				$avatar = new OC_Image();
240
-				/** @var ISimpleFile $file */
241
-				$file = $this->folder->getFile('avatar.' . $ext);
242
-				$avatar->loadFromData($file->getContent());
243
-				$avatar->resize($size);
244
-				$data = $avatar->data();
245
-			}
246
-
247
-			try {
248
-				$file = $this->folder->newFile($path);
249
-				$file->putContent($data);
250
-			} catch (NotPermittedException $e) {
251
-				$this->logger->error('Failed to save avatar for ' . $this->user->getUID());
252
-				throw new NotFoundException();
253
-			}
254
-
255
-		}
256
-
257
-		if ($this->config->getUserValue($this->user->getUID(), 'avatar', 'generated', null) === null) {
258
-			$generated = $this->folder->fileExists('generated') ? 'true' : 'false';
259
-			$this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', $generated);
260
-		}
261
-
262
-		return $file;
263
-	}
264
-
265
-	/**
266
-	 * Get the extension of the avatar. If there is no avatar throw Exception
267
-	 *
268
-	 * @return string
269
-	 * @throws NotFoundException
270
-	 */
271
-	private function getExtension() {
272
-		if ($this->folder->fileExists('avatar.jpg')) {
273
-			return 'jpg';
274
-		} elseif ($this->folder->fileExists('avatar.png')) {
275
-			return 'png';
276
-		}
277
-		throw new NotFoundException;
278
-	}
76
+    /**
77
+     * constructor
78
+     *
79
+     * @param ISimpleFolder $folder The folder where the avatars are
80
+     * @param IL10N $l
81
+     * @param User $user
82
+     * @param ILogger $logger
83
+     * @param IConfig $config
84
+     */
85
+    public function __construct(ISimpleFolder $folder,
86
+        IL10N $l,
87
+        $user,
88
+        ILogger $logger,
89
+        IConfig $config) {
90
+        $this->folder = $folder;
91
+        $this->l = $l;
92
+        $this->user = $user;
93
+        $this->logger = $logger;
94
+        $this->config = $config;
95
+    }
96
+
97
+    /**
98
+     * @inheritdoc
99
+     */
100
+    public function get($size = 64) {
101
+        try {
102
+            $file = $this->getFile($size);
103
+        } catch (NotFoundException $e) {
104
+            return false;
105
+        }
106
+
107
+        $avatar = new OC_Image();
108
+        $avatar->loadFromData($file->getContent());
109
+        return $avatar;
110
+    }
111
+
112
+    /**
113
+     * Check if an avatar exists for the user
114
+     *
115
+     * @return bool
116
+     */
117
+    public function exists() {
118
+
119
+        return $this->folder->fileExists('avatar.jpg') || $this->folder->fileExists('avatar.png');
120
+    }
121
+
122
+    /**
123
+     * sets the users avatar
124
+     * @param IImage|resource|string $data An image object, imagedata or path to set a new avatar
125
+     * @throws \Exception if the provided file is not a jpg or png image
126
+     * @throws \Exception if the provided image is not valid
127
+     * @throws NotSquareException if the image is not square
128
+     * @return void
129
+     */
130
+    public function set($data) {
131
+
132
+        if ($data instanceof IImage) {
133
+            $img = $data;
134
+            $data = $img->data();
135
+        } else {
136
+            $img = new OC_Image();
137
+            if (is_resource($data) && get_resource_type($data) === "gd") {
138
+                $img->setResource($data);
139
+            } elseif (is_resource($data)) {
140
+                $img->loadFromFileHandle($data);
141
+            } else {
142
+                try {
143
+                    // detect if it is a path or maybe the images as string
144
+                    $result = @realpath($data);
145
+                    if ($result === false || $result === null) {
146
+                        $img->loadFromData($data);
147
+                    } else {
148
+                        $img->loadFromFile($data);
149
+                    }
150
+                } catch (\Error $e) {
151
+                    $img->loadFromData($data);
152
+                }
153
+            }
154
+        }
155
+        $type = substr($img->mimeType(), -3);
156
+        if ($type === 'peg') {
157
+            $type = 'jpg';
158
+        }
159
+        if ($type !== 'jpg' && $type !== 'png') {
160
+            throw new \Exception($this->l->t('Unknown filetype'));
161
+        }
162
+
163
+        if (!$img->valid()) {
164
+            throw new \Exception($this->l->t('Invalid image'));
165
+        }
166
+
167
+        if (!($img->height() === $img->width())) {
168
+            throw new NotSquareException($this->l->t('Avatar image is not square'));
169
+        }
170
+
171
+        $this->remove();
172
+        $file = $this->folder->newFile('avatar.' . $type);
173
+        $file->putContent($data);
174
+
175
+        try {
176
+            $generated = $this->folder->getFile('generated');
177
+            $this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'false');
178
+            $generated->delete();
179
+        } catch (NotFoundException $e) {
180
+            //
181
+        }
182
+        $this->user->triggerChange('avatar', $file);
183
+    }	
184
+
185
+    /**
186
+     * remove the users avatar
187
+     * @return void
188
+     */
189
+    public function remove() {
190
+        $avatars = $this->folder->getDirectoryListing();
191
+
192
+        $this->config->setUserValue($this->user->getUID(), 'avatar', 'version',
193
+            (int) $this->config->getUserValue($this->user->getUID(), 'avatar', 'version', 0) + 1);
194
+
195
+        foreach ($avatars as $avatar) {
196
+            $avatar->delete();
197
+        }
198
+        $this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true');
199
+        $this->user->triggerChange('avatar', '');
200
+    }
201
+
202
+    /**
203
+     * @inheritdoc
204
+     */
205
+    public function getFile($size) {
206
+        try {
207
+            $ext = $this->getExtension();
208
+        } catch (NotFoundException $e) {
209
+            if (!$data = $this->generateAvatarFromSvg(1024)) {
210
+                $data = $this->generateAvatar($this->user->getDisplayName(), 1024);
211
+            }
212
+            $avatar = $this->folder->newFile('avatar.png');
213
+            $avatar->putContent($data);
214
+            $ext = 'png';
215
+
216
+            $this->folder->newFile('generated');
217
+            $this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', 'true');
218
+        }
219
+
220
+        if ($size === -1) {
221
+            $path = 'avatar.' . $ext;
222
+        } else {
223
+            $path = 'avatar.' . $size . '.' . $ext;
224
+        }
225
+
226
+        try {
227
+            $file = $this->folder->getFile($path);
228
+        } catch (NotFoundException $e) {
229
+            if ($size <= 0) {
230
+                throw new NotFoundException;
231
+            }
232
+
233
+            if ($this->folder->fileExists('generated')) {
234
+                if (!$data = $this->generateAvatarFromSvg($size)) {
235
+                    $data = $this->generateAvatar($this->user->getDisplayName(), $size);
236
+                }
237
+
238
+            } else {
239
+                $avatar = new OC_Image();
240
+                /** @var ISimpleFile $file */
241
+                $file = $this->folder->getFile('avatar.' . $ext);
242
+                $avatar->loadFromData($file->getContent());
243
+                $avatar->resize($size);
244
+                $data = $avatar->data();
245
+            }
246
+
247
+            try {
248
+                $file = $this->folder->newFile($path);
249
+                $file->putContent($data);
250
+            } catch (NotPermittedException $e) {
251
+                $this->logger->error('Failed to save avatar for ' . $this->user->getUID());
252
+                throw new NotFoundException();
253
+            }
254
+
255
+        }
256
+
257
+        if ($this->config->getUserValue($this->user->getUID(), 'avatar', 'generated', null) === null) {
258
+            $generated = $this->folder->fileExists('generated') ? 'true' : 'false';
259
+            $this->config->setUserValue($this->user->getUID(), 'avatar', 'generated', $generated);
260
+        }
261
+
262
+        return $file;
263
+    }
264
+
265
+    /**
266
+     * Get the extension of the avatar. If there is no avatar throw Exception
267
+     *
268
+     * @return string
269
+     * @throws NotFoundException
270
+     */
271
+    private function getExtension() {
272
+        if ($this->folder->fileExists('avatar.jpg')) {
273
+            return 'jpg';
274
+        } elseif ($this->folder->fileExists('avatar.png')) {
275
+            return 'png';
276
+        }
277
+        throw new NotFoundException;
278
+    }
279 279
 	
280
-	/**
281
-	 * {size} = 500
282
-	 * {fill} = hex color to fill
283
-	 * {letter} = Letter to display
284
-	 * 
285
-	 * Generate SVG avatar
286
-	 * @return string
287
-	 * 
288
-	 */
289
-	private function getAvatarVector(int $size): string {
290
-		$userDisplayName = $this->user->getDisplayName();
291
-
292
-		$bgRGB = $this->avatarBackgroundColor($userDisplayName);
293
-		$bgHEX = sprintf("%02x%02x%02x", $bgRGB->r, $bgRGB->g, $bgRGB->b);
294
-		$letter = mb_strtoupper(mb_substr($userDisplayName, 0, 1), 'UTF-8');
280
+    /**
281
+     * {size} = 500
282
+     * {fill} = hex color to fill
283
+     * {letter} = Letter to display
284
+     * 
285
+     * Generate SVG avatar
286
+     * @return string
287
+     * 
288
+     */
289
+    private function getAvatarVector(int $size): string {
290
+        $userDisplayName = $this->user->getDisplayName();
291
+
292
+        $bgRGB = $this->avatarBackgroundColor($userDisplayName);
293
+        $bgHEX = sprintf("%02x%02x%02x", $bgRGB->r, $bgRGB->g, $bgRGB->b);
294
+        $letter = mb_strtoupper(mb_substr($userDisplayName, 0, 1), 'UTF-8');
295 295
 		
296
-		$toReplace = ['{size}', '{fill}', '{letter}'];
297
-		return str_replace($toReplace, [$size, $bgHEX, $letter], $this->svgTemplate);
298
-	}
299
-
300
-	/**
301
-	 * Generate png avatar from svg with Imagick
302
-	 * 
303
-	 * @param int $size
304
-	 * @return string|boolean
305
-	 */
306
-	private function generateAvatarFromSvg(int $size) {
307
-		if (!extension_loaded('imagick')) {
308
-			return false;
309
-		}
310
-		try {
311
-			$font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf';
312
-			$svg = $this->getAvatarVector($size);
313
-			$avatar = new Imagick();
314
-			$avatar->setFont($font);
315
-			$avatar->readImageBlob($svg);
316
-			$avatar->setImageFormat('png');
317
-			$image = new OC_Image();
318
-			$image->loadFromData($avatar);
319
-			return $image->data();
320
-		} catch (\Exception $e) {
321
-			return false;
322
-		}
323
-	}
324
-
325
-	/**
326
-	 * Generate png avatar with GD
327
-	 * 
328
-	 * @param string $userDisplayName
329
-	 * @param int $size
330
-	 * @return string
331
-	 */
332
-	private function generateAvatar($userDisplayName, $size) {
333
-		$text = mb_strtoupper(mb_substr($userDisplayName, 0, 1), 'UTF-8');
334
-		$backgroundColor = $this->avatarBackgroundColor($userDisplayName);
335
-
336
-		$im = imagecreatetruecolor($size, $size);
337
-		$background = imagecolorallocate($im, $backgroundColor->r, $backgroundColor->g, $backgroundColor->b);
338
-		$white = imagecolorallocate($im, 255, 255, 255);
339
-		imagefilledrectangle($im, 0, 0, $size, $size, $background);
340
-
341
-		$font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf';
342
-
343
-		$fontSize = $size * 0.4;
344
-
345
-		list($x, $y) = $this->imageTTFCenter($im, $text, $font, $fontSize);
346
-
347
-		imagettftext($im, $fontSize, 0, $x, $y, $white, $font, $text);
348
-
349
-		ob_start();
350
-		imagepng($im);
351
-		$data = ob_get_contents();
352
-		ob_end_clean();
353
-
354
-		return $data;
355
-	}
356
-
357
-	/**
358
-	 * Calculate real image ttf center
359
-	 *
360
-	 * @param resource $image
361
-	 * @param string $text text string
362
-	 * @param string $font font path
363
-	 * @param int $size font size
364
-	 * @param int $angle
365
-	 * @return Array
366
-	 */
367
-	protected function imageTTFCenter($image, string $text, string $font, int $size, $angle = 0): array {
368
-		// Image width & height
369
-		$xi = imagesx($image);
370
-		$yi = imagesy($image);
371
-
372
-		// bounding box
373
-		$box = imagettfbbox($size, $angle, $font, $text);
374
-
375
-		// imagettfbbox can return negative int
376
-		$xr = abs(max($box[2], $box[4]));
377
-		$yr = abs(max($box[5], $box[7]));
378
-
379
-		// calculate bottom left placement
380
-		$x = intval(($xi - $xr) / 2);
381
-		$y = intval(($yi + $yr) / 2);
382
-
383
-		return array($x, $y);
384
-	}
385
-
386
-	/**
387
-	 * Calculate steps between two Colors
388
-	 * @param object Color $steps start color
389
-	 * @param object Color $ends end color
390
-	 * @return array [r,g,b] steps for each color to go from $steps to $ends
391
-	 */
392
-	private function stepCalc($steps, $ends) {
393
-		$step = array();
394
-		$step[0] = ($ends[1]->r - $ends[0]->r) / $steps;
395
-		$step[1] = ($ends[1]->g - $ends[0]->g) / $steps;
396
-		$step[2] = ($ends[1]->b - $ends[0]->b) / $steps;
397
-		return $step;
398
-	}
399
-
400
-	/**
401
-	 * Convert a string to an integer evenly
402
-	 * @param string $hash the text to parse
403
-	 * @param int $maximum the maximum range
404
-	 * @return int between 0 and $maximum
405
-	 */
406
-	private function mixPalette($steps, $color1, $color2) {
407
-		$count = $steps + 1;
408
-		$palette = array($color1);
409
-		$step = $this->stepCalc($steps, [$color1, $color2]);
410
-		for ($i = 1; $i < $steps; $i++) {
411
-			$r = intval($color1->r + ($step[0] * $i));
412
-			$g = intval($color1->g + ($step[1] * $i));
413
-			$b = intval($color1->b + ($step[2] * $i));
414
-			$palette[] = new Color($r, $g, $b);
415
-		}
416
-		return $palette;
417
-	}
418
-
419
-	/**
420
-	 * Convert a string to an integer evenly
421
-	 * @param string $hash the text to parse
422
-	 * @param int $maximum the maximum range
423
-	 * @return int between 0 and $maximum
424
-	 */
425
-	private function hashToInt($hash, $maximum) {
426
-		$final = 0;
427
-		$result = array();
428
-
429
-		// Splitting evenly the string
430
-		for ($i = 0; $i < strlen($hash); $i++) {
431
-			// chars in md5 goes up to f, hex:16
432
-			$result[] = intval(substr($hash, $i, 1), 16) % 16;
433
-		}
434
-		// Adds up all results
435
-		foreach ($result as $value) {
436
-			$final += $value;
437
-		}
438
-		// chars in md5 goes up to f, hex:16
439
-		return intval($final % $maximum);
440
-	}
441
-
442
-	/**
443
-	 * @param string $hash
444
-	 * @return Color Object containting r g b int in the range [0, 255]
445
-	 */
446
-	public function avatarBackgroundColor(string $hash) {
447
-		// Normalize hash
448
-		$hash = strtolower($hash);
296
+        $toReplace = ['{size}', '{fill}', '{letter}'];
297
+        return str_replace($toReplace, [$size, $bgHEX, $letter], $this->svgTemplate);
298
+    }
299
+
300
+    /**
301
+     * Generate png avatar from svg with Imagick
302
+     * 
303
+     * @param int $size
304
+     * @return string|boolean
305
+     */
306
+    private function generateAvatarFromSvg(int $size) {
307
+        if (!extension_loaded('imagick')) {
308
+            return false;
309
+        }
310
+        try {
311
+            $font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf';
312
+            $svg = $this->getAvatarVector($size);
313
+            $avatar = new Imagick();
314
+            $avatar->setFont($font);
315
+            $avatar->readImageBlob($svg);
316
+            $avatar->setImageFormat('png');
317
+            $image = new OC_Image();
318
+            $image->loadFromData($avatar);
319
+            return $image->data();
320
+        } catch (\Exception $e) {
321
+            return false;
322
+        }
323
+    }
324
+
325
+    /**
326
+     * Generate png avatar with GD
327
+     * 
328
+     * @param string $userDisplayName
329
+     * @param int $size
330
+     * @return string
331
+     */
332
+    private function generateAvatar($userDisplayName, $size) {
333
+        $text = mb_strtoupper(mb_substr($userDisplayName, 0, 1), 'UTF-8');
334
+        $backgroundColor = $this->avatarBackgroundColor($userDisplayName);
335
+
336
+        $im = imagecreatetruecolor($size, $size);
337
+        $background = imagecolorallocate($im, $backgroundColor->r, $backgroundColor->g, $backgroundColor->b);
338
+        $white = imagecolorallocate($im, 255, 255, 255);
339
+        imagefilledrectangle($im, 0, 0, $size, $size, $background);
340
+
341
+        $font = __DIR__ . '/../../core/fonts/OpenSans-Semibold.ttf';
342
+
343
+        $fontSize = $size * 0.4;
344
+
345
+        list($x, $y) = $this->imageTTFCenter($im, $text, $font, $fontSize);
346
+
347
+        imagettftext($im, $fontSize, 0, $x, $y, $white, $font, $text);
348
+
349
+        ob_start();
350
+        imagepng($im);
351
+        $data = ob_get_contents();
352
+        ob_end_clean();
353
+
354
+        return $data;
355
+    }
356
+
357
+    /**
358
+     * Calculate real image ttf center
359
+     *
360
+     * @param resource $image
361
+     * @param string $text text string
362
+     * @param string $font font path
363
+     * @param int $size font size
364
+     * @param int $angle
365
+     * @return Array
366
+     */
367
+    protected function imageTTFCenter($image, string $text, string $font, int $size, $angle = 0): array {
368
+        // Image width & height
369
+        $xi = imagesx($image);
370
+        $yi = imagesy($image);
371
+
372
+        // bounding box
373
+        $box = imagettfbbox($size, $angle, $font, $text);
374
+
375
+        // imagettfbbox can return negative int
376
+        $xr = abs(max($box[2], $box[4]));
377
+        $yr = abs(max($box[5], $box[7]));
378
+
379
+        // calculate bottom left placement
380
+        $x = intval(($xi - $xr) / 2);
381
+        $y = intval(($yi + $yr) / 2);
382
+
383
+        return array($x, $y);
384
+    }
385
+
386
+    /**
387
+     * Calculate steps between two Colors
388
+     * @param object Color $steps start color
389
+     * @param object Color $ends end color
390
+     * @return array [r,g,b] steps for each color to go from $steps to $ends
391
+     */
392
+    private function stepCalc($steps, $ends) {
393
+        $step = array();
394
+        $step[0] = ($ends[1]->r - $ends[0]->r) / $steps;
395
+        $step[1] = ($ends[1]->g - $ends[0]->g) / $steps;
396
+        $step[2] = ($ends[1]->b - $ends[0]->b) / $steps;
397
+        return $step;
398
+    }
399
+
400
+    /**
401
+     * Convert a string to an integer evenly
402
+     * @param string $hash the text to parse
403
+     * @param int $maximum the maximum range
404
+     * @return int between 0 and $maximum
405
+     */
406
+    private function mixPalette($steps, $color1, $color2) {
407
+        $count = $steps + 1;
408
+        $palette = array($color1);
409
+        $step = $this->stepCalc($steps, [$color1, $color2]);
410
+        for ($i = 1; $i < $steps; $i++) {
411
+            $r = intval($color1->r + ($step[0] * $i));
412
+            $g = intval($color1->g + ($step[1] * $i));
413
+            $b = intval($color1->b + ($step[2] * $i));
414
+            $palette[] = new Color($r, $g, $b);
415
+        }
416
+        return $palette;
417
+    }
418
+
419
+    /**
420
+     * Convert a string to an integer evenly
421
+     * @param string $hash the text to parse
422
+     * @param int $maximum the maximum range
423
+     * @return int between 0 and $maximum
424
+     */
425
+    private function hashToInt($hash, $maximum) {
426
+        $final = 0;
427
+        $result = array();
428
+
429
+        // Splitting evenly the string
430
+        for ($i = 0; $i < strlen($hash); $i++) {
431
+            // chars in md5 goes up to f, hex:16
432
+            $result[] = intval(substr($hash, $i, 1), 16) % 16;
433
+        }
434
+        // Adds up all results
435
+        foreach ($result as $value) {
436
+            $final += $value;
437
+        }
438
+        // chars in md5 goes up to f, hex:16
439
+        return intval($final % $maximum);
440
+    }
441
+
442
+    /**
443
+     * @param string $hash
444
+     * @return Color Object containting r g b int in the range [0, 255]
445
+     */
446
+    public function avatarBackgroundColor(string $hash) {
447
+        // Normalize hash
448
+        $hash = strtolower($hash);
449 449
 		
450
-		// Already a md5 hash?
451
-		if( preg_match('/^([0-9a-f]{4}-?){8}$/', $hash, $matches) !== 1 ) {
452
-			$hash = md5($hash);
453
-		}
450
+        // Already a md5 hash?
451
+        if( preg_match('/^([0-9a-f]{4}-?){8}$/', $hash, $matches) !== 1 ) {
452
+            $hash = md5($hash);
453
+        }
454 454
 
455
-		// Remove unwanted char
456
-		$hash = preg_replace('/[^0-9a-f]+/', '', $hash);
455
+        // Remove unwanted char
456
+        $hash = preg_replace('/[^0-9a-f]+/', '', $hash);
457 457
 
458
-		$red = new Color(182, 70, 157);
459
-		$yellow = new Color(221, 203, 85);
460
-		$blue = new Color(0, 130, 201); // Nextcloud blue
458
+        $red = new Color(182, 70, 157);
459
+        $yellow = new Color(221, 203, 85);
460
+        $blue = new Color(0, 130, 201); // Nextcloud blue
461 461
 
462
-		// Number of steps to go from a color to another
463
-		// 3 colors * 6 will result in 18 generated colors
464
-		$steps = 6;
462
+        // Number of steps to go from a color to another
463
+        // 3 colors * 6 will result in 18 generated colors
464
+        $steps = 6;
465 465
 
466
-		$palette1 = $this->mixPalette($steps, $red, $yellow);
467
-		$palette2 = $this->mixPalette($steps, $yellow, $blue);
468
-		$palette3 = $this->mixPalette($steps, $blue, $red);
466
+        $palette1 = $this->mixPalette($steps, $red, $yellow);
467
+        $palette2 = $this->mixPalette($steps, $yellow, $blue);
468
+        $palette3 = $this->mixPalette($steps, $blue, $red);
469 469
 
470
-		$finalPalette = array_merge($palette1, $palette2, $palette3);
470
+        $finalPalette = array_merge($palette1, $palette2, $palette3);
471 471
 
472
-		return $finalPalette[$this->hashToInt($hash, $steps * 3)];
473
-	}
472
+        return $finalPalette[$this->hashToInt($hash, $steps * 3)];
473
+    }
474 474
 
475
-	public function userChanged($feature, $oldValue, $newValue) {
476
-		// We only change the avatar on display name changes
477
-		if ($feature !== 'displayName') {
478
-			return;
479
-		}
475
+    public function userChanged($feature, $oldValue, $newValue) {
476
+        // We only change the avatar on display name changes
477
+        if ($feature !== 'displayName') {
478
+            return;
479
+        }
480 480
 
481
-		// If the avatar is not generated (so an uploaded image) we skip this
482
-		if (!$this->folder->fileExists('generated')) {
483
-			return;
484
-		}
481
+        // If the avatar is not generated (so an uploaded image) we skip this
482
+        if (!$this->folder->fileExists('generated')) {
483
+            return;
484
+        }
485 485
 
486
-		$this->remove();
487
-	}
486
+        $this->remove();
487
+    }
488 488
 
489 489
 }
Please login to merge, or discard this patch.
lib/public/IAvatar.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -80,12 +80,12 @@
 block discarded – undo
80 80
      */
81 81
     public function getFile($size);
82 82
 
83
-	/**
84
-	 * @param string $text
85
-	 * @return Color Object containting r g b int in the range [0, 255]
83
+    /**
84
+     * @param string $text
85
+     * @return Color Object containting r g b int in the range [0, 255]
86 86
      * @since 14.0.0
87
-	 */
88
-	public function avatarBackgroundColor(string $text);
87
+     */
88
+    public function avatarBackgroundColor(string $text);
89 89
 
90 90
     /**
91 91
      * Handle a changed user
Please login to merge, or discard this patch.