2013-06-20 38 views
3

如何獲得給定文件夾子樹中每個文件和文件夾的基本信息(ID,標題,MIME類型至少)儘可能少的API調用?即。不要調用API來下載每個子文件夾的詳細信息?谷歌驅動器PHP的:如何列出文件夾的完整子樹

我找到了解決方法來讀取所有具有某些非分層特徵(例如,所有者)的文件並在客戶端腳本中構建樹結構。我的文件不幸全部來自一個所有者(應用程序),所以我不能這樣做。


好的,下面是recursion-multiple-api-calls方法的示例代碼,對於某些用例來說,這可能足夠了。不過,我想找到更好的概念(不討論這個實現,而是另闢蹊徑,如何不叫每個文件夾的API):

class Foo { 

const FOLDER_MIME_TYPE = 'application/vnd.google-apps.folder'; 


public function getSubtreeForFolder($parentId, $sort=true) 
{ 
    $service = $this->createCrmGService(); 

    // A. folder info 
    $file = $service->files->get($parentId); 
    $ret = array(
     'id' => $parentId, 
     'name' => $file->getTitle(), 
     'description' => $file->getDescription(), 
     'mimetype' => $file->getMimeType(), 
     'is_folder' => true, 
     'children' => array(), 
     'node' => $file, 
    ); 

    if ($ret['mimetype'] != self::FOLDER_MIME_TYPE) { 
     throw new Exception(_t("{$ret['name']} is not a folder.")); 
    } 

    $items = $this->findAllFiles($queryString='trashed = false', $parentId, $fieldsFilter='items(alternateLink,description,fileSize,id,mimeType,title)', $service); 

    foreach ($items as $child) 
    { 
     if ($this->isFolder($child)) 
     { 
      $ret['children'][] = $this->getSubtreeForFolder($child->id, $sort); 
     } 

     else 
     { 
      // B. file info 
      $a['id'] = $child->id; 
      $a['name'] = $child->title; 
      $a['description'] = $child->description; 
      $a['is_folder'] = false; 
      $a['url'] = $file->getDownloadUrl(); 
      $a['url_detail'] = $child->getAlternateLink(); 
      $a['versionLabel'] = false; //FIXME 
      $a['node'] = $child; 

      if (!$a['versionLabel']) { 
       $a['versionLabel'] = '1.0'; //old files compatibility hack 
      } 
      $ret['children'][] = $a; 
     } 
    } 

    if ($sort && isset($ret['children'])) 
    { 
     if ($sort === true) { 
      $sort = create_function('$a, $b', 'if ($a[\'name\'] == $b[\'name\']) return 0; return strcasecmp($a[\'name\'], $b[\'name\']);'); 
     } 
     usort($ret['children'], $sort); 
    } 

    return $ret; 
} 


public function findAllFiles($queryString, $parentId=false, $fieldsFilter='items(id,title)', $service = false) 
{ 
    if (!$service) $service = $this->createCrmGService(); 

    $result = array(); 
    $pageToken = NULL; 

    if ($parentId) { 
     $queryString .= ($queryString ? ' AND ' : '') . "'{$parentId}' in parents"; 
    } 

    do { 
     try { 

      $parameters = array('q' => $queryString); 

      if ($fieldsFilter) $parameters['fields'] = $fieldsFilter; 

      if ($pageToken) { 
       $parameters['pageToken'] = $pageToken; 
      } 

      $files = $service->files->listFiles($parameters); 

      $result = array_merge($result, $files->getItems()); 

      $pageToken = $files->getNextPageToken(); 

     } catch (Exception $e) { 
      print "An error occurred: " . $e->getMessage(); 
      $pageToken = NULL; 
     } 
    } while ($pageToken); 

    return $result; 
} 


    /** 
    * @param Google_DriveFile $file 
    * @return boolean, jestli je $file slozka. 
    */ 
    protected function isFolder($file) 
    { 
     return $file->getMimeType() == self::FOLDER_MIME_TYPE; 
    } 

} 
+0

谷歌的產品API一般都有非常好的文檔。從此處開始:https://developers.google.com/drive/quickstart-php和https://developers.google.com/drive/v1/reference/files/get。 – DontVoteMeDown

+0

謝謝,但我真的閱讀這個文檔,並提出這個問題,因爲我還沒有找到解決方案。我錯過了什麼嗎? – ooouuiii

+0

我這麼認爲。查看這個參考頁面:https://developers.google.com/drive/v2/reference/files/list,它顯示瞭如何從文件列表中獲得響應(完整):https://developers.google。 com/drive/v2/reference/files#resource – DontVoteMeDown

回答

0

首先,我建議你不要讓所有的文件和文件夾。某些用戶在其雲端硬盤上上傳文件需要花費太多時間。此外,您的應用程序密鑰中有查詢限制。實際上,許多具有自定義文件選擇器的應用程序在每次用戶請求子文件夾時都會進行查詢。

其次,如果這是web應用程序,最好使用Google Picker。 Google Picker可以更快更高效地從雲端硬盤中挑選文件。有很多選項和過濾器,並且你可以很好地控制文件。

第三,您無法在樹狀結構中完整表示雲端硬盤的文件和文件夾。正如您在查詢中看到的,每個文件都有父母,這意味着每個文件/文件夾可以有多個父代。您需要考慮一些解決方法,比如只爲每個文件選擇一個父項。

如果您仍想獲取所有文件/文件夾信息,則在性能方面,最佳實施將遞歸調用Children.list()。僅供參考,文件ID'root'是保留的ID,您可以輕鬆入門。一旦你得到了孩子的ID,你可以批量查詢Files.get()多部分。這是遍歷Google Drive afaik文件系統的最快方式。

再說一遍,除非你有很好的理由,否則請不要嘗試一次遍歷Drive中的所有文件。有些用戶在其雲端硬盤中有很多文件,無論您的優化程度如何,都會讓他們永遠等待。此外,您將輕鬆達到查詢限制。

+0

感謝JunYoung提供了許多有趣的信息!我其實並沒有遍歷所有文件。它是Gdrive中的文件夾的CRM實體。我只需要顯示該實體文件夾的子樹(從未有多於幾十個文件,而且我總是隻需要它們的元數據)。因爲這是一個帶有一些上下文信息的應用程序小部件,我不確定我是否可以使用G.Picker,但我絕對檢查了這一點,特別是用「帶有多部分的Files.get()」的方式。謝謝! – ooouuiii

相關問題