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