_destination = $destination; $this->_directory = $directory; if(!$this->_destination->getClient()) throw new IOException("Unable to retrieve google drive service"); $path = $this->_destination->getRealPath($this->_directory); if(!$parent_id) $parent_id = $this->_destination->getFileId($path == '/' ? '' : $path); if(!$parent_id) return; $this->_parent_id = $parent_id; if(!$this->_destination->dirExists($this->_directory)) return; $this->rewind(); } /** * @param bool $rewind * * @return void * @throws IOException */ private function _loadChunk(bool $rewind=false):void { try { $marker = ''; if(!$rewind && $this->_list) { if(!$this->_list->getNextPageToken()) { $this->_list = null; return; } $marker = $this->_list->getNextPageToken(); } $this->_list = $this->_destination->_retries(function() use ($rewind, $marker) { $params = [ "fields" => 'files,nextPageToken', "q" => "'$this->_parent_id' in parents and trashed = false", "orderBy" => "name asc,modifiedTime desc", "pageSize" => self::CHUNK_LIMIT ]; if($marker) $params['pageToken'] = $marker; return $this->_destination->getClient()->listFiles($params); }, "Failed fetching list of files"); $this->_files = $this->_list ? $this->_list->getFiles() : []; } catch(Exception $e) { if($e->getCode() == 404) $this->_files = []; else throw new IOException($e->getMessage(), $e->getCode(), $e); } } /** * @return void * @throws IOException */ public function rewind():void { $this->_loadChunk(true); } /** * @return bool * @throws IOException */ public function hasNext():bool { if(!($this->_files && count($this->_files))) $this->_loadChunk(); return ($this->_files && count($this->_files)); } /** * @return ?iDestinationFile * @throws IOException */ public function getNext():?iDestinationFile { if(!$this->hasNext()) return null; $nextfile = array_shift($this->_files); $path = $this->_directory . '/' . $nextfile->getName(); $basename = basename($path); $file = new DestinationFile(); $file->setType($nextfile->getMimeType() == Client::MIMITYPE_DIR ? iDestinationFile::TYPE_DIRECTORY : iDestinationFile::TYPE_FILE); $file->setName($basename); $file->setPath($basename == $path ? '' : dirname($path)); $file->setSize($nextfile->getMimeType() == Client::MIMITYPE_DIR ? 4096 : $nextfile->getSize()); $file->setModifyTime($nextfile->getModificationTime()); $file->setFileData(json_encode([ 'id' => $nextfile->getId() ])); return $file; } }