Reputation: 459
I am trying to use Google drive API to carry out simple tasks like
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
Reputation: 5694
Drive API V3 has this:
Moving files between folders
To add or remove parents for an existing file, use the
addParents
andremoveParents
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
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:
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
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
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
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
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