File.php in One Click Upload 7.2
File
flowphp/src/Flow/File.php
View source
<?php
namespace Flow;
class File {
protected $request;
private $config;
private $identifier;
public function __construct(ConfigInterface $config, RequestInterface $request = null) {
$this->config = $config;
if ($request === null) {
$request = new Request();
}
$this->request = $request;
$this->identifier = call_user_func($this->config
->getHashNameCallback(), $request);
}
public function getIdentifier() {
return $this->identifier;
}
public function getChunkPath($index) {
return $this->config
->getTempDir() . DIRECTORY_SEPARATOR . basename($this->identifier) . '_' . (int) $index;
}
public function checkChunk() {
return file_exists($this
->getChunkPath($this->request
->getCurrentChunkNumber()));
}
public function validateChunk() {
$file = $this->request
->getFile();
if (!$file) {
return false;
}
if (!isset($file['tmp_name']) || !isset($file['size']) || !isset($file['error'])) {
return false;
}
if ($this->request
->getCurrentChunkSize() != $file['size']) {
return false;
}
if ($file['error'] !== UPLOAD_ERR_OK) {
return false;
}
return true;
}
public function saveChunk() {
$file = $this->request
->getFile();
return $this
->_move_uploaded_file($file['tmp_name'], $this
->getChunkPath($this->request
->getCurrentChunkNumber()));
}
public function validateFile() {
$totalChunks = $this->request
->getTotalChunks();
$totalChunksSize = 0;
for ($i = $totalChunks; $i >= 1; $i--) {
$file = $this
->getChunkPath($i);
if (!file_exists($file)) {
return false;
}
$totalChunksSize += filesize($file);
}
return $this->request
->getTotalSize() == $totalChunksSize;
}
public function save($destination) {
$fh = fopen($destination, 'wb');
if (!$fh) {
throw new FileOpenException('failed to open destination file: ' . $destination);
}
if (!flock($fh, LOCK_EX | LOCK_NB, $blocked)) {
if ($blocked) {
return false;
}
throw new FileLockException('failed to lock file: ' . $destination);
}
$totalChunks = $this->request
->getTotalChunks();
try {
$preProcessChunk = $this->config
->getPreprocessCallback();
for ($i = 1; $i <= $totalChunks; $i++) {
$file = $this
->getChunkPath($i);
$chunk = fopen($file, "rb");
if (!$chunk) {
throw new FileOpenException('failed to open chunk: ' . $file);
}
if ($preProcessChunk !== null) {
call_user_func($preProcessChunk, $chunk);
}
stream_copy_to_stream($chunk, $fh);
fclose($chunk);
}
} catch (\Exception $e) {
flock($fh, LOCK_UN);
fclose($fh);
throw $e;
}
if ($this->config
->getDeleteChunksOnSave()) {
$this
->deleteChunks();
}
flock($fh, LOCK_UN);
fclose($fh);
return true;
}
public function deleteChunks() {
$totalChunks = $this->request
->getTotalChunks();
for ($i = 1; $i <= $totalChunks; $i++) {
$path = $this
->getChunkPath($i);
if (file_exists($path)) {
unlink($path);
}
}
}
public function _move_uploaded_file($filePath, $destinationPath) {
return move_uploaded_file($filePath, $destinationPath);
}
}