186 lines
6.4 KiB
PHP
186 lines
6.4 KiB
PHP
<?php
|
|
|
|
namespace Lib\Google;
|
|
|
|
include_once 'lib/google/oauth2.php';
|
|
include_once 'config.php';
|
|
|
|
class GoogleDrive {
|
|
private const DRIVE_API_BASE = 'https://www.googleapis.com/drive/v3';
|
|
private GoogleOAuth2 $oauth;
|
|
|
|
// Required scopes for Drive API
|
|
private const DRIVE_SCOPES = [
|
|
'https://www.googleapis.com/auth/drive.file'
|
|
];
|
|
|
|
public function __construct(GoogleOAuth2 $oauth) {
|
|
$this->oauth = $oauth;
|
|
$this->oauth->addScopes(self::DRIVE_SCOPES);
|
|
}
|
|
|
|
/**
|
|
* List files and folders in Google Drive
|
|
* @param string|null $folderId Parent folder ID (null for root)
|
|
* @param array $options Additional query parameters
|
|
* @return array
|
|
* @throws \Exception
|
|
*/
|
|
public function listFiles(?string $folderId = null, array $options = []): array {
|
|
try {
|
|
$query = [];
|
|
|
|
if ($folderId) {
|
|
$query[] = "'{$folderId}' in parents";
|
|
} else {
|
|
$query[] = "'root' in parents";
|
|
}
|
|
|
|
// Add trashed=false to exclude deleted files
|
|
$query[] = "trashed=false";
|
|
|
|
// Handle mime type filtering through options
|
|
if (isset($options['mimeTypes'])) {
|
|
$mimeTypes = array_map(function($type) {
|
|
return "mimeType='" . $type . "'";
|
|
}, $options['mimeTypes']);
|
|
$query[] = '(' . implode(' or ', $mimeTypes) . ')';
|
|
unset($options['mimeTypes']); // Remove from options to avoid duplication in params
|
|
}
|
|
|
|
$params = array_merge([
|
|
'fields' => 'files(id, name, mimeType, size, modifiedTime, parents)',
|
|
'orderBy' => 'folder,name', // Sort folders first, then by name
|
|
'q' => implode(' and ', $query)
|
|
], $options);
|
|
|
|
$response = $this->oauth->makeAuthenticatedRequest(
|
|
self::DRIVE_API_BASE . '/files?' . http_build_query($params)
|
|
);
|
|
|
|
return $response;
|
|
} catch (\Exception $e) {
|
|
if ($this->isAuthenticationError($e)) {
|
|
throw new \Exception('Authentication required. Use getAuthorizationUrl() to start the auth flow.', 401);
|
|
}
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Download a file by its ID
|
|
* @param string $fileId
|
|
* @param string|null $mimeType Optional mime type for export (useful for Google Docs)
|
|
* @return string File content
|
|
* @throws \Exception
|
|
*/
|
|
public function downloadFile(string $fileId, ?string $mimeType = null): string {
|
|
try {
|
|
// First, get file metadata to determine if it's a Google Workspace file
|
|
$file = $this->getFile($fileId);
|
|
$isGoogleWorkspaceFile = substr($file['mimeType'], 0, 23) === 'application/vnd.google-apps';
|
|
|
|
// For Google Sheets, always use export
|
|
if ($file['mimeType'] === 'application/vnd.google-apps.spreadsheet') {
|
|
$endpoint = self::DRIVE_API_BASE . '/files/' . $fileId . '/export';
|
|
$endpoint .= '?mimeType=' . urlencode('text/csv');
|
|
|
|
return $this->oauth->makeAuthenticatedRequest(
|
|
$endpoint,
|
|
'GET',
|
|
['Accept: text/csv'],
|
|
null,
|
|
true
|
|
);
|
|
}
|
|
|
|
// For other files, use regular download
|
|
$endpoint = self::DRIVE_API_BASE . '/files/' . $fileId;
|
|
if ($isGoogleWorkspaceFile && $mimeType) {
|
|
$endpoint .= '/export';
|
|
$endpoint .= '?mimeType=' . urlencode($mimeType);
|
|
} else {
|
|
$endpoint .= '?alt=media';
|
|
}
|
|
|
|
return $this->oauth->makeAuthenticatedRequest(
|
|
$endpoint,
|
|
'GET',
|
|
['Accept: */*'],
|
|
null,
|
|
true
|
|
);
|
|
} catch (\Exception $e) {
|
|
if ($this->isAuthenticationError($e)) {
|
|
throw new \Exception('Authentication required. Use getAuthorizationUrl() to start the auth flow.', 401);
|
|
}
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get file metadata
|
|
* @param string $fileId
|
|
* @return array
|
|
* @throws \Exception
|
|
*/
|
|
public function getFile(string $fileId): array {
|
|
try {
|
|
return $this->oauth->makeAuthenticatedRequest(
|
|
self::DRIVE_API_BASE . '/files/' . $fileId . '?fields=id,name,mimeType,size,modifiedTime,parents'
|
|
);
|
|
} catch (\Exception $e) {
|
|
if ($this->isAuthenticationError($e)) {
|
|
throw new \Exception('Authentication required. Use getAuthorizationUrl() to start the auth flow.', 401);
|
|
}
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get authorization URL to start OAuth flow
|
|
* @param array $additionalParams
|
|
* @return string
|
|
*/
|
|
public function getAuthorizationUrl(array $additionalParams = []): string {
|
|
return $this->oauth->getAuthorizationUrl($additionalParams);
|
|
}
|
|
|
|
/**
|
|
* Check if the error is related to authentication
|
|
* @param \Exception $e
|
|
* @return bool
|
|
*/
|
|
private function isAuthenticationError(\Exception $e): bool {
|
|
return $e->getCode() === 401 || $e->getCode() === 403;
|
|
}
|
|
|
|
/**
|
|
* Get common MIME types for Google Workspace files
|
|
* @return array
|
|
*/
|
|
public static function getCommonExportMimeTypes(): array {
|
|
return [
|
|
'application/vnd.google-apps.spreadsheet' => [
|
|
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
'csv' => 'text/csv',
|
|
'pdf' => 'application/pdf'
|
|
],
|
|
'application/vnd.google-apps.document' => [
|
|
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
'pdf' => 'application/pdf',
|
|
'txt' => 'text/plain'
|
|
],
|
|
'application/vnd.google-apps.presentation' => [
|
|
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
'pdf' => 'application/pdf'
|
|
]
|
|
];
|
|
}
|
|
}
|
|
|
|
// Initialize the service
|
|
// $oauth = new GoogleOAuth2($clientId, $clientSecret, $redirectUri);
|
|
// $drive = new GoogleDrive($oauth);
|
|
|