Uploader::save()   C
last analyzed

Complexity

Conditions 11
Paths 9

Size

Total Lines 46
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 46
rs 5.2653
c 0
b 0
f 0
cc 11
eloc 14
nc 9
nop 2

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @package Cadmium\System\Utils
5
 * @author Anton Romanov
6
 * @copyright Copyright (c) 2015-2017, Anton Romanov
7
 * @link http://cadmium-cms.com
8
 */
9
10
namespace Utils {
11
12
	use Utils\Messages, Utils\Popup, Explorer, Language, Request;
13
14
	abstract class Uploader {
15
16
		private static $base_name = null, $file_name = null;
17
18
		/**
19
		 * Convert a PHP upload error to a usable error code
20
		 */
21
22
		private static function getErrorCode(int $error) : string {
23
24
			if ($error === UPLOAD_ERR_INI_SIZE)         return 'UPLOADER_ERROR_INI_SIZE';
25
26
			if ($error === UPLOAD_ERR_FORM_SIZE)        return 'UPLOADER_ERROR_FORM_SIZE';
27
28
			if ($error === UPLOAD_ERR_PARTIAL)          return 'UPLOADER_ERROR_PARTIAL';
29
30
			if ($error === UPLOAD_ERR_NO_FILE)          return 'UPLOADER_ERROR_NO_FILE';
31
32
			if ($error === UPLOAD_ERR_NO_TMP_DIR)       return 'UPLOADER_ERROR_NO_TMP_DIR';
33
34
			if ($error === UPLOAD_ERR_CANT_WRITE)       return 'UPLOADER_ERROR_CANT_WRITE';
35
36
			if ($error === UPLOAD_ERR_EXTENSION)        return 'UPLOADER_ERROR_EXTENSION';
37
38
			# ------------------------
39
40
			return 'UPLOADER_ERROR_UNKNOWN';
41
		}
42
43
		/**
44
		 * Display an error message
45
		 *
46
		 * @return false : the method always returns false
47
		 */
48
49 View Code Duplication
		private static function displayError(string $phrase, bool $popup) : bool {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
50
51
			$text = Language::get($phrase);
52
53
			if (!$popup) Messages::set('error', $text); else Popup::set('negative', $text);
54
55
			# ------------------------
56
57
			return false;
58
		}
59
60
		/**
61
		 * Save an uploaded file
62
		 *
63
		 * @return true|string|false : true on success, an error code on failure, or false if there are no uploaded files
64
		 */
65
66
		public static function save(string $name, string $dir_name) {
67
68
			if (false === ($file = Request::file($name))) return false;
69
70
			# Check for upload errors
71
72
			if ($file['error'] !== UPLOAD_ERR_OK) return self::getErrorCode($file['error']);
73
74
			# Check for secure upload
75
76
			if (!is_uploaded_file($file['tmp_name'])) return 'UPLOADER_ERROR_SECURITY';
77
78
			# Check size
79
80
			if ($file['size'] > CONFIG_UPLOADS_MAX_SIZE) return 'UPLOADER_ERROR_SIZE';
81
82
			# Check file extension
83
84
			$extensions = ['php', 'phtml', 'php3', 'php4', 'php5', 'phps'];
85
86
			$extension = strtolower(Explorer::getExtension($file['name'], false));
87
88
			if (in_array($extension, $extensions, true)) return 'UPLOADER_ERROR_TYPE';
89
90
			# Check target directory
91
92
			if (!Explorer::isDir($dir_name) && !Explorer::createDir($dir_name)) return 'UPLOADER_ERROR_DIR';
93
94
			# Check target file
95
96
			$base_name = basename($file['name']); $file_name = ($dir_name . '/' . $base_name);
97
98
			if (Explorer::isDir($file_name) || Explorer::isFile($file_name)) return 'UPLOADER_ERROR_EXISTS';
99
100
			# Save uploaded file
101
102
			if (!@move_uploaded_file($file['tmp_name'], $file_name)) return 'UPLOADER_ERROR_SAVE';
103
104
			# Set upload data
105
106
			self::$base_name = $base_name; self::$file_name = $file_name;
107
108
			# ------------------------
109
110
			return true;
111
		}
112
113
		/**
114
		 * Save an uploaded file and display an error if appeared
115
		 *
116
		 * @param $popup : tells to display a popup error message instead of a regular message
117
		 *
118
		 * @return bool : true on success or false on failure
119
		 */
120
121
		public static function handle(string $name, string $dir_name, bool $popup = false) : bool {
122
123
			$result = self::save($name, $dir_name);
124
125
			if (is_string($result)) return self::displayError($result, $popup);
126
127
			# ------------------------
128
129
			return $result;
130
		}
131
132
		/**
133
		 * Get a basename of a last successfully uploaded file
134
		 */
135
136
		public static function getBasename() : string {
137
138
			return self::$base_name;
139
		}
140
141
		/**
142
		 * Get a filename of a last successfully uploaded file
143
		 */
144
145
		public static function getFilename() : string {
146
147
			return self::$file_name;
148
		}
149
	}
150
}
151