Upload.php
120 lines
| 1 | <?php |
| 2 | /* |
| 3 | * |
| 4 | * JetBackup @ package |
| 5 | * Created By Idan Ben-Ezra |
| 6 | * |
| 7 | * Copyrights @ JetApps |
| 8 | * https://www.jetapps.com |
| 9 | * |
| 10 | **/ |
| 11 | namespace JetBackup\Upload; |
| 12 | |
| 13 | use JetBackup\Data\DBObject; |
| 14 | use JetBackup\Data\SleekStore; |
| 15 | use JetBackup\Entities\Util; |
| 16 | use JetBackup\Exception\IOException; |
| 17 | use JetBackup\Factory; |
| 18 | use JetBackup\JetBackup; |
| 19 | use SleekDB\QueryBuilder; |
| 20 | |
| 21 | defined("__JETBACKUP__") or die("Restricted Access."); |
| 22 | |
| 23 | class Upload extends DBObject { |
| 24 | |
| 25 | const COLLECTION = 'upload'; |
| 26 | |
| 27 | const UNIQUE_ID = 'unique_id'; |
| 28 | const FILENAME = 'filename'; |
| 29 | const CREATED = 'created'; |
| 30 | const SIZE = 'size'; |
| 31 | const UPLOADED = 'uploaded'; |
| 32 | |
| 33 | public function __construct($_id=null) { |
| 34 | parent::__construct(self::COLLECTION); |
| 35 | if($_id) $this->_loadById((int) $_id); |
| 36 | } |
| 37 | |
| 38 | public function loadByUploadId($unique_id) { |
| 39 | $this->_load([[self::UNIQUE_ID, '=', $unique_id]]); |
| 40 | } |
| 41 | |
| 42 | public function setUniqueId(string $id) { $this->set(self::UNIQUE_ID, $id); } |
| 43 | public function getUniqueId():string { return $this->get(self::UNIQUE_ID); } |
| 44 | |
| 45 | public function setFilename(string $name) { $this->set(self::FILENAME, $name); } |
| 46 | public function getFilename():string { return $this->get(self::FILENAME); } |
| 47 | |
| 48 | public function setCreated(int $created) { $this->set(self::CREATED, $created); } |
| 49 | public function getCreated():int { return $this->get(self::CREATED, 0); } |
| 50 | |
| 51 | public function setSize(int $size) { $this->set(self::SIZE, $size); } |
| 52 | public function getSize():int { return $this->get(self::SIZE, 0); } |
| 53 | |
| 54 | public function setUploaded(int $uploaded) { $this->set(self::UPLOADED, $uploaded); } |
| 55 | public function getUploaded():int { return $this->get(self::UPLOADED, 0); } |
| 56 | |
| 57 | /** |
| 58 | * @return string |
| 59 | * @throws IOException |
| 60 | */ |
| 61 | public function getFileLocation():string { |
| 62 | if(!$this->getUniqueId()) throw new IOException("No upload id was found"); |
| 63 | $directory = Factory::getLocations()->getTempDir() . JetBackup::SEP . $this->getUniqueId(); |
| 64 | if(!is_dir($directory)) mkdir($directory, 0700); |
| 65 | Util::secureFolder($directory); |
| 66 | return $directory . JetBackup::SEP . $this->getFilename(); |
| 67 | } |
| 68 | |
| 69 | /** |
| 70 | * @param string $data |
| 71 | * |
| 72 | * @return void |
| 73 | * @throws IOException |
| 74 | * @throws \SleekDB\Exceptions\IOException |
| 75 | * @throws \SleekDB\Exceptions\InvalidArgumentException |
| 76 | */ |
| 77 | public function writeChunk(string $file):void { |
| 78 | if($this->isCompleted()) throw new IOException("This file is already fully uploaded"); |
| 79 | if(!file_exists($file)) throw new IOException("The provided chunk file does not exist"); |
| 80 | |
| 81 | $length = filesize($file); |
| 82 | $uploaded = $this->getUploaded(); |
| 83 | |
| 84 | if($uploaded + $length > $this->getSize()) throw new IOException("File data provided is exceeded the provided file size"); |
| 85 | |
| 86 | $target = $this->getFileLocation(); |
| 87 | |
| 88 | $fd = fopen($target, 'a'); |
| 89 | if(!$fd) throw new IOException("Failed to open file '$target'"); |
| 90 | fseek($fd, $uploaded); |
| 91 | |
| 92 | $file_fd = fopen($file, 'rb'); |
| 93 | if(!$file_fd) throw new IOException("Failed to open chunk file '$file'"); |
| 94 | |
| 95 | while(!feof($file_fd)) fwrite($fd, fread($file_fd, 1024)); |
| 96 | |
| 97 | fclose($fd); |
| 98 | fclose($file_fd); |
| 99 | |
| 100 | $this->setUploaded($uploaded + $length); |
| 101 | $this->save(); |
| 102 | } |
| 103 | |
| 104 | public function isCompleted():bool { |
| 105 | return $this->getUploaded() >= $this->getSize(); |
| 106 | } |
| 107 | |
| 108 | public static function db():SleekStore { |
| 109 | return new SleekStore(self::COLLECTION); |
| 110 | } |
| 111 | |
| 112 | public static function query():QueryBuilder { |
| 113 | return self::db()->createQueryBuilder(); |
| 114 | } |
| 115 | |
| 116 | public function save():void { |
| 117 | if(!$this->getUniqueId()) $this->setUniqueId(Util::generateUniqueId()); |
| 118 | parent::save(); |
| 119 | } |
| 120 | } |