Passed
Push — master ( 0fd208...d9b2b3 )
by Morris
14:21 queued 10s
created
apps/dav/lib/CardDAV/PhotoCache.php 1 patch
Indentation   +241 added lines, -241 removed lines patch added patch discarded remove patch
@@ -35,245 +35,245 @@
 block discarded – undo
35 35
 
36 36
 class PhotoCache {
37 37
 
38
-	/** @var array  */
39
-	protected const ALLOWED_CONTENT_TYPES = [
40
-		'image/png' => 'png',
41
-		'image/jpeg' => 'jpg',
42
-		'image/gif' => 'gif',
43
-		'image/vnd.microsoft.icon' => 'ico',
44
-	];
45
-
46
-	/** @var IAppData */
47
-	protected $appData;
48
-
49
-	/** @var ILogger */
50
-	protected $logger;
51
-
52
-	/**
53
-	 * PhotoCache constructor.
54
-	 *
55
-	 * @param IAppData $appData
56
-	 * @param ILogger $logger
57
-	 */
58
-	public function __construct(IAppData $appData, ILogger $logger) {
59
-		$this->appData = $appData;
60
-		$this->logger = $logger;
61
-	}
62
-
63
-	/**
64
-	 * @param int $addressBookId
65
-	 * @param string $cardUri
66
-	 * @param int $size
67
-	 * @param Card $card
68
-	 *
69
-	 * @return ISimpleFile
70
-	 * @throws NotFoundException
71
-	 */
72
-	public function get($addressBookId, $cardUri, $size, Card $card) {
73
-		$folder = $this->getFolder($addressBookId, $cardUri);
74
-
75
-		if ($this->isEmpty($folder)) {
76
-			$this->init($folder, $card);
77
-		}
78
-
79
-		if (!$this->hasPhoto($folder)) {
80
-			throw new NotFoundException();
81
-		}
82
-
83
-		if ($size !== -1) {
84
-			$size = 2 ** ceil(log($size) / log(2));
85
-		}
86
-
87
-		return $this->getFile($folder, $size);
88
-	}
89
-
90
-	/**
91
-	 * @param ISimpleFolder $folder
92
-	 * @return bool
93
-	 */
94
-	private function isEmpty(ISimpleFolder $folder) {
95
-		return $folder->getDirectoryListing() === [];
96
-	}
97
-
98
-	/**
99
-	 * @param ISimpleFolder $folder
100
-	 * @param Card $card
101
-	 * @throws NotPermittedException
102
-	 */
103
-	private function init(ISimpleFolder $folder, Card $card): void {
104
-		$data = $this->getPhoto($card);
105
-
106
-		if ($data === false || !isset($data['Content-Type'])) {
107
-			$folder->newFile('nophoto');
108
-			return;
109
-		}
110
-
111
-		$contentType = $data['Content-Type'];
112
-		$extension = self::ALLOWED_CONTENT_TYPES[$contentType] ?? null;
113
-
114
-		if ($extension === null) {
115
-			$folder->newFile('nophoto');
116
-			return;
117
-		}
118
-
119
-		$file = $folder->newFile('photo.' . $extension);
120
-		$file->putContent($data['body']);
121
-	}
122
-
123
-	private function hasPhoto(ISimpleFolder $folder) {
124
-		return !$folder->fileExists('nophoto');
125
-	}
126
-
127
-	private function getFile(ISimpleFolder $folder, $size) {
128
-		$ext = $this->getExtension($folder);
129
-
130
-		if ($size === -1) {
131
-			$path = 'photo.' . $ext;
132
-		} else {
133
-			$path = 'photo.' . $size . '.' . $ext;
134
-		}
135
-
136
-		try {
137
-			$file = $folder->getFile($path);
138
-		} catch (NotFoundException $e) {
139
-			if ($size <= 0) {
140
-				throw new NotFoundException;
141
-			}
142
-
143
-			$photo = new \OC_Image();
144
-			/** @var ISimpleFile $file */
145
-			$file = $folder->getFile('photo.' . $ext);
146
-			$photo->loadFromData($file->getContent());
147
-
148
-			$ratio = $photo->width() / $photo->height();
149
-			if ($ratio < 1) {
150
-				$ratio = 1 / $ratio;
151
-			}
152
-
153
-			$size = (int) ($size * $ratio);
154
-			if ($size !== -1) {
155
-				$photo->resize($size);
156
-			}
157
-
158
-			try {
159
-				$file = $folder->newFile($path);
160
-				$file->putContent($photo->data());
161
-			} catch (NotPermittedException $e) {
162
-
163
-			}
164
-		}
165
-
166
-		return $file;
167
-	}
168
-
169
-	/**
170
-	 * @param int $addressBookId
171
-	 * @param string $cardUri
172
-	 * @return ISimpleFolder
173
-	 */
174
-	private function getFolder($addressBookId, $cardUri) {
175
-		$hash = md5($addressBookId . ' ' . $cardUri);
176
-		try {
177
-			return $this->appData->getFolder($hash);
178
-		} catch (NotFoundException $e) {
179
-			return $this->appData->newFolder($hash);
180
-		}
181
-	}
182
-
183
-	/**
184
-	 * Get the extension of the avatar. If there is no avatar throw Exception
185
-	 *
186
-	 * @param ISimpleFolder $folder
187
-	 * @return string
188
-	 * @throws NotFoundException
189
-	 */
190
-	private function getExtension(ISimpleFolder $folder): string {
191
-		foreach (self::ALLOWED_CONTENT_TYPES as $extension) {
192
-			if ($folder->fileExists('photo.' . $extension)) {
193
-				return $extension;
194
-			}
195
-		}
196
-
197
-		throw new NotFoundException('Avatar not found');
198
-	}
199
-
200
-	private function getPhoto(Card $node) {
201
-		try {
202
-			$vObject = $this->readCard($node->get());
203
-			if (!$vObject->PHOTO) {
204
-				return false;
205
-			}
206
-
207
-			$photo = $vObject->PHOTO;
208
-			$val = $photo->getValue();
209
-
210
-			// handle data URI. e.g PHOTO;VALUE=URI:data:image/jpeg;base64,/9j/4AAQSkZJRgABAQE
211
-			if ($photo->getValueType() === 'URI') {
212
-				$parsed = \Sabre\URI\parse($val);
213
-
214
-				// only allow data://
215
-				if ($parsed['scheme'] !== 'data') {
216
-					return false;
217
-				}
218
-				if (substr_count($parsed['path'], ';') === 1) {
219
-					list($type) = explode(';', $parsed['path']);
220
-				}
221
-				$val = file_get_contents($val);
222
-			} else {
223
-				// get type if binary data
224
-				$type = $this->getBinaryType($photo);
225
-			}
226
-
227
-			if (empty($type) || !isset(self::ALLOWED_CONTENT_TYPES[$type])) {
228
-				$type = 'application/octet-stream';
229
-			}
230
-
231
-			return [
232
-				'Content-Type' => $type,
233
-				'body'         => $val
234
-			];
235
-		} catch (\Exception $e) {
236
-			$this->logger->logException($e, [
237
-				'message' => 'Exception during vcard photo parsing'
238
-			]);
239
-		}
240
-		return false;
241
-	}
242
-
243
-	/**
244
-	 * @param string $cardData
245
-	 * @return \Sabre\VObject\Document
246
-	 */
247
-	private function readCard($cardData) {
248
-		return Reader::read($cardData);
249
-	}
250
-
251
-	/**
252
-	 * @param Binary $photo
253
-	 * @return string
254
-	 */
255
-	private function getBinaryType(Binary $photo) {
256
-		$params = $photo->parameters();
257
-		if (isset($params['TYPE']) || isset($params['MEDIATYPE'])) {
258
-			/** @var Parameter $typeParam */
259
-			$typeParam = isset($params['TYPE']) ? $params['TYPE'] : $params['MEDIATYPE'];
260
-			$type = $typeParam->getValue();
261
-
262
-			if (strpos($type, 'image/') === 0) {
263
-				return $type;
264
-			} else {
265
-				return 'image/' . strtolower($type);
266
-			}
267
-		}
268
-		return '';
269
-	}
270
-
271
-	/**
272
-	 * @param int $addressBookId
273
-	 * @param string $cardUri
274
-	 */
275
-	public function delete($addressBookId, $cardUri) {
276
-		$folder = $this->getFolder($addressBookId, $cardUri);
277
-		$folder->delete();
278
-	}
38
+    /** @var array  */
39
+    protected const ALLOWED_CONTENT_TYPES = [
40
+        'image/png' => 'png',
41
+        'image/jpeg' => 'jpg',
42
+        'image/gif' => 'gif',
43
+        'image/vnd.microsoft.icon' => 'ico',
44
+    ];
45
+
46
+    /** @var IAppData */
47
+    protected $appData;
48
+
49
+    /** @var ILogger */
50
+    protected $logger;
51
+
52
+    /**
53
+     * PhotoCache constructor.
54
+     *
55
+     * @param IAppData $appData
56
+     * @param ILogger $logger
57
+     */
58
+    public function __construct(IAppData $appData, ILogger $logger) {
59
+        $this->appData = $appData;
60
+        $this->logger = $logger;
61
+    }
62
+
63
+    /**
64
+     * @param int $addressBookId
65
+     * @param string $cardUri
66
+     * @param int $size
67
+     * @param Card $card
68
+     *
69
+     * @return ISimpleFile
70
+     * @throws NotFoundException
71
+     */
72
+    public function get($addressBookId, $cardUri, $size, Card $card) {
73
+        $folder = $this->getFolder($addressBookId, $cardUri);
74
+
75
+        if ($this->isEmpty($folder)) {
76
+            $this->init($folder, $card);
77
+        }
78
+
79
+        if (!$this->hasPhoto($folder)) {
80
+            throw new NotFoundException();
81
+        }
82
+
83
+        if ($size !== -1) {
84
+            $size = 2 ** ceil(log($size) / log(2));
85
+        }
86
+
87
+        return $this->getFile($folder, $size);
88
+    }
89
+
90
+    /**
91
+     * @param ISimpleFolder $folder
92
+     * @return bool
93
+     */
94
+    private function isEmpty(ISimpleFolder $folder) {
95
+        return $folder->getDirectoryListing() === [];
96
+    }
97
+
98
+    /**
99
+     * @param ISimpleFolder $folder
100
+     * @param Card $card
101
+     * @throws NotPermittedException
102
+     */
103
+    private function init(ISimpleFolder $folder, Card $card): void {
104
+        $data = $this->getPhoto($card);
105
+
106
+        if ($data === false || !isset($data['Content-Type'])) {
107
+            $folder->newFile('nophoto');
108
+            return;
109
+        }
110
+
111
+        $contentType = $data['Content-Type'];
112
+        $extension = self::ALLOWED_CONTENT_TYPES[$contentType] ?? null;
113
+
114
+        if ($extension === null) {
115
+            $folder->newFile('nophoto');
116
+            return;
117
+        }
118
+
119
+        $file = $folder->newFile('photo.' . $extension);
120
+        $file->putContent($data['body']);
121
+    }
122
+
123
+    private function hasPhoto(ISimpleFolder $folder) {
124
+        return !$folder->fileExists('nophoto');
125
+    }
126
+
127
+    private function getFile(ISimpleFolder $folder, $size) {
128
+        $ext = $this->getExtension($folder);
129
+
130
+        if ($size === -1) {
131
+            $path = 'photo.' . $ext;
132
+        } else {
133
+            $path = 'photo.' . $size . '.' . $ext;
134
+        }
135
+
136
+        try {
137
+            $file = $folder->getFile($path);
138
+        } catch (NotFoundException $e) {
139
+            if ($size <= 0) {
140
+                throw new NotFoundException;
141
+            }
142
+
143
+            $photo = new \OC_Image();
144
+            /** @var ISimpleFile $file */
145
+            $file = $folder->getFile('photo.' . $ext);
146
+            $photo->loadFromData($file->getContent());
147
+
148
+            $ratio = $photo->width() / $photo->height();
149
+            if ($ratio < 1) {
150
+                $ratio = 1 / $ratio;
151
+            }
152
+
153
+            $size = (int) ($size * $ratio);
154
+            if ($size !== -1) {
155
+                $photo->resize($size);
156
+            }
157
+
158
+            try {
159
+                $file = $folder->newFile($path);
160
+                $file->putContent($photo->data());
161
+            } catch (NotPermittedException $e) {
162
+
163
+            }
164
+        }
165
+
166
+        return $file;
167
+    }
168
+
169
+    /**
170
+     * @param int $addressBookId
171
+     * @param string $cardUri
172
+     * @return ISimpleFolder
173
+     */
174
+    private function getFolder($addressBookId, $cardUri) {
175
+        $hash = md5($addressBookId . ' ' . $cardUri);
176
+        try {
177
+            return $this->appData->getFolder($hash);
178
+        } catch (NotFoundException $e) {
179
+            return $this->appData->newFolder($hash);
180
+        }
181
+    }
182
+
183
+    /**
184
+     * Get the extension of the avatar. If there is no avatar throw Exception
185
+     *
186
+     * @param ISimpleFolder $folder
187
+     * @return string
188
+     * @throws NotFoundException
189
+     */
190
+    private function getExtension(ISimpleFolder $folder): string {
191
+        foreach (self::ALLOWED_CONTENT_TYPES as $extension) {
192
+            if ($folder->fileExists('photo.' . $extension)) {
193
+                return $extension;
194
+            }
195
+        }
196
+
197
+        throw new NotFoundException('Avatar not found');
198
+    }
199
+
200
+    private function getPhoto(Card $node) {
201
+        try {
202
+            $vObject = $this->readCard($node->get());
203
+            if (!$vObject->PHOTO) {
204
+                return false;
205
+            }
206
+
207
+            $photo = $vObject->PHOTO;
208
+            $val = $photo->getValue();
209
+
210
+            // handle data URI. e.g PHOTO;VALUE=URI:data:image/jpeg;base64,/9j/4AAQSkZJRgABAQE
211
+            if ($photo->getValueType() === 'URI') {
212
+                $parsed = \Sabre\URI\parse($val);
213
+
214
+                // only allow data://
215
+                if ($parsed['scheme'] !== 'data') {
216
+                    return false;
217
+                }
218
+                if (substr_count($parsed['path'], ';') === 1) {
219
+                    list($type) = explode(';', $parsed['path']);
220
+                }
221
+                $val = file_get_contents($val);
222
+            } else {
223
+                // get type if binary data
224
+                $type = $this->getBinaryType($photo);
225
+            }
226
+
227
+            if (empty($type) || !isset(self::ALLOWED_CONTENT_TYPES[$type])) {
228
+                $type = 'application/octet-stream';
229
+            }
230
+
231
+            return [
232
+                'Content-Type' => $type,
233
+                'body'         => $val
234
+            ];
235
+        } catch (\Exception $e) {
236
+            $this->logger->logException($e, [
237
+                'message' => 'Exception during vcard photo parsing'
238
+            ]);
239
+        }
240
+        return false;
241
+    }
242
+
243
+    /**
244
+     * @param string $cardData
245
+     * @return \Sabre\VObject\Document
246
+     */
247
+    private function readCard($cardData) {
248
+        return Reader::read($cardData);
249
+    }
250
+
251
+    /**
252
+     * @param Binary $photo
253
+     * @return string
254
+     */
255
+    private function getBinaryType(Binary $photo) {
256
+        $params = $photo->parameters();
257
+        if (isset($params['TYPE']) || isset($params['MEDIATYPE'])) {
258
+            /** @var Parameter $typeParam */
259
+            $typeParam = isset($params['TYPE']) ? $params['TYPE'] : $params['MEDIATYPE'];
260
+            $type = $typeParam->getValue();
261
+
262
+            if (strpos($type, 'image/') === 0) {
263
+                return $type;
264
+            } else {
265
+                return 'image/' . strtolower($type);
266
+            }
267
+        }
268
+        return '';
269
+    }
270
+
271
+    /**
272
+     * @param int $addressBookId
273
+     * @param string $cardUri
274
+     */
275
+    public function delete($addressBookId, $cardUri) {
276
+        $folder = $this->getFolder($addressBookId, $cardUri);
277
+        $folder->delete();
278
+    }
279 279
 }
Please login to merge, or discard this patch.