Passed
Push — master ( b27b0a...6db573 )
by Aimeos
04:19
created

Base::path()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 30
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 30
rs 9.9666
cc 3
nc 2
nop 3
1
<?php
2
3
/**
4
 * @license LGPLv3, https://opensource.org/licenses/LGPL-3.0
5
 * @copyright Aimeos (aimeos.org), 2023
6
 * @package MShop
7
 * @subpackage Media
8
 */
9
10
11
namespace Aimeos\MShop\Media\Manager;
12
13
use \Enshrined\Svgsanitize\Sanitizer;
0 ignored issues
show
Bug introduced by
The type \Enshrined\Svgsanitize\Sanitizer 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...
14
use \Intervention\Image\Interfaces\ImageInterface;
0 ignored issues
show
Bug introduced by
The type \Intervention\Image\Interfaces\ImageInterface 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...
15
16
17
/**
18
 * Base media manager implementation
19
 *
20
 * @package MShop
21
 * @subpackage Media
22
 */
23
abstract class Base extends \Aimeos\MShop\Common\Manager\Base
24
{
25
	/**
26
	 * Checks if the mime type is allowed
27
	 *
28
	 * @param string $mimetype Mime type
29
	 * @return bool TRUE if mime type is allowed
30
	 * @throws \Aimeos\MShop\Media\Exception If mime type is not allowed
31
	 */
32
	protected function isAllowed( string $mimetype ) : bool
33
	{
34
		$context = $this->context();
35
36
		/** mshop/media/manager/allowedtypes
37
		 * A list of mime types that are allowed for uploaded files
38
		 *
39
		 * The list of allowed mime types must be explicitly configured for the
40
		 * uploaded files. Trying to upload and store a file not available in
41
		 * the list of allowed mime types will result in an exception.
42
		 *
43
		 * @param array List of image mime types
44
		 * @since 2024.01
45
		 */
46
		$default = [
47
			'image/webp', 'image/jpeg', 'image/png', 'image/gif', 'image/svg+xml',
48
			'application/epub+zip', 'application/pdf', 'application/zip',
49
			'video/mp4', 'video/webm',
50
			'audio/mpeg', 'audio/ogg', 'audio/weba'
51
		];
52
		$allowed = $context->config()->get( 'mshop/media/manager/allowedtypes', $default );
53
54
		if( !in_array( $mimetype, $allowed ) )
55
		{
56
			$msg = sprintf( $context->translate( 'mshop', 'Uploading mimetype "%1$s" is not allowed' ), $mimetype );
57
			throw new \Aimeos\MShop\Media\Exception( $msg, 406 );
58
		}
59
60
		return true;
61
	}
62
63
64
	/**
65
	 * Creates a new file path from the given arguments
66
	 *
67
	 * @param string $filepath Original file name, can contain the path as well
68
	 * @param string $mimetype Mime type
69
	 * @param string $domain data domain
70
	 * @return string New file name including the file path
71
	 */
72
	protected function path( string $filepath, string $mimetype, string $domain ) : string
73
	{
74
		$context = $this->context();
75
76
		/** mshop/media/manager/extensions
77
		 * Available files extensions for mime types of uploaded files
78
		 *
79
		 * Uploaded files should have the right file extension (e.g. ".jpg" for
80
		 * JPEG images) so files are recognized correctly if downloaded by users.
81
		 * The extension of the uploaded file can't be trusted and only its mime
82
		 * type can be determined automatically. This configuration setting
83
		 * provides the file extensions for the configured mime types. You can
84
		 * add more mime type / file extension combinations if required.
85
		 *
86
		 * @param array Associative list of mime types as keys and file extensions as values
87
		 * @since 2018.04
88
		 * @category Developer
89
		 */
90
		$default = ['image/gif' => 'gif', 'image/jpeg' => 'jpg', 'image/png' => 'png', 'image/webp' => 'webp'];
91
		$list = $context->config()->get( 'mshop/media/manager/extensions', $default );
92
93
		$filename = basename( $filepath );
94
		$filename = \Aimeos\Base\Str::slug( substr( $filename, 0, strrpos( $filename, '.' ) ?: null ) );
95
		$filename = substr( md5( $filename . getmypid() . microtime( true ) ), -8 ) . '_' . $filename;
96
97
		$ext = isset( $list[$mimetype] ) ? '.' . $list[$mimetype] : '';
98
		$siteid = $context->locale()->getSiteId();
99
100
		// the "d" after {siteid} is the required extension for Windows (no dots at the end allowed)
101
		return "{$siteid}d/{$domain}/{$filename[0]}/{$filename[1]}/{$filename}{$ext}";
102
	}
103
104
105
	/**
106
	 * Returns the quality level of the resized images
107
	 *
108
	 * @return int Quality level from 0 to 100
109
	 */
110
	protected function quality() : int
111
	{
112
		/** mshop/media/manager/quality
113
		 * Quality level of saved images
114
		 *
115
		 * Qualitity level must be an integer from 0 (worst) to 100 (best).
116
		 * The higher the quality, the bigger the file size.
117
		 *
118
		 * @param int Quality level from 0 to 100
119
		 * @since 2024.01
120
		 */
121
		return $this->context()->config()->get( 'mshop/media/manager/quality', 75 );
122
	}
123
124
125
	/**
126
	 * Sanitizes the uploaded file
127
	 *
128
	 * @param string $content File content
129
	 * @param string $mimetype File mime type
130
	 * @return string Sanitized content
131
	 */
132
	protected function sanitize( string $content, string $mimetype ) : string
133
	{
134
		if( strncmp( 'image/svg', $mimetype, 9 ) === 0 )
135
		{
136
			$sanitizer = new Sanitizer();
137
			$sanitizer->removeRemoteReferences( true );
138
139
			if( ( $content = $sanitizer->sanitize( $content ) ) === false )
140
			{
141
				$msg = $this->context()->translate( 'mshop', 'Invalid SVG file: %1$s' );
142
				throw new \Aimeos\MShop\Media\Exception( sprintf( $msg, print_r( $sanitizer->getXmlIssues(), true ) ) );
0 ignored issues
show
Bug introduced by
It seems like print_r($sanitizer->getXmlIssues(), true) can also be of type true; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

142
				throw new \Aimeos\MShop\Media\Exception( sprintf( $msg, /** @scrutinizer ignore-type */ print_r( $sanitizer->getXmlIssues(), true ) ) );
Loading history...
143
			}
144
		}
145
146
		if( $fcn = self::macro( 'sanitize' ) ) {
147
			$content = $fcn( $content, $mimetype );
148
		}
149
150
		return $content;
151
	}
152
153
154
	/**
155
	 * Called after the image has been scaled
156
	 * Can be used to update the media item with image information.
157
	 *
158
	 * @param \Aimeos\MShop\Media\Item\Iface $item Media item with new preview URLs
159
	 * @param \Intervention\Image\Interfaces\ImageInterface $image Media object
160
	 */
161
	protected function scaled( \Aimeos\MShop\Media\Item\Iface $item, ImageInterface $image )
162
	{
163
	}
164
}
165