disktag = $tag;
$this->redirect_uri = 'https://scfonedrive.github.io';
if (getConfig('client_id', $tag) && getConfig('client_secret', $tag)) {
$this->client_id = getConfig('client_id', $tag);
$this->client_secret = getConfig('client_secret', $tag);
} else {
$this->client_id = '734ef928-d74c-4555-8d1b-d942fa0a1a41';
$this->client_secret = ':EK[e0/4vQ@mQgma8LmnWb6j4_C1CSIW';
}
$this->oauth_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/';
$this->api_url = 'https://graph.microsoft.com/v1.0';
$this->scope = 'https://graph.microsoft.com/Files.ReadWrite.All offline_access';
$res = $this->get_access_token(getConfig('refresh_token', $tag));
$this->client_secret = urlencode($this->client_secret);
$this->scope = urlencode($this->scope);
$this->DownurlStrName = '@microsoft.graph.downloadUrl';
$this->ext_api_url = '/me/drive/root';
}
public function isfine()
{
if (!$this->access_token) return false;
else return true;
}
public function show_base_class()
{
return get_class();
//$tmp[0] = get_class();
//$tmp[1] = get_class($this);
//return $tmp;
}
public function list_files($path = '/')
{
global $exts;
if (!($files = getcache('path_' . $path, $this->disktag))) {
// https://docs.microsoft.com/en-us/graph/api/driveitem-get?view=graph-rest-1.0
// https://docs.microsoft.com/zh-cn/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http
// https://developer.microsoft.com/zh-cn/graph/graph-explorer
$pos = splitlast($path, '/');
$parentpath = $pos[0];
if ($parentpath=='') $parentpath = '/';
$filename = $pos[1];
if ($parentfiles = getcache('path_' . $parentpath, $this->disktag)) {
if (isset($parentfiles['children'][$filename][$this->DownurlStrName])) {
if (in_array(splitlast($filename,'.')[1], $exts['txt'])) {
if (!(isset($parentfiles['children'][$filename]['content'])&&$parentfiles['children'][$filename]['content']['stat']==200)) {
$content1 = curl('GET', $parentfiles['children'][$filename][$this->DownurlStrName]);
$parentfiles['children'][$filename]['content'] = $content1;
savecache('path_' . $parentpath, $parentfiles, $this->disktag);
}
}
return $this->files_format($parentfiles['children'][$filename]);
}
}
$url = $this->api_url . $this->ext_api_url;
if ($path !== '/') {
$url .= ':' . $path;
if (substr($url,-1)=='/') $url=substr($url,0,-1);
}
$url .= '?expand=children(select=id,name,size,file,folder,parentReference,lastModifiedDateTime,'.$this->DownurlStrName.')';
$retry = 0;
$arr = [];
while ($retry<3&&!$arr['stat']) {
$arr = curl('GET', $url, '', ['Authorization' => 'Bearer ' . $this->access_token], 1);
$retry++;
}
//echo $url . '
' . json_encode($arr, JSON_PRETTY_PRINT) . ''; if ($arr['stat']<500) { $files = json_decode($arr['body'], true); //echo '
' . json_encode($files, JSON_PRETTY_PRINT) . ''; if (isset($files['folder'])) { if ($files['folder']['childCount']>200) { // files num > 200 , then get nextlink $page = $_POST['pagenum']==''?1:$_POST['pagenum']; if ($page>1) if (!($files = getcache('path_' . $path . '_' . $page, $this->disktag))) { $files = $this->fetch_files_children($files, $path, $page); //$files['children'] = children_name($files['children']); /*$url = $_SERVER['api_url']; if ($path !== '/') { $url .= ':' . $path; if (substr($url,-1)=='/') $url=substr($url,0,-1); $url .= ':/children?$top=9999&$select=id,name,size,file,folder,parentReference,lastModifiedDateTime,'.$this->DownurlStrName; } else { $url .= '/children?$top=9999&$select=id,name,size,file,folder,parentReference,lastModifiedDateTime,'.$this->DownurlStrName; } $children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $this->access_token])['body'], true); $files['children'] = $children['value'];*/ savecache('path_' . $path . '_' . $page, $files, $this->disktag); } } else { // files num < 200 , then cache //if (isset($files['children'])) { //$files['children'] = children_name($files['children']); //} savecache('path_' . $path, $files, $this->disktag); } } if (isset($files['file'])) { if (in_array(splitlast($files['name'],'.')[1], $exts['txt'])) { if (!(isset($files['content'])&&$files['content']['stat']==200)) { $content1 = curl('GET', $files[$this->DownurlStrName]); $files['content'] = $content1; savecache('path_' . $path, $files, $this->disktag); } } } if (isset($files['error'])) { $files['error']['stat'] = $arr['stat']; } } else { //error_log($arr['body']); $files = json_decode($arr['body'], true); if (isset($files['error'])) { $files['error']['stat'] = $arr['stat']; } else { $files['error']['stat'] = 503; $files['error']['code'] = 'unknownError'; $files['error']['message'] = 'unknownError'; } //$files = json_decode( '{"unknownError":{ "stat":'.$arr['stat'].',"message":"'.$arr['body'].'"}}', true); //error_log(json_encode($files, JSON_PRETTY_PRINT)); } } //echo '
' . json_encode($files, JSON_PRETTY_PRINT) . ''; return $this->files_format($files); } protected function files_format($files) { if (isset($files['file'])) { $tmp['type'] = 'file'; $tmp['id'] = $files['id']; $tmp['name'] = $files['name']; $tmp['time'] = $files['lastModifiedDateTime']; $tmp['size'] = $files['size']; $tmp['mime'] = $files['file']['mimeType']; $tmp['url'] = $files[$this->DownurlStrName]; $tmp['content'] = $files['content']; } elseif (isset($files['folder'])) { $tmp['type'] = 'folder'; $tmp['id'] = $files['id']; $tmp['name'] = $files['name']; $tmp['time'] = $files['lastModifiedDateTime']; $tmp['size'] = $files['size']; $tmp['childcount'] = $files['folder']['childCount']; $tmp['page'] = $files['folder']['page']; foreach ($files['children'] as $file) { if (isset($file['file'])) { $tmp['list'][$file['name']]['type'] = 'file'; //var_dump($file); //echo $file['name'] . ':' . $this->DownurlStrName . ':' . $file[$this->DownurlStrName] . PHP_EOL; $tmp['list'][$file['name']]['url'] = $file[$this->DownurlStrName]; $tmp['list'][$file['name']]['mime'] = $file['file']['mimeType']; } elseif (isset($file['folder'])) { $tmp['list'][$file['name']]['type'] = 'folder'; } $tmp['list'][$file['name']]['id'] = $file['id']; $tmp['list'][$file['name']]['name'] = $file['name']; $tmp['list'][$file['name']]['time'] = $file['lastModifiedDateTime']; $tmp['list'][$file['name']]['size'] = $file['size']; } } elseif (isset($files['error'])) { return $files; } //error_log(json_encode($tmp)); return $tmp; } protected function fetch_files_children($files, $path, $page) { $cachefilename = '.SCFcache_'.$_SERVER['function_name']; $maxpage = ceil($files['folder']['childCount']/200); if (!($files['children'] = getcache('files_' . $path . '_page_' . $page, $this->disktag))) { // down cache file get jump info. 下载cache文件获取跳页链接 $cachefile = $this->list_files(path_format($path . '/' .$cachefilename)); if ($cachefile['size']>0) { $pageinfo = curl('GET', $cachefile[$this->DownurlStrName])['body']; $pageinfo = json_decode($pageinfo,true); for ($page4=1;$page4<$maxpage;$page4++) { savecache('nextlink_' . $path . '_page_' . $page4, $pageinfo['nextlink_' . $path . '_page_' . $page4], $this->disktag); $pageinfocache['nextlink_' . $path . '_page_' . $page4] = $pageinfo['nextlink_' . $path . '_page_' . $page4]; } } $pageinfochange=0; for ($page1=$page;$page1>=1;$page1--) { $page3=$page1-1; $url = getcache('nextlink_' . $path . '_page_' . $page3, $this->disktag); if ($url == '') { if ($page1==1) { $url = $this->api_url . $this->ext_api_url; if ($path !== '/') { $url .= ':' . $path; if (substr($url,-1)=='/') $url=substr($url,0,-1); $url .= ':'; } $url .= '/children?$select=id,name,size,file,folder,parentReference,lastModifiedDateTime,'.$this->DownurlStrName; $children = json_decode(curl('GET', $url, false, ['Authorization' => 'Bearer ' . $this->access_token])['body'], true); // echo $url . '
' . json_encode($children, JSON_PRETTY_PRINT) . ''; savecache('files_' . $path . '_page_' . $page1, $children['value'], $this->disktag); $nextlink=getcache('nextlink_' . $path . '_page_' . $page1, $this->disktag); if ($nextlink!=$children['@odata.nextLink']) { savecache('nextlink_' . $path . '_page_' . $page1, $children['@odata.nextLink'], $this->disktag); $pageinfocache['nextlink_' . $path . '_page_' . $page1] = $children['@odata.nextLink']; $pageinfocache = clearbehindvalue($path,$page1,$maxpage,$pageinfocache); $pageinfochange = 1; } $url = $children['@odata.nextLink']; for ($page2=$page1+1;$page2<=$page;$page2++) { sleep(1); $children = json_decode(curl('GET', $url, false, ['Authorization' => 'Bearer ' . $this->access_token])['body'], true); savecache('files_' . $path . '_page_' . $page2, $children['value'], $this->disktag); $nextlink=getcache('nextlink_' . $path . '_page_' . $page2, $this->disktag); if ($nextlink!=$children['@odata.nextLink']) { savecache('nextlink_' . $path . '_page_' . $page2, $children['@odata.nextLink'], $this->disktag); $pageinfocache['nextlink_' . $path . '_page_' . $page2] = $children['@odata.nextLink']; $pageinfocache = clearbehindvalue($path,$page2,$maxpage,$pageinfocache); $pageinfochange = 1; } $url = $children['@odata.nextLink']; } //echo $url . '
' . json_encode($children, JSON_PRETTY_PRINT) . ''; $files['children'] = $children['value']; $files['folder']['page']=$page; $pageinfocache['filenum'] = $files['folder']['childCount']; $pageinfocache['dirsize'] = $files['size']; $pageinfocache['cachesize'] = $cachefile['size']; $pageinfocache['size'] = $files['size']-$cachefile['size']; if ($pageinfochange == 1) $this->MSAPI('PUT', path_format($path.'/'.$cachefilename), json_encode($pageinfocache, JSON_PRETTY_PRINT), $this->access_token)['body']; return $files; } } else { for ($page2=$page3+1;$page2<=$page;$page2++) { sleep(1); $children = json_decode(curl('GET', $url, false, ['Authorization' => 'Bearer ' . $this->access_token])['body'], true); savecache('files_' . $path . '_page_' . $page2, $children['value'], $this->disktag, 3300); $nextlink=getcache('nextlink_' . $path . '_page_' . $page2, $this->disktag); if ($nextlink!=$children['@odata.nextLink']) { savecache('nextlink_' . $path . '_page_' . $page2, $children['@odata.nextLink'], $this->disktag, 3300); $pageinfocache['nextlink_' . $path . '_page_' . $page2] = $children['@odata.nextLink']; $pageinfocache = clearbehindvalue($path,$page2,$maxpage,$pageinfocache); $pageinfochange = 1; } $url = $children['@odata.nextLink']; } //echo $url . '
' . json_encode($children, JSON_PRETTY_PRINT) . ''; $files['children'] = $children['value']; $files['folder']['page']=$page; $pageinfocache['filenum'] = $files['folder']['childCount']; $pageinfocache['dirsize'] = $files['size']; $pageinfocache['cachesize'] = $cachefile['size']; $pageinfocache['size'] = $files['size']-$cachefile['size']; if ($pageinfochange == 1) $this->MSAPI('PUT', path_format($path.'/'.$cachefilename), json_encode($pageinfocache, JSON_PRETTY_PRINT), $this->access_token)['body']; return $files; } } } else { $files['folder']['page']=$page; for ($page4=1;$page4<=$maxpage;$page4++) { if (!($url = getcache('nextlink_' . $path . '_page_' . $page4, $this->disktag))) { if ($files['folder'][$path.'_'.$page4]!='') savecache('nextlink_' . $path . '_page_' . $page4, $files['folder'][$path.'_'.$page4], $this->disktag); } else { $files['folder'][$path.'_'.$page4] = $url; } } } return $files; } public function Rename($file, $newname) { $oldname = spurlencode($file['name']); $oldname = path_format($file['path'] . '/' . $oldname); $data = '{"name":"' . $newname . '"}'; //echo $oldname; $result = $this->MSAPI('PATCH', $oldname, $data, $this->access_token); return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']); } public function Delete($file) { $filename = spurlencode($file['name']); $filename = path_format($file['path'] . '/' . $filename); //echo $filename; $result = $this->MSAPI('DELETE', $filename, '', $this->access_token); return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']); return output($result['body'], $result['stat']); } public function Encrypt($folder, $passfilename, $pass) { $filename = path_format($folder['path'] . '/' . urlencode($passfilename)); $result = $this->MSAPI('PUT', $filename, $pass, $this->access_token); $path1 = $folder['path']; if ($path1!='/'&&substr($path1, -1)=='/') $path1 = substr($path1, 0, -1); savecache('path_' . $path1 . '/?password', '', $this->disktag, 1); return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']); return output($result['body'], $result['stat']); } public function Move($file, $folder) { $filename = spurlencode($file['name']); $filename = path_format($file['path'] . '/' . $filename); $data = '{"parentReference":{"path": "/drive/root:' . $folder['path'] . '"}}'; $result = $this->MSAPI('PATCH', $filename, $data, $this->access_token); $path2 = spurlencode($folder['path'], '/'); if ($path2!='/'&&substr($path2, -1)=='/') $path2 = substr($path2, 0, -1); savecache('path_' . $path2, json_decode('{}', true), $this->disktag, 1); return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']); return output($result['body'], $result['stat']); } public function Copy($file) { $filename = spurlencode($file['name']); $filename = path_format($file['path'] . '/' . $filename); $namearr = splitlast($file['name'], '.'); date_default_timezone_set('UTC'); if ($namearr[0]!='') { $newname = $namearr[0] . ' (' . date("Ymd\THis\Z") . ')'; if ($namearr[1]!='') $newname .= '.' . $namearr[1]; } else { $newname = '.' . $namearr[1] . ' (' . date("Ymd\THis\Z") . ')'; } $data = '{ "name": "' . $newname . '" }'; $result = $this->MSAPI('copy', $filename, $data, $this->access_token); /*$num = 0; while ($result['stat']==409 && json_decode($result['body'], true)['error']['code']=='nameAlreadyExists') { $num++; if ($namearr[0]!='') { $newname = $namearr[0] . ' (' . getconstStr('Copy') . ' ' . $num . ')'; if ($namearr[1]!='') $newname .= '.' . $namearr[1]; } else { $newname = '.' . $namearr[1] . ' ('.getconstStr('Copy'). ' ' . $num .')'; } //$newname = spurlencode($newname); $data = '{ "name": "' . $newname . '" }'; $result = $this->MSAPI('copy', $filename, $data, $this->access_token); }*/ return output(json_encode($this->files_format(json_decode($result['body'], true))), $result['stat']); return output($result['body'], $result['stat']); } public function Edit($file, $content) { /*TXT一般不会超过4M,不用二段上传 $filename = $path1 . ':/createUploadSession'; $response=MSAPI('POST',$filename,'{"item": { "@microsoft.graph.conflictBehavior": "replace" }}',$_SERVER['access_token']); $uploadurl=json_decode($response,true)['uploadUrl']; echo MSAPI('PUT',$uploadurl,$data,$_SERVER['access_token']);*/ $result = $this->MSAPI('PUT', $file['path'], $content, $this->access_token); //return output($result['body'], $result['stat']); //echo $result; $resultarry = json_decode($result['body'],true); if (isset($resultarry['error'])) return message($resultarry['error']['message']. '
' . json_encode(json_decode($tmp['body']), JSON_PRETTY_PRINT) . '', $tmp['stat']); //return message('
' . json_encode($ret, JSON_PRETTY_PRINT) . '', 500); } if (isset($_GET['install1'])) { if (get_class($this)=='Onedrive' || get_class($this)=='OnedriveCN') { return message(' ' . getconstStr('JumptoOffice') . ' ', getconstStr('Wait') . ' 1s', 201); } else { return message('Something error, retry after a few seconds.', 'Retry', 201); } } if (isset($_GET['install0'])) { if ($_POST['disktag_add']!='') { $_POST['disktag_add'] = preg_replace('/[^0-9a-zA-Z|_]/i', '', $_POST['disktag_add']); $f = substr($_POST['disktag_add'], 0, 1); if (strlen($_POST['disktag_add'])==1) $_POST['disktag_add'] .= '_'; if (isCommonEnv($_POST['disktag_add'])) { return message('Do not input ' . $envs . '