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\PersonalFiles; |
9: | |
10: | use Aurora\Api; |
11: | use Aurora\Modules\PersonalFiles\Storages\Sabredav\Storage; |
12: | use Aurora\System\EventEmitter; |
13: | |
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: | * @package Filestorage |
20: | * |
21: | * @property Module $oModule |
22: | */ |
23: | class Manager extends \Aurora\System\Managers\AbstractManagerWithStorage |
24: | { |
25: | /** |
26: | * @var \Aurora\Modules\PersonalFiles\Storages\Sabredav\Storage |
27: | */ |
28: | public $oStorage; |
29: | |
30: | /** |
31: | * @param \Aurora\System\Module\AbstractModule $oModule |
32: | */ |
33: | public function __construct(\Aurora\System\Module\AbstractModule $oModule = null) |
34: | { |
35: | parent::__construct($oModule, new Storage($this)); |
36: | } |
37: | |
38: | /** |
39: | * Returns Min module decorator. |
40: | * |
41: | * @return \Aurora\Modules\Min\Module |
42: | */ |
43: | public function getMinModuleDecorator() |
44: | { |
45: | static $oMinModuleDecorator = null; |
46: | if ($oMinModuleDecorator === null) { |
47: | $oMinModuleDecorator = \Aurora\Modules\Min\Module::Decorator(); |
48: | } |
49: | |
50: | return $oMinModuleDecorator; |
51: | } |
52: | |
53: | /** |
54: | * Checks if file exists. |
55: | * |
56: | * @param int $UserId Account object. |
57: | * @param int $Type Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
58: | * @param string $Path Path to the folder which contains the file, empty string means the file is in the root folder. |
59: | * @param string $Name Filename. |
60: | * |
61: | * @return bool |
62: | */ |
63: | public function IsFileExists($UserId, $Type, $Path, $Name) |
64: | { |
65: | return $this->oStorage->isFileExists($UserId, $Type, $Path, $Name); |
66: | } |
67: | |
68: | /** |
69: | * Retrieves array of metadata on the specific file. |
70: | * |
71: | * @param int $iUserId Account object |
72: | * @param string $sType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
73: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
74: | * @param string $sName Filename. |
75: | * |
76: | * @return \Aurora\Modules\Files\Classes\FileItem |
77: | */ |
78: | public function getFileInfo($iUserId, $sType, $sPath, $sName) |
79: | { |
80: | $oResult = null; |
81: | |
82: | $oItem = \Afterlogic\DAV\Server::getNodeForPath('files/' . $sType . $sPath . '/' . $sName, $iUserId); |
83: | |
84: | if ($oItem) { |
85: | $oResult = $this->oStorage->getFileInfo($iUserId, $sType, $oItem, null, $sPath); |
86: | } |
87: | return $oResult; |
88: | } |
89: | |
90: | /** |
91: | * Retrieves array of metadata on the specific directory. |
92: | * |
93: | * @param int $iUserId Account object |
94: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
95: | * @param string $sPath Path to the folder. |
96: | * |
97: | * @return \Aurora\Modules\Files\Classes\FileItem |
98: | */ |
99: | public function getDirectoryInfo($iUserId, $iType, $sPath) |
100: | { |
101: | return $this->oStorage->getDirectoryInfo($iUserId, $iType, $sPath); |
102: | } |
103: | |
104: | /** |
105: | * Retrieves object on the specific directory. |
106: | * |
107: | * @param int $iUserId Account object |
108: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
109: | * |
110: | * @return \Aurora\Modules\Files\Classes\FileItem |
111: | */ |
112: | public function getDirectory($iUserId, $iType) |
113: | { |
114: | return $this->oStorage->getDirectory($iUserId, $iType); |
115: | } |
116: | |
117: | /** |
118: | * Allows for reading contents of the file. |
119: | * |
120: | * @param int $iUserId Account object |
121: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
122: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
123: | * @param string $sName Filename. |
124: | * |
125: | * @return resource|bool |
126: | */ |
127: | public function getFile($iUserId, $iType, $sPath, $sName) |
128: | { |
129: | return $this->oStorage->getFile($iUserId, $iType, $sPath, $sName); |
130: | } |
131: | |
132: | /** |
133: | * Creates public link for specific file or folder. |
134: | * |
135: | * @param int $iUserId |
136: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
137: | * @param string $sPath Path to the folder. |
138: | * @param string $sName Filename. |
139: | * @param string $sSize Size information, it will be displayed when recipient opens the link. |
140: | * @param string $bIsFolder If **true**, it is assumed the link is created for a folder, **false** otherwise. |
141: | * |
142: | * @return string|bool |
143: | */ |
144: | public function createPublicLink($iUserId, $iType, $sPath, $sName, $sSize, $bIsFolder) |
145: | { |
146: | return $this->oStorage->createPublicLink($iUserId, $iType, $sPath, $sName, $sSize, $bIsFolder); |
147: | } |
148: | |
149: | /** |
150: | * Removes public link created for specific file or folder. |
151: | * |
152: | * @param int $iUserId |
153: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
154: | * @param string $sPath Path to the folder. |
155: | * @param string $sName Filename. |
156: | * |
157: | * @return bool |
158: | */ |
159: | public function deletePublicLink($iUserId, $iType, $sPath, $sName) |
160: | { |
161: | return $this->oStorage->deletePublicLink($iUserId, $iType, $sPath, $sName); |
162: | } |
163: | |
164: | /** |
165: | * Performs search for files. |
166: | * |
167: | * @param int $iUserId |
168: | * @param string $sType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
169: | * @param string $sPath Path to the folder. |
170: | * @param string $sPattern Search string. |
171: | * @param string $sPublicHash Public hash. |
172: | * |
173: | * @return array|bool array of \Aurora\Modules\Files\Classes\FileItem. |
174: | */ |
175: | public function getFiles($iUserId, $sType, $sPath, $sPattern = '', $sPublicHash = null, $bIsShared = false) |
176: | { |
177: | $aFiles = $this->oStorage->getFiles($iUserId, $sType, $sPath, $sPattern, $sPublicHash, $bIsShared); |
178: | $aUsers = array(); |
179: | foreach ($aFiles as $oFile) { |
180: | if (!isset($aUsers[$oFile->Owner])) { |
181: | $oUser = \Aurora\Modules\Core\Module::Decorator()->GetUserByPublicId($oFile->Owner); |
182: | $aUsers[$oFile->Owner] = $oUser ? $oUser->PublicId : ''; |
183: | } |
184: | $oFile->Owner = $aUsers[$oFile->Owner]; |
185: | } |
186: | |
187: | return $aFiles; |
188: | } |
189: | |
190: | /** |
191: | * Creates a new folder. |
192: | * |
193: | * @param int $iUserId |
194: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
195: | * @param string $sPath Path to the parent folder, empty string means top-level folder is created. |
196: | * @param string $sFolderName Folder name. |
197: | * |
198: | * @return bool |
199: | */ |
200: | public function createFolder($iUserId, $iType, $sPath, $sFolderName) |
201: | { |
202: | return $this->oStorage->createFolder($iUserId, $iType, $sPath, $sFolderName); |
203: | } |
204: | |
205: | /** |
206: | * Creates a new file. |
207: | * |
208: | * @param int $iUserId Account object |
209: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
210: | * @param string $sPath Path to the folder which contains the file, empty string means the file is created in the root folder. |
211: | * @param string $sFileName Filename. |
212: | * @param $mData Data to be stored in the file. |
213: | * @param bool $bOverride If **true**, existing file with that name will be overwritten. |
214: | * |
215: | * @return bool |
216: | */ |
217: | public function createFile($iUserId, $iType, $sPath, $sFileName, $mData, $bOverride = true, $rangeType = 0, $offset = 0, $extendedProps = []) |
218: | { |
219: | if (!$bOverride) { |
220: | $sFileName = $this->oStorage->getNonExistentFileName($iUserId, $iType, $sPath, $sFileName); |
221: | } |
222: | // else if (!$rangeType) |
223: | // { |
224: | // // rangeType 2 means override existing file |
225: | // $rangeType = 2; |
226: | // } |
227: | |
228: | return $this->oStorage->createFile($iUserId, $iType, $sPath, $sFileName, $mData, $rangeType, $offset, $extendedProps); |
229: | } |
230: | |
231: | /** |
232: | * Creates a link to arbitrary online content. |
233: | * |
234: | * @param int $iUserId Account object |
235: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
236: | * @param string $sPath Path to the folder which contains the link. |
237: | * @param string $sLink URL of the item to be linked. |
238: | * @param string $sName Name of the link. |
239: | * |
240: | * @return bool |
241: | */ |
242: | public function createLink($iUserId, $iType, $sPath, $sLink, $sName) |
243: | { |
244: | return $this->oStorage->createLink($iUserId, $iType, $sPath, $sLink, $sName); |
245: | } |
246: | |
247: | /** |
248: | * Removes file or folder. |
249: | * |
250: | * @param int $iUserId Account object |
251: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
252: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
253: | * @param string $sName Filename. |
254: | * |
255: | * @return bool |
256: | */ |
257: | public function delete($iUserId, $iType, $sPath, $sName) |
258: | { |
259: | return $this->oStorage->delete($iUserId, $iType, $sPath, $sName); |
260: | } |
261: | |
262: | /** |
263: | * Renames file or folder. |
264: | * |
265: | * @param int $iUserId Account object |
266: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
267: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
268: | * @param string $sName Name of file or folder. |
269: | * @param string $sNewName New name. |
270: | * @param bool $bIsLink |
271: | * |
272: | * @return bool |
273: | */ |
274: | public function rename($iUserId, $iType, $sPath, $sName, $sNewName, $bIsLink) |
275: | { |
276: | return $this->oStorage->rename($iUserId, $iType, $sPath, $sName, $sNewName); |
277: | } |
278: | |
279: | /** |
280: | * Move file or folder to a different location. In terms of Aurora, item can be moved to a different storage as well. |
281: | * |
282: | * @param int $iUserId Account object |
283: | * @param int $iFromType Source storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
284: | * @param int $iToType Destination storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
285: | * @param string $sFromPath Path to the folder which contains the item. |
286: | * @param string $sToPath Destination path of the item. |
287: | * @param string $sName Current name of file or folder. |
288: | * @param string $sNewName New name of the item. |
289: | * |
290: | * @return bool |
291: | */ |
292: | public function move($iUserId, $iFromType, $iToType, $sFromPath, $sToPath, $sName, $sNewName) |
293: | { |
294: | $GLOBALS['__FILESTORAGE_MOVE_ACTION__'] = true; |
295: | $bResult = $this->oStorage->copy($iUserId, $iFromType, $iToType, $sFromPath, $sToPath, $sName, $sNewName, true); |
296: | $GLOBALS['__FILESTORAGE_MOVE_ACTION__'] = false; |
297: | return $bResult; |
298: | } |
299: | |
300: | /** |
301: | * Copies file or folder, optionally renames it. |
302: | * |
303: | * @param int $iUserId Account object |
304: | * @param int $iFromType Source storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
305: | * @param int $iToType Destination storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
306: | * @param string $sFromPath Path to the folder which contains the item. |
307: | * @param string $sToPath Destination path of the item. |
308: | * @param string $sName Current name of file or folder. |
309: | * @param string $sNewName New name of the item. |
310: | * |
311: | * @return bool |
312: | */ |
313: | public function copy($iUserId, $iFromType, $iToType, $sFromPath, $sToPath, $sName, $sNewName = null, $bMove = false) |
314: | { |
315: | return $this->oStorage->copy($iUserId, $iFromType, $iToType, $sFromPath, $sToPath, $sName, $sNewName, $bMove); |
316: | } |
317: | |
318: | /** |
319: | * Returns space used by the user in specified storages, in bytes. |
320: | * |
321: | * @param int $iUserId User identifier. |
322: | * @param array $aTypes Storage type list. Accepted values in array: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
323: | * |
324: | * @return int; |
325: | */ |
326: | public function getUserSpaceUsed($iUserId, $aTypes = array(\Aurora\System\Enums\FileStorageType::Personal)) |
327: | { |
328: | return $this->oStorage->getUserSpaceUsed($iUserId, $aTypes); |
329: | } |
330: | |
331: | /** |
332: | * Allows for obtaining filename which doesn't exist in current directory. For example, if you need to store **data.txt** file but it already exists, this method will return **data_1.txt**, or **data_2.txt** if that one already exists, and so on. |
333: | * |
334: | * @param int $iUserId Account object |
335: | * @param int $iType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
336: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
337: | * @param string $sFileName Filename. |
338: | * |
339: | * @return string |
340: | */ |
341: | public function getNonExistentFileName($iUserId, $iType, $sPath, $sFileName, $bWithoutGroup = false) |
342: | { |
343: | return $this->oStorage->getNonExistentFileName($iUserId, $iType, $sPath, $sFileName, $bWithoutGroup); |
344: | } |
345: | |
346: | /** |
347: | * |
348: | * @param string $sPublicId |
349: | */ |
350: | public function ClearFiles($sPublicId) |
351: | { |
352: | $this->oStorage->clearPrivateFiles($sPublicId); |
353: | } |
354: | |
355: | /** |
356: | * |
357: | * @param string $sUserPublicId |
358: | * @param string $sType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
359: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
360: | * @param string $sName Filename. |
361: | * @param array $aExtendedProps |
362: | * |
363: | * @return bool |
364: | */ |
365: | public function updateExtendedProps($sUserPublicId, $sType, $sPath, $sName, $aExtendedProps) |
366: | { |
367: | $bResult = false; |
368: | |
369: | $oItem = \Afterlogic\DAV\Server::getNodeForPath('files/' . $sType . $sPath . '/' . $sName, $sUserPublicId); |
370: | if ($oItem instanceof \Afterlogic\DAV\FS\File) { |
371: | $aCurrentExtendedProps = $oItem->getProperty('ExtendedProps'); |
372: | foreach ($aExtendedProps as $sPropName => $propValue) { |
373: | if ($propValue === null) { |
374: | unset($aCurrentExtendedProps[$sPropName]); |
375: | } else { |
376: | $aCurrentExtendedProps[$sPropName] = $propValue; |
377: | } |
378: | } |
379: | $oItem->setProperty('ExtendedProps', $aCurrentExtendedProps); |
380: | $bResult = true; |
381: | } |
382: | |
383: | return $bResult; |
384: | } |
385: | |
386: | /** |
387: | * |
388: | * @param string $sUserPublicId |
389: | * @param string $sType Storage type. Accepted values: **\Aurora\System\Enums\FileStorageType::Personal**, **\Aurora\System\Enums\FileStorageType::Corporate**, **\Aurora\System\Enums\FileStorageType::Shared**. |
390: | * @param string $sPath Path to the folder which contains the file, empty string means the file is in the root folder. |
391: | * @param string $sName Filename. |
392: | * |
393: | * @return bool |
394: | */ |
395: | public function getExtendedProps($sUserPublicId, $sType, $sPath, $sName) |
396: | { |
397: | $aResult = []; |
398: | |
399: | $oItem = \Afterlogic\DAV\Server::getNodeForPath('files/' . $sType . $sPath . '/' . $sName, $sUserPublicId); |
400: | if ($oItem instanceof \Afterlogic\DAV\FS\File) { |
401: | $aResult = $oItem->getProperty('ExtendedProps'); |
402: | } |
403: | |
404: | $aArgs = [ |
405: | 'UserId' => Api::getUserIdByPublicId($sUserPublicId), |
406: | 'Type' => $sType, |
407: | 'Path' => $sPath, |
408: | 'Name' => $sName, |
409: | 'Item' => $oItem |
410: | ]; |
411: | EventEmitter::getInstance()->emit('Files', 'PopulateExtendedProps', $aArgs, $aResult); |
412: | |
413: | return $aResult; |
414: | } |
415: | } |
416: |