Completed
Pull Request — master (#9197)
by John
407:05 queued 388:17
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   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -51,296 +51,296 @@
 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
-		// Let cache this!
149
-		$resp->addHeader('Pragma', 'public');
150
-		// Cache for 30 minutes
151
-		$resp->cacheFor(1800);
152
-
153
-		$expires = new \DateTime();
154
-		$expires->setTimestamp($this->timeFactory->getTime());
155
-		$expires->add(new \DateInterval('PT30M'));
156
-		$resp->addHeader('Expires', $expires->format(\DateTime::RFC1123));
157
-
158
-		return $resp;
159
-	}
160
-
161
-	/**
162
-	 * @NoAdminRequired
163
-	 *
164
-	 * @param string $path
165
-	 * @return JSONResponse
166
-	 */
167
-	public function postAvatar($path) {
168
-		$files = $this->request->getUploadedFile('files');
169
-
170
-		if (isset($path)) {
171
-			$path = stripslashes($path);
172
-			$userFolder = $this->rootFolder->getUserFolder($this->userId);
173
-			/** @var File $node */
174
-			$node = $userFolder->get($path);
175
-			if (!($node instanceof File)) {
176
-				return new JSONResponse(['data' => ['message' => $this->l->t('Please select a file.')]]);
177
-			}
178
-			if ($node->getSize() > 20*1024*1024) {
179
-				return new JSONResponse(
180
-					['data' => ['message' => $this->l->t('File is too big')]],
181
-					Http::STATUS_BAD_REQUEST
182
-				);
183
-			}
184
-
185
-			if ($node->getMimeType() !== 'image/jpeg' && $node->getMimeType() !== 'image/png') {
186
-				return new JSONResponse(
187
-					['data' => ['message' => $this->l->t('The selected file is not an image.')]],
188
-					Http::STATUS_BAD_REQUEST
189
-				);
190
-			}
191
-
192
-			try {
193
-				$content = $node->getContent();
194
-			} catch (\OCP\Files\NotPermittedException $e) {
195
-				return new JSONResponse(
196
-					['data' => ['message' => $this->l->t('The selected file cannot be read.')]],
197
-					Http::STATUS_BAD_REQUEST
198
-				);
199
-			}
200
-		} elseif (!is_null($files)) {
201
-			if (
202
-				$files['error'][0] === 0 &&
203
-				 is_uploaded_file($files['tmp_name'][0]) &&
204
-				!\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])
205
-			) {
206
-				if ($files['size'][0] > 20*1024*1024) {
207
-					return new JSONResponse(
208
-						['data' => ['message' => $this->l->t('File is too big')]],
209
-						Http::STATUS_BAD_REQUEST
210
-					);
211
-				}
212
-				$this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
213
-				$content = $this->cache->get('avatar_upload');
214
-				unlink($files['tmp_name'][0]);
215
-			} else {
216
-				return new JSONResponse(
217
-					['data' => ['message' => $this->l->t('Invalid file provided')]],
218
-					Http::STATUS_BAD_REQUEST
219
-				);
220
-			}
221
-		} else {
222
-			//Add imgfile
223
-			return new JSONResponse(
224
-				['data' => ['message' => $this->l->t('No image or file provided')]],
225
-				Http::STATUS_BAD_REQUEST
226
-			);
227
-		}
228
-
229
-		try {
230
-			$image = new \OC_Image();
231
-			$image->loadFromData($content);
232
-			$image->readExif($content);
233
-			$image->fixOrientation();
234
-
235
-			if ($image->valid()) {
236
-				$mimeType = $image->mimeType();
237
-				if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
238
-					return new JSONResponse(
239
-						['data' => ['message' => $this->l->t('Unknown filetype')]],
240
-						Http::STATUS_OK
241
-					);
242
-				}
243
-
244
-				$this->cache->set('tmpAvatar', $image->data(), 7200);
245
-				return new JSONResponse(
246
-					['data' => 'notsquare'],
247
-					Http::STATUS_OK
248
-				);
249
-			} else {
250
-				return new JSONResponse(
251
-					['data' => ['message' => $this->l->t('Invalid image')]],
252
-					Http::STATUS_OK
253
-				);
254
-			}
255
-		} catch (\Exception $e) {
256
-			$this->logger->logException($e, ['app' => 'core']);
257
-			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK);
258
-		}
259
-	}
260
-
261
-	/**
262
-	 * @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
263 121
      *
264
-	 * @return JSONResponse
265
-	 */
266
-	public function deleteAvatar() {
267
-		try {
268
-			$avatar = $this->avatarManager->getAvatar($this->userId);
269
-			$avatar->remove();
270
-			return new JSONResponse();
271
-		} catch (\Exception $e) {
272
-			$this->logger->logException($e, ['app' => 'core']);
273
-			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
274
-		}
275
-	}
276
-
277
-	/**
278
-	 * @NoAdminRequired
279
-	 *
280
-	 * @return JSONResponse|DataDisplayResponse
281
-	 */
282
-	public function getTmpAvatar() {
283
-		$tmpAvatar = $this->cache->get('tmpAvatar');
284
-		if (is_null($tmpAvatar)) {
285
-			return new JSONResponse(['data' => [
286
-										'message' => $this->l->t("No temporary profile picture available, try again")
287
-									]],
288
-									Http::STATUS_NOT_FOUND);
289
-		}
290
-
291
-		$image = new \OC_Image();
292
-		$image->loadFromData($tmpAvatar);
293
-
294
-		$resp = new DataDisplayResponse($image->data(),
295
-				Http::STATUS_OK,
296
-				['Content-Type' => $image->mimeType()]);
297
-
298
-		$resp->setETag((string)crc32($image->data()));
299
-		$resp->cacheFor(0);
300
-		$resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
301
-		return $resp;
302
-	}
303
-
304
-	/**
305
-	 * @NoAdminRequired
306
-	 *
307
-	 * @param array $crop
308
-	 * @return JSONResponse
309
-	 */
310
-	public function postCroppedAvatar($crop) {
311
-		if (is_null($crop)) {
312
-			return new JSONResponse(['data' => ['message' => $this->l->t("No crop data provided")]],
313
-									Http::STATUS_BAD_REQUEST);
314
-		}
315
-
316
-		if (!isset($crop['x'], $crop['y'], $crop['w'], $crop['h'])) {
317
-			return new JSONResponse(['data' => ['message' => $this->l->t("No valid crop data provided")]],
318
-									Http::STATUS_BAD_REQUEST);
319
-		}
320
-
321
-		$tmpAvatar = $this->cache->get('tmpAvatar');
322
-		if (is_null($tmpAvatar)) {
323
-			return new JSONResponse(['data' => [
324
-										'message' => $this->l->t("No temporary profile picture available, try again")
325
-									]],
326
-									Http::STATUS_BAD_REQUEST);
327
-		}
328
-
329
-		$image = new \OC_Image();
330
-		$image->loadFromData($tmpAvatar);
331
-		$image->crop($crop['x'], $crop['y'], (int)round($crop['w']), (int)round($crop['h']));
332
-		try {
333
-			$avatar = $this->avatarManager->getAvatar($this->userId);
334
-			$avatar->set($image);
335
-			// Clean up
336
-			$this->cache->remove('tmpAvatar');
337
-			return new JSONResponse(['status' => 'success']);
338
-		} catch (\OC\NotSquareException $e) {
339
-			return new JSONResponse(['data' => ['message' => $this->l->t('Crop is not square')]],
340
-									Http::STATUS_BAD_REQUEST);
341
-		} catch (\Exception $e) {
342
-			$this->logger->logException($e, ['app' => 'core']);
343
-			return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
344
-		}
345
-	}
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
+        // Let cache this!
149
+        $resp->addHeader('Pragma', 'public');
150
+        // Cache for 30 minutes
151
+        $resp->cacheFor(1800);
152
+
153
+        $expires = new \DateTime();
154
+        $expires->setTimestamp($this->timeFactory->getTime());
155
+        $expires->add(new \DateInterval('PT30M'));
156
+        $resp->addHeader('Expires', $expires->format(\DateTime::RFC1123));
157
+
158
+        return $resp;
159
+    }
160
+
161
+    /**
162
+     * @NoAdminRequired
163
+     *
164
+     * @param string $path
165
+     * @return JSONResponse
166
+     */
167
+    public function postAvatar($path) {
168
+        $files = $this->request->getUploadedFile('files');
169
+
170
+        if (isset($path)) {
171
+            $path = stripslashes($path);
172
+            $userFolder = $this->rootFolder->getUserFolder($this->userId);
173
+            /** @var File $node */
174
+            $node = $userFolder->get($path);
175
+            if (!($node instanceof File)) {
176
+                return new JSONResponse(['data' => ['message' => $this->l->t('Please select a file.')]]);
177
+            }
178
+            if ($node->getSize() > 20*1024*1024) {
179
+                return new JSONResponse(
180
+                    ['data' => ['message' => $this->l->t('File is too big')]],
181
+                    Http::STATUS_BAD_REQUEST
182
+                );
183
+            }
184
+
185
+            if ($node->getMimeType() !== 'image/jpeg' && $node->getMimeType() !== 'image/png') {
186
+                return new JSONResponse(
187
+                    ['data' => ['message' => $this->l->t('The selected file is not an image.')]],
188
+                    Http::STATUS_BAD_REQUEST
189
+                );
190
+            }
191
+
192
+            try {
193
+                $content = $node->getContent();
194
+            } catch (\OCP\Files\NotPermittedException $e) {
195
+                return new JSONResponse(
196
+                    ['data' => ['message' => $this->l->t('The selected file cannot be read.')]],
197
+                    Http::STATUS_BAD_REQUEST
198
+                );
199
+            }
200
+        } elseif (!is_null($files)) {
201
+            if (
202
+                $files['error'][0] === 0 &&
203
+                 is_uploaded_file($files['tmp_name'][0]) &&
204
+                !\OC\Files\Filesystem::isFileBlacklisted($files['tmp_name'][0])
205
+            ) {
206
+                if ($files['size'][0] > 20*1024*1024) {
207
+                    return new JSONResponse(
208
+                        ['data' => ['message' => $this->l->t('File is too big')]],
209
+                        Http::STATUS_BAD_REQUEST
210
+                    );
211
+                }
212
+                $this->cache->set('avatar_upload', file_get_contents($files['tmp_name'][0]), 7200);
213
+                $content = $this->cache->get('avatar_upload');
214
+                unlink($files['tmp_name'][0]);
215
+            } else {
216
+                return new JSONResponse(
217
+                    ['data' => ['message' => $this->l->t('Invalid file provided')]],
218
+                    Http::STATUS_BAD_REQUEST
219
+                );
220
+            }
221
+        } else {
222
+            //Add imgfile
223
+            return new JSONResponse(
224
+                ['data' => ['message' => $this->l->t('No image or file provided')]],
225
+                Http::STATUS_BAD_REQUEST
226
+            );
227
+        }
228
+
229
+        try {
230
+            $image = new \OC_Image();
231
+            $image->loadFromData($content);
232
+            $image->readExif($content);
233
+            $image->fixOrientation();
234
+
235
+            if ($image->valid()) {
236
+                $mimeType = $image->mimeType();
237
+                if ($mimeType !== 'image/jpeg' && $mimeType !== 'image/png') {
238
+                    return new JSONResponse(
239
+                        ['data' => ['message' => $this->l->t('Unknown filetype')]],
240
+                        Http::STATUS_OK
241
+                    );
242
+                }
243
+
244
+                $this->cache->set('tmpAvatar', $image->data(), 7200);
245
+                return new JSONResponse(
246
+                    ['data' => 'notsquare'],
247
+                    Http::STATUS_OK
248
+                );
249
+            } else {
250
+                return new JSONResponse(
251
+                    ['data' => ['message' => $this->l->t('Invalid image')]],
252
+                    Http::STATUS_OK
253
+                );
254
+            }
255
+        } catch (\Exception $e) {
256
+            $this->logger->logException($e, ['app' => 'core']);
257
+            return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_OK);
258
+        }
259
+    }
260
+
261
+    /**
262
+     * @NoAdminRequired
263
+     *
264
+     * @return JSONResponse
265
+     */
266
+    public function deleteAvatar() {
267
+        try {
268
+            $avatar = $this->avatarManager->getAvatar($this->userId);
269
+            $avatar->remove();
270
+            return new JSONResponse();
271
+        } catch (\Exception $e) {
272
+            $this->logger->logException($e, ['app' => 'core']);
273
+            return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
274
+        }
275
+    }
276
+
277
+    /**
278
+     * @NoAdminRequired
279
+     *
280
+     * @return JSONResponse|DataDisplayResponse
281
+     */
282
+    public function getTmpAvatar() {
283
+        $tmpAvatar = $this->cache->get('tmpAvatar');
284
+        if (is_null($tmpAvatar)) {
285
+            return new JSONResponse(['data' => [
286
+                                        'message' => $this->l->t("No temporary profile picture available, try again")
287
+                                    ]],
288
+                                    Http::STATUS_NOT_FOUND);
289
+        }
290
+
291
+        $image = new \OC_Image();
292
+        $image->loadFromData($tmpAvatar);
293
+
294
+        $resp = new DataDisplayResponse($image->data(),
295
+                Http::STATUS_OK,
296
+                ['Content-Type' => $image->mimeType()]);
297
+
298
+        $resp->setETag((string)crc32($image->data()));
299
+        $resp->cacheFor(0);
300
+        $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT')));
301
+        return $resp;
302
+    }
303
+
304
+    /**
305
+     * @NoAdminRequired
306
+     *
307
+     * @param array $crop
308
+     * @return JSONResponse
309
+     */
310
+    public function postCroppedAvatar($crop) {
311
+        if (is_null($crop)) {
312
+            return new JSONResponse(['data' => ['message' => $this->l->t("No crop data provided")]],
313
+                                    Http::STATUS_BAD_REQUEST);
314
+        }
315
+
316
+        if (!isset($crop['x'], $crop['y'], $crop['w'], $crop['h'])) {
317
+            return new JSONResponse(['data' => ['message' => $this->l->t("No valid crop data provided")]],
318
+                                    Http::STATUS_BAD_REQUEST);
319
+        }
320
+
321
+        $tmpAvatar = $this->cache->get('tmpAvatar');
322
+        if (is_null($tmpAvatar)) {
323
+            return new JSONResponse(['data' => [
324
+                                        'message' => $this->l->t("No temporary profile picture available, try again")
325
+                                    ]],
326
+                                    Http::STATUS_BAD_REQUEST);
327
+        }
328
+
329
+        $image = new \OC_Image();
330
+        $image->loadFromData($tmpAvatar);
331
+        $image->crop($crop['x'], $crop['y'], (int)round($crop['w']), (int)round($crop['h']));
332
+        try {
333
+            $avatar = $this->avatarManager->getAvatar($this->userId);
334
+            $avatar->set($image);
335
+            // Clean up
336
+            $this->cache->remove('tmpAvatar');
337
+            return new JSONResponse(['status' => 'success']);
338
+        } catch (\OC\NotSquareException $e) {
339
+            return new JSONResponse(['data' => ['message' => $this->l->t('Crop is not square')]],
340
+                                    Http::STATUS_BAD_REQUEST);
341
+        } catch (\Exception $e) {
342
+            $this->logger->logException($e, ['app' => 'core']);
343
+            return new JSONResponse(['data' => ['message' => $this->l->t('An error occurred. Please contact your admin.')]], Http::STATUS_BAD_REQUEST);
344
+        }
345
+    }
346 346
 }
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.