2013-06-20 36 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

相关问题