1: <?php
2: /**
3: * This code is licensed under AGPLv3 license or Afterlogic Software License
4: * if commercial version of the product was purchased.
5: * For full statements of the licenses see LICENSE-AFTERLOGIC and LICENSE-AGPL3 files.
6: */
7:
8: namespace Aurora\Modules\GoogleDrive;
9:
10: use GuzzleHttp\Psr7\Request;
11:
12: /**
13: * Adds ability to work with Google Drive file storage inside Aurora Files module.
14: *
15: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
16: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
17: * @copyright Copyright (c) 2023, Afterlogic Corp.
18: *
19: * @property Settings $oModuleSettings
20: *
21: * @package Modules
22: */
23: class Module extends \Aurora\System\Module\AbstractModule
24: {
25: protected static $sStorageType = 'google';
26: protected static $iStorageOrder = 200;
27:
28: protected $oClient = null;
29:
30: protected $oService = null;
31:
32: protected $aRequireModules = array(
33: 'Files',
34: 'OAuthIntegratorWebclient',
35: 'GoogleAuthWebclient'
36: );
37:
38: /**
39: * @return Module
40: */
41: public static function getInstance()
42: {
43: return parent::getInstance();
44: }
45:
46: /**
47: * @return Module
48: */
49: public static function Decorator()
50: {
51: return parent::Decorator();
52: }
53:
54: /**
55: * @return Settings
56: */
57: public function getModuleSettings()
58: {
59: return $this->oModuleSettings;
60: }
61:
62: protected function issetScope($sScope)
63: {
64: return \in_array($sScope, \explode(' ', $this->oModuleSettings->Scopes));
65: }
66:
67: public function init()
68: {
69: $this->AddEntries(
70: [
71: 'google-drive-thumb' => 'EntryThumbnail'
72: ]
73: );
74:
75: $this->subscribeEvent('GoogleAuthWebclient::PopulateScopes', array($this, 'onPopulateScopes'));
76: $this->subscribeEvent('Files::GetStorages::after', array($this, 'onAfterGetStorages'));
77: $this->subscribeEvent('Files::GetFile', array($this, 'onGetFile'));
78: $this->subscribeEvent('Files::GetItems', array($this, 'onGetItems'));
79: $this->subscribeEvent('Files::GetFileInfo::after', array($this, 'onAfterGetFileInfo'));
80: $this->subscribeEvent('Files::GetFile::after', array($this, 'onAfterGetFile'));
81: $this->subscribeEvent('Files::CreateFolder::after', array($this, 'onAfterCreateFolder'));
82: $this->subscribeEvent('Files::CreateFile', array($this, 'onCreateFile'));
83: $this->subscribeEvent('Files::CreatePublicLink::after', array($this, 'onAfterCreatePublicLink'));
84: $this->subscribeEvent('Files::DeletePublicLink::after', array($this, 'onAfterDeletePublicLink'));
85: $this->subscribeEvent('Files::Delete::after', array($this, 'onAfterDelete'));
86: $this->subscribeEvent('Files::Rename::after', array($this, 'onAfterRename'));
87: $this->subscribeEvent('Files::Move::after', array($this, 'onAfterMove'));
88: $this->subscribeEvent('Files::Copy::after', array($this, 'onAfterCopy'));
89: $this->subscribeEvent('Files::CheckUrl', array($this, 'onAfterCheckUrl'));
90: $this->subscribeEvent('Files::PopulateFileItem::after', array($this, 'onAfterPopulateFileItem'));
91:
92: $this->subscribeEvent('Google::GetSettings', array($this, 'onGetSettings'));
93: $this->subscribeEvent('Google::UpdateSettings::after', array($this, 'onAfterUpdateSettings'));
94:
95: $this->subscribeEvent('Files::GetItems::before', array($this, 'onCheckUrlFile'));
96: $this->subscribeEvent('Files::UploadFile::before', array($this, 'onCheckUrlFile'));
97: $this->subscribeEvent('Files::CreateFolder::before', array($this, 'onCheckUrlFile'));
98:
99: $this->subscribeEvent('Files::CheckQuota::after', array($this, 'onAfterCheckQuota'));
100: $this->subscribeEvent('Files::GetQuota::after', array($this, 'onAfterGetQuota'));
101: }
102:
103: public function onPopulateScopes($sScope, &$aResult)
104: {
105: $aScopes = \explode('|', $sScope);
106: foreach ($aScopes as $sScope) {
107: if ($sScope === 'storage') {
108: $aResult[] = 'https://www.googleapis.com/auth/drive';
109: }
110: }
111: }
112:
113: public function onAfterGetStorages($aArgs, &$mResult)
114: {
115: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
116:
117: if ($this->checkIfModuleConfigured()) {
118: $mResult[] = [
119: 'Type' => self::$sStorageType,
120: 'IsExternal' => true,
121: 'DisplayName' => 'Google Drive',
122: 'Order' => self::$iStorageOrder,
123: ];
124: }
125: }
126:
127: protected function GetClient()
128: {
129: if (!isset($this->oClient)) {
130: if (class_exists('Aurora\Modules\Google\Module')) {
131: $oGoogleModule = \Aurora\Modules\Google\Module::getInstance();
132: if (!$oGoogleModule->oModuleSettings->EnableModule || !$this->issetScope('storage')) {
133: return false;
134: }
135: } else {
136: return false;
137: }
138:
139: $oOAuthIntegratorWebclientModule = \Aurora\Modules\OAuthIntegratorWebclient\Module::Decorator();
140: $oSocialAccount = $oOAuthIntegratorWebclientModule->GetAccount(self::$sStorageType);
141: if ($oSocialAccount) {
142: $oGoogleModule = \Aurora\Modules\Google\Module::getInstance();
143: if ($oGoogleModule) {
144: $oClient = new \Google\Client();
145: $oClient->setClientId($oGoogleModule->oModuleSettings->Id);
146: $oClient->setClientSecret($oGoogleModule->oModuleSettings->Secret);
147: $oClient->addScope([
148: 'https://www.googleapis.com/auth/userinfo.email',
149: 'https://www.googleapis.com/auth/userinfo.profile',
150: 'https://www.googleapis.com/auth/drive'
151: ]);
152: $bRefreshToken = false;
153: try {
154: $oClient->setAccessToken($oSocialAccount->AccessToken);
155: } catch (\Exception $oException) {
156: $bRefreshToken = true;
157: }
158: if ($oClient->isAccessTokenExpired() || $bRefreshToken) {
159: $oClient->refreshToken($oSocialAccount->RefreshToken);
160: $oSocialAccount->AccessToken = $oClient->getAccessToken();
161: $oOAuthIntegratorWebclientModule->UpdateAccount($oSocialAccount);
162: }
163: if ($oClient->getAccessToken()) {
164: $this->oClient = $oClient;
165: }
166: }
167: }
168: }
169:
170: return $this->oClient;
171: }
172:
173: protected function GetDriveService()
174: {
175: if (!$this->checkIfModuleConfigured()) {
176: return false;
177: }
178:
179: if (!isset($this->oService)) {
180: $oClient = $this->GetClient();
181: if ($oClient) {
182: $this->oService = new \Google\Service\Drive($oClient);
183: }
184: }
185:
186: return $this->oService;
187: }
188:
189: protected function _dirname($sPath)
190: {
191: $sPath = \dirname($sPath);
192: return \str_replace(DIRECTORY_SEPARATOR, '/', $sPath);
193: }
194:
195: protected function _basename($sPath)
196: {
197: $aPath = \explode('/', $sPath);
198: return \end($aPath);
199: }
200:
201: /**
202: * @param string $sType
203: * @param string $sPath
204: * @param \Google\Service\Drive\DriveFile $oFile
205: */
206: protected function PopulateFileInfo($sType, $sPath, $oFile)
207: {
208: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
209:
210: $mResult = false;
211: if ($oFile) {
212: if (isset($oFile->shortcutDetails)) {
213: $oFile->mimeType = $oFile->shortcutDetails['targetMimeType'];
214: $oFile->id = $oFile->shortcutDetails['targetId'];
215: }
216:
217: $this->PopulateGoogleDriveFileInfo($oFile);
218:
219: $mResult /*@var $mResult \Aurora\Modules\Files\Classes\FileItem */ = new \Aurora\Modules\Files\Classes\FileItem();
220: $mResult->IsExternal = true;
221: $mResult->TypeStr = $sType;
222: $mResult->IsFolder = ($oFile->mimeType === "application/vnd.google-apps.folder");
223: $mResult->Id = $oFile->id;
224: $mResult->Name = $oFile->name;
225: $mResult->Path = '';
226: $mResult->Size = $oFile->size;
227: $mResult->FullPath = $oFile->id;
228: $mResult->ContentType = $oFile->mimeType;
229: if (isset($oFile->thumbnailLink)) {
230: $mResult->Thumb = true;
231: $mResult->ThumbnailUrl = '?google-drive-thumb/' . \Aurora\System\Utils::UrlSafeBase64Encode($oFile->thumbnailLink);
232: }
233:
234: if ($mResult->IsFolder) {
235: $mResult->AddAction([
236: 'list' => []
237: ]);
238: } else {
239: $mResult->AddAction([
240: 'view' => [
241: 'url' => '?download-file/' . $this->getItemHash($mResult) . '/view'
242: ]
243: ]);
244: $mResult->AddAction([
245: 'download' => [
246: 'url' => '?download-file/' . $this->getItemHash($mResult)
247: ]
248: ]);
249: }
250:
251: // $oItem->Owner = $oSocial->Name;
252: $mResult->LastModified = \date_timestamp_get(date_create($oFile->createdTime));
253: }
254:
255: return $mResult;
256: }
257:
258: protected function _getFileInfo($sName)
259: {
260: $mResult = false;
261: $oService = $this->GetDriveService();
262: if ($oService) {
263: $mResult = $oService->files->get($sName);
264: }
265:
266: return $mResult;
267: }
268:
269: /**
270: *
271: * @param \Aurora\Modules\Files\Classes\FileItem $oItem
272: * @return string
273: */
274: protected function getItemHash($oItem)
275: {
276: return \Aurora\System\Api::EncodeKeyValues(array(
277: 'UserId' => \Aurora\System\Api::getAuthenticatedUserId(),
278: 'Type' => $oItem->TypeStr,
279: 'Path' => '',
280: 'Name' => $oItem->FullPath,
281: 'FileName' => $oItem->Name
282: ));
283: }
284:
285: /**
286: * @param array $aArgs
287: * @param mixed $mResult
288: */
289: public function onAfterGetFileInfo($aArgs, &$mResult)
290: {
291: if ($aArgs['Type'] === self::$sStorageType) {
292: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
293: $oFileInfo = $this->_getFileInfo($aArgs['Id']);
294: if ($oFileInfo) {
295: $mResult = $this->PopulateFileInfo($aArgs['Type'], $aArgs['Path'], $oFileInfo);
296: return true;
297: }
298: }
299: }
300:
301: /**
302: */
303: public function onGetFile($aArgs, &$Result)
304: {
305: if ($aArgs['Type'] === self::$sStorageType) {
306: $oService = $this->GetDriveService();
307: if ($oService) {
308: $oFile = $oService->files->get($aArgs['Id']);
309:
310: $sMimeType = $this->getMimeTypeForExport($oFile);
311: $aArgs['Name'] = $oFile->name;
312:
313: if (empty($sMimeType)) {
314: $sFileData = $oService->files->get($aArgs['Id'], ['alt' => 'media']);
315: } else {
316: $sFileData = $oService->files->export($aArgs['Id'], $sMimeType, [
317: 'alt' => 'media'
318: ]);
319: }
320:
321: $Result = \fopen('php://memory', 'r+');
322: \fwrite($Result, $sFileData->getBody());
323: \rewind($Result);
324:
325: return true;
326: }
327: }
328: }
329:
330: public function onCheckUrlFile(&$aArgs, &$mResult)
331: {
332: if ($this->checkIfModuleConfigured() && (\pathinfo($aArgs['Path'], PATHINFO_EXTENSION) === 'url' || strpos($aArgs['Path'], '.url/'))) {
333: list($sUrl, $sId) = explode('.url', $aArgs['Path']);
334: $sUrl .= '.url';
335: $aArgs['Path'] = $sUrl;
336: $this->prepareArgs($aArgs);
337: if ($sId && $aArgs['Type'] === self::$sStorageType) {
338: $aArgs['Path'] = basename($sId);
339: } elseif ($aArgs['Type'] !== self::$sStorageType) {
340: $aArgs['Path'] = $sUrl . $sId;
341: }
342: }
343: }
344:
345: /**
346: * @param array $aArgs
347: * @param mixed $mResult
348: */
349: public function onGetItems($aArgs, &$mResult)
350: {
351: if ($aArgs['Type'] === self::$sStorageType) {
352: $mResult = [];
353: $oService = $this->GetDriveService();
354: if ($oService) {
355: $sPath = \ltrim(\basename($aArgs['Path']), '/');
356:
357: $aFileItems = [];
358: $sPageToken = null;
359:
360: if (empty($sPath)) {
361: $sPath = 'root';
362: }
363:
364: $sQuery = "'" . $sPath . "' in parents and trashed = false";
365: if (!empty($aArgs['Pattern'])) {
366: $sQuery .= " and name contains '" . $aArgs['Pattern'] . "'";
367: }
368:
369: do {
370: try {
371: $aParameters = [
372: 'q' => $sQuery,
373: 'fields' => '*',
374: 'orderBy' => 'name'
375: ];
376: if ($sPageToken) {
377: $aParameters['pageToken'] = $sPageToken;
378: }
379:
380: $oFiles = $oService->files->listFiles($aParameters);
381: $aFileItems = \array_merge($aFileItems, $oFiles->getFiles());
382: $sPageToken = $oFiles->getNextPageToken();
383: } catch (\Exception $e) {
384: $sPageToken = null;
385: }
386: } while ($sPageToken);
387:
388: foreach ($aFileItems as $oChild) {
389: $oItem /*@var $oItem \Aurora\Modules\Files\Classes\FileItem */ = $this->PopulateFileInfo($aArgs['Type'], $aArgs['Path'], $oChild);
390: if ($oItem) {
391: $mResult[] = $oItem;
392: }
393: }
394:
395: if (isset($aArgs['PathRequired']) && $aArgs['PathRequired'] === true) {
396: $mResult['Path'] = array();
397: if ($sPath !== 'root') {
398: $oPathInfo = $oService->files->get($sPath);
399: $mResult['Path'][] = $this->PopulateFileInfo($aArgs['Type'], $aArgs['Path'], $oPathInfo);
400: while (true) {
401: $aParrents = $oService->parents->listParents($sPath);
402: if ($aParrents == null || count($aParrents) == 0) {
403: break;
404: }
405: $oParrent = $aParrents[0];
406: $sPath = $oParrent->id;
407: if (!$oParrent->isRoot) {
408: $oItem = $oService->files->get($sPath);
409: if ($oItem) {
410: $mResult['Path'][] = $this->PopulateFileInfo($aArgs['Type'], $aArgs['Path'], $oItem);
411: }
412: }
413: }
414: }
415: }
416: }
417:
418: return true;
419: }
420: }
421:
422: protected function prepareArgs(&$aData)
423: {
424: $aPathInfo = \pathinfo($aData['Path']);
425: $sExtension = isset($aPathInfo['extension']) ? $aPathInfo['extension'] : '';
426: if ($sExtension === 'url') {
427: $aArgs = array(
428: 'UserId' => $aData['UserId'],
429: 'Type' => $aData['Type'],
430: 'Path' => $aPathInfo['dirname'],
431: 'Name' => $aPathInfo['basename'],
432: 'Id' => $aPathInfo['basename'],
433: 'IsThumb' => false
434: );
435: $mResult = false;
436: \Aurora\System\Api::GetModuleManager()->broadcastEvent(
437: 'Files',
438: 'GetFile',
439: $aArgs,
440: $mResult
441: );
442: if (\is_resource($mResult)) {
443: $aUrlFileInfo = \Aurora\System\Utils::parseIniString(\stream_get_contents($mResult));
444: if ($aUrlFileInfo && isset($aUrlFileInfo['URL'])) {
445: if ((false !== \strpos($aUrlFileInfo['URL'], 'drive.google.com'))) {
446: $aData['Type'] = 'google';
447: $aData['Path'] = $this->GetIdByLink($aUrlFileInfo['URL']);
448: }
449: }
450: }
451: }
452: }
453:
454: /**
455: * @param array $aArgs
456: * @param mixed $mResult
457: */
458: public function onAfterCreateFolder(&$aArgs, &$mResult)
459: {
460: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
461:
462: if ($aArgs['Type'] === self::$sStorageType) {
463: $oService = $this->GetDriveService();
464: if ($oService) {
465: $folder = new \Google\Service\Drive\DriveFile();
466: $folder->setName($aArgs['FolderName']);
467: $folder->setMimeType('application/vnd.google-apps.folder');
468:
469: // Set the parent folder.
470: if ($aArgs['Path'] != null) {
471: $folder->setParents(array($aArgs['Path']));
472: }
473:
474: try {
475: $oService->files->create($folder, array());
476: $mResult = true;
477: } catch (\Exception $ex) {
478: $mResult = false;
479: }
480: }
481: }
482: }
483:
484: /**
485: * @param array $aArgs
486: * @param mixed $mResult
487: */
488: public function onCreateFile($aArgs, &$mResult)
489: {
490: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
491:
492: if ($aArgs['Type'] === self::$sStorageType) {
493: $oService = $this->GetDriveService();
494: if ($oService) {
495: $sMimeType = \MailSo\Base\Utils::MimeContentType($aArgs['Name']);
496: $file = new \Google\Service\Drive\DriveFile();
497: $file->setName($aArgs['Name']);
498: $file->setMimeType($sMimeType);
499:
500: $Path = \trim($aArgs['Path'], '/');
501: // Set the parent folder.
502: if ($Path != null) {
503: $file->setParents(array($Path));
504: }
505:
506: try {
507: $sData = '';
508: if (\is_resource($aArgs['Data'])) {
509: \rewind($aArgs['Data']);
510: $sData = \stream_get_contents($aArgs['Data']);
511: } else {
512: $sData = $aArgs['Data'];
513: }
514: $oService->files->create($file, array(
515: 'data' => $sData,
516: 'mimeType' => $sMimeType,
517: 'uploadType' => 'media'
518: ));
519: $mResult = true;
520: } catch (\Exception $ex) {
521: $mResult = false;
522: }
523: }
524: }
525: }
526:
527: /**
528: * @param array $aArgs
529: * @param mixed $mResult
530: */
531: public function onAfterDelete(&$aArgs, &$mResult)
532: {
533: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
534:
535: if ($aArgs['Type'] === self::$sStorageType) {
536: $oService = $this->GetDriveService();
537: if ($oService) {
538: $mResult = false;
539:
540: foreach ($aArgs['Items'] as $aItem) {
541: try {
542: $oService->files->delete($aItem['Name']);
543: $mResult = true;
544: } catch (\Exception $ex) {
545: $mResult = false;
546: }
547: }
548: }
549: }
550: }
551:
552: /**
553: * @param array $aArgs
554: * @param mixed $mResult
555: */
556: public function onAfterRename(&$aArgs, &$mResult)
557: {
558: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
559:
560: if ($aArgs['Type'] === self::$sStorageType) {
561: $oService = $this->GetDriveService();
562: if ($oService) {
563: $mResult = false;
564:
565: $file = new \Google\Service\Drive\DriveFile();
566: $file->setName($aArgs['NewName']);
567:
568: $additionalParams = array();
569:
570: try {
571: $oService->files->update($aArgs['Name'], $file, $additionalParams);
572: $mResult = true;
573: } catch (\Exception $ex) {
574: $mResult = false;
575: }
576: }
577: }
578: }
579:
580: /**
581: * @param array $aArgs
582: * @param mixed $mResult
583: */
584: public function onAfterMove(&$aArgs, &$mResult)
585: {
586: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
587:
588: if ($aArgs['FromType'] === self::$sStorageType) {
589: $oService = $this->GetDriveService();
590: if ($oService) {
591: $mResult = false;
592:
593: $aArgs['FromPath'] = $aArgs['FromPath'] === '' ? 'root' : \trim($aArgs['FromPath'], '/');
594: $aArgs['ToPath'] = $aArgs['ToPath'] === '' ? 'root' : \trim($aArgs['ToPath'], '/');
595:
596: foreach ($aArgs['Files'] as $aItem) {
597: $oFile = $oService->files->get($aItem['Name'], ['fields' => 'parents']);
598: try {
599: $previousParents = join(',', $oFile->parents);
600: $emptyFileMetadata = new \Google\Service\Drive\DriveFile();
601: $oFile = $oService->files->update(
602: $aItem['Name'],
603: $emptyFileMetadata,
604: [
605: 'addParents' => $aArgs['ToPath'],
606: 'removeParents' => $previousParents,
607: 'fields' => 'id, parents']
608: );
609:
610: $mResult = true;
611: } catch (\Exception $ex) {
612: $mResult = false;
613: }
614: }
615: }
616: }
617: }
618:
619: /**
620: * @param array $aArgs
621: * @param mixed $mResult
622: */
623: public function onAfterCopy(&$aArgs, &$mResult)
624: {
625: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
626:
627: if ($aArgs['FromType'] === self::$sStorageType) {
628: $oService = $this->GetDriveService();
629: if ($oService) {
630: $mResult = false;
631:
632: $aArgs['ToPath'] = $aArgs['ToPath'] === '' ? 'root' : \trim($aArgs['ToPath'], '/');
633:
634: foreach ($aArgs['Files'] as $aItem) {
635: try {
636: $emptyFileMetadata = new \Google\Service\Drive\DriveFile();
637: $emptyFileMetadata->parents = [$aArgs['ToPath']];
638: $oService->files->copy(
639: $aItem['Name'],
640: $emptyFileMetadata,
641: [
642: 'fields' => 'id, parents']
643: );
644:
645: $mResult = true;
646: } catch (\Exception $ex) {
647: $mResult = false;
648: }
649: }
650: }
651: }
652: }
653:
654: /**
655: * @param array $aArgs
656: * @param mixed $oItem
657: */
658: public function onAfterPopulateFileItem($aArgs, &$oItem)
659: {
660: if ($oItem->IsLink) {
661: if (false !== strpos($oItem->LinkUrl, 'drive.google.com')) {
662: $oItem->LinkType = 'google';
663:
664: $oFileInfo = $this->GetLinkInfo($oItem->LinkUrl);
665: if ($oFileInfo) {
666: if (isset($oFileInfo->thumbnailLink)) {
667: $oItem->Thumb = true;
668: $oItem->ThumbnailUrl = $oFileInfo->thumbnailLink;
669: }
670: if ($oFileInfo->mimeType === "application/vnd.google-apps.folder") {
671: $oItem->UnshiftAction(array(
672: 'list' => array()
673: ));
674:
675: $oItem->Thumb = true;
676: $oItem->ThumbnailUrl = \MailSo\Base\Http::SingletonInstance()->GetFullUrl() . 'modules/' . self::GetName() . '/images/drive.png';
677: } else {
678: $oItem->Size = isset($oFileInfo->fileSize) ? $oFileInfo->fileSize : $oItem->Size;
679: }
680: }
681: return true;
682: }
683: }
684: }
685:
686: protected function getMimeTypeForExport(&$oFileInfo)
687: {
688: switch($oFileInfo->mimeType) {
689: case 'application/vnd.google-apps.document':
690: $oFileInfo->name = $oFileInfo->name . '.docx';
691: return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
692: break;
693: case 'application/vnd.google-apps.spreadsheet':
694: $oFileInfo->name = $oFileInfo->name . '.xlsx';
695: return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
696: break;
697: case 'application/vnd.google-apps.drawing':
698: $oFileInfo->name = $oFileInfo->name . '.png';
699: return 'image/png';
700: break;
701: case 'application/vnd.google-apps.presentation':
702: $oFileInfo->name = $oFileInfo->name . '.pptx';
703: return 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
704: break;
705: default:
706: return '';
707: break;
708: }
709: }
710:
711: protected function PopulateGoogleDriveFileInfo(&$oFileInfo)
712: {
713: if ($oFileInfo->mimeType !== "application/vnd.google-apps.folder") {
714: $this->getMimeTypeForExport($oFileInfo);
715: }
716: }
717:
718: protected function GetIdByLink($sLink)
719: {
720: $matches = array();
721: \preg_match("%https://\w+\.google\.com/\w+/\w+/(.*)\?.*%", $sLink, $matches);
722: if (!isset($matches[1])) {
723: \preg_match("%https://\w+\.google\.com/open\?id=(.*)%", $sLink, $matches);
724: }
725:
726: return isset($matches[1]) ? $matches[1] : '';
727: }
728:
729: protected function GetLinkInfo($sLink, $bLinkAsId = false)
730: {
731: $mResult = false;
732: $sGDId = '';
733: if ($bLinkAsId) {
734: $sGDId = $sLink;
735: } else {
736: $sGDId = $this->GetIdByLink($sLink);
737: }
738:
739: if ($sGDId !== '') {
740: $oFileInfo = $this->_getFileInfo($sGDId);
741: if ($oFileInfo) {
742: $this->PopulateGoogleDriveFileInfo($oFileInfo);
743: $mResult = $oFileInfo;
744: } else {
745: $mResult = false;
746: }
747: } else {
748: $mResult = false;
749: }
750:
751: return $mResult;
752: }
753:
754: /**
755: * Passes data to connect to service.
756: *
757: * @ignore
758: * @param string $aArgs Service type to verify if data should be passed.
759: * @param boolean|array $mResult variable passed by reference to take the result.
760: */
761: public function onGetSettings($aArgs, &$mResult)
762: {
763: $oUser = \Aurora\System\Api::getAuthenticatedUser();
764:
765: if ($oUser) {
766: $aScope = array(
767: 'Name' => 'storage',
768: 'Description' => $this->i18N('SCOPE_FILESTORAGE'),
769: 'Value' => false
770: );
771: if ($oUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) {
772: $aScope['Value'] = $this->issetScope('storage');
773: $mResult['Scopes'][] = $aScope;
774: }
775: if ($oUser->isNormalOrTenant()) {
776: if ($aArgs['OAuthAccount'] instanceof \Aurora\Modules\OAuthIntegratorWebclient\Models\OauthAccount) {
777: $aScope['Value'] = $aArgs['OAuthAccount']->issetScope('storage');
778: }
779: if ($this->issetScope('storage')) {
780: $mResult['Scopes'][] = $aScope;
781: }
782: }
783: }
784: }
785:
786: public function onAfterUpdateSettings($aArgs, &$mResult)
787: {
788: $sScope = '';
789: if (isset($aArgs['Scopes']) && is_array($aArgs['Scopes'])) {
790: foreach ($aArgs['Scopes'] as $aScope) {
791: if ($aScope['Name'] === 'storage') {
792: if ($aScope['Value']) {
793: $sScope = 'storage';
794: break;
795: }
796: }
797: }
798: }
799: $this->setConfig('Scopes', $sScope);
800: $this->saveModuleConfig();
801: }
802:
803: public function onAfterCheckUrl(&$aArgs, &$aReslult) {}
804:
805: public function onAfterGetQuota(&$aArgs, &$aResult)
806: {
807: if ($aArgs['Type'] === self::$sStorageType) {
808: $mResult = [0, 0];
809: return true;
810: }
811: }
812:
813: public function onAfterCheckQuota(&$aArgs, &$mResult)
814: {
815: if ($aArgs['Type'] === self::$sStorageType) {
816: $mResult = true;
817: return true;
818: }
819: }
820:
821: public function EntryThumbnail()
822: {
823: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser);
824:
825: $sUrl = \Aurora\System\Utils::UrlSafeBase64Decode(\Aurora\System\Router::getItemByIndex(1, ''));
826:
827: $request = new Request(
828: 'GET',
829: $sUrl
830: );
831:
832: $client = $this->GetClient();
833: $response = $client->execute($request);
834: echo $response->getBody();
835: }
836:
837: protected function checkIfModuleConfigured()
838: {
839: $bEnableGoogleModule = false;
840:
841: if (class_exists('Aurora\Modules\Google\Module')) {
842: $oGoogleModule = \Aurora\Modules\Google\Module::getInstance();
843: $bEnableGoogleModule = $oGoogleModule->oModuleSettings->EnableModule;
844: }
845:
846: $oOAuthAccount = \Aurora\Modules\OAuthIntegratorWebclient\Module::Decorator()->GetAccount(self::$sStorageType);
847:
848: return ($oOAuthAccount instanceof \Aurora\Modules\OAuthIntegratorWebclient\Models\OauthAccount
849: && $oOAuthAccount->Type === self::$sStorageType
850: && $bEnableGoogleModule
851: && $this->issetScope('storage')
852: && $oOAuthAccount->issetScope('storage'));
853: }
854: }
855: