final stage
This commit is contained in:
@@ -45,6 +45,11 @@ class StorageRepositoryService
|
||||
if (empty($config['client_id']) || empty($config['client_secret']) || empty($config['refresh_token'])) {
|
||||
return ['success' => false, 'message' => 'Configurazione incompleta: client_id, client_secret e refresh_token sono necessari per Google Drive.'];
|
||||
}
|
||||
|
||||
$apiError = $this->checkGoogleDriveApiStatus($config);
|
||||
if ($apiError) {
|
||||
return ['success' => false, 'message' => $apiError];
|
||||
}
|
||||
}
|
||||
|
||||
$filesystem = $this->buildFilesystem($repo);
|
||||
@@ -61,6 +66,42 @@ class StorageRepositoryService
|
||||
}
|
||||
}
|
||||
|
||||
private function checkGoogleDriveApiStatus(array $config): ?string
|
||||
{
|
||||
try {
|
||||
$client = new \Google_Client();
|
||||
$client->setClientId($config['client_id']);
|
||||
$client->setClientSecret($config['client_secret']);
|
||||
$client->addScope(\Google_Service_Drive::DRIVE);
|
||||
$token = $client->refreshToken($config['refresh_token']);
|
||||
$client->setAccessToken($token);
|
||||
|
||||
$service = new \Google_Service_Drive($client);
|
||||
|
||||
$rootId = $config['root_folder_id'] ?? 'root';
|
||||
$service->files->get($rootId, ['fields' => 'id']);
|
||||
|
||||
return null;
|
||||
} catch (\Google\Service\Exception $e) {
|
||||
$errors = $e->getErrors();
|
||||
$reason = $errors[0]['reason'] ?? '';
|
||||
$message = $errors[0]['message'] ?? $e->getMessage();
|
||||
|
||||
if ($reason === 'accessNotConfigured' || str_contains($message, 'Drive API has not been used')) {
|
||||
$projectNumber = explode('-', $config['client_id'] ?? '')[0] ?? '';
|
||||
return 'Google Drive API non abilitata. Vai su https://console.developers.google.com/apis/api/drive.googleapis.com/overview?project=' . $projectNumber . ' e clicca "Enable".';
|
||||
}
|
||||
|
||||
if ($e->getCode() === 404) {
|
||||
return 'Cartella root non trovata (ID: ' . ($config['root_folder_id'] ?? 'root') . '). Verifica che il folder ID sia corretto.';
|
||||
}
|
||||
|
||||
return 'Errore API Google Drive: ' . $message;
|
||||
} catch (\Exception $e) {
|
||||
return 'Errore di connessione Google Drive: ' . $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public function listContents(StorageRepository $repo, string $path = '/'): array
|
||||
{
|
||||
try {
|
||||
@@ -198,4 +239,126 @@ class StorageRepositoryService
|
||||
|
||||
return new Filesystem($adapter);
|
||||
}
|
||||
|
||||
public function readGoogleDriveFile(StorageRepository $repo, string $normalizedPath, string $basename): array
|
||||
{
|
||||
$config = $repo->getDecryptedConfig();
|
||||
|
||||
$client = new \Google_Client();
|
||||
$client->setClientId($config['client_id']);
|
||||
$client->setClientSecret($config['client_secret']);
|
||||
$client->addScope(\Google_Service_Drive::DRIVE);
|
||||
$token = $client->refreshToken($config['refresh_token']);
|
||||
$client->setAccessToken($token);
|
||||
|
||||
$service = new \Google_Service_Drive($client);
|
||||
$rootFolderId = $config['root_folder_id'] ?? 'root';
|
||||
|
||||
$fileId = $this->findGoogleDriveFileId($service, $rootFolderId, $normalizedPath);
|
||||
$file = $service->files->get($fileId, ['fields' => 'id,name,mimeType,size']);
|
||||
|
||||
$mimeType = $file->getMimeType();
|
||||
|
||||
if ($mimeType && str_starts_with($mimeType, 'application/vnd.google-apps.')) {
|
||||
return $this->exportGoogleDriveDoc($service, $fileId, $mimeType, $basename);
|
||||
}
|
||||
|
||||
$response = $service->files->get($fileId, ['alt' => 'media']);
|
||||
$body = $response->getBody();
|
||||
$stream = $body instanceof \Psr\Http\Message\StreamInterface ? $body->detach() : null;
|
||||
|
||||
if (!$stream) {
|
||||
$stream = fopen('php://temp', 'r+');
|
||||
fwrite($stream, (string) $body);
|
||||
rewind($stream);
|
||||
}
|
||||
|
||||
$fileSize = $file->getSize();
|
||||
|
||||
return [
|
||||
'stream' => $stream,
|
||||
'mimeType' => $mimeType,
|
||||
'basename' => $basename,
|
||||
'fileSize' => $fileSize !== null ? (int) $fileSize : null,
|
||||
];
|
||||
}
|
||||
|
||||
private function exportGoogleDriveDoc(\Google_Service_Drive $service, string $fileId, string $googleMimeType, string $originalBasename): array
|
||||
{
|
||||
$exportMap = [
|
||||
'application/vnd.google-apps.document' => [
|
||||
'mime' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
'ext' => 'docx',
|
||||
],
|
||||
'application/vnd.google-apps.spreadsheet' => [
|
||||
'mime' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
'ext' => 'xlsx',
|
||||
],
|
||||
'application/vnd.google-apps.presentation' => [
|
||||
'mime' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||
'ext' => 'pptx',
|
||||
],
|
||||
'application/vnd.google-apps.drawing' => [
|
||||
'mime' => 'image/png',
|
||||
'ext' => 'png',
|
||||
],
|
||||
];
|
||||
|
||||
$format = $exportMap[$googleMimeType] ?? ['mime' => 'application/pdf', 'ext' => 'pdf'];
|
||||
|
||||
$response = $service->files->export($fileId, $format['mime'], ['alt' => 'media']);
|
||||
$body = $response->getBody();
|
||||
$stream = $body instanceof \Psr\Http\Message\StreamInterface ? $body->detach() : null;
|
||||
|
||||
if (!$stream) {
|
||||
$stream = fopen('php://temp', 'r+');
|
||||
fwrite($stream, (string) $body);
|
||||
rewind($stream);
|
||||
}
|
||||
|
||||
$nameWithoutExt = pathinfo($originalBasename, PATHINFO_FILENAME);
|
||||
$newBasename = $nameWithoutExt . '.' . $format['ext'];
|
||||
|
||||
Log::info("StorageRepository: exported Google Drive file {$fileId} from {$googleMimeType} to {$format['mime']} as {$newBasename}");
|
||||
|
||||
return [
|
||||
'stream' => $stream,
|
||||
'mimeType' => $format['mime'],
|
||||
'basename' => $newBasename,
|
||||
'fileSize' => null,
|
||||
];
|
||||
}
|
||||
|
||||
private function findGoogleDriveFileId(\Google_Service_Drive $service, string $rootFolderId, string $path): string
|
||||
{
|
||||
$path = trim($path, '/');
|
||||
if ($path === '') {
|
||||
return $rootFolderId;
|
||||
}
|
||||
|
||||
$parts = explode('/', $path);
|
||||
$currentParentId = $rootFolderId;
|
||||
|
||||
foreach ($parts as $name) {
|
||||
$optParams = [
|
||||
'q' => sprintf("trashed = false and '%s' in parents and name = '%s'",
|
||||
str_replace("'", "\\'", $currentParentId),
|
||||
str_replace("'", "\\'", $name)
|
||||
),
|
||||
'fields' => 'files(id, name, mimeType)',
|
||||
'pageSize' => 1,
|
||||
];
|
||||
|
||||
$results = $service->files->listFiles($optParams);
|
||||
$files = $results->getFiles();
|
||||
|
||||
if (empty($files)) {
|
||||
throw new \RuntimeException("Elemento non trovato su Google Drive: {$name} (path: {$path})");
|
||||
}
|
||||
|
||||
$currentParentId = $files[0]->getId();
|
||||
}
|
||||
|
||||
return $currentParentId;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user