Preview   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 189
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 59
dl 0
loc 189
rs 10
c 0
b 0
f 0
wmc 17

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getPreviewData() 0 16 3
A getErrorData() 0 2 1
A prepareEmptyThumbnail() 0 11 3
A getFile() 0 12 2
A exitController() 0 6 2
A getThumbnail() 0 13 2
A getExceptionData() 0 4 1
A getData() 0 19 3
1
<?php
2
/**
3
 * Nextcloud - Gallery
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the COPYING file.
7
 *
8
 * @author Olivier Paroz <[email protected]>
9
 * @author Robin Appelman <[email protected]>
10
 *
11
 * @copyright Olivier Paroz 2017
12
 * @copyright Robin Appelman 2017
13
 */
14
15
namespace OCA\Gallery\Controller;
16
17
use OCP\IURLGenerator;
0 ignored issues
show
Bug introduced by
The type OCP\IURLGenerator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use OCP\ILogger;
0 ignored issues
show
Bug introduced by
The type OCP\ILogger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use OCP\Files\File;
0 ignored issues
show
Bug introduced by
The type OCP\Files\File was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
21
use OCP\AppFramework\Http;
0 ignored issues
show
Bug introduced by
The type OCP\AppFramework\Http was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
23
use OCA\Gallery\Service\ServiceException;
24
use OCA\Gallery\Service\NotFoundServiceException;
25
use OCA\Gallery\Service\ConfigService;
26
use OCA\Gallery\Service\ThumbnailService;
27
use OCA\Gallery\Service\PreviewService;
28
use OCA\Gallery\Service\DownloadService;
29
30
/**
31
 * Class Preview
32
 *
33
 * @package OCA\Gallery\Controller
34
 */
