NitinJ
NitinJ

Reputation: 459

How to move files and folders using google drive API?

I am trying to use Google drive API to carry out simple tasks like

  1. Moving files across folders.
  2. List item

Moving folders.

As far as I could find Google drive API does not provide a way to move files across folders.

With /parent and /children API parent folder of a file can be specified but it does not work for a folder. Moreover the parent attribute associated with a file does not move it under that folder. It just associates a parent attribute with the file(which is not at all useful for my case)

Upvotes: 29

Views: 38847

Answers (6)

intotecho
intotecho

Reputation: 5694

Drive API V3 has this:

Moving files between folders

To add or remove parents for an existing file, use the addParents and removeParents query parameters on the files.update method.

Both parameters may be used to move a file from one folder to another: https://developers.google.com/drive/v3/web/folder#inserting_a_file_in_a_folder

Upvotes: 40

Francisco Luz
Francisco Luz

Reputation: 2943

This sample code uses Google Drive API v3.

Gfk = Google File Key ( can be the id of either a file or a folder ).

Methods:

  • moveTo | Moves a file/folder from its first parent folder to a given destination folder. The file/folder gets removed from its original first parent folder;
  • addParents and removeParents | Only adds or removes one or move parents. addParents does NOT remove any original parent, only adds.
class Gfiles {
    private $service;

    public function setService(\Google_Client $client) : self {
        $this->service = (new \Google_Service_Drive($client))->files;
        return $this;
    }

    public function moveTo(string $gfk, string $to_gfk) : \Google_Service_Drive_DriveFile {
        $body = new \Google_Service_Drive_DriveFile();
        // Gets the first parent. You should further implement this if you wish a different behaviour.
        $from_gfk = $this->service->get($gfk, ['fields' => 'parents'])->parents[0];

        $this->service->update($gfk, $body, ['addParents' => $to_gfk]);
        $this->service->update($gfk, $body, ['removeParents' => $from_gfk]);
        return $this->service->get($gfk, ['fields' => 'parents']);
    }

    /**
     * $parents_gfk expects an array like ['gfk parent 1', 'gfk parent 2'].
     */
    private function updateParents(string $method, string $gfk, array $parents_gfk) : \Google_Service_Drive_DriveFile {
        $body = new \Google_Service_Drive_DriveFile();
        $parents = join(',', $parents_gfk);

        $this->service->update($gfk, $body, [$method => $parents]);
        return $this->service->get($gfk, ['fields' => 'parents']);
    }

    public function addParents(string $gfk, array $parents_gfk) : \Google_Service_Drive_DriveFile {
        return $this->updateParents('addParents', $gfk, $parents_gfk);
    }

    public function removeParents(string $gfk, array $parents_gfk) : \Google_Service_Drive_DriveFile {
        return $this->updateParents('removeParents', $gfk, $parents_gfk);
    }
}

Upvotes: 2

pinoyyid
pinoyyid

Reputation: 22316

To move FILE-A from FOLDER-1 to FOLDER-2, you can use the delete and add calls at https://developers.google.com/drive/v2/reference/parents to remove FOLDER-1 as a parent and add FOLDER-2.

You can also do a Patch on the file with the updated parents array.

Upvotes: 12

Hafez Divandari
Hafez Divandari

Reputation: 9069

Here is the one step method to move file to the new folder using Patch and the PHP client library:

/**
 * Move a file.
 *
 * @param Google_Service_Drive_DriveFile $service Drive API service instance.
 * @param string $fileId ID of the file to move.
 * @param string $newParentId Id of the folder to move to.
 * @return Google_Service_Drive_DriveFile The updated file. NULL is returned if an API error occurred.
 */
function moveFile($service, $fileId, $newParentId) {
  try {
    $file = new Google_Service_Drive_DriveFile();

    $parent = new Google_Service_Drive_ParentReference();
    $parent->setId($newParentId);

    $file->setParents(array($parent));

    $updatedFile = $service->files->patch($fileId, $file);

    return $updatedFile;
  } catch (Exception $e) {
    print "An error occurred: " . $e->getMessage();
  }
}

Update: If you want to use Drive API v3, use below code documented here:

/**
 * Move a file.
 *
 * @param Google_Service_Drive_DriveFile $service Drive API service instance.
 * @param string $fileId ID of the file to move.
 * @param string $newParentId Id of the folder to move to.
 * @return Google_Service_Drive_DriveFile The updated file. NULL is returned if an API error occurred.
 */
function moveFile($service, $fileId, $newParentId) {
  try {

    $emptyFileMetadata = new Google_Service_Drive_DriveFile();
    // Retrieve the existing parents to remove
    $file = $service->files->get($fileId, array('fields' => 'parents'));
    $previousParents = join(',', $file->parents);
    // Move the file to the new folder
    $file = $service->files->update($fileId, $emptyFileMetadata, array(
      'addParents' => $newParentId,
      'removeParents' => $previousParents,
      'fields' => 'id, parents'));

    return $file;
  } catch (Exception $e) {
    print "An error occurred: " . $e->getMessage();
  }
}

Upvotes: 5

Christopher Robot
Christopher Robot

Reputation: 311

You can actually still do it in one step really just set the request as so in Javascript:

Body must have:

body.parents = [{ 'id': parentId }];

Request should be:

var request = gapi.client.request({
  'path': 'drive/v2/files/'+fileId,
  'method': 'PUT',
  'params': {'uploadType': 'multipart', 'alt': 'json'}, 
  'headers': { 
    'Authorization': TOKEN
  },
  'body': body
});

And then to execute:

request.execute(function(resp) { });

Upvotes: 4

Alex
Alex

Reputation: 673

I have used this code:

        File file =  driveService.files().get(fileId).execute()
        File targetFolder = driveService.files().get(folderId).execute()
        ParentReference newParent = new ParentReference()
        newParent.setSelfLink(targetFolder.getSelfLink())
        newParent.setParentLink(targetFolder.parents[0].getSelfLink())
        newParent.setId(folderId)
        newParent.setKind(targetFolder.getKind())
        newParent.setIsRoot(false)
        def parentsList = new ArrayList<ParentReference>()
        parentsList.add(newParent)
        file.setParents(parentsList)
        File updatedFile = driveService.files().update(fileId, file).execute()

Upvotes: 0

Related Questions