Passed
Push — master ( e9f5c7...75c659 )
by Morris
11:10 queued 11s
created
lib/private/Preview/Generator.php 1 patch
Indentation   +432 added lines, -432 removed lines patch added patch discarded remove patch
@@ -43,450 +43,450 @@
 block discarded – undo
43 43
 
44 44
 class Generator {
45 45
 
46
-	/** @var IPreview */
47
-	private $previewManager;
48
-	/** @var IConfig */
49
-	private $config;
50
-	/** @var IAppData */
51
-	private $appData;
52
-	/** @var GeneratorHelper */
53
-	private $helper;
54
-	/** @var EventDispatcherInterface */
55
-	private $eventDispatcher;
56
-
57
-	/**
58
-	 * @param IConfig $config
59
-	 * @param IPreview $previewManager
60
-	 * @param IAppData $appData
61
-	 * @param GeneratorHelper $helper
62
-	 * @param EventDispatcherInterface $eventDispatcher
63
-	 */
64
-	public function __construct(
65
-		IConfig $config,
66
-		IPreview $previewManager,
67
-		IAppData $appData,
68
-		GeneratorHelper $helper,
69
-		EventDispatcherInterface $eventDispatcher
70
-	) {
71
-		$this->config = $config;
72
-		$this->previewManager = $previewManager;
73
-		$this->appData = $appData;
74
-		$this->helper = $helper;
75
-		$this->eventDispatcher = $eventDispatcher;
76
-	}
77
-
78
-	/**
79
-	 * Returns a preview of a file
80
-	 *
81
-	 * The cache is searched first and if nothing usable was found then a preview is
82
-	 * generated by one of the providers
83
-	 *
84
-	 * @param File $file
85
-	 * @param int $width
86
-	 * @param int $height
87
-	 * @param bool $crop
88
-	 * @param string $mode
89
-	 * @param string $mimeType
90
-	 * @return ISimpleFile
91
-	 * @throws NotFoundException
92
-	 * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
93
-	 */
94
-	public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
95
-		$specification = [
96
-			'width' => $width,
97
-			'height' => $height,
98
-			'crop' => $crop,
99
-			'mode' => $mode,
100
-		];
101
-		$this->eventDispatcher->dispatch(
102
-			IPreview::EVENT,
103
-			new GenericEvent($file, $specification)
104
-		);
105
-
106
-		// since we only ask for one preview, and the generate method return the last one it created, it returns the one we want
107
-		return $this->generatePreviews($file, [$specification], $mimeType);
108
-	}
109
-
110
-	/**
111
-	 * Generates previews of a file
112
-	 *
113
-	 * @param File $file
114
-	 * @param array $specifications
115
-	 * @param string $mimeType
116
-	 * @return ISimpleFile the last preview that was generated
117
-	 * @throws NotFoundException
118
-	 * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
119
-	 */
120
-	public function generatePreviews(File $file, array $specifications, $mimeType = null) {
121
-		//Make sure that we can read the file
122
-		if (!$file->isReadable()) {
123
-			throw new NotFoundException('Cannot read file');
124
-		}
125
-
126
-		if ($mimeType === null) {
127
-			$mimeType = $file->getMimeType();
128
-		}
129
-
130
-		$previewFolder = $this->getPreviewFolder($file);
131
-
132
-		$previewVersion = '';
133
-		if ($file instanceof IVersionedPreviewFile) {
134
-			$previewVersion = $file->getPreviewVersion() . '-';
135
-		}
136
-
137
-		// Get the max preview and infer the max preview sizes from that
138
-		$maxPreview = $this->getMaxPreview($previewFolder, $file, $mimeType, $previewVersion);
139
-		$maxPreviewImage = null; // only load the image when we need it
140
-		if ($maxPreview->getSize() === 0) {
141
-			$maxPreview->delete();
142
-			throw new NotFoundException('Max preview size 0, invalid!');
143
-		}
144
-
145
-		[$maxWidth, $maxHeight] = $this->getPreviewSize($maxPreview, $previewVersion);
146
-
147
-		$preview = null;
148
-
149
-		foreach ($specifications as $specification) {
150
-			$width = $specification['width'] ?? -1;
151
-			$height = $specification['height'] ?? -1;
152
-			$crop = $specification['crop'] ?? false;
153
-			$mode = $specification['mode'] ?? IPreview::MODE_FILL;
154
-
155
-			// If both width and height are -1 we just want the max preview
156
-			if ($width === -1 && $height === -1) {
157
-				$width = $maxWidth;
158
-				$height = $maxHeight;
159
-			}
160
-
161
-			// Calculate the preview size
162
-			[$width, $height] = $this->calculateSize($width, $height, $crop, $mode, $maxWidth, $maxHeight);
163
-
164
-			// No need to generate a preview that is just the max preview
165
-			if ($width === $maxWidth && $height === $maxHeight) {
166
-				// ensure correct return value if this was the last one
167
-				$preview = $maxPreview;
168
-				continue;
169
-			}
170
-
171
-			// Try to get a cached preview. Else generate (and store) one
172
-			try {
173
-				try {
174
-					$preview = $this->getCachedPreview($previewFolder, $width, $height, $crop, $maxPreview->getMimeType(), $previewVersion);
175
-				} catch (NotFoundException $e) {
176
-					if (!$this->previewManager->isMimeSupported($mimeType)) {
177
-						throw new NotFoundException();
178
-					}
179
-
180
-					if ($maxPreviewImage === null) {
181
-						$maxPreviewImage = $this->helper->getImage($maxPreview);
182
-					}
183
-
184
-					$preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion);
185
-				}
186
-			} catch (\InvalidArgumentException $e) {
187
-				throw new NotFoundException("", 0, $e);
188
-			}
189
-
190
-			if ($preview->getSize() === 0) {
191
-				$preview->delete();
192
-				throw new NotFoundException('Cached preview size 0, invalid!');
193
-			}
194
-		}
195
-
196
-		// Free memory being used by the embedded image resource.  Without this the image is kept in memory indefinitely.
197
-		// Garbage Collection does NOT free this memory.  We have to do it ourselves.
198
-		if ($maxPreviewImage instanceof \OC_Image) {
199
-			$maxPreviewImage->destroy();
200
-		}
201
-
202
-		return $preview;
203
-	}
204
-
205
-	/**
206
-	 * @param ISimpleFolder $previewFolder
207
-	 * @param File $file
208
-	 * @param string $mimeType
209
-	 * @param string $prefix
210
-	 * @return ISimpleFile
211
-	 * @throws NotFoundException
212
-	 */
213
-	private function getMaxPreview(ISimpleFolder $previewFolder, File $file, $mimeType, $prefix) {
214
-		$nodes = $previewFolder->getDirectoryListing();
215
-
216
-		foreach ($nodes as $node) {
217
-			$name = $node->getName();
218
-			if (($prefix === '' || strpos($name, $prefix) === 0) && strpos($name, 'max')) {
219
-				return $node;
220
-			}
221
-		}
222
-
223
-		$previewProviders = $this->previewManager->getProviders();
224
-		foreach ($previewProviders as $supportedMimeType => $providers) {
225
-			if (!preg_match($supportedMimeType, $mimeType)) {
226
-				continue;
227
-			}
228
-
229
-			foreach ($providers as $providerClosure) {
230
-				$provider = $this->helper->getProvider($providerClosure);
231
-				if (!($provider instanceof IProviderV2)) {
232
-					continue;
233
-				}
234
-
235
-				if (!$provider->isAvailable($file)) {
236
-					continue;
237
-				}
238
-
239
-				$maxWidth = (int)$this->config->getSystemValue('preview_max_x', 4096);
240
-				$maxHeight = (int)$this->config->getSystemValue('preview_max_y', 4096);
241
-
242
-				$preview = $this->helper->getThumbnail($provider, $file, $maxWidth, $maxHeight);
243
-
244
-				if (!($preview instanceof IImage)) {
245
-					continue;
246
-				}
247
-
248
-				// Try to get the extention.
249
-				try {
250
-					$ext = $this->getExtention($preview->dataMimeType());
251
-				} catch (\InvalidArgumentException $e) {
252
-					// Just continue to the next iteration if this preview doesn't have a valid mimetype
253
-					continue;
254
-				}
255
-
256
-				$path = $prefix . (string)$preview->width() . '-' . (string)$preview->height() . '-max.' . $ext;
257
-				try {
258
-					$file = $previewFolder->newFile($path);
259
-					$file->putContent($preview->data());
260
-				} catch (NotPermittedException $e) {
261
-					throw new NotFoundException();
262
-				}
263
-
264
-				return $file;
265
-			}
266
-		}
267
-
268
-		throw new NotFoundException();
269
-	}
270
-
271
-	/**
272
-	 * @param ISimpleFile $file
273
-	 * @param string $prefix
274
-	 * @return int[]
275
-	 */
276
-	private function getPreviewSize(ISimpleFile $file, string $prefix = '') {
277
-		$size = explode('-', substr($file->getName(), strlen($prefix)));
278
-		return [(int)$size[0], (int)$size[1]];
279
-	}
280
-
281
-	/**
282
-	 * @param int $width
283
-	 * @param int $height
284
-	 * @param bool $crop
285
-	 * @param string $mimeType
286
-	 * @param string $prefix
287
-	 * @return string
288
-	 */
289
-	private function generatePath($width, $height, $crop, $mimeType, $prefix) {
290
-		$path = $prefix . (string)$width . '-' . (string)$height;
291
-		if ($crop) {
292
-			$path .= '-crop';
293
-		}
294
-
295
-		$ext = $this->getExtention($mimeType);
296
-		$path .= '.' . $ext;
297
-		return $path;
298
-	}
299
-
300
-
301
-	/**
302
-	 * @param int $width
303
-	 * @param int $height
304
-	 * @param bool $crop
305
-	 * @param string $mode
306
-	 * @param int $maxWidth
307
-	 * @param int $maxHeight
308
-	 * @return int[]
309
-	 */
310
-	private function calculateSize($width, $height, $crop, $mode, $maxWidth, $maxHeight) {
311
-
312
-		/*
46
+    /** @var IPreview */
47
+    private $previewManager;
48
+    /** @var IConfig */
49
+    private $config;
50
+    /** @var IAppData */
51
+    private $appData;
52
+    /** @var GeneratorHelper */
53
+    private $helper;
54
+    /** @var EventDispatcherInterface */
55
+    private $eventDispatcher;
56
+
57
+    /**
58
+     * @param IConfig $config
59
+     * @param IPreview $previewManager
60
+     * @param IAppData $appData
61
+     * @param GeneratorHelper $helper
62
+     * @param EventDispatcherInterface $eventDispatcher
63
+     */
64
+    public function __construct(
65
+        IConfig $config,
66
+        IPreview $previewManager,
67
+        IAppData $appData,
68
+        GeneratorHelper $helper,
69
+        EventDispatcherInterface $eventDispatcher
70
+    ) {
71
+        $this->config = $config;
72
+        $this->previewManager = $previewManager;
73
+        $this->appData = $appData;
74
+        $this->helper = $helper;
75
+        $this->eventDispatcher = $eventDispatcher;
76
+    }
77
+
78
+    /**
79
+     * Returns a preview of a file
80
+     *
81
+     * The cache is searched first and if nothing usable was found then a preview is
82
+     * generated by one of the providers
83
+     *
84
+     * @param File $file
85
+     * @param int $width
86
+     * @param int $height
87
+     * @param bool $crop
88
+     * @param string $mode
89
+     * @param string $mimeType
90
+     * @return ISimpleFile
91
+     * @throws NotFoundException
92
+     * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
93
+     */
94
+    public function getPreview(File $file, $width = -1, $height = -1, $crop = false, $mode = IPreview::MODE_FILL, $mimeType = null) {
95
+        $specification = [
96
+            'width' => $width,
97
+            'height' => $height,
98
+            'crop' => $crop,
99
+            'mode' => $mode,
100
+        ];
101
+        $this->eventDispatcher->dispatch(
102
+            IPreview::EVENT,
103
+            new GenericEvent($file, $specification)
104
+        );
105
+
106
+        // since we only ask for one preview, and the generate method return the last one it created, it returns the one we want
107
+        return $this->generatePreviews($file, [$specification], $mimeType);
108
+    }
109
+
110
+    /**
111
+     * Generates previews of a file
112
+     *
113
+     * @param File $file
114
+     * @param array $specifications
115
+     * @param string $mimeType
116
+     * @return ISimpleFile the last preview that was generated
117
+     * @throws NotFoundException
118
+     * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
119
+     */
120
+    public function generatePreviews(File $file, array $specifications, $mimeType = null) {
121
+        //Make sure that we can read the file
122
+        if (!$file->isReadable()) {
123
+            throw new NotFoundException('Cannot read file');
124
+        }
125
+
126
+        if ($mimeType === null) {
127
+            $mimeType = $file->getMimeType();
128
+        }
129
+
130
+        $previewFolder = $this->getPreviewFolder($file);
131
+
132
+        $previewVersion = '';
133
+        if ($file instanceof IVersionedPreviewFile) {
134
+            $previewVersion = $file->getPreviewVersion() . '-';
135
+        }
136
+
137
+        // Get the max preview and infer the max preview sizes from that
138
+        $maxPreview = $this->getMaxPreview($previewFolder, $file, $mimeType, $previewVersion);
139
+        $maxPreviewImage = null; // only load the image when we need it
140
+        if ($maxPreview->getSize() === 0) {
141
+            $maxPreview->delete();
142
+            throw new NotFoundException('Max preview size 0, invalid!');
143
+        }
144
+
145
+        [$maxWidth, $maxHeight] = $this->getPreviewSize($maxPreview, $previewVersion);
146
+
147
+        $preview = null;
148
+
149
+        foreach ($specifications as $specification) {
150
+            $width = $specification['width'] ?? -1;
151
+            $height = $specification['height'] ?? -1;
152
+            $crop = $specification['crop'] ?? false;
153
+            $mode = $specification['mode'] ?? IPreview::MODE_FILL;
154
+
155
+            // If both width and height are -1 we just want the max preview
156
+            if ($width === -1 && $height === -1) {
157
+                $width = $maxWidth;
158
+                $height = $maxHeight;
159
+            }
160
+
161
+            // Calculate the preview size
162
+            [$width, $height] = $this->calculateSize($width, $height, $crop, $mode, $maxWidth, $maxHeight);
163
+
164
+            // No need to generate a preview that is just the max preview
165
+            if ($width === $maxWidth && $height === $maxHeight) {
166
+                // ensure correct return value if this was the last one
167
+                $preview = $maxPreview;
168
+                continue;
169
+            }
170
+
171
+            // Try to get a cached preview. Else generate (and store) one
172
+            try {
173
+                try {
174
+                    $preview = $this->getCachedPreview($previewFolder, $width, $height, $crop, $maxPreview->getMimeType(), $previewVersion);
175
+                } catch (NotFoundException $e) {
176
+                    if (!$this->previewManager->isMimeSupported($mimeType)) {
177
+                        throw new NotFoundException();
178
+                    }
179
+
180
+                    if ($maxPreviewImage === null) {
181
+                        $maxPreviewImage = $this->helper->getImage($maxPreview);
182
+                    }
183
+
184
+                    $preview = $this->generatePreview($previewFolder, $maxPreviewImage, $width, $height, $crop, $maxWidth, $maxHeight, $previewVersion);
185
+                }
186
+            } catch (\InvalidArgumentException $e) {
187
+                throw new NotFoundException("", 0, $e);
188
+            }
189
+
190
+            if ($preview->getSize() === 0) {
191
+                $preview->delete();
192
+                throw new NotFoundException('Cached preview size 0, invalid!');
193
+            }
194
+        }
195
+
196
+        // Free memory being used by the embedded image resource.  Without this the image is kept in memory indefinitely.
197
+        // Garbage Collection does NOT free this memory.  We have to do it ourselves.
198
+        if ($maxPreviewImage instanceof \OC_Image) {
199
+            $maxPreviewImage->destroy();
200
+        }
201
+
202
+        return $preview;
203
+    }
204
+
205
+    /**
206
+     * @param ISimpleFolder $previewFolder
207
+     * @param File $file
208
+     * @param string $mimeType
209
+     * @param string $prefix
210
+     * @return ISimpleFile
211
+     * @throws NotFoundException
212
+     */
213
+    private function getMaxPreview(ISimpleFolder $previewFolder, File $file, $mimeType, $prefix) {
214
+        $nodes = $previewFolder->getDirectoryListing();
215
+
216
+        foreach ($nodes as $node) {
217
+            $name = $node->getName();
218
+            if (($prefix === '' || strpos($name, $prefix) === 0) && strpos($name, 'max')) {
219
+                return $node;
220
+            }
221
+        }
222
+
223
+        $previewProviders = $this->previewManager->getProviders();
224
+        foreach ($previewProviders as $supportedMimeType => $providers) {
225
+            if (!preg_match($supportedMimeType, $mimeType)) {
226
+                continue;
227
+            }
228
+
229
+            foreach ($providers as $providerClosure) {
230
+                $provider = $this->helper->getProvider($providerClosure);
231
+                if (!($provider instanceof IProviderV2)) {
232
+                    continue;
233
+                }
234
+
235
+                if (!$provider->isAvailable($file)) {
236
+                    continue;
237
+                }
238
+
239
+                $maxWidth = (int)$this->config->getSystemValue('preview_max_x', 4096);
240
+                $maxHeight = (int)$this->config->getSystemValue('preview_max_y', 4096);
241
+
242
+                $preview = $this->helper->getThumbnail($provider, $file, $maxWidth, $maxHeight);
243
+
244
+                if (!($preview instanceof IImage)) {
245
+                    continue;
246
+                }
247
+
248
+                // Try to get the extention.
249
+                try {
250
+                    $ext = $this->getExtention($preview->dataMimeType());
251
+                } catch (\InvalidArgumentException $e) {
252
+                    // Just continue to the next iteration if this preview doesn't have a valid mimetype
253
+                    continue;
254
+                }
255
+
256
+                $path = $prefix . (string)$preview->width() . '-' . (string)$preview->height() . '-max.' . $ext;
257
+                try {
258
+                    $file = $previewFolder->newFile($path);
259
+                    $file->putContent($preview->data());
260
+                } catch (NotPermittedException $e) {
261
+                    throw new NotFoundException();
262
+                }
263
+
264
+                return $file;
265
+            }
266
+        }
267
+
268
+        throw new NotFoundException();
269
+    }
270
+
271
+    /**
272
+     * @param ISimpleFile $file
273
+     * @param string $prefix
274
+     * @return int[]
275
+     */
276
+    private function getPreviewSize(ISimpleFile $file, string $prefix = '') {
277
+        $size = explode('-', substr($file->getName(), strlen($prefix)));
278
+        return [(int)$size[0], (int)$size[1]];
279
+    }
280
+
281
+    /**
282
+     * @param int $width
283
+     * @param int $height
284
+     * @param bool $crop
285
+     * @param string $mimeType
286
+     * @param string $prefix
287
+     * @return string
288
+     */
289
+    private function generatePath($width, $height, $crop, $mimeType, $prefix) {
290
+        $path = $prefix . (string)$width . '-' . (string)$height;
291
+        if ($crop) {
292
+            $path .= '-crop';
293
+        }
294
+
295
+        $ext = $this->getExtention($mimeType);
296
+        $path .= '.' . $ext;
297
+        return $path;
298
+    }
299
+
300
+
301
+    /**
302
+     * @param int $width
303
+     * @param int $height
304
+     * @param bool $crop
305
+     * @param string $mode
306
+     * @param int $maxWidth
307
+     * @param int $maxHeight
308
+     * @return int[]
309
+     */
310
+    private function calculateSize($width, $height, $crop, $mode, $maxWidth, $maxHeight) {
311
+
312
+        /*
313 313
 		 * If we are not cropping we have to make sure the requested image
314 314
 		 * respects the aspect ratio of the original.
315 315
 		 */
316
-		if (!$crop) {
317
-			$ratio = $maxHeight / $maxWidth;
316
+        if (!$crop) {
317
+            $ratio = $maxHeight / $maxWidth;
318 318
 
319
-			if ($width === -1) {
320
-				$width = $height / $ratio;
321
-			}
322
-			if ($height === -1) {
323
-				$height = $width * $ratio;
324
-			}
319
+            if ($width === -1) {
320
+                $width = $height / $ratio;
321
+            }
322
+            if ($height === -1) {
323
+                $height = $width * $ratio;
324
+            }
325 325
 
326
-			$ratioH = $height / $maxHeight;
327
-			$ratioW = $width / $maxWidth;
326
+            $ratioH = $height / $maxHeight;
327
+            $ratioW = $width / $maxWidth;
328 328
 
329
-			/*
329
+            /*
330 330
 			 * Fill means that the $height and $width are the max
331 331
 			 * Cover means min.
332 332
 			 */
333
-			if ($mode === IPreview::MODE_FILL) {
334
-				if ($ratioH > $ratioW) {
335
-					$height = $width * $ratio;
336
-				} else {
337
-					$width = $height / $ratio;
338
-				}
339
-			} elseif ($mode === IPreview::MODE_COVER) {
340
-				if ($ratioH > $ratioW) {
341
-					$width = $height / $ratio;
342
-				} else {
343
-					$height = $width * $ratio;
344
-				}
345
-			}
346
-		}
347
-
348
-		if ($height !== $maxHeight && $width !== $maxWidth) {
349
-			/*
333
+            if ($mode === IPreview::MODE_FILL) {
334
+                if ($ratioH > $ratioW) {
335
+                    $height = $width * $ratio;
336
+                } else {
337
+                    $width = $height / $ratio;
338
+                }
339
+            } elseif ($mode === IPreview::MODE_COVER) {
340
+                if ($ratioH > $ratioW) {
341
+                    $width = $height / $ratio;
342
+                } else {
343
+                    $height = $width * $ratio;
344
+                }
345
+            }
346
+        }
347
+
348
+        if ($height !== $maxHeight && $width !== $maxWidth) {
349
+            /*
350 350
 			 * Scale to the nearest power of four
351 351
 			 */
352
-			$pow4height = 4 ** ceil(log($height) / log(4));
353
-			$pow4width = 4 ** ceil(log($width) / log(4));
354
-
355
-			// Minimum size is 64
356
-			$pow4height = max($pow4height, 64);
357
-			$pow4width = max($pow4width, 64);
358
-
359
-			$ratioH = $height / $pow4height;
360
-			$ratioW = $width / $pow4width;
361
-
362
-			if ($ratioH < $ratioW) {
363
-				$width = $pow4width;
364
-				$height /= $ratioW;
365
-			} else {
366
-				$height = $pow4height;
367
-				$width /= $ratioH;
368
-			}
369
-		}
370
-
371
-		/*
352
+            $pow4height = 4 ** ceil(log($height) / log(4));
353
+            $pow4width = 4 ** ceil(log($width) / log(4));
354
+
355
+            // Minimum size is 64
356
+            $pow4height = max($pow4height, 64);
357
+            $pow4width = max($pow4width, 64);
358
+
359
+            $ratioH = $height / $pow4height;
360
+            $ratioW = $width / $pow4width;
361
+
362
+            if ($ratioH < $ratioW) {
363
+                $width = $pow4width;
364
+                $height /= $ratioW;
365
+            } else {
366
+                $height = $pow4height;
367
+                $width /= $ratioH;
368
+            }
369
+        }
370
+
371
+        /*
372 372
 		 * Make sure the requested height and width fall within the max
373 373
 		 * of the preview.
374 374
 		 */
375
-		if ($height > $maxHeight) {
376
-			$ratio = $height / $maxHeight;
377
-			$height = $maxHeight;
378
-			$width /= $ratio;
379
-		}
380
-		if ($width > $maxWidth) {
381
-			$ratio = $width / $maxWidth;
382
-			$width = $maxWidth;
383
-			$height /= $ratio;
384
-		}
385
-
386
-		return [(int)round($width), (int)round($height)];
387
-	}
388
-
389
-	/**
390
-	 * @param ISimpleFolder $previewFolder
391
-	 * @param ISimpleFile $maxPreview
392
-	 * @param int $width
393
-	 * @param int $height
394
-	 * @param bool $crop
395
-	 * @param int $maxWidth
396
-	 * @param int $maxHeight
397
-	 * @param string $prefix
398
-	 * @return ISimpleFile
399
-	 * @throws NotFoundException
400
-	 * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
401
-	 */
402
-	private function generatePreview(ISimpleFolder $previewFolder, IImage $maxPreview, $width, $height, $crop, $maxWidth, $maxHeight, $prefix) {
403
-		$preview = $maxPreview;
404
-		if (!$preview->valid()) {
405
-			throw new \InvalidArgumentException('Failed to generate preview, failed to load image');
406
-		}
407
-
408
-		if ($crop) {
409
-			if ($height !== $preview->height() && $width !== $preview->width()) {
410
-				//Resize
411
-				$widthR = $preview->width() / $width;
412
-				$heightR = $preview->height() / $height;
413
-
414
-				if ($widthR > $heightR) {
415
-					$scaleH = $height;
416
-					$scaleW = $maxWidth / $heightR;
417
-				} else {
418
-					$scaleH = $maxHeight / $widthR;
419
-					$scaleW = $width;
420
-				}
421
-				$preview = $preview->preciseResizeCopy((int)round($scaleW), (int)round($scaleH));
422
-			}
423
-			$cropX = (int)floor(abs($width - $preview->width()) * 0.5);
424
-			$cropY = (int)floor(abs($height - $preview->height()) * 0.5);
425
-			$preview = $preview->cropCopy($cropX, $cropY, $width, $height);
426
-		} else {
427
-			$preview = $maxPreview->resizeCopy(max($width, $height));
428
-		}
429
-
430
-
431
-		$path = $this->generatePath($width, $height, $crop, $preview->dataMimeType(), $prefix);
432
-		try {
433
-			$file = $previewFolder->newFile($path);
434
-			$file->putContent($preview->data());
435
-		} catch (NotPermittedException $e) {
436
-			throw new NotFoundException();
437
-		}
438
-
439
-		return $file;
440
-	}
441
-
442
-	/**
443
-	 * @param ISimpleFolder $previewFolder
444
-	 * @param int $width
445
-	 * @param int $height
446
-	 * @param bool $crop
447
-	 * @param string $mimeType
448
-	 * @param string $prefix
449
-	 * @return ISimpleFile
450
-	 *
451
-	 * @throws NotFoundException
452
-	 */
453
-	private function getCachedPreview(ISimpleFolder $previewFolder, $width, $height, $crop, $mimeType, $prefix) {
454
-		$path = $this->generatePath($width, $height, $crop, $mimeType, $prefix);
455
-
456
-		return $previewFolder->getFile($path);
457
-	}
458
-
459
-	/**
460
-	 * Get the specific preview folder for this file
461
-	 *
462
-	 * @param File $file
463
-	 * @return ISimpleFolder
464
-	 */
465
-	private function getPreviewFolder(File $file) {
466
-		try {
467
-			$folder = $this->appData->getFolder($file->getId());
468
-		} catch (NotFoundException $e) {
469
-			$folder = $this->appData->newFolder($file->getId());
470
-		}
471
-
472
-		return $folder;
473
-	}
474
-
475
-	/**
476
-	 * @param string $mimeType
477
-	 * @return null|string
478
-	 * @throws \InvalidArgumentException
479
-	 */
480
-	private function getExtention($mimeType) {
481
-		switch ($mimeType) {
482
-			case 'image/png':
483
-				return 'png';
484
-			case 'image/jpeg':
485
-				return 'jpg';
486
-			case 'image/gif':
487
-				return 'gif';
488
-			default:
489
-				throw new \InvalidArgumentException('Not a valid mimetype: "' . $mimeType . '"');
490
-		}
491
-	}
375
+        if ($height > $maxHeight) {
376
+            $ratio = $height / $maxHeight;
377
+            $height = $maxHeight;
378
+            $width /= $ratio;
379
+        }
380
+        if ($width > $maxWidth) {
381
+            $ratio = $width / $maxWidth;
382
+            $width = $maxWidth;
383
+            $height /= $ratio;
384
+        }
385
+
386
+        return [(int)round($width), (int)round($height)];
387
+    }
388
+
389
+    /**
390
+     * @param ISimpleFolder $previewFolder
391
+     * @param ISimpleFile $maxPreview
392
+     * @param int $width
393
+     * @param int $height
394
+     * @param bool $crop
395
+     * @param int $maxWidth
396
+     * @param int $maxHeight
397
+     * @param string $prefix
398
+     * @return ISimpleFile
399
+     * @throws NotFoundException
400
+     * @throws \InvalidArgumentException if the preview would be invalid (in case the original image is invalid)
401
+     */
402
+    private function generatePreview(ISimpleFolder $previewFolder, IImage $maxPreview, $width, $height, $crop, $maxWidth, $maxHeight, $prefix) {
403
+        $preview = $maxPreview;
404
+        if (!$preview->valid()) {
405
+            throw new \InvalidArgumentException('Failed to generate preview, failed to load image');
406
+        }
407
+
408
+        if ($crop) {
409
+            if ($height !== $preview->height() && $width !== $preview->width()) {
410
+                //Resize
411
+                $widthR = $preview->width() / $width;
412
+                $heightR = $preview->height() / $height;
413
+
414
+                if ($widthR > $heightR) {
415
+                    $scaleH = $height;
416
+                    $scaleW = $maxWidth / $heightR;
417
+                } else {
418
+                    $scaleH = $maxHeight / $widthR;
419
+                    $scaleW = $width;
420
+                }
421
+                $preview = $preview->preciseResizeCopy((int)round($scaleW), (int)round($scaleH));
422
+            }
423
+            $cropX = (int)floor(abs($width - $preview->width()) * 0.5);
424
+            $cropY = (int)floor(abs($height - $preview->height()) * 0.5);
425
+            $preview = $preview->cropCopy($cropX, $cropY, $width, $height);
426
+        } else {
427
+            $preview = $maxPreview->resizeCopy(max($width, $height));
428
+        }
429
+
430
+
431
+        $path = $this->generatePath($width, $height, $crop, $preview->dataMimeType(), $prefix);
432
+        try {
433
+            $file = $previewFolder->newFile($path);
434
+            $file->putContent($preview->data());
435
+        } catch (NotPermittedException $e) {
436
+            throw new NotFoundException();
437
+        }
438
+
439
+        return $file;
440
+    }
441
+
442
+    /**
443
+     * @param ISimpleFolder $previewFolder
444
+     * @param int $width
445
+     * @param int $height
446
+     * @param bool $crop
447
+     * @param string $mimeType
448
+     * @param string $prefix
449
+     * @return ISimpleFile
450
+     *
451
+     * @throws NotFoundException
452
+     */
453
+    private function getCachedPreview(ISimpleFolder $previewFolder, $width, $height, $crop, $mimeType, $prefix) {
454
+        $path = $this->generatePath($width, $height, $crop, $mimeType, $prefix);
455
+
456
+        return $previewFolder->getFile($path);
457
+    }
458
+
459
+    /**
460
+     * Get the specific preview folder for this file
461
+     *
462
+     * @param File $file
463
+     * @return ISimpleFolder
464
+     */
465
+    private function getPreviewFolder(File $file) {
466
+        try {
467
+            $folder = $this->appData->getFolder($file->getId());
468
+        } catch (NotFoundException $e) {
469
+            $folder = $this->appData->newFolder($file->getId());
470
+        }
471
+
472
+        return $folder;
473
+    }
474
+
475
+    /**
476
+     * @param string $mimeType
477
+     * @return null|string
478
+     * @throws \InvalidArgumentException
479
+     */
480
+    private function getExtention($mimeType) {
481
+        switch ($mimeType) {
482
+            case 'image/png':
483
+                return 'png';
484
+            case 'image/jpeg':
485
+                return 'jpg';
486
+            case 'image/gif':
487
+                return 'gif';
488
+            default:
489
+                throw new \InvalidArgumentException('Not a valid mimetype: "' . $mimeType . '"');
490
+        }
491
+    }
492 492
 }
Please login to merge, or discard this patch.