35
trait Preview {
36
37
	use HttpError;
38
39
	/** @var IURLGenerator */
40
	private $urlGenerator;
41
	/** @var ConfigService */
42
	private $configService;
43
	/**  @var ThumbnailService */
44
	private $thumbnailService;
45
	/**  @var PreviewService */
46
	private $previewService;
47
	/** @var DownloadService */
48
	private $downloadService;
49
	/** @var ILogger */
50
	private $logger;
51
	/** @type bool */
52
	private $download = false;
53
54
	/**
55
	 * Exits the controller in a live environment and throws an exception when testing
56
	 */
57
	protected function exitController() {
58
		if (defined('PHPUNIT_RUN')) {
59
			throw new \Exception();
60
			// @codeCoverageIgnoreStart
61
		} else {
62
			exit();
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
63
		}
64
		// @codeCoverageIgnoreEnd
65
	}
66
67
	/**
68
	 * Retrieves the thumbnail to send back to the browser
69
	 *
70
	 * The thumbnail is either a resized preview of the file or the original file
71
	 * Thumbnails are base64encoded before getting sent back
72
	 *
73
	 *
74
	 * @param int $fileId the ID of the file of which we need a thumbnail preview of
75
	 * @param bool $square whether the thumbnail should be square
76
	 * @param double $scale whether we're allowed to scale the preview up
77
	 *
78
	 * @return array<string,array|string>
79
	 */
80
	private function getThumbnail($fileId, $square, $scale) {
81
		list($width, $height, $aspect, $animatedPreview, $base64Encode) =
82
			$this->thumbnailService->getThumbnailSpecs($square, $scale);
83
		/** @type File $file */
84
		list($file, $preview, $status) =
85
			$this->getData(
86
				$fileId, $width, $height, $aspect, $animatedPreview, $base64Encode
0 ignored issues
show
Bug introduced by
$height of type double is incompatible with the type integer expected by parameter $height of OCA\Gallery\Controller\Preview::getData(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
				$fileId, $width, /** @scrutinizer ignore-type */ $height, $aspect, $animatedPreview, $base64Encode
Loading history...
Bug introduced by
$width of type double is incompatible with the type integer expected by parameter $width of OCA\Gallery\Controller\Preview::getData(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
				$fileId, /** @scrutinizer ignore-type */ $width, $height, $aspect, $animatedPreview, $base64Encode
Loading history...
87
			);
88
		if ($preview === null) {
89
			$preview = $this->prepareEmptyThumbnail($file, $status);
0 ignored issues
show
Bug introduced by
$status of type OC_Image|string is incompatible with the type integer expected by parameter $status of OCA\Gallery\Controller\P...prepareEmptyThumbnail(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

89
			$preview = $this->prepareEmptyThumbnail($file, /** @scrutinizer ignore-type */ $status);
Loading history...
90
		}
91
92
		return [$preview, $status];
93
	}
94
95
	/**
96
	 * Returns either a generated preview, the file as-is or an empty object
97
	 *
98
	 * @param int $fileId
99
	 * @param int $width
100
	 * @param int $height
101
	 * @param bool $keepAspect
102
	 * @param bool $animatedPreview
103
	 * @param bool $base64Encode
104
	 *
105
	 * @return array<string,\OC_Image|string>
106
	 *
107
	 * @throws NotFoundServiceException
108
	 */
109
	private function getData(
110
		$fileId, $width, $height, $keepAspect = true, $animatedPreview = true, $base64Encode = false
111
	) {
112
		/** @type File $file */
113
		list($file, $status) = $this->getFile($fileId);
114
		try {
115
			if (!is_null($file)) {
116
				$data = $this->getPreviewData(
117
					$file, $animatedPreview, $width, $height, $keepAspect, $base64Encode
118
				);
119
			} else {
120
				$data = $this->getErrorData($status);
121
			}
122
		} catch (ServiceException $exception) {
123
			$data = $this->getExceptionData($exception);
124
		}
125
		array_unshift($data, $file);
126
127
		return $data;
128
	}
129
130
	/**
131
	 * Returns the file of which a preview will be generated
132
	 *
133
	 * @param int $fileId
134
	 *
135
	 * @return array<File|int|null>
136
	 */
137
	private function getFile($fileId) {
138
		$status = Http::STATUS_OK;
139
		try {
140
			/** @type File $file */
141
			$file = $this->previewService->getFile($fileId);
142
			$this->configService->validateMimeType($file->getMimeType());
143
		} catch (ServiceException $exception) {
144
			$file = null;
145
			$status = $this->getHttpStatusCode($exception);
146
		}
147
148
		return [$file, $status];
149
	}
150
151
	/**
152
	 * @param File $file
153
	 * @param bool $animatedPreview
154
	 * @param int $width
155
	 * @param int $height
156
	 * @param bool $keepAspect
157
	 * @param bool $base64Encode
158
	 *
159
	 * @return array<\OC_Image|string, int>
160
	 */
161
	private function getPreviewData(
162
		$file, $animatedPreview, $width, $height, $keepAspect, $base64Encode
163
	) {
164
		$status = Http::STATUS_OK;
165
		if ($this->previewService->isPreviewRequired($file, $animatedPreview)) {
166
			$preview = $this->previewService->createPreview(
167
				$file, $width, $height, $keepAspect, $base64Encode
168
			);
169
		} else {
170
			$preview = $this->downloadService->downloadFile($file, $base64Encode);
171
		}
172
		if (!$preview) {
173
			list($preview, $status) = $this->getErrorData();
174
		}
175
176
		return [$preview, $status];
177
	}
178
179
	/**
180
	 * Returns an error array
181
	 *
182
	 * @param $status
183
	 *
184
	 * @return array<null|int>
185
	 */
186
	private function getErrorData($status = Http::STATUS_INTERNAL_SERVER_ERROR) {
187
		return [null, $status];
188
	}
189
190
	/**
191
	 * Returns an error array
192
	 *
193
	 * @param ServiceException $exception
194
	 *
195
	 * @return array<null|int|string>
196
	 */
197
	private function getExceptionData($exception) {
198
		$code = $this->getHttpStatusCode($exception);
199
200
		return $this->getErrorData($code);
201
	}
202
203
	/**
204
	 * Prepares an empty Thumbnail array to send back
205
	 *
206
	 * When we can't even get the file information, we send an empty mimeType
207
	 *
208
	 * @param File $file
209
	 * @param int $status
210
	 *
211
	 * @return array<string,null|string>
212
	 */
213
	private function prepareEmptyThumbnail($file, $status) {
214
		$thumbnail = [];
215
		if ($status !== Http::STATUS_NOT_FOUND) {
216
			$mimeType = '';
217
			if ($file) {
0 ignored issues
show
introduced by
$file is of type OCP\Files\File, thus it always evaluated to true.
Loading history...
218
				$mimeType = $file->getMimeType();
219
			}
220
			$thumbnail = ['preview' => null, 'mimetype' => $mimeType];
221
		}
222
223
		return $thumbnail;
224
	}
225
226
}
227