BxDolStorageS3.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) BoonEx Pty Limited - http://www.boonex.com/
  4. * CC-BY License - http://creativecommons.org/licenses/by/3.0/
  5. *
  6. * @defgroup DolphinCore Dolphin Core
  7. * @{
  8. */
  9. define ('BX_DOL_STORAGE_PUBLIC', 'public');
  10. define ('BX_DOL_STORAGE_PRIVATE', 'private');
  11. define ('BX_DOL_STORAGE_DIR_RIGHT', 0700);
  12. define ('BX_DOL_STORAGE_FILE_RIGHT', 0400);
  13. bx_import('BxDolStorage');
  14. require_once(BX_DIRECTORY_PATH_PLUGINS . 'amazon-s3/S3.php');
  15. /**
  16. * File storage in Amazon S3.
  17. * @see BxDolStorage
  18. */
  19. class BxDolStorageS3 extends BxDolStorage
  20. {
  21. protected $_s3;
  22. protected $_sBucket;
  23. protected $_sDomain;
  24. protected $_bSSL;
  25. protected $_bReducedRedundancy;
  26. /**
  27. * constructor
  28. */
  29. public function __construct($aObject)
  30. {
  31. parent::__construct($aObject);
  32. $sAccessKey = getParam('sys_storage_s3_access_key');
  33. $sSecretKey = getParam('sys_storage_s3_secret_key');
  34. $this->_s3 = new S3($sAccessKey, $sSecretKey);
  35. $this->_sBucket = getParam('sys_storage_s3_bucket');
  36. $this->_sDomain = getParam('sys_storage_s3_domain');
  37. $this->_bSSL = isset($this->_aParams['ssl']) && $this->_aParams['ssl'] ? true : false;
  38. $this->_bReducedRedundancy = isset($this->_aParams['reduced_redundancy']) && $this->_aParams['reduced_redundancy'] ? true : false;
  39. }
  40. /**
  41. * Get file url.
  42. * @param $iFileId file
  43. * @return file url
  44. */
  45. public function getFileUrlById($iFileId)
  46. {
  47. $aFile = $this->_oDb->getFileById($iFileId);
  48. if (!$aFile)
  49. return false;
  50. if ($aFile['private']) {
  51. $sFileLocation = $this->getObjectBaseDir($aFile['private']) . $aFile['path'];
  52. if ($this->_sDomain)
  53. return $this->_s3->getAuthenticatedURL($this->_sDomain, $sFileLocation, $this->_aObject['token_life'], true, $this->_bSSL);
  54. else
  55. return $this->_s3->getAuthenticatedURL($this->_sBucket, $sFileLocation, $this->_aObject['token_life'], false, $this->_bSSL);
  56. }
  57. return $this->getObjectBaseUrl($aFile['private']) . $aFile['path'];
  58. }
  59. /**
  60. * Set file private or public.
  61. */
  62. public function setFilePrivate($iFileId, $isPrivate = true)
  63. {
  64. $aFile = $this->_oDb->getFileById($iFileId);
  65. $sFileLocation = $this->getObjectBaseDir($aFile['private']) . $aFile['path'];
  66. if (($aACP = $this->_s3->getAccessControlPolicy($this->_sBucket, $sFileLocation)) === false) {
  67. $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_GET);
  68. return false;
  69. }
  70. if (!is_array($aACP['acl']) || !$aACP['acl']) {
  71. $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_GET);
  72. return false;
  73. }
  74. // check current permissions
  75. $aNewACP = $aACP;
  76. unset($aNewACP['acl']);
  77. $aNewACP['acl'] = array();
  78. $aGroupPublic = false;
  79. $aGroupPrivate = false;
  80. foreach ($aACP['acl'] as $r) {
  81. if ('Group' == $r['type']) {
  82. if (isset($r['uri']) && $r['uri'] == 'http://acs.amazonaws.com/groups/global/AllUsers')
  83. $aGroupPublic = $r;
  84. elseif (isset($r['uri']) && $r['uri'] == 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers')
  85. $aGroupPrivate = $r;
  86. else
  87. $aNewACP['acl'][] = $r;
  88. } else {
  89. $aNewACP['acl'][] = $r;
  90. }
  91. }
  92. // determine permissions changing
  93. $aGroupAdd = false;
  94. if ($isPrivate && (!$aGroupPrivate || $aGroupPublic)) {
  95. // make private
  96. $aGroupAdd = array (
  97. 'type' => 'Group',
  98. 'uri' => 'http://acs.amazonaws.com/groups/global/AuthenticatedUsers',
  99. 'permission' => 'READ',
  100. );
  101. } elseif (!$isPrivate && ($aGroupPrivate || !$aGroupPublic)) {
  102. // make public
  103. $aGroupAdd = array (
  104. 'type' => 'Group',
  105. 'uri' => 'http://acs.amazonaws.com/groups/global/AllUsers',
  106. 'permission' => 'READ',
  107. );
  108. }
  109. // change permission if necessary
  110. if ($aGroupAdd) {
  111. $aNewACP['acl'][] = $aGroupAdd;
  112. if (!$this->_s3->setAccessControlPolicy($this->_sBucket, $sFileLocation, $aNewACP)) {
  113. $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_GET);
  114. return false;
  115. }
  116. }
  117. return parent::setFilePrivate($iFileId, $isPrivate);
  118. }
  119. // ----------------
  120. protected function addFileToEngine($sTmpFile, $sLocalId, $sName, $isPrivate, $iProfileId)
  121. {
  122. $sMimeType = $this->getMimeTypeByFileName($sName);
  123. $sExt = $this->getFileExt($sName);
  124. $sPath = $this->genPath($sLocalId, $this->_aObject['levels']);
  125. $sRemoteNamePath = $sPath . $sLocalId . ($sExt ? '.' . $sExt : '');
  126. $aMetaHeaders = array();
  127. $aRequestHeaders = array (
  128. "Content-Type" => $sMimeType,
  129. );
  130. if ($this->_iCacheControl > 0) {
  131. $aRequestHeaders = array_merge ($aRequestHeaders, array (
  132. "Cache-Control" => "max-age=" . ($isPrivate && $this->_iCacheControl > $this->_aObject['token_life'] ? $this->_aObject['token_life'] : $this->_iCacheControl),
  133. ));
  134. }
  135. $sStorageClass = $this->_bReducedRedundancy ? S3::STORAGE_CLASS_RRS : S3::STORAGE_CLASS_STANDARD;
  136. $sACL = $isPrivate ? S3::ACL_AUTHENTICATED_READ : S3::ACL_PUBLIC_READ;
  137. $aInputFile = $this->_s3->inputFile($sTmpFile);
  138. if (!$this->_s3->putObject($aInputFile, $this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath, $sACL, $aMetaHeaders, $aRequestHeaders, $sStorageClass)) {
  139. $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD);
  140. return false;
  141. }
  142. return true;
  143. }
  144. protected function deleteFileFromEngine($sFilePath, $isPrivate)
  145. {
  146. $sFileLocation = $this->getObjectBaseDir($isPrivate) . $sFilePath;
  147. if (!$this->_s3->deleteObject($this->_sBucket, $sFileLocation)) {
  148. $this->setErrorCode(BX_DOL_STORAGE_ERR_UNLINK);
  149. return false;
  150. }
  151. return true;
  152. }
  153. protected function genRemoteNamePath ($sPath, $sLocalId, $sExt)
  154. {
  155. return $sPath . $sLocalId . ($sExt ? '.' . $sExt : '');
  156. }
  157. protected function getObjectBaseDir ($isPrivate = false)
  158. {
  159. return $this->_aObject['object'] . '/';
  160. }
  161. protected function getObjectBaseUrl ($isPrivate = false)
  162. {
  163. $sProto = $this->_bSSL ? 'https://' : 'http://';
  164. return $sProto . $this->_sBucket . '.s3.amazonaws.com/' . $this->getObjectBaseDir($isPrivate);
  165. }
  166. }
  167. /** @} */