Passed
Push — master ( 5f245b...7344eb )
by Wanderson
01:25
created

File::generateIdealName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Win\File;
4
5
/**
6
 * Arquivos
7
 *
8
 */
9
class File {
10
11
	private $name = null;
12
	private $tempName = null;
13
	private $extension = null;
14
	private $size = 0;
15
16
	/** @var Directory */
17
	private $directory = null;
18
	protected $uploadPrepared = false;
19
	private $oldName = null;
20
	protected static $maxSize = 10;
21
	protected static $validExtensions = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'csv', 'doc', 'docx', 'odt', 'pdf', 'txt', 'md', 'mp3', 'wav', 'mpeg'];
22
23
	/* Construtor */
24
25
	public function __construct($name = '') {
26
		if (is_file($name)) {
27
			$this->name = pathinfo($name, PATHINFO_BASENAME);
28
			$this->tempName = pathinfo($name, PATHINFO_BASENAME);
29
			$this->extension = pathinfo($name, PATHINFO_EXTENSION);
30
			$directoryPath = (pathinfo($name, PATHINFO_DIRNAME));
31
			$this->directory = new Directory($directoryPath);
32
			$this->size = 1;
33
		}
34
	}
35
36
	/* Metodos de acesso */
37
38
	public function getName() {
39
		return $this->name;
40
	}
41
42
	public function getTempName() {
43
		return $this->tempName;
44
	}
45
46
	public function getExtension() {
47
		if (is_null($this->extension)):
48
			$this->extension = static::getExtensionByName($this->name);
49
		endif;
50
		return $this->extension;
51
	}
52
53
	public function getSize() {
54
		return $this->size;
55
	}
56
57
	public function getDirectory() {
58
		return $this->directory;
59
	}
60
61
	public function getOldName() {
62
		return $this->oldName;
63
	}
64
65
	public function setName($name) {
66
		$this->name = $name;
67
	}
68
69
	public function setTempName($tempName) {
70
		$this->tempName = $tempName;
71
	}
72
73
	/** @param string $directory */
74
	public function setDirectory($directory) {
75
		$this->directory = new Directory($directory);
76
	}
77
78
	public function setOldName($oldName) {
79
		$this->oldName = $oldName;
80
	}
81
82
	public function getFullName() {
83
		return $this->getDirectory() . $this->getName();
84
	}
85
86
	public static function getValidExtensions() {
87
		return static::$validExtensions;
88
	}
89
90
	public function __toString() {
91
		if ($this->getName() != '') {
92
			return $this->getFullName();
93
		} else {
94
			return '';
95
		}
96
	}
97
98
	/* Metodos */
99
100
	/**
101
	 * Recebe o Arquivo temporário
102
	 * @param array $files $_FILES['arquivo']
103
	 * @example $obj->receiveFiles($_FILES['arquivo']);
104
	 */
105
	function receiveFiles($files) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
106
		if ($this->getName() != '') {
107
			$this->oldName = $this->getFullName();
108
		}
109
		if (!empty($files['name'])) {
110
			$this->tempName = $files['tmp_name'];
111
			$this->extension = static::getExtensionByName($files['name']);
112
			$this->size = $files['size'];
113
			$this->uploadPrepared = true;
114
		}
115
	}
116
117
	/**
118
	 * Recebe o Arquivo temporário
119
	 * @param string $fileName $_POST['arquivo']
120
	 * @example $obj->receivePost($_POST['arquivo']);
121
	 */
122
	public function receivePost($fileName) {
123
		if ($this->getName() != '') {
124
			$this->oldName = $this->getFullName();
125
		}
126
		if (!empty($fileName) && file_exists($fileName)) {
127
			$this->tempName = $fileName;
128
			$this->extension = static::getExtensionByName($fileName);
129
			$this->size = -1;
130
			$this->uploadPrepared = true;
131
		}
132
	}
133
134
	/**
135
	 * Realiza o envio para a pasta, reduzindo o tamanho e com um nome aleatório
136
	 * @param string $newName [opcional] escolhe o nome que será salvo
137
	 * @return string|null Retorna algum erro ou NULL
138
	 */
139
	public function upload($newName = '') {
140
		if ($this->uploadPrepared) {
141
			$error = $this->validateUpload();
142
			if (!$error) {
143
				$this->generateIdealName($newName);
144
				$this->removeOld();
145
				$this->remove();
146
				$this->moveTmpFile();
147
			}
148
		}
149
		return $error;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $error does not seem to be defined for all execution paths leading up to this point.
Loading history...
150
	}
151
152
	/** @return null|string */
153
	protected function validateUpload() {
154
		if (!file_exists($this->tempName)) {
155
			return 'Houve um erro ao enviar o arquivo, verifique se o arquivo não ultrapasse o tamanho máximo permitido. ';
156
		} elseif (!in_array($this->extension, static::$validExtensions)) {
157
			return 'Tipo de arquivo inválido, somente ' . strtoupper(implode('/', static::$validExtensions)) . '.';
158
		} elseif ((!file_exists($this->directory) && !$this->directory->create())) {
159
			return 'O diretorio ' . $this->directory . ' não existe.';
160
		} elseif ($this->size > (static::$maxSize * 1024 * 1024) or $this->size == 0) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
161
			return 'O tamanho do arquivo deve ser entre 0kb e ' . static::$maxSize . 'Mb.';
162
		}
163
		return null;
164
	}
165
166
	/** @param string $newName */
167
	protected function generateIdealName($newName) {
168
		if (empty($newName)) {
169
			$this->name = strtolower(md5(uniqid(time())) . '.' . $this->extension);
170
		} else {
171
			$this->name = strtolower($newName . '.' . $this->extension);
172
		}
173
	}
174
175
	/** Move o arquivo que era temporário */
176
	protected function moveTmpFile() {
177
		if ($this->size === -1) {
178
			$this->move();
179
		} else {
180
			move_uploaded_file($this->getTempName(), $this->getFullName());
181
		}
182
	}
183
184
	/**
185
	 * Retorna TRUE se arquivo existe
186
	 * @return boolean
187
	 */
188
	public function exists() {
189
		return ($this->getName() && is_file($this->getFullName()));
190
	}
191
192
	/** Move o arquivo de $temp para $diretorio atual */
193
	public function move() {
194
		if (file_exists($this->getTempName())) {
195
			if ($this->getName() == '') {
196
				$this->setName(md5(uniqid(time())));
197
			}
198
			rename($this->getTempName(), $this->getFullName());
199
			$this->setTempName($this->getFullName());
200
		}
201
	}
202
203
	/** Exclui o arquivo no diretório */
204
	public function remove() {
205
		if ($this->exists()) {
206
			unlink($this->getFullName());
207
		}
208
	}
209
210
	/** Exclui o arquivo que existia antes de enviar */
211
	public function removeOld() {
212
		if ($this->oldName) {
213
			$oldFile = new File($this->oldName);
214
			$oldFile->remove();
215
		}
216
	}
217
218
	/**
219
	 * Remove diretório(s) por expressão regular
220
	 * @param string $regExp
221
	 * @return int quantidade de diretórios removidos
222
	 */
223
	public static function removeRegExp($regExp) {
224
		$fileNames = glob($regExp);
225
		foreach ($fileNames as $filename) {
226
			unlink($filename);
227
		}
228
		return count($fileNames);
229
	}
230
231
	/**
232
	 * Retorna a extensão do arquivo
233
	 * @param string $name nome do arquivo
234
	 * @return string
235
	 */
236
	protected static function getExtensionByName($name) {
237
		$ext = explode('.', $name);
238
		return strtolower(end($ext));
239
	}
240
241
	/**
242
	 * Salva o conteúdo no arquivo
243
	 * @param string $content
244
	 * @param string $mode
245
	 * @return boolean
246
	 */
247
	public function write($content = '', $mode = 'a') {
248
		if (!is_null($this->getName())) {
249
			$this->directory->create();
250
			$fp = fopen($this->getFullName(), $mode);
251
			if ($fp !== false) {
252
				fwrite($fp, $content);
253
				fclose($fp);
254
				return true;
255
			}
256
			return false;
257
		}
258
	}
259
260
	/**
261
	 * Retorna o conteúdo do arquivo
262
	 * @param string $content
263
	 */
264
	public function read() {
265
		return file_get_contents($this->getFullName());
266
	}
267
268
}
269