.gitignore000064400000000056144761607140006547 0ustar00/vendor/ /tests/ composer.lock test/config.phpcomposer.json000064400000000712144761607140007300 0ustar00{ "name": "boru/backblaze", "type": "library", "autoload": { "psr-4": { "boru\\backblaze\\": "src/" } }, "authors": [ { "name": "Daniel Hayes", "email": "dhayes@boruapps.com" } ], "require": { "boru/dhutils": "^1.0" }, "repositories": [ { "type": "composer", "url": "https://satis.boruapps.com" } ] } instructions-composer.txt000064400000000311144761607140011703 0ustar00{ "require": { "boru/dhcli": "dev-master" }, "repositories": [ { "type": "composer", "url": "https://satis.boruapps.com" } ] }src/BackBlazeBase.php000064400000004364144761607140010476 0ustar00debug_name."-t","trace","TRACE"); //_trace() dhGlobal::addLogLevel($this->debug_name."-d","debug","DEBUG"); //_debug() dhGlobal::addLogLevel($this->debug_name."-i","info"," INFO"); //_info() dhGlobal::addLogLevel($this->debug_name."-w","warn"," WARN"); //_warn() dhGlobal::addLogLevel($this->debug_name."-e","error","ERROR"); //_error() } protected function _trace(...$args) { if($this->debugDoTrace) { array_unshift($args,$this->debug_prefix." - "); array_unshift($args,$this->debug_name."-t"); return call_user_func_array([$this,"log"],$args); } return; } protected function _debug(...$args) { array_unshift($args,$this->debug_prefix." - "); array_unshift($args,$this->debug_name."-d"); return call_user_func_array([$this,"log"],$args); } protected function _info(...$args) { array_unshift($args,$this->debug_prefix." - "); array_unshift($args,$this->debug_name."-i"); return call_user_func_array([$this,"log"],$args); } protected function _warn(...$args) { array_unshift($args,$this->debug_prefix." - "); array_unshift($args,$this->debug_name."-w"); return call_user_func_array([$this,"log"],$args); } protected function _error(...$args) { array_unshift($args,$this->debug_prefix." - "); array_unshift($args,$this->debug_name."-e"); return call_user_func_array([$this,"log"],$args); } public function log(...$args) { return dhGlobal::log(...$args); } } class BackBlazeBaseException extends \Exception { protected $debug_name = "backblaze"; public function __construct($method,$message=null,$code=null) { if(!is_null($message)) { dhGlobal::log($this->debug_name."-e",$method." ".$code." ".print_r($message,true)); } parent::__construct($message,$code); } }src/Bucket.php000064400000001045144761607140007273 0ustar00"", "bucketName"=>"", "bucketType"=>"", "bucketInfo"=>"", "corsRules"=>"", "fileLockConfiguration"=>"", "defaultServerSideEncryption"=>"", "lifecycleRules"=>"", "revision"=>"", "options"=>"", ]; }src/BucketFile.php000064400000004246144761607140010101 0ustar00"", "action"=>"", "bucketId"=>"", "contentLength"=>"", "contentMd5"=>"", "contentSha1"=>"", "contentType"=>"", "fileId"=>"", "fileInfo"=>"", "fileName"=>"", "fileRetention"=>"", "legalHold"=>"", "serverSideEncryption"=>"", "uploadTimestamp"=>"", "name"=>"", "path"=>"", ]; public function __construct($arr=null,$separator=".") { parent::__construct($arr,$separator); $fileName = $this->get("fileName",null); if(!is_null($fileName)) { $parts = explode("/",$fileName); $name = array_pop($parts); if(empty($name)) { $name = array_pop($parts)."/"; } $path = implode("/",$parts)."/"; $this->set("name",$name); $this->set("path",$path); } } public function modified($format=null) { $millis = $this->get("fileInfo.src_last_modified_millis",false); if($millis !== false) { $timestamp = $millis/1000; $dt = new \DateTime(date("Y-m-d H:i:s",$timestamp)); if(is_null($format)) { return $dt; } return $dt->format($format); } return false; } public function name() { return $this->get("name",null); } public function path() { return $this->get("path",null); } public function fileName() { return $this->get("fileName",null); } public function fileId() { return $this->get("fileId",null); } public function fileInfo() { return $this->get("fileInfo",null); } public function sha1() { return $this->get("contentSha1",null); } public function contentType() { return $this->get("contentType",null); } public function action() { return $this->get("action",null); } public function size() { return $this->get("contentLength"); } }src/Client.php000064400000053307144761607140007304 0ustar00setupDebug(); $this->setKeyId($keyId); $this->setApplicationKey($applicationKey); if(is_null($this->client)) { $this->client = new \boru\dhutils\dhHttp(); } $this->initCache(dhGlobal::getDot($options,"cacheFile","")); $this->accountInfo = isset($options["accountInfo"]) ? $options["accountInfo"] : []; if(empty($this->accountInfo)) { $this->loadCache(); } if(($this->getAccount("accountId",false) === false || $this->getAccount("authorizationToken",false) === false) && !is_null($this->getKeyId()) && !is_null($this->getApplicationKey())) { $this->authorizeAccount(); } else { $this->_info("Loaded accountInfo from cache ".$this->cacheFile->path()); } if($this->getAccount("accountId",false) === false || $this->getAccount("authorizationToken",false) === false) { throw new ClientException(__METHOD__,"Authentication not successful, unable to proceed",-1); } $this->writeCache(); } protected function initCache($cacheFilePath="") { if(empty($cacheFilePath)) { $dir = sys_get_temp_dir(); if(substr($dir,-(strlen(DIRECTORY_SEPARATOR)) != DIRECTORY_SEPARATOR)) { $dir.=DIRECTORY_SEPARATOR; } $cacheFilePath = $dir.'bblazePhp'; } $this->cacheFile = new File([ "path"=>$cacheFilePath, "readMeta"=>true, "create"=>true, "overwrite"=>false ]); return $this; } protected function loadCache() { $cached = $this->cacheFile->content(); if(!empty($cached)) { $j = json_decode($cached,true); if(is_array($j)) { $this->accountInfo = $j; } } return $this; } protected function writeCache() { $this->cacheFile->write(json_encode($this->accountInfo)); return $this; } public function authorizeAccount() { $this->_trace("funcStart",__METHOD__); $response = $this->request("get","/b2_authorize_account",[]); if(is_array($response)) { $this->accountInfo = $response; } else { $this->_trace("funcEnd",__METHOD__); return false; } $this->_info("authorizeAccount successful"); $this->_trace("funcEnd",__METHOD__); return true; } public function createBucket($bucketName,$type=Bucket::T_PRIVATE) { $this->_trace("funcStart",__METHOD__); $params = [ "bucketType"=>$type, "bucketName"=>$bucketName, "accountId"=>$this->getAccount("accountId") ]; $response = $this->request("post","/b2_create_bucket",$params); //do something with this. if(is_array($response)) { $this->_info("createBucket successful",$response["bucketName"]); $this->_trace("funcEnd",__METHOD__); $bucket = new Bucket($response); $this->_bucketCache[$bucket->get("bucketId")] = $bucket; return $bucket; } $this->_trace("funcEnd",__METHOD__); return false; } public function listBuckets($force=false) { $this->_trace("funcStart",__METHOD__); if(!$force && (time() - $this->_bucketCacheLastList) < $this->bucketCacheTime && !empty($this->_bucketCache)) { $this->_trace("funcEnd (cache-hit)",__METHOD__); $this->_info("listBuckets (cache) successful",count($this->_bucketCache),"returned"); return $this->_bucketCache; } $buckets = []; $params = [ "accountId"=>$this->getAccount("accountId"), ]; $response = $this->request("post","/b2_list_buckets",$params); if(is_array($response) && isset($response["buckets"])) { foreach($response["buckets"] as $bucket) { $buckets[] = new Bucket($bucket); } } $this->_info("listBuckets successful",count($buckets),"returned"); $this->_trace("funcEnd",__METHOD__); $this->_bucketCache = $buckets; $this->_bucketCacheLastList = time(); return $buckets; } public function getBucketBy($option="bucketName",$value) { $this->_trace("funcStart",__METHOD__); $buckets = $this->listBuckets(); foreach($buckets as $bucket) { if($bucket->get($option) == $value) { $this->_trace("funcEnd",__METHOD__); return $bucket; } } $this->_trace("funcEnd",__METHOD__); return false; } public function getBucketFromOptions($options=[]) { $this->_trace("funcStart",__METHOD__); if(isset($options["bucket"])) { $this->_trace("funcEnd",__METHOD__); return $options["bucket"]; } elseif(isset($options["bucketId"])) { $this->_trace("funcEnd",__METHOD__); return $this->getBucketBy("bucketId",$options["bucketId"]); } elseif(isset($options["bucketName"])) { $this->_trace("funcEnd",__METHOD__); return $this->getBucketBy("bucketName",$options["bucketName"]); } $this->_trace("funcEnd",__METHOD__); return false; } public function listFiles($options=[]) { /** * $options = [ * "bucket" / "bucketId" / "bucketName", * "fileName" -- to get a file by filename * "maxFileCount" (defaults to 1), * "prefix" -- prefix to search for * "delimiter" -- delimiter to use * "startFileName" -- filename offset to start listing at * "includeDirs" -- defaults to false * ] */ $bucket = $this->getBucketFromOptions($options); $fileName = dhGlobal::getDot($options,"fileName",null); $maxFileCount = dhGlobal::getDot($options,"maxFileCount",1); $prefix = dhGlobal::getDot($options,"prefix",null); $delimiter = dhGlobal::getDot($options,"delimiter",null); $startFileName = dhGlobal::getDot($options,"startFileName",null); $includeDirs = dhGlobal::getDot($options,"includeDirs",null); $this->_trace("funcStart",__METHOD__); $files = []; if(!is_null($fileName)) { $nextFile = $fileName; } else { $nextFile = is_null($startFileName) ? '' : $startFileName; } while(true) { $params = [ "bucketId"=>$bucket->get("bucketId"), "startFileName"=>$nextFile, "maxFileCount"=>$maxFileCount, ]; if(!is_null($prefix)) { $params["prefix"] = $prefix; } if(!is_null($delimiter)) { $params["delimiter"] = $delimiter; } $response = $this->request("post","/b2_list_file_names",$params); if(is_array($response) && isset($response["files"])) { foreach($response["files"] as $file) { if(substr($file['fileName'],-1) == "/" && $delimiter != "/" && !$includeDirs) { continue; } if(!is_null($fileName)) { if($file["fileName"] == $fileName) { $this->listFilesAddToArray($files,new BucketFile($file),$options); break; } } else { $this->listFilesAddToArray($files,new BucketFile($file),$options); //$files[] = new BucketFile($file); } } if(is_null($response['nextFileName'])) { break; } else { print_r($response); } } } $this->_trace("funcEnd",__METHOD__); return $files; } protected function listFilesAddToArray(&$array,$bucketFile,$options) { $arrayFormat = dhGlobal::getDot($options,"arrayFormat",null); if(is_null($arrayFormat) || $arrayFormat == "default" || empty($arrayFormat)) { $array[] = $bucketFile; return; } if($arrayFormat == "name") { $array[$bucketFile->name()] = $bucketFile; } if($arrayFormat == "fullName") { $array[$bucketFile->fileName()] = $bucketFile; } } public function getFileById($fileId) { $this->_trace("funcStart",__METHOD__); $params = ['fileId' => $fileId]; $response = $this->request("post","/b2_get_file_info",$params); $this->_trace("funcEnd",__METHOD__); return new BucketFile($response); } public function getFileByName($bucket,$fileName) { $this->_trace("funcStart",__METHOD__); $files = $this->listFiles($bucket,1,$fileName,null,$fileName); foreach($files as $file) { if($file->get("fileName") == $fileName) { $this->_trace("funcEnd",__METHOD__); return $file; } } $this->_trace("funcEnd",__METHOD__); return false; } /** * Upload a document to a bucket * * the input is an array of options. You can either specify a dhutils File object 'file' or the individual file attributes of 'fileName', 'content', 'contentType' and 'modifiedTime' * * If not using the dhutils File object, fileName and content are mandatory. ContentType and modifiedTime are optional. modifiedTime is expected as a unixtimestamp * * @param array $options */ public function upload($options=[]) { $this->_trace("funcStart",__METHOD__); //bucket, bucketId, bucketName //fileName = full path to upload to, no leading / //content = file content, or a fopen(filename,'r') //contentType (optional) //modifiedTime (optional) if(($bucket = $this->getBucketFromOptions($options)) === false) { throw new ClientException(__METHOD__,"No bucket option provided (bucket, bucketId, bucketName)"); } $file = dhGlobal::getDot($options,"file",null); if(!is_null($file) && $file instanceof File) { $fileName = dhGlobal::trimString("/",$file->path(),dhGlobal::TRIM_START); $modifiedTime = $file->mtime("millis"); $fileSize = $file->size(); $fileHash = $file->sha1(); $contentType = $file->mimeType(); $content = $file->content(); } else { $modifiedTime = dhGlobal::getDot($options,"modifiedTimeMillis",false); if(!$modifiedTime) { $mt = dhGlobal::getDot($options,"modifiedTime",false); if(is_object($mt)) { $modifiedTime = $mt->format("U")*1000; } elseif(is_numeric($mt)) { $modifiedTime = $mt * 1000; } else { try { $mt = new \DateTime($mt); $modifiedTime = $mt->format("U")*1000; } catch (\Exception $e) { } } } if(!$modifiedTime) { $modifiedTime = floor(microtime(true)*1000); } //size, //hash $fileInfo = dhGlobal::getFileHashAndSize($options["content"]); $fileSize = $fileInfo["size"]; $fileHash = $fileInfo["hash"]; $fileName = $options["fileName"]; $contentType = dhGlobal::getDot($options,"contentType","b2/x-auto"); $content = &$options["content"]; } if($fileSize <= $this->uploadNormalLimit) { $return = $this->uploadNormal($bucket,$fileName,$contentType,$fileSize,$fileHash,$modifiedTime,$content); } else { $return = $this->uploadMultiPart($bucket,$fileName,$contentType,$fileSize,$fileHash,$modifiedTime,$content); } $this->_trace("funcEnd",__METHOD__); return $return; } public function getUploadUrlAuth($bucket,$cache=false) { $params = ['bucketId' => $bucket->get("bucketId")]; $response = $this->request("post","/b2_get_upload_url",$params); $this->accountInfo["uploadAuth"] = $response; if($cache) { $this->writeCache(); } return $response; } protected function uploadNormal($bucket,$fileName,$contentType,$fileSize,$fileHash,$modifiedTime,$content) { $response = $this->getAccount("uploadAuth",null); if(is_null($response)) { $response = $this->getUploadUrlAuth($bucket,true); } $req = $this->makeRequest("post",$response["uploadUrl"]) ->authToken($response["authorizationToken"]) ->header("Content-Type",$contentType) ->header("Content-Length",$fileSize) ->header("X-Bz-File-Name",$fileName) ->header("X-Bz-Content-Sha1",$fileHash) ->header("X-Bz-Info-src_last_modified_millis",$modifiedTime) ->rawBody($content); $this->_trace("funcEnd",__METHOD__); $response = $this->sendRequest($req,true); if(!is_object($response) && is_array($response)) { return new BucketFile($response); } else { if(is_object($response)) { if($response->getStatusCode() == 401 && $response->getReasonPhrase() == "unauthorized") { throw new ClientException(__METHOD__,"401-unauthorized returned from BackBlaze. Account credentials are not valid to perform this action",-1); } elseif($response->getStatusCode() == 401) { if($this->uploadTries >= 5) { throw new ClientException(__METHOD__,"upload re-try limit (5) hit"); } $this->uploadTries++; $this->accountInfo["uploadAuth"] = null; $retryDelay = $this->uploadDelay * 1000; $this->uploadDelay *= $this->uploadBackoff; usleep($retryDelay); return $this->uploadNormal($bucket,$fileName,$contentType,$fileSize,$fileHash,$modifiedTime,$content); } else { throw new ClientException(__METHOD__,$req->getMethod()." Request to ".$req->getUrl()." failed with status code ".$response->getStatusCode()." - ".$response->getReasonPhrase().PHP_EOL.PHP_EOL.$response->body().PHP_EOL,$response->getStatusCode()); } } } } protected function uploadMultiPart($bucket,$fileName,$contentType,$fileSize,$fileHash,$modifiedTime,$content) { $this->_trace("funcStart",__METHOD__); $params = [ 'bucketId' => $bucket->get("bucketId"), 'fileName' => $fileName, 'contentType' => $contentType, ]; $response = $this->request("post","/b2_get_upload_url",$params); $newFileId = $response['fileId']; $parts = []; $partsTotal = ceil($fileSize/$this->multiPartSize); for($i=0;$i<$partsTotal;$i++) { $sizeSent = $i * $this->mutiPartSize; $remainingSize = $fileSize - $sizeSent; $size = $remainingSize > $this->multiPartSize ? $this->multiPartSize : $remainingSize; $partInfo = dhGlobal::getFileHashAndSize($content,$sizeSent,$size); $partSize = $partInfo["size"]; $partHash = $partInfo["hash"]; $parts[] = $partHash; $response = $this->request("post","/b2_get_upload_part_url",["fileId"=>$newFileId]); $request = $this->makeRequest("post",$response["uploadUrl"]) ->authToken($response["authorizationToken"]) ->header("X-Bz-Part-Number",$i+1) ->header("Content-Length",$partSize) ->header("X-Bz-Content-Sha1",$partHash) ->rawBody(dhGlobal::getPartOfFile($content,$sizeSent,$size)); $response = $this->sendRequest($request,true); } $response = $this->request("post","/b2_finish_large_file",["fileId"=>$newFileId,"partSha1Array"=>$parts]); $this->_trace("funcEnd",__METHOD__); return new BucketFile($response); } public function makeRequest($method,$uri='') { $this->_trace("funcStart",__METHOD__); $methods = ["get","post","put","delete","options"]; if(substr($uri,0,4) != "http") { if(substr($uri,0,1) != "/") { $uri = "/".$uri; } $url = $this->getAccount("apiUrl",$this->apiUrl); $url .= $this->apiVersion.$uri; } else { $url = $uri; } if(!in_array(strtolower($method),$methods)) { throw new ClientException(__METHOD__,"HTTP Method $method not valid, options are [".implode(",",$methods)."]"); } $method = strtoupper($method); $this->_trace("funcEnd",__METHOD__); return $this->client->request($method,$url); } public function sendRequest($request,$json=true,$options=[]) { $this->_trace("funcStart",__METHOD__); try { $response = $request->send(); } catch(\Exception $e) { throw new ClientException(__METHOD__,$e->getMessage(),$e->getCode()); } if($response->getStatusCode() === 200) { if($json) { $this->_trace("funcEnd",__METHOD__); return $response->body(true,true); } else { $this->_trace("funcEnd",__METHOD__); return $response->body(); } } else { if(!empty($options) && isset($options["returnError"])) { return $response; } else { throw new ClientException(__METHOD__,$request->getMethod()." Request to ".$request->getUrl()." failed with status code ".$response->getStatusCode()." - ".$response->getReasonPhrase().PHP_EOL.PHP_EOL.$response->body().PHP_EOL,$response->getStatusCode()); } } } public function request($method,$uri='',$params=[],$json=true) { $this->_trace("funcStart",__METHOD__); $request = $this->makeRequest($method,$uri); if(isset($this->accountInfo["authorizationToken"])) { $request->authToken($this->accountInfo["authorizationToken"]); } else { $request->authBasic($this->keyId,$this->applicationKey); } if(!empty($params)) { if(is_object($params)) { $arr = $params->get(); foreach($arr as $k=>$v) { if(method_exists($request,$k)) { call_user_func([$request,$k],$v); } } } if(is_array($params)) { foreach($params as $k=>$v) { $request->json($k,$v); } } } $this->_trace("funcEnd",__METHOD__); return $this->sendRequest($request,$json); } public function getAccount($item=null,$default=false) { $this->_trace("funcStart",__METHOD__); if(is_null($this->accountInfo)) { $this->_trace("funcEnd",__METHOD__); return $default; } if(is_null($item)) { $this->_trace("funcEnd",__METHOD__); return $this->accountInfo; } elseif(!isset($this->accountInfo[$item])) { $this->_trace("funcEnd",__METHOD__); return $default; } $this->_trace("funcEnd",__METHOD__); return $this->accountInfo[$item]; } /** * Get the value of keyId */ public function getKeyId() { return $this->keyId; } /** * Set the value of keyId * * @return self */ public function setKeyId($keyId) { $this->keyId = $keyId; return $this; } /** * Get the value of applicationKey */ public function getApplicationKey() { return $this->applicationKey; } /** * Set the value of applicationKey * * @return self */ public function setApplicationKey($applicationKey) { $this->applicationKey = $applicationKey; return $this; } } class ClientException extends BackBlazeBaseException { protected $debug_name = "backblaze"; }src/Path.php000064400000022125144761607140006754 0ustar00setupDebug(); if(isset($options["localDirectory"]) && !empty($options["localDirectory"])) { $this->localDir = new Directory([ "path"=>$options["localDirectory"], "scan"=>true, "recursive"=>true ]); } elseif(isset($options["localDir"]) && !empty($options["localDir"])) { $this->localDir = new Directory([ "path"=>$options["localDir"], "scan"=>true, "recursive"=>true ]); } if(is_null($this->localDir)) { throw new PathException(__METHOD__,"local directory not specified in options (localDir or localDirectory)",-1); } $this->bucketPath = dhGlobal::getDot($options,"bucketPath",null); if(is_null($this->bucketPath)) { throw new PathException(__METHOD__,"remote bucketPath not specified in options (bucketPath)",-1); } if(substr($this->bucketPath,-1) != "/") { $this->bucketPath.="/"; } if(substr($this->bucketPath,0,1) == "/") { if($this->bucketPath == "/") { $this->bucketPath = ""; } else { $this->bucketPath = substr($this->bucketPath,1); } } $this->setClientFromOptions($options); $this->setBucketFromOptions($options); } public function getStats() { $stats = [ "directories"=>count($this->directories), "files"=>0, "size"=>0, "changed"=>[ "files"=>0, "size"=>0, ], "uploaded"=>[ "files"=>0, "size"=>0 ] ]; foreach($this->files as $file) { $stats["files"]++; $stats["size"]+=$file->size(); $changed = $file->get("changed",false); $uploaded = $file->get("uploaded",false); if($changed) { $stats["changed"]["files"]++; $stats["changed"]["size"]+=$file->size(); } if($uploaded) { $stats["uploaded"]["files"]++; $stats["uploaded"]["size"]+=$file->size(); } } return $stats; } public function scan(callable $fileComplete=null,callable $directoryComplete=null) { $this->_info("scan started"); $this->syncDirectory($this->localDir,true,false,$fileComplete,$directoryComplete); } public function sync($forceFullSync=false,callable $fileComplete=null,callable $directoryComplete=null) { $this->_info("sync started"); $this->syncDirectory($this->localDir,false,$forceFullSync,$fileComplete,$directoryComplete); } protected function syncDirectory($Directory,$scanOnly=false,$forceFullSync=false,callable $fileComplete=null,callable $directoryComplete=null) { //Get backblaze files and info for the parent directory.. $bdir = $this->bucketPath.substr($Directory->path(),1)."/"; $files = $Directory->files(); $dirs = $Directory->dirs(); $fileCount = is_array($files) ? count($files) : 0; $dirCount = is_array($dirs) ? count($dirs) : 0; $bbFiles = $this->client->listFiles([ "bucket"=>$this->bucket, "maxFileCount"=>1000, "delimiter"=>"/", "prefix"=>$bdir, "arrayFormat"=>"name" ]); $bbFileCount = is_array($bbFiles) ? count($bbFiles) : 0; $this->_info("Starting ".$bdir." - Files:".$fileCount." Subdirs:".$dirCount." BackBlaze:".$bbFileCount." "); $filesProcessed = []; if(!empty($files) && is_array($files)) { $count=0; foreach($files as $file) { $this->files[$file->path()] = $file; $fRef = &$this->files[$file->path()]; $count++; $name = $file->name(); $bbFile = isset($bbFiles[$name]) ? $bbFiles[$name] : false; $fRef->set("backblazeFile",$bbFile); $changed = true; if(!$forceFullSync) { if($bbFile !== false) { if(strlen($file->sha1())>10) { if($file->sha1() == $bbFile->sha1()) { //$this->_debug("sha match on",$file->path()); $changed = false; } } } } $uploaded = false; if($changed) { $this->changed[] = &$this->files[$file->path()]; if(!$scanOnly) { try { $this->client->upload([ "bucket"=>$this->bucket, "file"=>$file ]); $uploaded = true; $this->uploaded[] = &$this->files[$file->path()]; } catch (\Exception $e) { } } } $fRef->set("changed",$changed); $fRef->set("uploaded",$uploaded); $filesProcessed[] = &$this->files[$file->path()]; if(is_callable($fileComplete)) { $fileComplete([ "sync"=>$this, "file"=>$fRef, "num"=>$count-1, "fileCount"=>$fileCount, "bbFileCount"=>$bbFileCount ]); } else { $this->_trace("Processed ".$fRef->path()." - ".( $changed ? ($uploaded ? "Uploaded" : "Changed") : "Skipped" ) ); } } $file = null; $bbFile = null; unset($fRef); } if(is_callable($directoryComplete)) { $directoryComplete([ "sync"=>$this, "directory"=>$Directory, "processed"=>$filesProcessed, "fileCount"=>$fileCount, "bbFileCount"=>$bbFileCount ]); } $Directory->set("filesProcessed",$filesProcessed); $Directory->set("fileCount",$fileCount); $Directory->set("bbFileCount",$bbFileCount); $this->directories[$Directory->path()] = $Directory; $this->_info("complete with ".$Directory->path()." .. processed ".count($filesProcessed)." files"); unset($filesProcessed); if(!empty($dirs) && is_array($dirs)) { foreach($dirs as $dir) { $this->syncDirectory($dir,$scanOnly,$forceFullSync,$fileComplete,$directoryComplete); } } } public function setClientFromOptions($options=[]) { if(isset($options["client"])) { $this->client = $options["client"]; return $this->client; } $keyId = dhGlobal::getDot($options,"keyId",null); $applicationKey = dhGlobal::getDot($options,"applicationKey",null); $accountInfo = dhGlobal::getDot($options,"accountInfo",[]); $options["accountInfo"] = $accountInfo; $cacheFile = dhGlobal::getDot($options,"cacheFile",false); if($cacheFile !== false) { $options["cacheFile"] = $cacheFile; } $this->client = new Client($keyId,$applicationKey,$options); return $this->client; } public function setBucketFromOptions($options=[]) { $this->_trace("funcStart",__METHOD__); if(isset($options["bucket"])) { $this->bucket = $options["bucket"]; } elseif(isset($options["bucketId"])) { $this->bucket = $this->client->getBucketBy("bucketId",$options["bucketId"]); } elseif(isset($options["bucketName"])) { $this->bucket = $this->client->getBucketBy("bucketName",$options["bucketName"]); } $this->_trace("funcEnd",__METHOD__); if(is_null($this->bucket)) { return false; } return $this->bucket; } } class PathException extends BackBlazeBaseException { protected $debug_name = "backblaze-path"; }src/UploadTool.php000064400000005063144761607140010144 0ustar00client = new Client($keyId,$applicationKey,$accountInfo); $this->fileList = dhGlobal::getDot($options,"fileList",[]); $dir = dhGlobal::getDot($options,"dir",false); if($dir !== false) { $this->initDir($dir); } } public function initDir($initDir,$seperator=DIRECTORY_SEPARATOR) { $directories = []; if(is_array($initDir)) { $directories = $initDir; } else { $directories = [$initDir]; } foreach($directories as $directory) { $this->directories[] = new Directory($directory,true,true); } return $this->fileList; } protected function _trace(...$args) { if($this->debugDoTrace) { array_unshift($args,"UploadTool -"); array_unshift($args,"blaze-t"); return call_user_func_array([$this,"log"],$args); } return; } protected function _debug(...$args) { array_unshift($args,"UploadTool -"); array_unshift($args,"blaze-d"); return $this->log($args); } protected function _info(...$args) { array_unshift($args,"UploadTool -"); array_unshift($args,"blaze-i"); return call_user_func_array([$this,"log"],$args); } protected function _warn(...$args) { array_unshift($args,"UploadTool -"); array_unshift($args,"blaze-w"); return call_user_func_array([$this,"log"],$args); } protected function _error(...$args) { array_unshift($args,"UploadTool -"); array_unshift($args,"blaze-e"); return call_user_func_array([$this,"log"],$args); } public function log(...$args) { return dhGlobal::log(...$args); } }test/basic.php000064400000001574144761607140007336 0ustar00listBuckets(); $bucket = $client->getBucketBy("bucketName","dhtest"); $options = [ "bucket"=>$bucket ]; $files = $client->listFiles($options); foreach($files as $file) { $modified = $file->modified(); echo $file->get("fileId")." - ".$file->get("fileName")."\t".$file->modified("Y-m-d H:i:s")."\n"; } return; //print_r($client->createBucket("dhtest")); //works $bucket = $client->getBucketBy("bucketName","dhtest"); $options = [ "bucket"=>$bucket, "fileName"=>"testfile.txt", "content"=>file_get_contents("testfile.txt"), ]; $client->upload($options);test/init.php000064400000000334144761607140007211 0ustar00$keyId,"appKey"=>$appKey]; }