1: | <?php |
2: | |
3: | |
4: | |
5: | |
6: | |
7: | |
8: | namespace Aurora\Modules\Files; |
9: | |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: | |
17: | |
18: | |
19: | |
20: | use Afterlogic\DAV\Constants; |
21: | use Afterlogic\DAV\Server; |
22: | use Aurora\Api; |
23: | use Aurora\Modules\Core\Models\User; |
24: | use Aurora\Modules\Core\Models\Tenant; |
25: | use Aurora\Modules\Files\Enums\ErrorCodes; |
26: | use Aurora\System\EventEmitter; |
27: | use Aurora\System\Exceptions\ApiException; |
28: | |
29: | class Module extends \Aurora\System\Module\AbstractModule |
30: | { |
31: | protected static $sStorageType = ''; |
32: | |
33: | |
34: | |
35: | |
36: | public $oApiFileCache = null; |
37: | |
38: | |
39: | |
40: | |
41: | |
42: | protected $oMinModuleDecorator = null; |
43: | |
44: | public function getFilecacheManager() |
45: | { |
46: | if ($this->oApiFileCache === null) { |
47: | $this->oApiFileCache = new \Aurora\System\Managers\Filecache(); |
48: | } |
49: | |
50: | return $this->oApiFileCache; |
51: | } |
52: | |
53: | |
54: | |
55: | |
56: | |
57: | public static function Decorator() |
58: | { |
59: | return parent::Decorator(); |
60: | } |
61: | |
62: | |
63: | |
64: | |
65: | |
66: | |
67: | |
68: | |
69: | public function init() |
70: | { |
71: | $this->subscribeEvent('Files::GetStorages::after', array($this, 'onAfterGetStorages'), 1000); |
72: | $this->subscribeEvent('Core::CreateUser::after', array($this, 'onAfterCreateUser'), 1000); |
73: | $this->subscribeEvent('Files::Rename::after', array($this, 'onAfterRename'), 1000); |
74: | $this->subscribeEvent('Files::Move::after', array($this, 'onAfterMove'), 1000); |
75: | |
76: | $this->subscribeEvent('Core::getInheritedAttributes', array($this, 'onGetInheritedAttributes'), 1000); |
77: | |
78: | $this->AddEntries( |
79: | array( |
80: | 'upload' => 'UploadFileData', |
81: | 'download-file' => 'EntryDownloadFile' |
82: | ) |
83: | ); |
84: | $this->denyMethodsCallByWebApi(['getRawFile', 'getRawFileData', 'GetItems']); |
85: | |
86: | $this->aErrors = [ |
87: | Enums\ErrorCodes::NotFound => $this->i18N('INFO_NOTFOUND'), |
88: | Enums\ErrorCodes::NotPermitted => $this->i18N('INFO_NOTPERMITTED'), |
89: | Enums\ErrorCodes::AlreadeExists => $this->i18N('ERROR_ITEM_ALREADY_EXISTS'), |
90: | Enums\ErrorCodes::CantDeleteSharedItem => $this->i18N('ERROR_CANNOT_DELETE_SHARED_ITEM'), |
91: | Enums\ErrorCodes::CannotCopyOrMoveItemToItself => $this->i18N('ERROR_CANNOT_COPY_OR_MOVE_ITEM_TO_ITSELF'), |
92: | Enums\ErrorCodes::NotPossibleToMoveSharedFileToCorporateStorage => $this->i18N('ERROR_NOT_POSSIBLE_TO_MOVE_SHARED_FILE_OR_DIR_TO_CORPORATE_STORAGE'), |
93: | ]; |
94: | } |
95: | |
96: | public function onGetInheritedAttributes(&$aArgs, &$aResult) |
97: | { |
98: | if (isset($aArgs['ClassName']) && ($aArgs['ClassName'] === User::class || $aArgs['ClassName'] === Tenant::class)) { |
99: | $aResult[] = 'Files::UserSpaceLimitMb'; |
100: | if ($aArgs['ClassName'] === Tenant::class) { |
101: | $aResult[] = 'Files::TenantSpaceLimitMb'; |
102: | } |
103: | } |
104: | } |
105: | |
106: | |
107: | |
108: | |
109: | |
110: | |
111: | private function getMinModuleDecorator() |
112: | { |
113: | return \Aurora\System\Api::GetModuleDecorator('Min'); |
114: | } |
115: | |
116: | |
117: | |
118: | |
119: | |
120: | |
121: | |
122: | protected function checkStorageType($Type) |
123: | { |
124: | return $Type === static::$sStorageType; |
125: | } |
126: | |
127: | public function getRawFileData($iUserId, $sType, $sPath, $sFileName, $SharedHash = null, $sAction = '', $iOffset = 0, $iChunkSize = 0) |
128: | { |
129: | $bDownload = true; |
130: | $bThumbnail = false; |
131: | $mResult = false; |
132: | |
133: | switch ($sAction) { |
134: | case 'view': |
135: | $bDownload = false; |
136: | $bThumbnail = false; |
137: | break; |
138: | case 'thumb': |
139: | $bDownload = false; |
140: | $bThumbnail = true; |
141: | break; |
142: | case 'download': |
143: | $bDownload = true; |
144: | $bThumbnail = false; |
145: | |
146: | break; |
147: | default: |
148: | $bDownload = true; |
149: | $bThumbnail = false; |
150: | break; |
151: | } |
152: | if (!$bDownload || $iChunkSize == 0) { |
153: | $iLength = -1; |
154: | $iOffset = -1; |
155: | } else { |
156: | $iLength = $iChunkSize; |
157: | $iOffset = $iChunkSize * $iOffset; |
158: | } |
159: | |
160: | $oModuleDecorator = $this->getMinModuleDecorator(); |
161: | $mMin = ($oModuleDecorator && $SharedHash !== null) ? $oModuleDecorator->GetMinByHash($SharedHash) : array(); |
162: | |
163: | $iUserId = (!empty($mMin['__hash__'])) ? $mMin['UserId'] : $iUserId; |
164: | |
165: | try { |
166: | if ($iUserId && $SharedHash !== null) { |
167: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
168: | \Afterlogic\DAV\Server::setUser($iUserId); |
169: | } else { |
170: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
171: | if ($iUserId !== \Aurora\System\Api::getAuthenticatedUserId()) { |
172: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::AccessDenied); |
173: | } |
174: | } |
175: | } catch (\Aurora\System\Exceptions\ApiException $oEx) { |
176: | echo 'Access denied'; |
177: | exit(); |
178: | } |
179: | |
180: | if (isset($sType, $sPath, $sFileName)) { |
181: | $sContentType = (empty($sFileName)) ? 'text/plain' : \MailSo\Base\Utils::MimeContentType($sFileName); |
182: | |
183: | $mResult = false; |
184: | if ($bThumbnail) { |
185: | $sRawKey = (string) \Aurora\System\Router::getItemByIndex(1, ''); |
186: | if (!empty($sRawKey)) { |
187: | \Aurora\System\Managers\Response::verifyCacheByKey($sRawKey); |
188: | } |
189: | $mResult = \Aurora\System\Managers\Thumb::GetResourceCache($iUserId, $sFileName); |
190: | } |
191: | if (!$mResult) { |
192: | $aArgs = array( |
193: | 'UserId' => $iUserId, |
194: | 'Type' => $sType, |
195: | 'Path' => $sPath, |
196: | 'Name' => &$sFileName, |
197: | 'Id' => $sFileName, |
198: | 'IsThumb' => $bThumbnail, |
199: | 'Offset' => $iOffset, |
200: | 'ChunkSize' => $iChunkSize |
201: | ); |
202: | $this->broadcastEvent( |
203: | 'GetFile', |
204: | $aArgs, |
205: | $mResult |
206: | ); |
207: | } |
208: | } |
209: | |
210: | return $mResult; |
211: | } |
212: | |
213: | |
214: | |
215: | |
216: | |
217: | |
218: | |
219: | |
220: | |
221: | |
222: | |
223: | |
224: | |
225: | public function getRawFile($iUserId, $sType, $sPath, $sFileName, $SharedHash = null, $sAction = '', $iOffset = 0, $iChunkSize = 0, $bShared = false) |
226: | { |
227: | |
228: | if ($sAction !== 'download' && strtolower(pathinfo($sFileName, PATHINFO_EXTENSION)) === 'svg') { |
229: | $this->oHttp->StatusHeader(403); |
230: | exit(); |
231: | } |
232: | |
233: | $bDownload = true; |
234: | $bThumbnail = false; |
235: | |
236: | switch ($sAction) { |
237: | case 'view': |
238: | $bDownload = false; |
239: | $bThumbnail = false; |
240: | break; |
241: | case 'thumb': |
242: | $bDownload = false; |
243: | $bThumbnail = true; |
244: | break; |
245: | case 'download': |
246: | $bDownload = true; |
247: | $bThumbnail = false; |
248: | |
249: | break; |
250: | default: |
251: | $bDownload = true; |
252: | $bThumbnail = false; |
253: | break; |
254: | } |
255: | if (!$bDownload || $iChunkSize == 0) { |
256: | $iLength = -1; |
257: | $iOffset = -1; |
258: | } else { |
259: | $iLength = $iChunkSize; |
260: | $iOffset = $iChunkSize * $iOffset; |
261: | } |
262: | |
263: | $oModuleDecorator = $this->getMinModuleDecorator(); |
264: | $mMin = ($oModuleDecorator && $SharedHash !== null) ? $oModuleDecorator->GetMinByHash($SharedHash) : array(); |
265: | |
266: | $iUserId = (!empty($mMin['__hash__'])) ? $mMin['UserId'] : $iUserId; |
267: | |
268: | try { |
269: | if ($iUserId && $SharedHash !== null) { |
270: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
271: | \Afterlogic\DAV\Server::setUser($iUserId); |
272: | } else { |
273: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
274: | if ($iUserId !== \Aurora\System\Api::getAuthenticatedUserId()) { |
275: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::AccessDenied); |
276: | } |
277: | } |
278: | } catch (\Aurora\System\Exceptions\ApiException $oEx) { |
279: | |
280: | $this->oHttp->StatusHeader(403); |
281: | exit; |
282: | } |
283: | |
284: | if (isset($sType, $sPath, $sFileName)) { |
285: | $sContentType = (empty($sFileName)) ? 'text/plain' : \MailSo\Base\Utils::MimeContentType($sFileName); |
286: | |
287: | $mResult = false; |
288: | if ($bThumbnail) { |
289: | $sRawKey = (string) \Aurora\System\Router::getItemByIndex(1, ''); |
290: | if (!empty($sRawKey)) { |
291: | \Aurora\System\Managers\Response::verifyCacheByKey($sRawKey); |
292: | } |
293: | $mResult = \Aurora\System\Managers\Thumb::GetResourceCache($iUserId, $sFileName); |
294: | if ($mResult) { |
295: | $sContentType = \MailSo\Base\Utils::MimeContentType($sFileName); |
296: | \Aurora\System\Managers\Response::OutputHeaders($bDownload, $sContentType, $sFileName); |
297: | echo $mResult; |
298: | exit(); |
299: | } |
300: | } |
301: | |
302: | if (!$mResult) { |
303: | $aArgs = array( |
304: | 'UserId' => $iUserId, |
305: | 'Type' => $sType, |
306: | 'Path' => $sPath, |
307: | 'Name' => &$sFileName, |
308: | 'Id' => $sFileName, |
309: | 'IsThumb' => $bThumbnail, |
310: | 'Offset' => $iOffset, |
311: | 'ChunkSize' => $iChunkSize, |
312: | 'Shared' => $bShared |
313: | ); |
314: | $this->broadcastEvent( |
315: | 'GetFile', |
316: | $aArgs, |
317: | $mResult |
318: | ); |
319: | } |
320: | |
321: | if (false !== $mResult) { |
322: | if (is_resource($mResult)) { |
323: | $sContentType = \MailSo\Base\Utils::MimeContentType($sFileName); |
324: | \Aurora\System\Managers\Response::OutputHeaders($bDownload, $sContentType, $sFileName); |
325: | |
326: | \header('Cache-Control: no-cache', true); |
327: | |
328: | if ($bThumbnail) { |
329: | return \Aurora\System\Managers\Thumb::GetResource( |
330: | $iUserId, |
331: | $mResult, |
332: | $sFileName |
333: | ); |
334: | } elseif ($sContentType === 'text/html' && !$bDownload) { |
335: | echo(\MailSo\Base\HtmlUtils::ClearHtmlSimple(stream_get_contents($mResult, $iLength, $iOffset))); |
336: | } elseif ($sContentType === 'text/plain') { |
337: | echo(stream_get_contents($mResult, $iLength, $iOffset)); |
338: | } elseif ($iLength > -1 && $iOffset > -1) { |
339: | \MailSo\Base\Utils::GetFilePart($mResult, $iLength, $iOffset); |
340: | } else { |
341: | \MailSo\Base\Utils::FpassthruWithTimeLimitReset($mResult); |
342: | } |
343: | |
344: | @fclose($mResult); |
345: | } else { |
346: | |
347: | $this->oHttp->StatusHeader(404); |
348: | exit; |
349: | } |
350: | } |
351: | } |
352: | } |
353: | |
354: | |
355: | |
356: | |
357: | |
358: | |
359: | |
360: | |
361: | |
362: | |
363: | |
364: | public function UploadFileData() |
365: | { |
366: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
367: | $mResult = false; |
368: | $aPaths = \Aurora\System\Application::GetPaths(); |
369: | if (isset($aPaths[1]) && strtolower($aPaths[1]) === strtolower(self::GetName())) { |
370: | $sType = isset($aPaths[2]) ? strtolower($aPaths[2]) : 'personal'; |
371: | $rData = fopen("php://input", "r"); |
372: | $aFilePath = array_slice($aPaths, 3); |
373: | $sFilePath = urldecode(implode('/', $aFilePath)); |
374: | |
375: | $bOverwrite = true; |
376: | if (strpos($sFilePath, '!') === 0) { |
377: | $sFilePath = substr($sFilePath, 1); |
378: | $bOverwrite = false; |
379: | } |
380: | |
381: | $iUserId = \Aurora\System\Api::getAuthenticatedUserId( |
382: | \Aurora\System\Api::getAuthTokenFromHeaders() |
383: | ); |
384: | $oUser = \Aurora\System\Api::getAuthenticatedUser($iUserId); |
385: | if ($oUser) { |
386: | if ($rData) { |
387: | $aArgs = array( |
388: | 'UserId' => $oUser->UUID, |
389: | 'Type' => $sType, |
390: | 'Path' => dirname($sFilePath), |
391: | 'Name' => basename($sFilePath), |
392: | 'Data' => $rData, |
393: | 'Overwrite' => $bOverwrite, |
394: | 'RangeType' => 0, |
395: | 'Offset' => 0, |
396: | 'ExtendedProps' => array() |
397: | ); |
398: | $this->broadcastEvent( |
399: | 'CreateFile', |
400: | $aArgs, |
401: | $mResult |
402: | ); |
403: | } else { |
404: | $mResult = false; |
405: | } |
406: | } else { |
407: | $mResult = false; |
408: | } |
409: | } |
410: | if ($mResult) { |
411: | echo 'true'; |
412: | } else { |
413: | echo 'false'; |
414: | } |
415: | } |
416: | |
417: | |
418: | |
419: | |
420: | |
421: | |
422: | |
423: | |
424: | |
425: | |
426: | |
427: | |
428: | |
429: | |
430: | |
431: | |
432: | |
433: | |
434: | |
435: | |
436: | |
437: | |
438: | |
439: | |
440: | |
441: | |
442: | |
443: | |
444: | |
445: | |
446: | |
447: | |
448: | |
449: | |
450: | |
451: | |
452: | |
453: | |
454: | |
455: | |
456: | |
457: | |
458: | |
459: | |
460: | |
461: | |
462: | |
463: | |
464: | |
465: | |
466: | |
467: | |
468: | |
469: | |
470: | |
471: | |
472: | |
473: | |
474: | |
475: | public function GetSettings() |
476: | { |
477: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
478: | |
479: | $aAppData = array( |
480: | 'EnableUploadSizeLimit' => $this->getConfig('EnableUploadSizeLimit', false), |
481: | 'UploadSizeLimitMb' => $this->getConfig('UploadSizeLimitMb', 0), |
482: | 'CustomTabTitle' => $this->getConfig('CustomTabTitle', ''), |
483: | 'UserSpaceLimitMb' => $this->getConfig('UserSpaceLimitMb', 0), |
484: | 'TenantSpaceLimitMb' => $this->getConfig('TenantSpaceLimitMb', 0) |
485: | ); |
486: | |
487: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
488: | if ($oAuthenticatedUser instanceof User |
489: | && ($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::NormalUser |
490: | || $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin |
491: | || $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin)) { |
492: | $aAppData['Storages'] = \Aurora\Modules\Files\Module::Decorator()->GetStorages(); |
493: | } |
494: | |
495: | $sPublicHash = \Aurora\System\Router::getItemByIndex(1); |
496: | if (isset($sPublicHash)) { |
497: | $aAppData['PublicHash'] = $sPublicHash; |
498: | $oModuleDecorator = $this->getMinModuleDecorator(); |
499: | $mMin = ($oModuleDecorator && $sPublicHash !== null) ? $oModuleDecorator->GetMinByHash($sPublicHash) : array(); |
500: | if (isset($mMin['__hash__']) && $mMin['IsFolder']) { |
501: | $aAppData['PublicFolderName'] = $mMin['Name']; |
502: | } |
503: | } |
504: | return $aAppData; |
505: | } |
506: | |
507: | public function GetSettingsForEntity($EntityType, $EntityId) |
508: | { |
509: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
510: | |
511: | $aResult = []; |
512: | if ($EntityType === 'Tenant') { |
513: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
514: | $oTenant = \Aurora\Modules\Core\Module::Decorator()->GetTenantUnchecked($EntityId); |
515: | if ($oTenant instanceof Tenant) { |
516: | $aResult = [ |
517: | 'TenantSpaceLimitMb' => $oTenant->{self::GetName() . '::TenantSpaceLimitMb'}, |
518: | 'UserSpaceLimitMb' => $oTenant->{self::GetName() . '::UserSpaceLimitMb'}, |
519: | 'AllocatedSpace' => $this->GetAllocatedSpaceForUsersInTenant($oTenant->Id) |
520: | ]; |
521: | } |
522: | } |
523: | if ($EntityType === 'User') { |
524: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
525: | $oUser = \Aurora\Modules\Core\Module::Decorator()->GetUserUnchecked($EntityId); |
526: | if ($oUser instanceof User) { |
527: | $aResult = [ |
528: | 'UserSpaceLimitMb' => $oUser->{self::GetName() . '::UserSpaceLimitMb'}, |
529: | ]; |
530: | } |
531: | } |
532: | |
533: | return $aResult; |
534: | } |
535: | |
536: | |
537: | |
538: | |
539: | |
540: | |
541: | |
542: | |
543: | |
544: | |
545: | |
546: | |
547: | |
548: | |
549: | |
550: | |
551: | |
552: | |
553: | |
554: | |
555: | |
556: | |
557: | |
558: | |
559: | |
560: | |
561: | |
562: | |
563: | |
564: | |
565: | |
566: | |
567: | |
568: | |
569: | |
570: | |
571: | |
572: | |
573: | |
574: | |
575: | |
576: | |
577: | |
578: | |
579: | |
580: | |
581: | |
582: | |
583: | |
584: | |
585: | |
586: | |
587: | |
588: | |
589: | |
590: | |
591: | public function UpdateSettings($EnableUploadSizeLimit, $UploadSizeLimitMb) |
592: | { |
593: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
594: | |
595: | $this->setConfig('EnableUploadSizeLimit', $EnableUploadSizeLimit); |
596: | $this->setConfig('UploadSizeLimitMb', $UploadSizeLimitMb); |
597: | return (bool) $this->saveModuleConfig(); |
598: | } |
599: | |
600: | |
601: | |
602: | |
603: | |
604: | |
605: | |
606: | |
607: | |
608: | |
609: | |
610: | |
611: | |
612: | |
613: | |
614: | |
615: | |
616: | |
617: | |
618: | |
619: | |
620: | |
621: | |
622: | |
623: | |
624: | |
625: | |
626: | |
627: | |
628: | |
629: | |
630: | |
631: | |
632: | |
633: | |
634: | |
635: | |
636: | |
637: | |
638: | |
639: | |
640: | |
641: | |
642: | |
643: | |
644: | |
645: | |
646: | |
647: | |
648: | |
649: | |
650: | |
651: | |
652: | |
653: | |
654: | |
655: | |
656: | |
657: | |
658: | |
659: | |
660: | |
661: | |
662: | |
663: | |
664: | |
665: | |
666: | |
667: | |
668: | |
669: | |
670: | |
671: | |
672: | |
673: | |
674: | |
675: | public function UploadFile($UserId, $Type, $Path, $UploadData, $SubPath = '', $Overwrite = true, $RangeType = 0, $Offset = 0, $ExtendedProps = []) |
676: | { |
677: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
678: | |
679: | $sUserPublicId = \Aurora\System\Api::getUserPublicIdById($UserId); |
680: | |
681: | $sError = ''; |
682: | $mResponse = array(); |
683: | |
684: | if ($sUserPublicId) { |
685: | if (is_array($UploadData)) { |
686: | if (isset($ExtendedProps['FirstChunk']) && $RangeType == 1 && self::Decorator()->IsFileExists($UserId, $Type, $Path, $UploadData['name'])) { |
687: | $sError = \Aurora\System\Notifications::FileAlreadyExists; |
688: | } elseif (!isset($ExtendedProps['FirstChunk']) && $RangeType == 1 && !self::Decorator()->IsFileExists($UserId, $Type, $Path, $UploadData['name'])) { |
689: | $sError = \Aurora\System\Notifications::FileNotFound; |
690: | } else { |
691: | $iSize = (int) $UploadData['size']; |
692: | $iUploadSizeLimitMb = $this->getConfig('UploadSizeLimitMb', 0); |
693: | if ($iUploadSizeLimitMb > 0 && $iSize/(1024*1024) > $iUploadSizeLimitMb) { |
694: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::CanNotUploadFileLimit); |
695: | } |
696: | |
697: | if (!self::Decorator()->CheckQuota($UserId, $Type, $iSize)) { |
698: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::CanNotUploadFileQuota); |
699: | } |
700: | |
701: | if ($SubPath !== '' && !self::Decorator()->IsFileExists($UserId, $Type, $Path, $SubPath)) { |
702: | try { |
703: | self::Decorator()->CreateFolder($UserId, $Type, $Path, $SubPath); |
704: | } catch (\Exception $oException) { |
705: | |
706: | |
707: | if ($oException->getMessage() !== 'Can\'t create a directory') { |
708: | throw $oException; |
709: | } |
710: | } |
711: | } |
712: | |
713: | $sUploadName = $UploadData['name']; |
714: | $sMimeType = \MailSo\Base\Utils::MimeContentType($sUploadName); |
715: | |
716: | $sSavedName = 'upload-post-'.md5($UploadData['name'].$UploadData['tmp_name']); |
717: | $rData = false; |
718: | if (\is_resource($UploadData['tmp_name'])) { |
719: | $rData = $UploadData['tmp_name']; |
720: | } elseif ($this->getFilecacheManager()->moveUploadedFile($sUserPublicId, $sSavedName, $UploadData['tmp_name'], '', self::GetName())) { |
721: | $rData = $this->getFilecacheManager()->getFile($sUserPublicId, $sSavedName, '', self::GetName()); |
722: | } |
723: | if ($rData) { |
724: | $aArgs = array( |
725: | 'UserId' => $UserId, |
726: | 'Type' => $Type, |
727: | 'Path' => $SubPath === '' ? $Path : $Path . '/' . $SubPath, |
728: | 'Name' => $sUploadName, |
729: | 'Data' => $rData, |
730: | 'Overwrite' => $Overwrite, |
731: | 'RangeType' => $RangeType, |
732: | 'Offset' => $Offset, |
733: | 'ExtendedProps' => $ExtendedProps |
734: | ); |
735: | $mResult = false; |
736: | $this->broadcastEvent( |
737: | 'CreateFile', |
738: | $aArgs, |
739: | $mResult |
740: | ); |
741: | |
742: | if ($mResult) { |
743: | $mResponse['File'] = array( |
744: | 'Name' => $sUploadName, |
745: | 'TempName' => $sSavedName, |
746: | 'MimeType' => $sMimeType, |
747: | 'Size' => (int) $iSize |
748: | ); |
749: | } else { |
750: | $mResponse = false; |
751: | } |
752: | } else { |
753: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::CanNotUploadFileErrorData); |
754: | } |
755: | } |
756: | } else { |
757: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
758: | } |
759: | } else { |
760: | $sError = 'auth'; |
761: | } |
762: | |
763: | if (0 < strlen($sError)) { |
764: | $mResponse['Error'] = $sError; |
765: | } |
766: | |
767: | return $mResponse; |
768: | } |
769: | |
770: | public function EntryDownloadFile() |
771: | { |
772: | |
773: | |
774: | $sHash = (string) \Aurora\System\Router::getItemByIndex(1, ''); |
775: | $sAction = (string) \Aurora\System\Router::getItemByIndex(2, 'download'); |
776: | $iOffset = (int) \Aurora\System\Router::getItemByIndex(3, ''); |
777: | $iChunkSize = (int) \Aurora\System\Router::getItemByIndex(4, ''); |
778: | |
779: | $aValues = \Aurora\System\Api::DecodeKeyValues($sHash); |
780: | |
781: | $iUserId = isset($aValues['UserId']) ? (int) $aValues['UserId'] : 0; |
782: | $sType = isset($aValues['Type']) ? $aValues['Type'] : ''; |
783: | $sPath = isset($aValues['Path']) ? $aValues['Path'] : ''; |
784: | $sFileName = isset($aValues['Name']) ? $aValues['Name'] : ''; |
785: | $sPublicHash = isset($aValues['PublicHash']) ? $aValues['PublicHash'] : null; |
786: | $bShared = isset($aValues['Shared']) ? $aValues['Shared'] : null; |
787: | |
788: | $this->getRawFile($iUserId, $sType, $sPath, $sFileName, $sPublicHash, $sAction, $iOffset, $iChunkSize, $bShared); |
789: | } |
790: | |
791: | |
792: | |
793: | |
794: | |
795: | |
796: | |
797: | |
798: | |
799: | |
800: | |
801: | |
802: | |
803: | |
804: | |
805: | |
806: | |
807: | |
808: | |
809: | |
810: | |
811: | |
812: | |
813: | |
814: | |
815: | |
816: | |
817: | |
818: | |
819: | |
820: | |
821: | |
822: | |
823: | |
824: | |
825: | |
826: | |
827: | |
828: | |
829: | |
830: | |
831: | |
832: | |
833: | public function ViewFile($UserId, $Type, $Path, $Name, $SharedHash) |
834: | { |
835: | |
836: | $this->getRawFile( |
837: | \Aurora\System\Api::getUserPublicIdById($UserId), |
838: | $Type, |
839: | $Path, |
840: | $Name, |
841: | $SharedHash, |
842: | false |
843: | ); |
844: | } |
845: | |
846: | |
847: | |
848: | |
849: | |
850: | |
851: | |
852: | |
853: | |
854: | |
855: | |
856: | |
857: | |
858: | |
859: | |
860: | |
861: | |
862: | |
863: | |
864: | |
865: | |
866: | |
867: | |
868: | |
869: | |
870: | |
871: | |
872: | |
873: | |
874: | |
875: | |
876: | |
877: | |
878: | |
879: | |
880: | |
881: | |
882: | |
883: | |
884: | |
885: | |
886: | |
887: | |
888: | public function GetFileThumbnail($UserId, $Type, $Path, $Name, $SharedHash) |
889: | { |
890: | return false; |
891: | |
892: | |
893: | |
894: | |
895: | |
896: | |
897: | |
898: | |
899: | |
900: | |
901: | |
902: | |
903: | } |
904: | |
905: | |
906: | |
907: | |
908: | |
909: | |
910: | |
911: | |
912: | |
913: | |
914: | |
915: | |
916: | |
917: | |
918: | |
919: | |
920: | |
921: | |
922: | |
923: | |
924: | |
925: | |
926: | |
927: | |
928: | |
929: | |
930: | |
931: | |
932: | |
933: | |
934: | |
935: | |
936: | |
937: | |
938: | |
939: | |
940: | |
941: | |
942: | |
943: | |
944: | |
945: | |
946: | |
947: | |
948: | |
949: | |
950: | |
951: | |
952: | |
953: | |
954: | |
955: | |
956: | |
957: | |
958: | |
959: | |
960: | |
961: | |
962: | public function GetStorages() |
963: | { |
964: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
965: | return []; |
966: | } |
967: | |
968: | |
969: | |
970: | |
971: | public function GetSubModules() |
972: | { |
973: | return []; |
974: | } |
975: | |
976: | |
977: | |
978: | |
979: | |
980: | |
981: | |
982: | |
983: | |
984: | |
985: | |
986: | |
987: | |
988: | |
989: | |
990: | |
991: | |
992: | |
993: | |
994: | |
995: | |
996: | |
997: | |
998: | |
999: | |
1000: | |
1001: | |
1002: | |
1003: | |
1004: | |
1005: | |
1006: | |
1007: | |
1008: | |
1009: | |
1010: | |
1011: | |
1012: | |
1013: | |
1014: | |
1015: | |
1016: | |
1017: | |
1018: | |
1019: | |
1020: | |
1021: | |
1022: | |
1023: | |
1024: | |
1025: | |
1026: | |
1027: | |
1028: | |
1029: | |
1030: | |
1031: | |
1032: | |
1033: | |
1034: | public function GetQuota($UserId, $Type) |
1035: | { |
1036: | return [ |
1037: | 'Limit' => 0, |
1038: | 'Used' => 0 |
1039: | ]; |
1040: | } |
1041: | |
1042: | public function CheckQuota($UserId, $Type, $Size) |
1043: | { |
1044: | return false; |
1045: | } |
1046: | |
1047: | public function GetItems($UserId, $Type, $Path, $Pattern, $PublicHash = null, $Shared = false) |
1048: | { |
1049: | $aArgs = [ |
1050: | 'UserId' => $UserId, |
1051: | 'Type' => $Type, |
1052: | 'Path' => $Path, |
1053: | 'Pattern' => $Pattern, |
1054: | 'PublicHash' => $PublicHash, |
1055: | 'Shared' => $Shared |
1056: | ]; |
1057: | $mResult = []; |
1058: | |
1059: | $this->broadcastEvent('GetItems', $aArgs, $mResult); |
1060: | |
1061: | $aItems = []; |
1062: | if (is_array($mResult)) { |
1063: | foreach ($mResult as $oItem) { |
1064: | if ($oItem instanceof Classes\FileItem) { |
1065: | $aItems[] = self::Decorator()->PopulateFileItem($aArgs['UserId'], $oItem); |
1066: | } |
1067: | } |
1068: | |
1069: | $mResult = $aItems; |
1070: | } |
1071: | |
1072: | return $aItems; |
1073: | } |
1074: | |
1075: | |
1076: | |
1077: | |
1078: | |
1079: | |
1080: | |
1081: | |
1082: | |
1083: | |
1084: | |
1085: | |
1086: | |
1087: | |
1088: | |
1089: | |
1090: | |
1091: | |
1092: | |
1093: | |
1094: | |
1095: | |
1096: | |
1097: | |
1098: | |
1099: | |
1100: | |
1101: | |
1102: | |
1103: | |
1104: | |
1105: | |
1106: | |
1107: | |
1108: | |
1109: | |
1110: | |
1111: | |
1112: | |
1113: | |
1114: | |
1115: | |
1116: | |
1117: | |
1118: | |
1119: | |
1120: | |
1121: | |
1122: | |
1123: | |
1124: | |
1125: | |
1126: | |
1127: | |
1128: | |
1129: | |
1130: | |
1131: | |
1132: | |
1133: | |
1134: | |
1135: | |
1136: | |
1137: | |
1138: | |
1139: | |
1140: | |
1141: | |
1142: | |
1143: | public function GetFiles($UserId, $Type, $Path, $Pattern, $Shared = false) |
1144: | { |
1145: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1146: | return [ |
1147: | 'Items' => self::Decorator()->GetItems($UserId, $Type, $Path, $Pattern, null, $Shared), |
1148: | 'Quota' => self::Decorator()->GetQuota($UserId, $Type) |
1149: | ]; |
1150: | } |
1151: | |
1152: | |
1153: | |
1154: | |
1155: | |
1156: | |
1157: | public function onAfterGetStorages($aArgs, &$mResult) |
1158: | { |
1159: | if (is_array($mResult)) { |
1160: | \usort($mResult, function ($aItem1, $aItem2) { |
1161: | $aItem1['Order'] = isset($aItem1['Order']) ? $aItem1['Order'] : 1000; |
1162: | $aItem2['Order'] = isset($aItem2['Order']) ? $aItem2['Order'] : 1000; |
1163: | |
1164: | return ($aItem1['Order'] == $aItem2['Order']) ? 0 : ($aItem1['Order'] > $aItem2['Order'] ? +1 : -1); |
1165: | }); |
1166: | } |
1167: | } |
1168: | |
1169: | |
1170: | |
1171: | |
1172: | |
1173: | |
1174: | |
1175: | |
1176: | |
1177: | |
1178: | |
1179: | private function generateMinArray($iUserId, $sType, $sPath, $sName, $sSize, $bIsFolder = false) |
1180: | { |
1181: | $aData = null; |
1182: | if ($iUserId) { |
1183: | $aData = array( |
1184: | 'UserId' => $iUserId, |
1185: | 'Type' => $sType, |
1186: | 'Path' => $sPath, |
1187: | 'Name' => $sName, |
1188: | 'Size' => $sSize, |
1189: | 'IsFolder' => $bIsFolder |
1190: | ); |
1191: | } |
1192: | |
1193: | return $aData; |
1194: | } |
1195: | |
1196: | protected function updateMinHash($iUserId, $sType, $sPath, $sName, $sNewType, $sNewPath, $sNewName) |
1197: | { |
1198: | $sUserPublicId = \Aurora\Api::getUserPublicIdById($iUserId); |
1199: | $sID = \Aurora\Modules\Min\Module::generateHashId([$sUserPublicId, $sType, $sPath, $sName]); |
1200: | $sNewID = \Aurora\Modules\Min\Module::generateHashId([$sUserPublicId, $sNewType, $sNewPath, $sNewName]); |
1201: | |
1202: | $mData = $this->getMinModuleDecorator()->GetMinByID($sID); |
1203: | |
1204: | if ($mData) { |
1205: | $aData = $this->generateMinArray($sUserPublicId, $sNewType, $sNewPath, $sNewName, $mData['Size']); |
1206: | if ($aData) { |
1207: | $this->getMinModuleDecorator()->UpdateMinByID($sID, $aData, $sNewID); |
1208: | } |
1209: | } |
1210: | } |
1211: | |
1212: | |
1213: | |
1214: | |
1215: | |
1216: | |
1217: | public function onAfterRename($aArgs, &$mResult) |
1218: | { |
1219: | if ($mResult && isset($aArgs['UserId'])) { |
1220: | $this->updateMinHash($aArgs['UserId'], $aArgs['Type'], $aArgs['Path'], $aArgs['Name'], $aArgs['Type'], $aArgs['Path'], $aArgs['NewName']); |
1221: | } |
1222: | } |
1223: | |
1224: | public function onAfterMove($aArgs, &$mResult) |
1225: | { |
1226: | if ($mResult && isset($aArgs['Files']) && is_array($aArgs['Files']) && count($aArgs['Files']) > 0) { |
1227: | foreach ($aArgs['Files'] as $aFile) { |
1228: | $this->updateMinHash($aArgs['UserId'], $aFile['FromType'], $aFile['FromPath'], $aFile['Name'], $aArgs['ToType'], $aArgs['ToPath'], $aFile['Name']); |
1229: | } |
1230: | } |
1231: | } |
1232: | |
1233: | |
1234: | |
1235: | |
1236: | |
1237: | |
1238: | public function onAfterCreateUser($aArgs, &$mResult) |
1239: | { |
1240: | if ($mResult) { |
1241: | $oUser = \Aurora\Modules\Core\Module::getInstance()->GetUserUnchecked($mResult); |
1242: | if ($oUser) { |
1243: | $oTenant = \Aurora\Modules\Core\Module::getInstance()->GetTenantUnchecked($oUser->IdTenant); |
1244: | $oUser->setExtendedProp($this->GetName() . '::UserSpaceLimitMb', $oTenant->{$this->GetName() . '::UserSpaceLimitMb'}); |
1245: | $oUser->save(); |
1246: | } |
1247: | } |
1248: | } |
1249: | |
1250: | |
1251: | |
1252: | |
1253: | |
1254: | public function PopulateFileItem($UserId, $Item) |
1255: | { |
1256: | return $Item; |
1257: | } |
1258: | |
1259: | |
1260: | |
1261: | |
1262: | |
1263: | public function PopulateFileItems($UserId, $Items) |
1264: | { |
1265: | return $Items; |
1266: | } |
1267: | |
1268: | |
1269: | |
1270: | |
1271: | |
1272: | |
1273: | |
1274: | |
1275: | |
1276: | public function GetFileContent($UserId, $Type, $Path, $Name) |
1277: | { |
1278: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1279: | |
1280: | } |
1281: | |
1282: | |
1283: | |
1284: | |
1285: | |
1286: | |
1287: | |
1288: | |
1289: | |
1290: | |
1291: | public function GetFileInfo($UserId, $Type, $Path, $Id) |
1292: | { |
1293: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1294: | |
1295: | return null; |
1296: | } |
1297: | |
1298: | |
1299: | |
1300: | |
1301: | |
1302: | |
1303: | |
1304: | |
1305: | |
1306: | |
1307: | |
1308: | |
1309: | |
1310: | |
1311: | |
1312: | |
1313: | |
1314: | |
1315: | |
1316: | |
1317: | |
1318: | |
1319: | |
1320: | |
1321: | |
1322: | |
1323: | |
1324: | |
1325: | |
1326: | |
1327: | |
1328: | |
1329: | |
1330: | |
1331: | |
1332: | |
1333: | |
1334: | |
1335: | |
1336: | |
1337: | |
1338: | |
1339: | |
1340: | |
1341: | |
1342: | |
1343: | |
1344: | |
1345: | |
1346: | |
1347: | |
1348: | |
1349: | |
1350: | |
1351: | |
1352: | |
1353: | |
1354: | |
1355: | |
1356: | public function GetPublicFiles($Hash, $Path) |
1357: | { |
1358: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); |
1359: | |
1360: | $mResult = []; |
1361: | |
1362: | $oMinDecorator = $this->getMinModuleDecorator(); |
1363: | if ($oMinDecorator) { |
1364: | $mMin = $oMinDecorator->GetMinByHash($Hash); |
1365: | if (!empty($mMin['__hash__'])) { |
1366: | $sUserPublicId = $mMin['UserId']; |
1367: | if ($sUserPublicId) { |
1368: | $oUser = \Aurora\System\Api::GetModuleDecorator('Core')->GetUserByPublicId($sUserPublicId); |
1369: | if ($oUser) { |
1370: | $bPrevState = \Aurora\System\Api::skipCheckUserRole(true); |
1371: | $sMinPath = implode('/', array($mMin['Path'], $mMin['Name'])); |
1372: | $mPos = strpos($Path, $sMinPath); |
1373: | if ($mPos === 0 || $Path === '') { |
1374: | if ($mPos !== 0) { |
1375: | $Path = $sMinPath . $Path; |
1376: | } |
1377: | $Path = str_replace('.', '', $Path); |
1378: | $mResult = [ |
1379: | 'Items' => self::Decorator()->GetItems($oUser->Id, $mMin['Type'], $Path, '', $Hash) |
1380: | ]; |
1381: | } |
1382: | \Aurora\System\Api::skipCheckUserRole($bPrevState); |
1383: | } |
1384: | } |
1385: | } |
1386: | } |
1387: | |
1388: | return $mResult; |
1389: | } |
1390: | |
1391: | |
1392: | |
1393: | |
1394: | |
1395: | |
1396: | |
1397: | |
1398: | |
1399: | |
1400: | |
1401: | |
1402: | |
1403: | |
1404: | |
1405: | |
1406: | |
1407: | |
1408: | |
1409: | |
1410: | |
1411: | |
1412: | |
1413: | |
1414: | |
1415: | |
1416: | |
1417: | |
1418: | |
1419: | |
1420: | |
1421: | |
1422: | |
1423: | |
1424: | |
1425: | |
1426: | |
1427: | |
1428: | |
1429: | |
1430: | |
1431: | |
1432: | |
1433: | |
1434: | |
1435: | |
1436: | |
1437: | |
1438: | |
1439: | |
1440: | |
1441: | |
1442: | |
1443: | |
1444: | |
1445: | |
1446: | |
1447: | |
1448: | |
1449: | |
1450: | |
1451: | public function CreateFolder($UserId, $Type, $Path, $FolderName) |
1452: | { |
1453: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1454: | |
1455: | return false; |
1456: | } |
1457: | |
1458: | |
1459: | |
1460: | |
1461: | |
1462: | |
1463: | |
1464: | |
1465: | |
1466: | |
1467: | |
1468: | |
1469: | |
1470: | |
1471: | |
1472: | |
1473: | |
1474: | |
1475: | |
1476: | |
1477: | |
1478: | |
1479: | |
1480: | |
1481: | |
1482: | |
1483: | |
1484: | |
1485: | |
1486: | |
1487: | |
1488: | |
1489: | |
1490: | |
1491: | |
1492: | |
1493: | |
1494: | |
1495: | |
1496: | |
1497: | |
1498: | |
1499: | |
1500: | |
1501: | |
1502: | |
1503: | |
1504: | |
1505: | |
1506: | |
1507: | |
1508: | |
1509: | |
1510: | |
1511: | |
1512: | |
1513: | |
1514: | |
1515: | |
1516: | |
1517: | |
1518: | |
1519: | |
1520: | |
1521: | |
1522: | |
1523: | |
1524: | |
1525: | public function CreateLink($UserId, $Type, $Path, $Link, $Name) |
1526: | { |
1527: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1528: | return false; |
1529: | } |
1530: | |
1531: | |
1532: | |
1533: | |
1534: | |
1535: | |
1536: | |
1537: | |
1538: | |
1539: | |
1540: | |
1541: | |
1542: | |
1543: | |
1544: | |
1545: | |
1546: | |
1547: | |
1548: | |
1549: | |
1550: | |
1551: | |
1552: | |
1553: | |
1554: | |
1555: | |
1556: | |
1557: | |
1558: | |
1559: | |
1560: | |
1561: | |
1562: | |
1563: | |
1564: | |
1565: | |
1566: | |
1567: | |
1568: | |
1569: | |
1570: | |
1571: | |
1572: | |
1573: | |
1574: | |
1575: | |
1576: | |
1577: | |
1578: | |
1579: | |
1580: | |
1581: | |
1582: | |
1583: | |
1584: | |
1585: | |
1586: | |
1587: | |
1588: | |
1589: | |
1590: | public function Delete($UserId, $Type, $Items) |
1591: | { |
1592: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1593: | |
1594: | return false; |
1595: | } |
1596: | |
1597: | |
1598: | |
1599: | |
1600: | |
1601: | |
1602: | |
1603: | |
1604: | |
1605: | |
1606: | |
1607: | |
1608: | |
1609: | |
1610: | |
1611: | |
1612: | |
1613: | |
1614: | |
1615: | |
1616: | |
1617: | |
1618: | |
1619: | |
1620: | |
1621: | |
1622: | |
1623: | |
1624: | |
1625: | |
1626: | |
1627: | |
1628: | |
1629: | |
1630: | |
1631: | |
1632: | |
1633: | |
1634: | |
1635: | |
1636: | |
1637: | |
1638: | |
1639: | |
1640: | |
1641: | |
1642: | |
1643: | |
1644: | |
1645: | |
1646: | |
1647: | |
1648: | |
1649: | |
1650: | |
1651: | |
1652: | |
1653: | |
1654: | |
1655: | |
1656: | public function LeaveShare($UserId, $Type, $Items) |
1657: | { |
1658: | $aArgs = [ |
1659: | 'UserId' => $UserId, |
1660: | 'Type' => $Type, |
1661: | 'Items' => $Items |
1662: | ]; |
1663: | EventEmitter::getInstance()->emit('Files', 'Delete::before', $aArgs); |
1664: | |
1665: | $UserId = $aArgs['UserId']; |
1666: | $Type = $aArgs['Type']; |
1667: | $Items = $aArgs['Items']; |
1668: | |
1669: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1670: | $aNodes = []; |
1671: | foreach ($Items as $aItem) { |
1672: | try { |
1673: | $oNode = Server::getNodeForPath(Constants::FILESTORAGE_PATH_ROOT . '/' . $Type . '/' . $aItem['Path'] . '/' . $aItem['Name']); |
1674: | $aItems[] = $oNode; |
1675: | } catch (\Exception $oEx) { |
1676: | Api::LogException($oEx); |
1677: | throw new ApiException(ErrorCodes::NotFound); |
1678: | } |
1679: | |
1680: | if (!($oNode instanceof \Afterlogic\DAV\FS\Shared\File || $oNode instanceof \Afterlogic\DAV\FS\Shared\Directory)) { |
1681: | throw new ApiException(ErrorCodes::CantDeleteSharedItem); |
1682: | } |
1683: | |
1684: | $oItem = new Classes\FileItem(); |
1685: | $oItem->Id = $aItem['Name']; |
1686: | $oItem->Name = $aItem['Name']; |
1687: | $oItem->TypeStr = $Type; |
1688: | $oItem->Path = $aItem['Path']; |
1689: | |
1690: | self::Decorator()->DeletePublicLink($UserId, $Type, $aItem['Path'], $aItem['Name']); |
1691: | \Aurora\System\Managers\Thumb::RemoveFromCache($UserId, $oItem->getHash(), $aItem['Name']); |
1692: | } |
1693: | |
1694: | $aArgs = [ |
1695: | 'UserId' => $UserId, |
1696: | 'Type' => $Type, |
1697: | 'Items' => $aItems |
1698: | ]; |
1699: | $mResult = false; |
1700: | |
1701: | EventEmitter::getInstance()->emit('Files', 'LeaveShare', $aArgs, $mResult); |
1702: | |
1703: | return $mResult; |
1704: | } |
1705: | |
1706: | |
1707: | |
1708: | |
1709: | |
1710: | |
1711: | |
1712: | |
1713: | |
1714: | |
1715: | |
1716: | |
1717: | |
1718: | |
1719: | |
1720: | |
1721: | |
1722: | |
1723: | |
1724: | |
1725: | |
1726: | |
1727: | |
1728: | |
1729: | |
1730: | |
1731: | |
1732: | |
1733: | |
1734: | |
1735: | |
1736: | |
1737: | |
1738: | |
1739: | |
1740: | |
1741: | |
1742: | |
1743: | |
1744: | |
1745: | |
1746: | |
1747: | |
1748: | |
1749: | |
1750: | |
1751: | |
1752: | |
1753: | |
1754: | |
1755: | |
1756: | |
1757: | |
1758: | |
1759: | |
1760: | |
1761: | |
1762: | |
1763: | |
1764: | |
1765: | |
1766: | |
1767: | |
1768: | |
1769: | |
1770: | |
1771: | public function Rename($UserId, $Type, $Path, $Name, $NewName, $IsLink) |
1772: | { |
1773: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1774: | |
1775: | if ($Name === '') { |
1776: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
1777: | } |
1778: | |
1779: | $oItem = new Classes\FileItem(); |
1780: | $oItem->Id = $Name; |
1781: | $oItem->Name = $Name; |
1782: | $oItem->TypeStr = $Type; |
1783: | $oItem->Path = $Path; |
1784: | |
1785: | \Aurora\System\Managers\Thumb::RemoveFromCache($UserId, $oItem->getHash(), $Name); |
1786: | |
1787: | |
1788: | return false; |
1789: | } |
1790: | |
1791: | |
1792: | |
1793: | |
1794: | |
1795: | |
1796: | |
1797: | |
1798: | |
1799: | |
1800: | |
1801: | |
1802: | |
1803: | |
1804: | |
1805: | |
1806: | |
1807: | |
1808: | |
1809: | |
1810: | |
1811: | |
1812: | |
1813: | |
1814: | |
1815: | |
1816: | |
1817: | |
1818: | |
1819: | |
1820: | |
1821: | |
1822: | |
1823: | |
1824: | |
1825: | |
1826: | |
1827: | |
1828: | |
1829: | |
1830: | |
1831: | |
1832: | |
1833: | |
1834: | |
1835: | |
1836: | |
1837: | |
1838: | |
1839: | |
1840: | |
1841: | |
1842: | |
1843: | |
1844: | |
1845: | |
1846: | |
1847: | |
1848: | |
1849: | |
1850: | |
1851: | |
1852: | |
1853: | |
1854: | |
1855: | |
1856: | |
1857: | |
1858: | |
1859: | |
1860: | public function Copy($UserId, $FromType, $ToType, $FromPath, $ToPath, $Files) |
1861: | { |
1862: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1863: | return null; |
1864: | } |
1865: | |
1866: | |
1867: | |
1868: | |
1869: | |
1870: | |
1871: | |
1872: | |
1873: | |
1874: | |
1875: | |
1876: | |
1877: | |
1878: | |
1879: | |
1880: | |
1881: | |
1882: | |
1883: | |
1884: | |
1885: | |
1886: | |
1887: | |
1888: | |
1889: | |
1890: | |
1891: | |
1892: | |
1893: | |
1894: | |
1895: | |
1896: | |
1897: | |
1898: | |
1899: | |
1900: | |
1901: | |
1902: | |
1903: | |
1904: | |
1905: | |
1906: | |
1907: | |
1908: | |
1909: | |
1910: | |
1911: | |
1912: | |
1913: | |
1914: | |
1915: | |
1916: | |
1917: | |
1918: | |
1919: | |
1920: | |
1921: | |
1922: | |
1923: | |
1924: | |
1925: | |
1926: | |
1927: | |
1928: | |
1929: | |
1930: | |
1931: | |
1932: | |
1933: | |
1934: | |
1935: | public function Move($UserId, $FromType, $ToType, $FromPath, $ToPath, $Files) |
1936: | { |
1937: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
1938: | |
1939: | foreach ($Files as $aFile) { |
1940: | if (!$aFile['IsFolder']) { |
1941: | $oItem = new Classes\FileItem(); |
1942: | $oItem->Id = $aFile['Name']; |
1943: | $oItem->Name = $aFile['Name']; |
1944: | $oItem->TypeStr = $FromType; |
1945: | $oItem->Path = $FromPath; |
1946: | |
1947: | \Aurora\System\Managers\Thumb::RemoveFromCache($UserId, $oItem->getHash(), $aFile['Name']); |
1948: | } |
1949: | } |
1950: | |
1951: | return false; |
1952: | } |
1953: | |
1954: | |
1955: | |
1956: | |
1957: | |
1958: | |
1959: | |
1960: | |
1961: | |
1962: | |
1963: | |
1964: | |
1965: | |
1966: | |
1967: | |
1968: | |
1969: | |
1970: | |
1971: | |
1972: | |
1973: | |
1974: | |
1975: | |
1976: | |
1977: | |
1978: | |
1979: | |
1980: | |
1981: | |
1982: | |
1983: | |
1984: | |
1985: | |
1986: | |
1987: | |
1988: | |
1989: | |
1990: | |
1991: | |
1992: | |
1993: | |
1994: | |
1995: | |
1996: | |
1997: | |
1998: | |
1999: | |
2000: | |
2001: | |
2002: | |
2003: | |
2004: | |
2005: | |
2006: | |
2007: | |
2008: | |
2009: | |
2010: | |
2011: | |
2012: | |
2013: | |
2014: | |
2015: | |
2016: | |
2017: | |
2018: | public function CreatePublicLink($UserId, $Type, $Path, $Name, $Size, $IsFolder) |
2019: | { |
2020: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2021: | return false; |
2022: | } |
2023: | |
2024: | |
2025: | |
2026: | |
2027: | |
2028: | |
2029: | |
2030: | |
2031: | |
2032: | |
2033: | |
2034: | |
2035: | |
2036: | |
2037: | |
2038: | |
2039: | |
2040: | |
2041: | |
2042: | |
2043: | |
2044: | |
2045: | |
2046: | |
2047: | |
2048: | |
2049: | |
2050: | |
2051: | |
2052: | |
2053: | |
2054: | |
2055: | |
2056: | |
2057: | |
2058: | |
2059: | |
2060: | |
2061: | |
2062: | |
2063: | |
2064: | |
2065: | |
2066: | |
2067: | |
2068: | |
2069: | |
2070: | |
2071: | |
2072: | |
2073: | |
2074: | |
2075: | |
2076: | |
2077: | |
2078: | |
2079: | |
2080: | |
2081: | |
2082: | |
2083: | |
2084: | public function DeletePublicLink($UserId, $Type, $Path, $Name) |
2085: | { |
2086: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2087: | return false; |
2088: | } |
2089: | |
2090: | |
2091: | |
2092: | |
2093: | |
2094: | |
2095: | |
2096: | |
2097: | |
2098: | |
2099: | |
2100: | |
2101: | public function CheckUrl($Url) |
2102: | { |
2103: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2104: | $mResult = false; |
2105: | |
2106: | if (substr($Url, 0, 11) === 'javascript:') { |
2107: | $Url = substr($Url, 11); |
2108: | } |
2109: | |
2110: | $aArgs = array( |
2111: | 'Url' => $Url |
2112: | ); |
2113: | $this->broadcastEvent( |
2114: | 'CheckUrl', |
2115: | $aArgs, |
2116: | $mResult |
2117: | ); |
2118: | |
2119: | return $mResult; |
2120: | } |
2121: | |
2122: | |
2123: | |
2124: | |
2125: | public function GetFilesForUpload($UserId, $Hashes = array()) |
2126: | { |
2127: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2128: | $sUUID = \Aurora\System\Api::getUserUUIDById($UserId); |
2129: | |
2130: | $mResult = false; |
2131: | if (is_array($Hashes) && 0 < count($Hashes)) { |
2132: | $mResult = array(); |
2133: | foreach ($Hashes as $sHash) { |
2134: | $aData = \Aurora\System\Api::DecodeKeyValues($sHash); |
2135: | if (\is_array($aData) && 0 < \count($aData)) { |
2136: | $oFileInfo = self::Decorator()->GetFileInfo($UserId, $aData['Type'], $aData['Path'], $aData['Id']); |
2137: | |
2138: | $aArgs = array( |
2139: | 'UserId' => $UserId, |
2140: | 'Type' => $aData['Type'], |
2141: | 'Path' => $aData['Path'], |
2142: | 'Name' => $aData['Name'], |
2143: | 'Id' => $aData['Id'] |
2144: | ); |
2145: | $rFile = false; |
2146: | $this->broadcastEvent( |
2147: | 'GetFile', |
2148: | $aArgs, |
2149: | $rFile |
2150: | ); |
2151: | |
2152: | $sTempName = md5('Files/Tmp/'.$aData['Type'].$aData['Path'].$aData['Name'].microtime(true).rand(1000, 9999)); |
2153: | |
2154: | if (is_resource($rFile) && $this->getFilecacheManager()->putFile($sUUID, $sTempName, $rFile)) { |
2155: | $aItem = array( |
2156: | 'Name' => $oFileInfo->Name, |
2157: | 'TempName' => $sTempName, |
2158: | 'Size' => $oFileInfo->Size, |
2159: | 'Hash' => $sHash, |
2160: | 'MimeType' => '' |
2161: | ); |
2162: | |
2163: | $aItem['MimeType'] = \MailSo\Base\Utils::MimeContentType($aItem['Name']); |
2164: | $aItem['NewHash'] = \Aurora\System\Api::EncodeKeyValues(array( |
2165: | 'TempFile' => true, |
2166: | 'UserId' => $UserId, |
2167: | 'Name' => $aItem['Name'], |
2168: | 'TempName' => $sTempName |
2169: | )); |
2170: | |
2171: | $aActions = array( |
2172: | 'view' => array( |
2173: | 'url' => '?file-cache/' . $aItem['NewHash'] .'/view' |
2174: | ), |
2175: | 'download' => array( |
2176: | 'url' => '?file-cache/' . $aItem['NewHash'] |
2177: | ) |
2178: | ); |
2179: | $aItem['Actions'] = $aActions; |
2180: | |
2181: | $mResult[] = $aItem; |
2182: | |
2183: | if (is_resource($rFile)) { |
2184: | @fclose($rFile); |
2185: | } |
2186: | } |
2187: | } |
2188: | } |
2189: | } else { |
2190: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2191: | } |
2192: | |
2193: | return $mResult; |
2194: | } |
2195: | |
2196: | |
2197: | |
2198: | |
2199: | |
2200: | |
2201: | |
2202: | |
2203: | |
2204: | public function IsFileExists($UserId, $Type, $Path, $Name) |
2205: | { |
2206: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2207: | return true; |
2208: | } |
2209: | |
2210: | |
2211: | |
2212: | |
2213: | |
2214: | |
2215: | |
2216: | |
2217: | public function GetNonExistentFileName($UserId, $Type, $Path, $Name, $WithoutGroup = false) |
2218: | { |
2219: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2220: | return $Name; |
2221: | } |
2222: | |
2223: | |
2224: | |
2225: | |
2226: | |
2227: | |
2228: | |
2229: | |
2230: | public function SaveFilesAsTempFiles($UserId, $Files) |
2231: | { |
2232: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2233: | |
2234: | $mResult = false; |
2235: | |
2236: | if (is_array($Files) && count($Files) > 0) { |
2237: | $mResult = array(); |
2238: | foreach ($Files as $aFile) { |
2239: | $Storage = $aFile['Storage']; |
2240: | $Path = $aFile['Path']; |
2241: | $Name = $aFile['Name']; |
2242: | $Id = $aFile['Name']; |
2243: | |
2244: | $aArgs = array( |
2245: | 'UserId' => $UserId, |
2246: | 'Type' => $Storage, |
2247: | 'Path' => $Path, |
2248: | 'Name' => &$Name, |
2249: | 'Id' => $Id, |
2250: | 'IsThumb' => false, |
2251: | 'Offset' => 0, |
2252: | 'ChunkSize' => 0 |
2253: | ); |
2254: | $mFileResource = false; |
2255: | $this->broadcastEvent( |
2256: | 'GetFile', |
2257: | $aArgs, |
2258: | $mFileResource |
2259: | ); |
2260: | |
2261: | if (is_resource($mFileResource)) { |
2262: | $sUUID = \Aurora\System\Api::getUserUUIDById($UserId); |
2263: | try { |
2264: | $sTempName = md5($sUUID.$Storage.$Path.$Name); |
2265: | |
2266: | if (!$this->getFilecacheManager()->isFileExists($sUUID, $sTempName)) { |
2267: | $this->getFilecacheManager()->putFile($sUUID, $sTempName, $mFileResource); |
2268: | } |
2269: | |
2270: | if ($this->getFilecacheManager()->isFileExists($sUUID, $sTempName)) { |
2271: | $mResult[] = \Aurora\System\Utils::GetClientFileResponse( |
2272: | null, |
2273: | $UserId, |
2274: | $Name, |
2275: | $sTempName, |
2276: | $this->getFilecacheManager()->fileSize($sUUID, $sTempName) |
2277: | ); |
2278: | } |
2279: | } catch (\Exception $oException) { |
2280: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::FilesNotAllowed, $oException); |
2281: | } |
2282: | } |
2283: | } |
2284: | } |
2285: | |
2286: | return $mResult; |
2287: | } |
2288: | |
2289: | public function UpdateSettingsForEntity($EntityType, $EntityId, $UserSpaceLimitMb, $TenantSpaceLimitMb) |
2290: | { |
2291: | $bResult = false; |
2292: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
2293: | |
2294: | if ($EntityType === '') { |
2295: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2296: | $this->setConfig('TenantSpaceLimitMb', $TenantSpaceLimitMb); |
2297: | $this->setConfig('UserSpaceLimitMb', $UserSpaceLimitMb); |
2298: | return $this->saveModuleConfig(); |
2299: | } |
2300: | if ($EntityType === 'Tenant') { |
2301: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
2302: | $oTenant = \Aurora\Modules\Core\Module::Decorator()->GetTenantUnchecked($EntityId); |
2303: | |
2304: | if ($oTenant instanceof Tenant |
2305: | && $oAuthenticatedUser instanceof User |
2306: | && (($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oTenant->Id === $oAuthenticatedUser->IdTenant) |
2307: | || $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin)) { |
2308: | if ($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) { |
2309: | $oTenant->setExtendedProp(self::GetName() . '::TenantSpaceLimitMb', $TenantSpaceLimitMb); |
2310: | } |
2311: | if (is_int($UserSpaceLimitMb)) { |
2312: | if ($UserSpaceLimitMb <= $TenantSpaceLimitMb || $TenantSpaceLimitMb === 0) { |
2313: | $oTenant->setExtendedProp(self::GetName() . '::UserSpaceLimitMb', $UserSpaceLimitMb); |
2314: | } else { |
2315: | throw new \Aurora\System\Exceptions\ApiException(1, null, 'User space limit must be less then tenant space limit'); |
2316: | } |
2317: | } |
2318: | |
2319: | $bResult = \Aurora\Modules\Core\Module::Decorator()->UpdateTenantObject($oTenant); |
2320: | } |
2321: | } |
2322: | if ($EntityType === 'User') { |
2323: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
2324: | $oUser = \Aurora\Modules\Core\Module::Decorator()->GetUserUnchecked($EntityId); |
2325: | |
2326: | if ($oUser instanceof \Aurora\Modules\Core\Models\User |
2327: | && $oAuthenticatedUser instanceof \Aurora\Modules\Core\Models\User |
2328: | && (($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oUser->IdTenant === $oAuthenticatedUser->IdTenant) |
2329: | || $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin)) { |
2330: | $oTenant = \Aurora\Modules\Core\Module::Decorator()->GetTenantUnchecked($oUser->IdTenant); |
2331: | |
2332: | $iTenantSpaceLimitMb = $oTenant->{self::GetName() . '::TenantSpaceLimitMb'}; |
2333: | if ($iTenantSpaceLimitMb > 0) { |
2334: | $iAllocatedSpaceForUsersInTenant = $this->GetAllocatedSpaceForUsersInTenant($oUser->IdTenant); |
2335: | $iNewAllocatedSpaceForUsersInTenant = $iAllocatedSpaceForUsersInTenant - $oUser->{self::GetName() . '::UserSpaceLimitMb'} + $UserSpaceLimitMb; |
2336: | if ($iNewAllocatedSpaceForUsersInTenant > $iTenantSpaceLimitMb) { |
2337: | throw new \Aurora\System\Exceptions\ApiException(1, null, 'Over quota'); |
2338: | } |
2339: | } |
2340: | |
2341: | $oUser->setExtendedProp(self::GetName() . '::UserSpaceLimitMb', $UserSpaceLimitMb); |
2342: | |
2343: | $bResult = \Aurora\Modules\Core\Module::Decorator()->UpdateUserObject($oUser); |
2344: | } |
2345: | } |
2346: | |
2347: | return $bResult; |
2348: | } |
2349: | |
2350: | public function UpdateUserSpaceLimit($UserId, $Limit) |
2351: | { |
2352: | $mResult = false; |
2353: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::TenantAdmin); |
2354: | |
2355: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
2356: | $oUser = \Aurora\Modules\Core\Module::Decorator()->GetUserUnchecked($UserId); |
2357: | |
2358: | if ($oUser instanceof \Aurora\Modules\Core\Models\User && $oAuthenticatedUser instanceof \Aurora\Modules\Core\Models\User && ( |
2359: | ($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oUser->IdTenant === $oAuthenticatedUser->IdTenant) || |
2360: | $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin |
2361: | ) |
2362: | ) { |
2363: | $oUser->setExtendedProp(self::GetName() . '::UserSpaceLimitMb', $Limit); |
2364: | $mResult = \Aurora\Modules\Core\Module::Decorator()->UpdateUserObject($oUser); |
2365: | } |
2366: | |
2367: | return $mResult; |
2368: | } |
2369: | |
2370: | public function UpdateTenantSpaceLimit($TenantId, $Limit) |
2371: | { |
2372: | $mResult = false; |
2373: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::SuperAdmin); |
2374: | |
2375: | $oAuthenticatedUser = \Aurora\System\Api::getAuthenticatedUser(); |
2376: | $oTenant= \Aurora\Modules\Core\Module::Decorator()->GetTenantUnchecked($TenantId); |
2377: | |
2378: | if ($oTenant instanceof Tenant && $oAuthenticatedUser instanceof User && ( |
2379: | ($oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::TenantAdmin && $oTenant->Id === $oAuthenticatedUser->IdTenant) || |
2380: | $oAuthenticatedUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin |
2381: | ) |
2382: | ) { |
2383: | $oTenant->setExtendedProp(self::GetName() . '::UserSpaceLimitMb', $Limit); |
2384: | $mResult = \Aurora\Modules\Core\Module::Decorator()->UpdateUserObject($oTenant); |
2385: | } |
2386: | |
2387: | return $mResult; |
2388: | } |
2389: | |
2390: | public function GetAllocatedSpaceForUsersInTenant($TenantId) |
2391: | { |
2392: | return User::where('IdTenant', $TenantId)->sum('Properties->Files::UserSpaceLimitMb'); |
2393: | } |
2394: | |
2395: | public function CheckAllocatedSpaceLimitForUsersInTenant($oTenant, $UserSpaceLimitMb) |
2396: | { |
2397: | $iTenantSpaceLimitMb = $oTenant->{self::GetName() . '::TenantSpaceLimitMb'}; |
2398: | $iAllocatedSpaceForUsersInTenant = $this->GetAllocatedSpaceForUsersInTenant($oTenant->Id); |
2399: | |
2400: | if ($iTenantSpaceLimitMb > 0 && $iAllocatedSpaceForUsersInTenant + $UserSpaceLimitMb > $iTenantSpaceLimitMb) { |
2401: | throw new \Aurora\System\Exceptions\ApiException(1, null, 'Over quota'); |
2402: | } |
2403: | } |
2404: | |
2405: | |
2406: | |
2407: | |
2408: | |
2409: | |
2410: | |
2411: | |
2412: | |
2413: | |
2414: | |
2415: | |
2416: | public function UpdateExtendedProps($UserId, $Type, $Path, $Name, $ExtendedProps) |
2417: | { |
2418: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2419: | |
2420: | return false; |
2421: | |
2422: | } |
2423: | |
2424: | public function GetExtendedProps($UserId = null, $Type = null, $Path = null, $Name = null) |
2425: | { |
2426: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2427: | |
2428: | if ($UserId === null || $Type === null || $Path === null || $Name === null) { |
2429: | throw new \Aurora\System\Exceptions\ApiException(\Aurora\System\Notifications::InvalidInputParameter); |
2430: | } |
2431: | |
2432: | return false; |
2433: | |
2434: | } |
2435: | |
2436: | public function GetAccessInfoForPath($UserId, $Type, $Path) |
2437: | { |
2438: | \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); |
2439: | |
2440: | |
2441: | return false; |
2442: | } |
2443: | |
2444: | } |
2445: | |