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