芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/www/cloud.pulsehost.co.uk/modules/DropboxFilestorage/Module.php
oModuleSettings; } protected function issetScope($sScope) { return in_array($sScope, explode(' ', $this->oModuleSettings->Scopes)); } /***** private functions *****/ /** * Initializes DropBox Module. * * @ignore */ public function init() { $this->subscribeEvent('Files::GetStorages::after', array($this, 'onAfterGetStorages')); $this->subscribeEvent('Files::GetFile', array($this, 'onGetFile')); $this->subscribeEvent('Files::GetItems', array($this, 'onGetItems')); $this->subscribeEvent('Files::CreateFolder::after', array($this, 'onAfterCreateFolder')); $this->subscribeEvent('Files::CreateFile', array($this, 'onCreateFile')); $this->subscribeEvent('Files::Delete::after', array($this, 'onAfterDelete')); $this->subscribeEvent('Files::Rename::after', array($this, 'onAfterRename')); $this->subscribeEvent('Files::Move::after', array($this, 'onAfterMove')); $this->subscribeEvent('Files::Copy::after', array($this, 'onAfterCopy')); $this->subscribeEvent('Files::GetFileInfo::after', array($this, 'onAfterGetFileInfo')); $this->subscribeEvent('Files::PopulateFileItem::after', array($this, 'onAfterPopulateFileItem')); $this->subscribeEvent('Dropbox::GetSettings', array($this, 'onGetSettings')); $this->subscribeEvent('Dropbox::UpdateSettings::after', array($this, 'onAfterUpdateSettings')); $this->subscribeEvent('Files::GetItems::before', array($this, 'onCheckUrlFile')); $this->subscribeEvent('Files::UploadFile::before', array($this, 'onCheckUrlFile')); $this->subscribeEvent('Files::CreateFolder::before', array($this, 'onCheckUrlFile')); $this->subscribeEvent('Files::CheckQuota::after', array($this, 'onAfterCheckQuota')); } /** * Obtains DropBox client if passed $sType is DropBox account type. * * @return \Kunnu\Dropbox\Dropbox */ protected function getClient() { $oDropboxModule = \Aurora\Modules\Dropbox\Module::getInstance(); if ($oDropboxModule) { if (!$oDropboxModule->oModuleSettings->EnableModule || !$this->issetScope('storage')) { return false; } } else { return false; } if ($this->oClient === null) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); $oOAuthIntegratorWebclientModule = \Aurora\Modules\OAuthIntegratorWebclient\Module::Decorator(); $oOAuthAccount = $oOAuthIntegratorWebclientModule->GetAccount(self::$sStorageType); $oTokenData = \json_decode($oOAuthAccount->AccessToken); if ($oTokenData && $oOAuthAccount) { $accessToken = $oTokenData->access_token; $iCreated = (int) $oTokenData->created; $iExpiresIn = (int) $oTokenData->expires_in; $now = new \DateTime(); $now->setTimezone(new \DateTimeZone('GMT')); if ($now->getTimestamp() > ($iCreated + $iExpiresIn) && isset($oOAuthAccount->RefreshToken)) { $oConnector = new \Aurora\Modules\DropboxAuthWebclient\Classes\Connector($this); $aResult = $oConnector->RefreshAccessToken( $oDropboxModule->oModuleSettings->Id, $oDropboxModule->oModuleSettings->Secret, $oOAuthAccount->RefreshToken ); if (isset($aResult['access_token'])) { $oTokenData->access_token = $aResult['access_token']; $oTokenData->created = $now->getTimestamp(); $oTokenData->expires_in = $aResult['expires_in']; $oOAuthAccount->AccessToken = \json_encode($oTokenData); $oOAuthAccount->save(); $accessToken = $oTokenData->access_token; } } $oDropboxApp = new \Kunnu\Dropbox\DropboxApp( $oDropboxModule->oModuleSettings->Id, $oDropboxModule->oModuleSettings->Secret, $accessToken ); $this->oClient = new \Kunnu\Dropbox\Dropbox($oDropboxApp); } } return $this->oClient; } /** * Write to the $mResult variable information about DropBox storage. * * @ignore * @param array $aArgs * @param array $mResult */ public function onAfterGetStorages($aArgs, &$mResult) { if ($this->CheckDropboxAccess()) { $mResult[] = [ 'Type' => self::$sStorageType, 'IsExternal' => true, 'DisplayName' => 'Dropbox', 'Order' => self::$iStorageOrder, 'IsDroppable' => true ]; } } /** * Returns directory name for the specified path. * * @param string $sPath Path to the file. * @return string */ protected function getDirName($sPath) { $sPath = dirname($sPath); return str_replace(DIRECTORY_SEPARATOR, '/', $sPath); } /** * Returns base name for the specified path. * * @param string $sPath Path to the file. * @return string */ protected function getBaseName($sPath) { $aPath = explode('/', $sPath); return end($aPath); } /** * * @param \Aurora\Modules\Files\Classes\FileItem $oItem * @return string */ protected function getItemHash($oItem) { return \Aurora\System\Api::EncodeKeyValues(array( 'UserId' => \Aurora\System\Api::getAuthenticatedUserId(), 'Type' => $oItem->TypeStr, 'Path' => '', 'Name' => $oItem->FullPath, 'FileName' => $oItem->Name )); } protected function hasThumb($sName) { return in_array( pathinfo($sName, PATHINFO_EXTENSION), ['jpg', 'jpeg', 'png', 'tiff', 'tif', 'gif', 'bmp'] ); } /** * Populates file info. * * @param \Kunnu\Dropbox\Models\FileMetadata|\Kunnu\Dropbox\Models\FolderMetadata $aData contains information about file. * @return \Aurora\Modules\Files\Classes\FileItem|false */ protected function populateFileInfo($aData) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); $mResult = false; if ($aData) { $sPath = ltrim($this->getDirName($aData->getPathDisplay()), '/'); $mResult /*@var $mResult \Aurora\Modules\Files\Classes\FileItem */ = new \Aurora\Modules\Files\Classes\FileItem(); $mResult->IsExternal = true; $mResult->TypeStr = self::$sStorageType; $mResult->IsFolder = ($aData instanceof \Kunnu\Dropbox\Models\FolderMetadata); $mResult->Id = $aData->getName(); $mResult->Name = $mResult->Id; $mResult->Path = !empty($sPath) ? '/' . $sPath : $sPath; $mResult->Size = !$mResult->IsFolder ? $aData->getSize() : 0; // $bResult->Owner = $oSocial->Name; if (!$mResult->IsFolder) { $mResult->LastModified = date("U", strtotime($aData->getServerModified())); } // $mResult->Shared = isset($aData['shared']) ? $aData['shared'] : false; $mResult->FullPath = $mResult->Name !== '' ? $mResult->Path . '/' . $mResult->Name : $mResult->Path ; $mResult->ContentType = \Aurora\System\Utils::MimeContentType($mResult->Name); $mResult->Thumb = $this->hasThumb($mResult->Name); if ($mResult->IsFolder) { $mResult->AddAction([ 'list' => [] ]); } else { $mResult->AddAction([ 'view' => [ 'url' => '?download-file/' . $this->getItemHash($mResult) . '/view' ] ]); $mResult->AddAction([ 'download' => [ 'url' => '?download-file/' . $this->getItemHash($mResult) ] ]); } } return $mResult; } /** * Writes to the $mResult variable open file source if $sType is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * @return bool|void */ public function onGetFile($aArgs, &$mResult) { if ($aArgs['Type'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $sFullPath = $aArgs['Path'] . '/' . ltrim($aArgs['Name'], '/'); if (isset($aArgs['IsThumb']) && (bool)$aArgs['IsThumb'] === true) { $oThumbnail = $oClient->getThumbnail($sFullPath, 'medium', 'png'); if ($oThumbnail) { $mResult = \fopen('php://memory', 'r+'); \fwrite($mResult, $oThumbnail->getContents()); \rewind($mResult); } } else { $mDownloadResult = $oClient->download($sFullPath); if ($mDownloadResult) { $mResult = \fopen('php://memory', 'r+'); \fwrite($mResult, $mDownloadResult->getContents()); \rewind($mResult); } } } return true; } } /** * Writes to $aArgs variable list of DropBox files if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs Is passed by reference. * @param mixed $mResult * * @return bool|void */ public function onGetItems($aArgs, &$mResult) { if ($aArgs['Type'] === self::$sStorageType) { $mResult = array(); $oClient = $this->getClient(); if ($oClient) { $aItems = array(); $Path = '/' . ltrim($aArgs['Path'], '/'); if (empty($aArgs['Pattern'])) { $oListFolderContents = $oClient->listFolder($Path); $oItems = $oListFolderContents->getItems(); $aItems = $oItems->all(); } else { $oListFolderContents = $oClient->search($Path, $aArgs['Pattern']); $oItems = $oListFolderContents->getItems(); $aItems = $oItems->all(); } foreach ($aItems as $oChild) { if ($oChild instanceof \Kunnu\Dropbox\Models\SearchResult) { $oChild = $oChild->getMetadata(); } $oItem /*@var $oItem \Aurora\Modules\Files\Classes\FileItem */ = $this->populateFileInfo($oChild); if ($oItem) { $mResult[] = $oItem; } } } return true; } } /** * Creates folder if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onAfterCreateFolder($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); if ($aArgs['Type'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $mResult = false; $sPath = $aArgs['Path']; if ($oClient->createFolder($sPath . '/' . $aArgs['FolderName']) !== null) { $mResult = true; } } return true; } } /** * Creates file if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onCreateFile($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); if ($aArgs['Type'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $mResult = false; $Path = $aArgs['Path'] . '/' . $aArgs['Name']; $rData = $aArgs['Data']; if (!is_resource($aArgs['Data'])) { $rData = fopen('php://memory', 'r+'); fwrite($rData, $aArgs['Data']); rewind($rData); } $oDropboxFile = \Kunnu\Dropbox\DropboxFile::createByStream($aArgs['Name'], $rData); if ($oClient->upload($oDropboxFile, $Path)) { $mResult = true; } return true; } } } /** * Deletes file if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onAfterDelete($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); if ($aArgs['Type'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $mResult = false; foreach ($aArgs['Items'] as $aItem) { $oClient->delete($aItem['Path'] . '/' . $aItem['Name']); $mResult = true; } } return true; } } /** * Renames file if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onAfterRename($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); if ($aArgs['Type'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $mResult = false; $sPath = $aArgs['Path']; if ($oClient->move($sPath . '/' . $aArgs['Name'], $sPath . '/' . $aArgs['NewName'])) { $mResult = true; } } } } /** * Moves file if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onAfterMove($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); if ($aArgs['FromType'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $mResult = false; if ($aArgs['ToType'] === $aArgs['FromType']) { foreach ($aArgs['Files'] as $aFile) { $oClient->move($aArgs['FromPath'] . '/' . $aFile['Name'], $aArgs['ToPath'] . '/' . $aFile['Name']); } $mResult = true; } } return true; } } /** * Copies file if $aArgs['Type'] is DropBox account type. * * @ignore * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onAfterCopy($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::NormalUser); if ($aArgs['FromType'] === self::$sStorageType) { $oClient = $this->getClient(); if ($oClient) { $mResult = false; if ($aArgs['ToType'] === $aArgs['FromType']) { foreach ($aArgs['Files'] as $aFile) { $oClient->copy($aArgs['FromPath'] . '/' . $aFile['Name'], $aArgs['ToPath'] . '/' . $aFile['Name']); } $mResult = true; } } return true; } } protected function _getFileInfo($sPath, $sName) { $mResult = false; $oClient = $this->GetClient(); if ($oClient) { $mResult = $oClient->getMetadata($sPath . '/' . $sName); } return $mResult; } /** * @ignore * @todo not used * @param array $aArgs * @param mixed $mResult * * @return bool|void */ public function onAfterGetFileInfo($aArgs, &$mResult) { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); if (self::$sStorageType === $aArgs['Type']) { $mFileInfo = $this->_getFileInfo($aArgs['Path'], $aArgs['Id']); if ($mFileInfo) { $mResult = $this->PopulateFileInfo($mFileInfo); } return true; } } /** * @ignore * @todo not used * @param array $aArgs * @param mixed $oItem * * @return bool|void */ public function onAfterPopulateFileItem($aArgs, &$oItem) { if ($oItem->IsLink) { if (false !== strpos($oItem->LinkUrl, 'dl.dropboxusercontent.com') || false !== strpos($oItem->LinkUrl, 'dropbox.com')) { $aMetadata = $this->getMetadataLink($oItem->LinkUrl); if (isset($aMetadata['path_lower']) && $aMetadata['.tag'] == 'folder') { $oItem->UnshiftAction(array( 'list' => array() )); $oItem->Thumb = true; $oItem->ThumbnailUrl = \MailSo\Base\Http::SingletonInstance()->GetFullUrl() . 'modules/' . self::GetName() . '/images/dropbox.png'; } $oItem->LinkType = 'dropbox'; return true; } } return false; } protected function getMetadataLink($sLink) { if (!$this->CheckDropboxAccess()) { return null; } $oClient = $this->getClient(); $response = $oClient->postToAPI( '/sharing/get_shared_link_metadata', array( 'url' => $sLink ) ); if ($response->getHttpStatusCode() === 404) { return null; } if ($response->getHttpStatusCode() !== 200) { return null; } $metadata = $response->getDecodedBody(); if (array_key_exists("is_deleted", $metadata) && $metadata["is_deleted"]) { return null; } return $metadata; } public function onCheckUrlFile(&$aArgs, &$mResult) { if ($this->CheckDropboxAccess() && (\pathinfo($aArgs['Path'], PATHINFO_EXTENSION) === 'url' || strpos($aArgs['Path'], '.url/'))) { list($sUrl, $sPath) = explode('.url', $aArgs['Path']); $sUrl .= '.url'; $aArgs['Path'] = $sUrl; $this->prepareArgs($aArgs); if ($sPath && $aArgs['Type'] === self::$sStorageType) { $aArgs['Path'] .= $sPath; } elseif ($aArgs['Type'] !== self::$sStorageType) { $aArgs['Path'] = $sUrl . $sPath; } } } protected function prepareArgs(&$aData) { $aPathInfo = pathinfo($aData['Path']); $sExtension = isset($aPathInfo['extension']) ? $aPathInfo['extension'] : ''; if ($sExtension === 'url') { $aArgs = array( 'UserId' => $aData['UserId'], 'Type' => $aData['Type'], 'Path' => $aPathInfo['dirname'], 'Name' => $aPathInfo['basename'], 'Id' => $aPathInfo['basename'], 'IsThumb' => false ); $mResult = false; \Aurora\System\Api::GetModuleManager()->broadcastEvent( 'Files', 'GetFile', $aArgs, $mResult ); if (is_resource($mResult)) { $aUrlFileInfo = \Aurora\System\Utils::parseIniString(stream_get_contents($mResult)); if ($aUrlFileInfo && isset($aUrlFileInfo['URL'])) { if (false !== strpos($aUrlFileInfo['URL'], 'dl.dropboxusercontent.com') || false !== strpos($aUrlFileInfo['URL'], 'dropbox.com')) { $aData['Type'] = 'dropbox'; $aMetadata = $this->getMetadataLink($aUrlFileInfo['URL']); if (isset($aMetadata['path_lower'])) { $aData['Path'] = $aMetadata['path_lower']; } } } } } } /***** private functions *****/ /** * Passes data to connect to service. * * @ignore * @param string $aArgs Service type to verify if data should be passed. * @param boolean|array $mResult variable passed by reference to take the result. */ public function onGetSettings($aArgs, &$mResult) { $oUser = \Aurora\System\Api::getAuthenticatedUser(); if ($oUser) { $aScope = array( 'Name' => 'storage', 'Description' => $this->i18N('SCOPE_FILESTORAGE'), 'Value' => false ); if ($oUser->Role === \Aurora\System\Enums\UserRole::SuperAdmin) { $aScope['Value'] = $this->issetScope('storage'); $mResult['Scopes'][] = $aScope; } if ($oUser->isNormalOrTenant()) { if ($aArgs['OAuthAccount'] instanceof \Aurora\Modules\OAuthIntegratorWebclient\Models\OauthAccount) { $aScope['Value'] = $aArgs['OAuthAccount']->issetScope('storage'); } if ($this->issetScope('storage')) { $mResult['Scopes'][] = $aScope; } } } } public function onAfterUpdateSettings($aArgs, &$mResult) { $sScope = ''; if (isset($aArgs['Scopes']) && is_array($aArgs['Scopes'])) { foreach ($aArgs['Scopes'] as $aScope) { if ($aScope['Name'] === 'storage') { if ($aScope['Value']) { $sScope = 'storage'; break; } } } } $this->setConfig('Scopes', $sScope); $this->saveModuleConfig(); } /** * Checks if storage type is personal. * * @param string $Type Storage type. * @return bool */ protected function checkStorageType($Type) { return $Type === static::$sStorageType; } /** * @ignore * @param array $aArgs Arguments of event. * @param mixed $mResult Is passed by reference. */ public function onAfterCheckQuota($aArgs, &$mResult) { $Type = $aArgs['Type']; if ($this->checkStorageType($Type)) { $mResult = true; return true; } } protected function CheckDropboxAccess() { \Aurora\System\Api::checkUserRoleIsAtLeast(\Aurora\System\Enums\UserRole::Anonymous); $bEnableDropboxModule = false; if (class_exists('Aurora\Modules\Dropbox\Module')) { $oDropboxModule = \Aurora\Modules\Dropbox\Module::getInstance(); $bEnableDropboxModule = $oDropboxModule->oModuleSettings->EnableModule; } $oOAuthIntegratorWebclientModule = \Aurora\Modules\OAuthIntegratorWebclient\Module::Decorator(); $oOAuthAccount = $oOAuthIntegratorWebclientModule->GetAccount(self::$sStorageType); return ($oOAuthAccount instanceof \Aurora\Modules\OAuthIntegratorWebclient\Models\OauthAccount && $oOAuthAccount->Type === self::$sStorageType && $bEnableDropboxModule && $this->issetScope('storage') && $oOAuthAccount->issetScope('storage')); } }