2013-06-20 3 views
3

가능한 한 적은 API 호출로 주어진 폴더의 하위 트리에있는 각 파일 및 폴더에 대한 기본 정보 (ID, 제목, 마임 유형)를 얻는 방법은 무엇입니까? 즉. 모든 하위 폴더의 세부 정보를 다운로드하기 위해 API를 호출하지 않습니까?Google 드라이브 PHP : 폴더의 전체 하위 트리를 나열하는 방법

일부 비 계층 적 특성 (예 : 소유자)이있는 모든 파일을 읽고 클라이언트 스크립트에서 트리 구조를 작성하는 해결 방법을 발견했습니다. 불행히도 내 파일은 한 소유자 (응용 프로그램)에서 가져온 것이므로이 방법으로는 처리 할 수 ​​없습니다.


확인, 여기에 몇 가지 사용 사례에 대한 충분한 될 수있는 재귀-여러 API를 호출 방법에 대한 예제 코드입니다. 하지만 더 나은 개념을 찾을 싶습니다 (이 구현을 논의하기 위해 아니지만, 또 다른 방법은, 어떻게 각 폴더에 대한 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

Google의 제품 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

첫째, 난 당신이 모든 파일과 폴더를 얻을 수없는 제안 . 드라이브에 파일을 많이 업로드 한 사용자에게는 너무 많은 시간이 걸립니다. 또한 응용 프로그램 키에 쿼리 제한이 있습니다. 사실 사용자 지정 파일 선택기가있는 많은 응용 프로그램은 사용자가 하위 폴더를 요청할 때마다 쿼리를 만듭니다.

두 번째로 webapp 인 경우 Google Picker을 사용하는 것이 좋습니다. Google Picker는 드라이브에서 파일을 선택하는 방법이 훨씬 빠르고 효율적입니다. 다양한 옵션과 필터가 있으며 파일을 적절하게 제어 할 수 있습니다.

셋째, 드라이브의 파일과 폴더를 트리 구조로 완전히 표현할 수 없습니다. 쿼리에서 볼 수 있듯이 각 파일에는 부모이 있습니다. 즉, 각 파일/폴더에 둘 이상의 부모가있을 수 있습니다. 각 파일에 대해 부모 중 한 명만 선택하는 것과 같은 몇 가지 해결 방법을 생각해 볼 필요가 있습니다.

성능 측면에서 모든 파일/폴더 정보를 계속 가져 오려면 최상의 구현은 Children.list()을 재귀 호출해야합니다. FYI, file id 'root'는 쉽게 시작할 수있는 예약 된 ID입니다. 그리고 일단 아이들의 이드를 얻으면, 멀티 파트로 Files.get()의 배치 쿼리를 만들 수 있습니다. 이것은 Google 드라이브 afaik의 파일 시스템을 탐색하는 가장 빠른 방법입니다.

아주 좋은 이유가없는 한, 드라이브의 모든 파일을 한 번에 탐색하지 마십시오. 드라이브에 많은 파일을 가지고있는 일부 사용자가 있습니다. 사용자가 얼마나 훌륭한 최적화를하든 영원히 기다리게 할 것입니다. 또한 쿼리 제한을 쉽게 누를 수 있습니다.

+0

재미있는 정보를 많이 준 JunYoung에게 감사드립니다! 사실 모든 파일을 조사하지 않습니다. Gdrive에 폴더가있는 CRM 엔티티입니다. 이 엔티티의 폴더에 하위 트리 만 표시해야합니다 (수십 개의 파일이 존재하지 않으며 항상 메타 데이터 만 필요합니다). 이것은 일부 컨텍스트 정보가있는 응용 프로그램 위젯이므로 G.Picker를 사용할 수 있는지 확실하지 않지만이 방법과 특히 "multipart를 사용하여 Files.get()"을 사용하여 확실히 확인합니다. 감사! – ooouuiii

관련 문제