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\FilesWebclient;
9:
10: /**
11: * This module displays the web interface for managing files.
12: *
13: * @license https://www.gnu.org/licenses/agpl-3.0.html AGPL-3.0
14: * @license https://afterlogic.com/products/common-licensing Afterlogic Software License
15: * @copyright Copyright (c) 2023, Afterlogic Corp.
16: *
17: * @package Modules
18: */
19: class Module extends \Aurora\System\Module\AbstractWebclientModule
20: {
21: /**
22: *
23: * @var \CApiModuleDecorator
24: */
25: protected $oMinModuleDecorator = null;
26:
27: /**
28: *
29: * @var \CApiModuleDecorator
30: */
31: protected $oFilesModuleDecorator = null;
32:
33: /**
34: * @var array
35: */
36: protected $aRequireModules = ['Files', 'Min'];
37:
38: /***** private functions *****/
39: /**
40: * Initializes Files Module.
41: *
42: * @ignore
43: */
44: public function init()
45: {
46: $this->oFilesModuleDecorator = \Aurora\Modules\Files\Module::Decorator();
47: $this->oMinModuleDecorator = \Aurora\Modules\Min\Module::Decorator();
48:
49: $this->AddEntry('files-pub', 'EntryPub');
50: }
51:
52: /***** private functions *****/
53:
54: /***** public functions *****/
55: /**
56: * @ignore
57: */
58: public function EntryPub()
59: {
60: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
61:
62: $sHash = (string) \Aurora\System\Router::getItemByIndex(1, '');
63: $sAction = (string) \Aurora\System\Router::getItemByIndex(2, 'download');
64: $bSecure = \Aurora\System\Router::getItemByIndex(3, '') === 'secure';
65: $bDownload = !(!empty($sAction) && $sAction === 'view');
66: $bList = (!empty($sAction) && $sAction === 'list');
67: $sPassword = $bSecure ? rawurldecode(\Aurora\System\Router::getItemByIndex(4, '')) : '';
68: $aHash = $this->oMinModuleDecorator->GetMinByHash($sHash);
69:
70: $sType = isset($aHash['Type']) ? $aHash['Type'] : '';
71: $sPath = isset($aHash['Path']) ? $aHash['Path'] : '';
72: $sName = isset($aHash['Name']) ? $aHash['Name'] : '';
73: $sFullPath = \ltrim($sPath, '/') . '/' . \ltrim($sName, '/');
74: $sResourceId = $sType . '/' . \ltrim($sFullPath, '/');
75: if (isset($aHash['UserId'])) {
76: $aArgs = [
77: 'UserId' => $aHash['UserId'],
78: 'ResourceType' => 'file',
79: 'ResourceId' => $sResourceId,
80: 'Action' => $sAction
81: ];
82: $this->broadcastEvent('AddToActivityHistory', $aArgs);
83: }
84:
85: if ($bList) {
86: $sResult = '';
87: if ($this->oMinModuleDecorator) {
88: $mResult = null;
89: $this->broadcastEvent(
90: 'FileEntryPub',
91: $aHash,
92: $mResult
93: );
94: if ($mResult) {
95: $sResult = $mResult;
96: } else {
97: if (\is_array($aHash) && isset($aHash['IsFolder']) && $aHash['IsFolder']) {
98: $oApiIntegrator = \Aurora\System\Managers\Integrator::getInstance();
99:
100: if ($oApiIntegrator) {
101: $oCoreClientModule = \Aurora\System\Api::GetModule('CoreWebclient');
102: if ($oCoreClientModule instanceof \Aurora\System\Module\AbstractModule) {
103: $sResult = \file_get_contents($oCoreClientModule->GetPath().'/templates/Index.html');
104: if (\is_string($sResult)) {
105: $oSettings =& \Aurora\System\Api::GetSettings();
106: $sFrameOptions = $oSettings->GetValue('XFrameOptions', '');
107: if (0 < \strlen($sFrameOptions)) {
108: @\header('X-Frame-Options: '.$sFrameOptions);
109: }
110:
111: $aConfig = array(
112: 'public_app' => true,
113: 'modules_list' => $oApiIntegrator->GetModulesForEntry('FilesWebclient')
114: );
115:
116: $sResult = \strtr($sResult, array(
117: '{{AppVersion}}' => AU_APP_VERSION,
118: '{{IntegratorDir}}' => $oApiIntegrator->isRtl() ? 'rtl' : 'ltr',
119: '{{IntegratorLinks}}' => $oApiIntegrator->buildHeadersLink(),
120: '{{IntegratorBody}}' => $oApiIntegrator->buildBody($aConfig)
121: ));
122: }
123: }
124: }
125: } elseif ($aHash && isset($aHash['__hash__'], $aHash['Name'], $aHash['Size'])) {
126: $sUrl = (bool) $this->getConfig('ServerUseUrlRewrite', false) ? '/download/' : '?/files-pub/';
127:
128: $sUrlRewriteBase = (string) $this->getConfig('ServerUrlRewriteBase', '');
129: if (!empty($sUrlRewriteBase)) {
130: $sUrlRewriteBase = '<base href="'.$sUrlRewriteBase.'" />';
131: }
132:
133: $oModuleManager = \Aurora\System\Api::GetModuleManager();
134: $sTheme = $oModuleManager->getModuleConfigValue('CoreWebclient', 'Theme');
135: $sResult = \file_get_contents($this->GetPath().'/templates/FilesPub.html');
136: if (\is_string($sResult)) {
137: $sResult = \strtr($sResult, array(
138: '{{Url}}' => $sUrl.$aHash['__hash__'],
139: '{{FileName}}' => $aHash['Name'],
140: '{{FileSize}}' => \Aurora\System\Utils::GetFriendlySize($aHash['Size']),
141: '{{FileType}}' => \Aurora\System\Utils::GetFileExtension($aHash['Name']),
142: '{{BaseUrl}}' => $sUrlRewriteBase,
143: '{{Theme}}' => $sTheme,
144: ));
145: } else {
146: \Aurora\System\Api::Log('Empty template.', \Aurora\System\Enums\LogLevel::Error);
147: }
148: } else {
149: $oModuleManager = \Aurora\System\Api::GetModuleManager();
150: $sTheme = $oModuleManager->getModuleConfigValue('CoreWebclient', 'Theme');
151: $sResult = \file_get_contents($this->GetPath().'/templates/NotFound.html');
152: $sResult = \strtr($sResult, array(
153: '{{NotFound}}' => $this->oFilesModuleDecorator->i18N('INFO_NOTFOUND'),
154: '{{Theme}}' => $sTheme,
155: ));
156: }
157: }
158: }
159:
160: \Aurora\Modules\CoreWebclient\Module::Decorator()->SetHtmlOutputHeaders();
161: return $sResult;
162: } else {
163: \header('Cache-Control: no-cache', true);
164: if ($this->oMinModuleDecorator) {
165: if (isset($aHash['__hash__'])
166: && ((isset($aHash['IsFolder']) && (bool) $aHash['IsFolder'] === false) || !isset($aHash['IsFolder']))
167: && (
168: (
169: isset($aHash['Password'])
170: && $sPassword
171: && \Aurora\System\Utils::EncryptValue($sPassword) === $aHash['Password']
172: )
173: || !isset($aHash['Password'])
174: )
175: && isset($aHash['Type']) && isset($aHash['Path']) && isset($aHash['Name'])
176: ) {
177: $bskipCheckUserRoleStatus = \Aurora\Api::skipCheckUserRole(true);
178: echo $this->oFilesModuleDecorator->getRawFile(
179: null,
180: $aHash['Type'],
181: $aHash['Path'],
182: $aHash['Name'],
183: $sHash,
184: $sAction
185: );
186: \Aurora\Api::skipCheckUserRole($bskipCheckUserRoleStatus);
187: $aArgs = [
188: 'UserId' => $aHash['UserId'],
189: 'ResourceType' => 'file',
190: 'ResourceId' => $sResourceId,
191: 'Action' => $sAction . '-finish'
192: ];
193: $this->broadcastEvent('AddToActivityHistory', $aArgs);
194: } else {
195: $aArgs = [
196: 'UserId' => $aHash['UserId'],
197: 'ResourceType' => 'file',
198: 'ResourceId' => $sResourceId,
199: 'Action' => 'wrong-password'
200: ];
201: $this->broadcastEvent('AddToActivityHistory', $aArgs);
202:
203: $sResult = \file_get_contents($this->GetPath().'/templates/NotFound.html');
204: $sResult = \strtr($sResult, array(
205: '{{NotFound}}' => $this->oFilesModuleDecorator->i18N('INFO_NOTFOUND')
206: ));
207:
208: \Aurora\Modules\CoreWebclient\Module::Decorator()->SetHtmlOutputHeaders();
209: return $sResult;
210: }
211: }
212: }
213: }
214:
215: public function GetSettings()
216: {
217: \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous);
218:
219: $aModuleSettings = array(
220: 'EditFileNameWithoutExtension' => $this->getConfig('EditFileNameWithoutExtension', false),
221: 'ShowCommonSettings' => $this->getConfig('ShowCommonSettings', false),
222: 'ServerUrlRewriteBase' => $this->getConfig('ServerUrlRewriteBase', false),
223: 'ServerUseUrlRewrite' => $this->getConfig('ServerUseUrlRewrite', false),
224: 'ShowFilesApps' => $this->getConfig('ShowFilesApps', true),
225: 'BottomLeftCornerLinks' => $this->getConfig('BottomLeftCornerLinks', []),
226: 'PublicLinksEnabled' => $this->getConfig('PublicLinksEnabled', true),
227: 'FilesSortBy' => $this->getConfig('FilesSortBy', [])
228: );
229:
230: return $aModuleSettings;
231: }
232: }
233: