Changeset 15476
- Timestamp:
- 09/01/11 02:04:56 (9 months ago)
- Location:
- trunk
- Files:
-
- 14 added
- 11 edited
-
contact.php (modified) (1 diff)
-
inc/classes/BxDolDb.php (modified) (1 diff)
-
inc/classes/BxDolStorage.php (modified) (9 diffs)
-
inc/classes/BxDolStorageLocal.php (modified) (2 diffs)
-
inc/classes/BxDolStorageQuery.php (modified) (2 diffs)
-
inc/classes/BxDolStorageS3.php (modified) (2 diffs)
-
inc/classes/BxDolUploader.php (added)
-
inc/js/classes/BxDolUploader.js (added)
-
inc/languages.inc.php (modified) (1 diff)
-
install/langs/lang-en.php (modified) (2 diffs)
-
install/sql/v70.sql (modified) (1 diff)
-
plugins/fileuploader.js (added)
-
storage_uploader.php (added)
-
templates/base/css/uploaders.css (added)
-
templates/base/images/loading-spinner.gif (added)
-
templates/base/popup_box.html (modified) (1 diff)
-
templates/base/scripts/BxBaseFormView.php (modified) (9 diffs)
-
templates/base/scripts/BxBaseUploaderHTML5.php (added)
-
templates/base/scripts/BxBaseUploaderSimple.php (added)
-
templates/base/uploader_button_html5.html (added)
-
templates/base/uploader_button_simple.html (added)
-
templates/base/uploader_form_html5.html (added)
-
templates/base/uploader_form_simple.html (added)
-
templates/tmpl_uni/scripts/BxTemplUploaderHTML5.php (added)
-
templates/tmpl_uni/scripts/BxTemplUploaderSimple.php (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/contact.php
r15338 r15476 90 90 ), 91 91 ), 92 93 94 'attachments' => array( 95 'type' => 'files', 96 'storage_object' => 'sample2', 97 'uploaders' => array ('Simple', 'HTML5'), 98 'name' => 'attachments', 99 'caption' => _t('_Attachments'), 100 'required' => true, 101 ), 102 92 103 'captcha' => array( 93 104 'type' => 'captcha', -
trunk/inc/classes/BxDolDb.php
r15425 r15476 619 619 * This function is usefull when you need to form array of parameters to pass to IN(...) SQL construction. 620 620 * Example: 621 * \code621 * @code 622 622 * $a = array(2, 4.5, 'apple', 'car'); 623 623 * $s = "SELECT * FROM `t` WHERE `a` IN (" . $oDb->implode_escape($a) . ")"; 624 624 * echo $s; // outputs: SELECT * FROM `t` WHERE `a` IN (2, 4.5, 'apple', 'car') 625 * \endcode625 * @endcode 626 626 * 627 627 * @param $mixed array or parameters or just one paramter -
trunk/inc/classes/BxDolStorage.php
r15453 r15476 33 33 */ 34 34 35 define('BX_DOL_STORAGE_ERR_NO_INPUT_METHOD', 1000); ///< there is such input method available 35 36 define('BX_DOL_STORAGE_ERR_NO_FILE', 1001); ///< there is no file to upload 36 37 define('BX_DOL_STORAGE_INVALID_FILE', 1002); ///< uploaded file is invalid or hack attempts … … 53 54 define('BX_DOL_STORAGE_DEFAULT_MIME_TYPE', 'octet/stream'); ///< default mime type if it is not find by extension 54 55 56 55 57 bx_import('BxDolStorageQuery'); 56 58 … … 159 161 * @return id of added file on success, false on error - to get exact error code call getErrorCode() 160 162 */ 161 public function storeFile($sFilePath, $sName, $isPrivate = false, $iProfileId = 0) { } 163 public function storeFile($sMethod, $aMethodParams, $sName = false, $isPrivate = false, $iProfileId = 0) { 164 165 // setup input source using helper classes, like $_FILES or some URL for example 166 167 $sHelperClass = 'BxDolStorageHelper' . $sMethod; 168 if (!class_exists($sHelperClass)) { 169 $this->setErrorCode(BX_DOL_STORAGE_ERR_NO_INPUT_METHOD); 170 return false; 171 } 172 173 $oHelper = new $sHelperClass($aMethodParams); 174 175 // check for errors, like size and extentions checking 176 177 if ($iImmediateError = $oHelper->getImmediateError()) { 178 $this->setErrorCode($iImmediateError); 179 return false; 180 } 181 182 $sExt = $this->getFileExt($oHelper->getName()); 183 $sMimeType = $this->getMimeTypeByFileName($oHelper->getName()); 184 185 if (!$this->isValidExt($sExt)) { 186 $this->setErrorCode(BX_DOL_STORAGE_ERR_WRONG_EXT); 187 return false; 188 } 189 190 // before aupload callback + additional checking 191 192 if (!$this->onBeforeFileAdd (array( 193 'profile_id' => $iProfileId, 194 'file_name' => $oHelper->getName(), 195 'mime_type' => $sMimeType, 196 'ext' => $sExt, 197 'size' => $oHelper->getSize(), 198 'private' => $isPrivate ? 1 : 0, 199 ))) { 200 return false; 201 } 202 203 // create tmp file 204 205 $sTmpFile = $temp_file = tempnam(sys_get_temp_dir(), 'bxdol');; 206 if (!$oHelper->save($sTmpFile)) { 207 $this->setErrorCode(BX_DOL_STORAGE_INVALID_FILE); 208 return false; 209 } 210 211 // store file to storage engine 212 213 $sLocalId = $this->genRandName(); 214 $sPath = $this->genPath($sLocalId, $this->_aObject['levels']); 215 $sRemoteNamePath = $this->genRemoteNamePath ($sPath, $sLocalId, $sExt); 216 217 if (!$this->addFileToEngine($sTmpFile, $sLocalId, $oHelper->getName(), $isPrivate, $iProfileId)) { 218 unlink($sTmpFile); 219 $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD); 220 } 221 unlink($sTmpFile); 222 223 // add record in db 224 225 $iTime = time(); 226 $iSize = $oHelper->getSize(); 227 $bFileAdded = $this->_oDb->addFile($iProfileId, $sLocalId, $sRemoteNamePath, $oHelper->getName(), $sMimeType, $sExt, $iSize, $iTime, $isPrivate); 228 $iId = $this->_oDb->lastId(); 229 if (!$bFileAdded || !$iId) { 230 $this->deleteFileFromEngine($sPath . $sLocalId, $isPrivate); 231 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB); 232 return false; 233 } 234 235 // after upload callback + triggers update 236 237 if (!$this->onFileAdded (array( 238 'id' => $iId, 239 'profile_id' => $iProfileId, 240 'remote_id' => $sLocalId, 241 'path' => $sPath . $sLocalId, 242 'file_name' => $oHelper->getName(), 243 'mime_type' => $sMimeType, 244 'size' => $iSize, 245 'private' => $isPrivate ? 1 : 0, 246 ))) { 247 $this->deleteFileFromEngine($sPath . $sLocalId, $isPrivate); 248 $this->_oDb->deleteFile($iId); 249 return false; 250 } 251 252 return $iId; 253 } 254 255 /** 256 * convert default multiple files array into more logical one 257 */ 258 public function convertMultipleFilesArray($aFiles) { 259 260 if (!is_array($aFiles) || !is_array($aFiles['name'])) 261 return false; 262 $aRet = array (); 263 foreach ($aFiles['name'] as $i => $sName) { 264 foreach ($aFiles as $sKey => $r) { 265 if (!$aFiles['name'][$i]) 266 break; 267 $aRet[$i][$sKey] = $aFiles[$sKey][$i]; 268 } 269 } 270 return $aRet; 271 } 162 272 163 273 /** 164 274 * the same as storeFile, but it tries to do it directly from uploaded file 165 275 */ 166 public function storeUploadedFile($aFile, $isPrivate = false, $iProfileId = 0) { } 276 public function storeFileFromForm($aFile, $isPrivate = false, $iProfileId = 0) { 277 return $this->storeFile('Form', array('file' => $aFile), false, $isPrivate, $iProfileId); 278 } 279 280 /** 281 * the same as storeFile, but it tries to do it directly from HTML5 file upload method 282 */ 283 public function storeFileFromXhr($sName, $isPrivate = false, $iProfileId = 0) { 284 return $this->storeFile('Xhr', array('name' => $sName), false, $isPrivate, $iProfileId); 285 } 167 286 168 287 /** 169 288 * Delete file by file id. 170 289 */ 171 public function deleteFile($iFileId) { } 290 public function deleteFile($iFileId, $iProfileId = 0) { 291 292 $aFile = $this->_oDb->getFileById ($iFileId); 293 if (!$aFile) { 294 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILE_NOT_FOUND); 295 return false; 296 } 297 298 if (!$this->onBeforeFileDelete ($aFile, $iProfileId)) { 299 return false; 300 } 301 302 if (!$this->deleteFileFromEngine($aFile['path'], $aFile['private'])) { 303 return false; 304 } 305 306 if (!$this->_oDb->deleteFile($aFile['id'])) { 307 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB); 308 return false; 309 } 310 311 if (!$this->onFileDeleted ($aFile, $iProfileId)) { 312 return false; 313 } 314 315 return true; 316 } 172 317 173 318 /** … … 178 323 public function getFileUrlById($iFileId) { } 179 324 325 /** 326 * Get file info array by file id. 327 */ 328 public function getFile($iFileId) { 329 return $this->_oDb->getFileById($iFileId); 330 } 331 332 /** 333 * Call this function after saving/associate just uploaded file id, so file is not ghost. 334 * Ghost files appear on download form automaticaly during next upload, 335 * for example if file was uploaded but was not submitted for some reason, 336 * so this mechanism ensure that file is not lost. 337 * @param $mixedFileIds array of file ids or just file id 338 * @param $iProfileId profile id 339 * @param return number of deleted ghost files 340 */ 341 public function afterUploadCleanup($mixedFileIds, $iProfileId) { 342 return $this->_oDb->deleteGhosts($mixedFileIds, $iProfileId); 343 } 344 345 public function getGhosts($iProfileId) { 346 return $this->_oDb->getGhosts($iProfileId); 347 } 180 348 181 349 public function tmpDebugGetFilesList() { 182 350 $sQuery = "SELECT * FROM `" . $this->_aObject['table_files'] . "`"; 183 351 return $this->_oDb->getAll($sQuery); 352 } 353 354 public function getRestrictionsTextExtensions ($iProfileId) { 355 switch ($this->_aObject['ext_mode']) { 356 case 'allow-deny': 357 if (!$this->_aObject['ext_allow']) 358 return _t('_sys_storage_restriction_ext_all_denied'); 359 return _t('_sys_storage_restriction_ext_allowed', $this->_aObject['ext_allow']); 360 case 'deny-allow': 361 if (!$this->_aObject['ext_deny']) 362 return _t('_sys_storage_restriction_ext_all_allowed'); 363 return _t('_sys_storage_restriction_ext_denied', $this->_aObject['ext_deny']); 364 default: 365 return _t('_sys_storage_restriction_ext_all_denied'); 366 } 367 } 368 369 public function getRestrictionsTextFileSize ($iProfileId) { 370 return _t('_sys_storage_restriction_size', _t_format_size($this->getMaxUploadFileSize($iProfileId))); 371 } 372 373 public function getRestrictionsTextArray ($iProfileId) { 374 $aTypes = array('Extensions', 'FileSize'); 375 $aRet = array(); 376 foreach ($aTypes as $sType) { 377 $sFunc = 'getRestrictionsText' . $sType; 378 $s = $this->$sFunc ($iProfileId); 379 if ($s) 380 $aRet[] = $s; 381 } 382 return $aRet; 184 383 } 185 384 … … 237 436 } 238 437 438 if (!$this->_oDb->insertGhosts ($aFileInfo['id'], $aFileInfo['profile_id'])) { 439 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB); 440 return false; 441 } 442 239 443 $this->setErrorCode(BX_DOL_STORAGE_ERR_OK); 240 444 $bRet = true; … … 269 473 } 270 474 475 $this->_oDb->deleteGhosts ($aFileInfo['id'], $aFileInfo['profile_id']); 476 271 477 $this->setErrorCode(BX_DOL_STORAGE_ERR_OK); 272 478 $bRet = true; … … 278 484 279 485 // ------------ internal functions 280 281 protected function storeUploadedFileBegin($aFile, $isPrivate = false, $iProfileId = 0) {282 283 if (!$aFile['size'] || !$aFile['tmp_name']) {284 $this->setErrorCode(BX_DOL_STORAGE_ERR_NO_FILE);285 return false;286 }287 288 if (UPLOAD_ERR_OK != $aFile['error']) {289 $this->setErrorCode((int)$aFile['error']);290 return false;291 }292 293 $sExt = $this->getFileExt($aFile['name']);294 $sMimeType = $this->getMimeTypeByFileName($aFile['name']);295 296 if (!$this->isValidExt($sExt)) {297 $this->setErrorCode(BX_DOL_STORAGE_ERR_WRONG_EXT);298 return false;299 }300 301 if (!$this->onBeforeFileAdd (array(302 'profile_id' => $iProfileId,303 'file_name' => $aFile['name'],304 'mime_type' => $sMimeType,305 'ext' => $sExt,306 'size' => $aFile['size'],307 'private' => $isPrivate ? 1 : 0,308 ))) {309 return false;310 }311 312 return true;313 }314 486 315 487 protected function setErrorCode($i) { … … 335 507 $sRet .= substr($s, 0, $i++) . '/'; 336 508 return $sRet; 509 } 510 511 protected function genRemoteNamePath ($sPath, $sLocalId, $sExt) { 512 return $sPath . $sLocalId; 337 513 } 338 514 … … 382 558 } 383 559 560 561 /** 562 * Handle file uploads via XMLHttpRequest 563 */ 564 class BxDolStorageHelperXhr { 565 566 var $sName; 567 568 function BxDolStorageHelperXhr ($aParams) { 569 $this->sName = $aParams['name']; 570 } 571 572 function getImmediateError() { 573 return BX_DOL_STORAGE_ERR_OK; 574 } 575 576 function save($path) { 577 $input = fopen("php://input", "r"); 578 $temp = tmpfile(); 579 $realSize = stream_copy_to_stream($input, $temp); 580 fclose($input); 581 582 if (false === $this->getSize() || $realSize != $this->getSize()) { 583 return false; 584 } 585 586 $target = fopen($path, "w"); 587 fseek($temp, 0, SEEK_SET); 588 stream_copy_to_stream($temp, $target); 589 fclose($target); 590 591 return true; 592 } 593 594 function getName() { 595 return $this->sName; 596 } 597 598 function getSize() { 599 if (isset($_SERVER["CONTENT_LENGTH"])) 600 return (int)$_SERVER["CONTENT_LENGTH"]; 601 else 602 return false; 603 } 604 } 605 606 /** 607 * Handle file uploads via regular form post (uses the $_FILES array) 608 */ 609 class BxDolStorageHelperForm { 610 611 var $aFile; 612 613 function BxDolStorageHelperForm ($aParams) { 614 $this->aFile = $aParams['file']; 615 } 616 617 function getImmediateError() { 618 619 if (!$this->aFile['size'] || !$this->aFile['tmp_name']) 620 return BX_DOL_STORAGE_ERR_NO_FILE; 621 622 if (UPLOAD_ERR_OK != $this->aFile['error']) 623 return (int)$this->aFile['error']; 624 625 return BX_DOL_STORAGE_ERR_OK; 626 } 627 628 function save($path) { 629 if (!move_uploaded_file($this->aFile['tmp_name'], $path)){ 630 return false; 631 } 632 return true; 633 } 634 635 function getName() { 636 return $this->aFile['name']; 637 } 638 639 function getSize() { 640 return $this->aFile['size']; 641 } 642 } 643 -
trunk/inc/classes/BxDolStorageLocal.php
r15453 r15476 19 19 public function BxDolStorageLocal($aObject) { 20 20 parent::BxDolStorage($aObject); 21 }22 23 /**24 * Store file in the storage area.25 * @param $sFilePath full path to the the file, with path and file, it maybe temporary uploaded file26 * @param $sName file name with extention27 * @param $isPrivate private or public file28 * @return id of added file on success, false on error - to get exact error code call getErrorCode()29 */30 public function storeFile($sFilePath, $sName, $isPrivate = false, $iProfileId = 0) { }31 32 /**33 * the same as storeFile, but it tries to do it directly from uploaded file34 */35 public function storeUploadedFile($aFile, $isPrivate = false, $iProfileId = 0) {36 37 if (!$this->storeUploadedFileBegin($aFile, $isPrivate, $iProfileId))38 return false;39 40 $sExt = $this->getFileExt($aFile['name']);41 $sMimeType = $this->getMimeTypeByFileName($aFile['name']);42 43 $sLocalId = $this->genRandName();44 $sPath = $this->genPath($sLocalId, $this->_aObject['levels']);45 $sNewFileDir = $this->getObjectBaseDir($isPrivate) . $sPath;46 $sNewFilePath = $sNewFileDir . $sLocalId;47 48 $this->mkdir($sNewFileDir);49 if (!file_exists($sNewFileDir) || !is_writable($sNewFileDir)) {50 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILESYSTEM_PERM);51 return false;52 }53 54 if (!move_uploaded_file($aFile['tmp_name'], $sNewFilePath)) {55 $this->setErrorCode(BX_DOL_STORAGE_INVALID_FILE);56 return false;57 }58 59 if (!chmod ($sNewFilePath, BX_DOL_STORAGE_FILE_RIGHTS)) {60 unlink($sNewFilePath);61 $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD);62 return false;63 }64 65 $iTime = time();66 $iSize = filesize($sNewFilePath);67 if (!$this->_oDb->addFile($iProfileId, $sLocalId, $sPath . $sLocalId, $aFile['name'], $sMimeType, $sExt, $iSize, $iTime, $isPrivate)) {68 unlink($sNewFilePath);69 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB);70 return false;71 }72 73 $iId = $this->_oDb->lastId();74 if (!$iId) {75 unlink($sNewFilePath);76 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB);77 return false;78 }79 80 if (!$this->onFileAdded (array(81 'id' => $iId,82 'profile_id' => $iProfileId,83 'remote_id' => $sLocalId,84 'path' => $sPath . $sLocalId,85 'file_name' => $aFile['name'],86 'mime_type' => $sMimeType,87 'size' => $iSize,88 'private' => $isPrivate ? 1 : 0,89 ))) {90 $this->_oDb->deleteFile($iId);91 unlink($sNewFilePath);92 return false;93 }94 95 return $iId;96 }97 98 /**99 * Delete file by file id.100 */101 public function deleteFile($iFileId, $iProfileId = 0) {102 103 $aFile = $this->_oDb->getFileById ($iFileId);104 if (!$aFile) {105 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILE_NOT_FOUND);106 return false;107 }108 109 $sFileLocation = $this->getObjectBaseDir($aFile['private']) . $aFile['path'];110 111 if (!file_exists($sFileLocation)) {112 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILE_NOT_FOUND);113 return false;114 }115 116 if (!$this->onBeforeFileDelete ($aFile, $iProfileId)) {117 return false;118 }119 120 if (!unlink($sFileLocation)) {121 $this->setErrorCode(BX_DOL_STORAGE_ERR_UNLINK);122 return false;123 }124 125 if (!$this->_oDb->deleteFile($aFile['id'])) {126 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB);127 return false;128 }129 130 if (!$this->onFileDeleted ($aFile, $iProfileId)) {131 return false;132 }133 134 return true;135 21 } 136 22 … … 190 76 // ---------------- 191 77 78 protected function addFileToEngine($sTmpFile, $sLocalId, $sName, $isPrivate, $iProfileId) { 79 80 $sPath = $this->genPath($sLocalId, $this->_aObject['levels']); 81 $sNewFileDir = $this->getObjectBaseDir($isPrivate) . $sPath; 82 $sNewFilePath = $sNewFileDir . $sLocalId; 83 84 $this->mkdir($sNewFileDir); 85 if (!file_exists($sNewFileDir) || !is_writable($sNewFileDir)) { 86 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILESYSTEM_PERM); 87 return false; 88 } 89 90 if (!copy($sTmpFile, $sNewFilePath)) { 91 $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD); 92 return false; 93 } 94 95 if (!chmod ($sNewFilePath, BX_DOL_STORAGE_FILE_RIGHTS)) { 96 unlink($sNewFilePath); 97 $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD); 98 return false; 99 } 100 101 return true; 102 } 103 104 protected function deleteFileFromEngine($sFilePath, $isPrivate) { 105 106 $sFileLocation = $this->getObjectBaseDir($isPrivate) . $sFilePath; 107 108 if (!file_exists($sFileLocation)) { 109 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILE_NOT_FOUND); 110 return false; 111 } 112 113 if (!unlink($sFileLocation)) { 114 $this->setErrorCode(BX_DOL_STORAGE_ERR_UNLINK); 115 return false; 116 } 117 118 return true; 119 } 120 192 121 protected function getObjectBaseDir ($isPrivate = false) { 193 122 return BX_DIRECTORY_STORAGE . $this->_aObject['object'] . '/'; -
trunk/inc/classes/BxDolStorageQuery.php
r15452 r15476 47 47 $sQuery = $this->prepare(" 48 48 UPDATE `sys_objects_storage` 49 SET `current_size` = `current_size` + ?, `current_number` = `current_number` + ?, `ts` = ?49 SET `current_size` = `current_size` + ?, `current_number` = `current_number` + (?), `ts` = ? 50 50 WHERE `object` = ?", 51 51 $iSize, $iNumber, $iTime, $this->_aObject['object'] … … 127 127 } 128 128 129 public function insertGhosts($mixedFileIds, $iProfileId) { 130 131 $iTime = time(); 132 if (!is_array($mixedFileIds)) 133 $mixedFileIds = array($mixedFileIds); 134 135 $iCount = 0; 136 foreach ($mixedFileIds as $iFileId) { 137 $sQuery = $this->prepare("INSERT INTO `sys_storage_ghosts` SET `id` = ?, `profile_id` = ?, `object` = ?, `created` = ?", $iFileId, $iProfileId, $this->_aObject['object'], $iTime); 138 $iCount += $this->query($sQuery); 139 } 140 return $iCount; 141 } 142 143 public function deleteGhosts($mixedFileIds, $iProfileId) { 144 $sQuery = $this->prepare("DELETE FROM `sys_storage_ghosts` WHERE `profile_id` = ? AND `object` = ? AND `id` IN (" . $this->implode_escape($mixedFileIds) . ")", $iProfileId, $this->_aObject['object']); 145 $iCount = $this->query($sQuery); 146 if ($iCount) 147 $this->query("OPTIMIZE TABLE `sys_storage_ghosts`"); 148 return $iCount; 149 } 150 151 public function getGhosts($iProfileId) { 152 $sQuery = $this->prepare("SELECT `f`.* FROM `sys_storage_ghosts` AS `g` INNER JOIN " . $this->_sTableFiles . " AS `f` ON (`f`.`id` = `g`.`id` AND `f`.`profile_id` = ?) WHERE `g`.`profile_id` = ? AND `g`.`object` = ?", $iProfileId, $iProfileId, $this->_aObject['object']); 153 return $this->getAll($sQuery); 154 } 155 129 156 public function prune() { 130 157 $iTime = time(); -
trunk/inc/classes/BxDolStorageS3.php
r15453 r15476 42 42 43 43 /** 44 * Store file in the storage area.45 * @param $sFilePath full path to the the file, with path and file, it maybe temporary uploaded file46 * @param $sName file name with extention47 * @param $isPrivate private or public file48 * @return id of added file on success, false on error - to get exact error code call getErrorCode()49 */50 public function storeFile($sFilePath, $sName, $isPrivate = false, $iProfileId = 0) { }51 52 /**53 * the same as storeFile, but it tries to do it directly from uploaded file54 */55 public function storeUploadedFile($aFile, $isPrivate = false, $iProfileId = 0) {56 57 if (!$this->storeUploadedFileBegin($aFile, $isPrivate, $iProfileId))58 return false;59 60 $sExt = $this->getFileExt($aFile['name']);61 $sMimeType = $this->getMimeTypeByFileName($aFile['name']);62 63 $sLocalId = $this->genRandName();64 $sTmpFile = BX_DIRECTORY_PATH_TMP . $sLocalId;65 $sPath = $this->genPath($sLocalId, $this->_aObject['levels']);66 $sRemoteNamePath = $sPath . $sLocalId . '.' . $sExt;67 68 if (!move_uploaded_file($aFile['tmp_name'], $sTmpFile)) {69 $this->setErrorCode(BX_DOL_STORAGE_INVALID_FILE);70 return false;71 }72 73 $aMetaHeaders = array();74 $aRequestHeaders = array (75 "Content-Type" => $sMimeType,76 );77 if ($this->_iCacheControl > 0) {78 $aRequestHeaders = array_merge ($aRequestHeaders, array (79 "Cache-Control" => "max-age=" . ($isPrivate && $this->_iCacheControl > $this->_aObject['token_life'] ? $this->_aObject['token_life'] : $this->_iCacheControl),80 ));81 }82 83 $sStorageClass = $this->_bReducedRedundancy ? S3::STORAGE_CLASS_RRS : S3::STORAGE_CLASS_STANDARD;84 $sACL = $isPrivate ? S3::ACL_AUTHENTICATED_READ : S3::ACL_PUBLIC_READ;85 $aInputFile = $this->_s3->inputFile($sTmpFile);86 if (!$this->_s3->putObject($aInputFile, $this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath, $sACL, $aMetaHeaders, $aRequestHeaders, $sStorageClass)) {87 $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD);88 return false;89 }90 91 $iTime = time();92 $iSize = filesize($sTmpFile);93 if (!$this->_oDb->addFile($iProfileId, $sLocalId, $sRemoteNamePath, $aFile['name'], $sMimeType, $sExt, $iSize, $iTime, $isPrivate)) {94 $this->_s3->deleteObject($this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath);95 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB);96 return false;97 }98 99 $iId = $this->_oDb->lastId();100 if (!$iId) {101 $this->_s3->deleteObject($this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath);102 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB);103 return false;104 }105 106 if (!$this->onFileAdded (array(107 'id' => $iId,108 'profile_id' => $iProfileId,109 'remote_id' => $sLocalId,110 'path' => $sRemoteNamePath,111 'file_name' => $aFile['name'],112 'mime_type' => $sMimeType,113 'size' => $iSize,114 'private' => $isPrivate ? 1 : 0,115 ))) {116 $this->_oDb->deleteFile($iId);117 $this->_s3->deleteObject($this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath);118 return false;119 }120 121 return $iId;122 }123 124 /**125 * Delete file by file id.126 */127 public function deleteFile($iFileId, $iProfileId = 0) {128 129 $aFile = $this->_oDb->getFileById ($iFileId);130 if (!$aFile) {131 $this->setErrorCode(BX_DOL_STORAGE_ERR_FILE_NOT_FOUND);132 return false;133 }134 135 $sFileLocation = $this->getObjectBaseDir($aFile['private']) . $aFile['path'];136 137 if (!$this->onBeforeFileDelete ($aFile, $iProfileId)) {138 return false;139 }140 141 if (!$this->_s3->deleteObject($this->_sBucket, $sFileLocation)) {142 $this->setErrorCode(BX_DOL_STORAGE_ERR_UNLINK);143 return false;144 }145 146 if (!$this->_oDb->deleteFile($aFile['id'])) {147 $this->setErrorCode(BX_DOL_STORAGE_ERR_DB);148 return false;149 }150 151 if (!$this->onFileDeleted ($aFile, $iProfileId)) {152 return false;153 }154 155 return true;156 }157 158 /**159 44 * Get file url, you need to override this to generate custom url for private files. 160 45 * @param $iFileId file … … 181 66 // ---------------- 182 67 68 protected function addFileToEngine($sTmpFile, $sLocalId, $sName, $isPrivate, $iProfileId) { 69 70 $sMimeType = $this->getMimeTypeByFileName($sName); 71 $sExt = $this->getFileExt($sName); 72 $sPath = $this->genPath($sLocalId, $this->_aObject['levels']); 73 $sRemoteNamePath = $sPath . $sLocalId . ($sExt ? '.' . $sExt : ''); 74 75 $aMetaHeaders = array(); 76 $aRequestHeaders = array ( 77 "Content-Type" => $sMimeType, 78 ); 79 if ($this->_iCacheControl > 0) { 80 $aRequestHeaders = array_merge ($aRequestHeaders, array ( 81 "Cache-Control" => "max-age=" . ($isPrivate && $this->_iCacheControl > $this->_aObject['token_life'] ? $this->_aObject['token_life'] : $this->_iCacheControl), 82 )); 83 } 84 85 $sStorageClass = $this->_bReducedRedundancy ? S3::STORAGE_CLASS_RRS : S3::STORAGE_CLASS_STANDARD; 86 $sACL = $isPrivate ? S3::ACL_AUTHENTICATED_READ : S3::ACL_PUBLIC_READ; 87 $aInputFile = $this->_s3->inputFile($sTmpFile); 88 if (!$this->_s3->putObject($aInputFile, $this->_sBucket, $this->getObjectBaseDir($isPrivate) . $sRemoteNamePath, $sACL, $aMetaHeaders, $aRequestHeaders, $sStorageClass)) { 89 $this->setErrorCode(BX_DOL_STORAGE_ERR_ENGINE_ADD); 90 return false; 91 } 92 93 return true; 94 } 95 96 protected function deleteFileFromEngine($sFilePath, $isPrivate) { 97 98 $sFileLocation = $this->getObjectBaseDir($isPrivate) . $sFilePath; 99 100 if (!$this->_s3->deleteObject($this->_sBucket, $sFileLocation)) { 101 $this->setErrorCode(BX_DOL_STORAGE_ERR_UNLINK); 102 return false; 103 } 104 105 return true; 106 } 107 108 protected function genRemoteNamePath ($sPath, $sLocalId, $sExt) { 109 return $sPath . $sLocalId . ($sExt ? '.' . $sExt : ''); 110 } 111 183 112 protected function getObjectBaseDir ($isPrivate = false) { 184 113 return $this->_aObject['object'] . '/'; -
trunk/inc/languages.inc.php
r15470 r15476 490 490 } 491 491 } 492 493 function _t_format_size ($iSize) { 494 $a = array ( 495 1024 => '_sys_format_size_b', 496 1024*1024 => '_sys_format_size_kb', 497 1024*1024*1024 => '_sys_format_size_mb', 498 1024*1024*1024*1024 => '_sys_format_size_gb', 499 1024*1024*1024*1024*1024 => '_sys_format_size_tb', 500 ); 501 foreach ($a as $i => $sKey) 502 if ($iSize < $i) 503 return _t($sKey, round($iSize / ($i / 1024), 1)); 504 return _t('_sys_format_size_b', 0); 505 } -
trunk/install/langs/lang-en.php
r15472 r15476 84 84 '_Error' => 'Error', 85 85 '_Explanation' => 'Explanation', 86 '_Failed' => 'Failed', 86 87 '_FAQ' => 'FAQ', 87 88 '_Female' => 'Woman', … … 2840 2841 '_adm_mobile_page_homepage' => 'Homepage', 2841 2842 '_adm_mobile_page_profile' => 'Profile', 2843 2844 '_sys_format_size_b' => '{0} bytes', 2845 '_sys_format_size_kb' => '{0} Kb', 2846 '_sys_format_size_mb' => '{0} Mb', 2847 '_sys_format_size_gb' => '{0} Gb', 2848 '_sys_format_size_tb' => '{0} Tb', 2849 2850 '_sys_storage_restriction_ext_all_allowed' => 'Files of any type are allowed.', 2851 '_sys_storage_restriction_ext_all_denied' => 'Sorry, all file types are restricted for now', 2852 '_sys_storage_restriction_ext_allowed' => 'Only files with the following types are allowed: {0}', 2853 '_sys_storage_restriction_ext_denied' => 'All file types are allowed, except the following: {0}', 2854 2855 '_sys_storage_restriction_size' => 'Max file size is {0}', 2856 2857 '_sys_uploader_confirm_leaving_page' => 'Upload is is progress! Leaving the page means abort uploading!', 2858 '_sys_uploader_confirm_close_popup' => 'Are you sure? It may cancel files uploading.', 2859 '_sys_uploader_upload_canceled' => 'Upload was canceled', 2860 2861 '_sys_uploader_simple_button_name' => 'Simple Upload', 2862 '_sys_uploader_simple_title' => 'Simple Upload', 2863 '_sys_uploader_simple_submit_button' => 'Upload', 2864 '_sys_uploader_simple_attach_one_more_file' => '+ Add more files', 2865 2866 '_sys_uploader_html5_title' => 'Multiple Upload', 2867 '_sys_uploader_html5_button_name' => 'Multiple Upload', 2868 '_sys_uploader_html5_shoose_file' => 'Choose a file', 2869 '_sys_uploader_html5_drop_area' => 'Drop files here to upload', 2842 2870 ); 2843 2871 ?> -
trunk/install/sql/v70.sql
r15472 r15476 3690 3690 ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 3691 3691 3692 CREATE TABLE IF NOT EXISTS `sys_storage_ghosts` ( 3693 `id` int(11) NOT NULL, 3694 `profile_id` int(10) unsigned NOT NULL, 3695 `object` varchar(32) NOT NULL, 3696 `created` int(10) unsigned NOT NULL, 3697 UNIQUE KEY `id` (`id`,`object`) 3698 ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 3699 3692 3700 CREATE TABLE IF NOT EXISTS `sys_storage_mime_types` ( 3693 3701 `ext` varchar(32) NOT NULL, -
trunk/templates/base/popup_box.html
r15474 r15476 21 21 <div class="bx-clear"></div> 22 22 </div> 23 <div class="bx-db-content bx-def-padding -sec">__content__</div>23 <div class="bx-db-content bx-def-padding">__content__</div> 24 24 </div> 25 25 </div> -
trunk/templates/base/scripts/BxBaseFormView.php
r15332 r15476 161 161 162 162 case 'select_box': 163 $sRow = $this->genRowSelectBox($aInput); 163 $sRow = $this->genRowCustom($aInput, 'genInputSelectBox'); 164 break; 165 166 case 'files': 167 $sRow = $this->genRowCustom($aInput, 'genInputFiles'); 164 168 break; 165 169 … … 188 192 $sErrorIcon = $this->genErrorIcon(empty($aInput['error']) ? '' : $aInput['error']); 189 193 190 $aInput['tr_attrs']['class'] = "bx-form-element-wrapper bx-def-margin- sec-top" . (isset($aInput['tr_attrs']['class']) ? ' ' . $aInput['tr_attrs']['class'] : '');194 $aInput['tr_attrs']['class'] = "bx-form-element-wrapper bx-def-margin-top" . (isset($aInput['tr_attrs']['class']) ? ' ' . $aInput['tr_attrs']['class'] : ''); 191 195 if (isset($aInput['name'])) 192 196 $aInput['tr_attrs']['id'] = "bx-form-element-" . $aInput['name']; … … 256 260 * @return string 257 261 */ 258 function genRow SelectBox(&$aInput) {262 function genRowCustom(&$aInput, $sCustomMethod) { 259 263 260 264 $sCaption = isset($aInput['caption']) ? bx_process_output($aInput['caption']) : ''; … … 265 269 $sInfoIcon = !empty($aInput['info']) ? $this->genInfoIcon($aInput['info']) : ''; 266 270 267 $sErrorIcon = $this->genErrorIcon(empty($aInput['error']) ? '' : $aInput['error']); 268 $sInput = $this-> genInputSelectBox($aInput, $sInfoIcon, $sErrorIcon);269 270 $aInput['tr_attrs']['class'] = "bx-form-element-wrapper bx-def-margin- sec-top" . (isset($aInput['tr_attrs']['class']) ? ' ' . $aInput['tr_attrs']['class'] : '');271 $sErrorIcon = $this->genErrorIcon(empty($aInput['error']) ? '' : $aInput['error']); 272 $sInput = $this->$sCustomMethod($aInput, $sInfoIcon, $sErrorIcon); 273 274 $aInput['tr_attrs']['class'] = "bx-form-element-wrapper bx-def-margin-top" . (isset($aInput['tr_attrs']['class']) ? ' ' . $aInput['tr_attrs']['class'] : ''); 271 275 if (isset($aInput['name'])) 272 276 $aInput['tr_attrs']['id'] = "bx-form-element-" . $aInput['name']; … … 280 284 </div> 281 285 282 <div class=" value$sClassAdd">286 <div class="bx-form-value$sClassAdd"> 283 287 <div class="clear_both"></div> 284 288 $sInput … … 482 486 483 487 // add default className to attributes 484 $aAttrs['class'] = "bx-def-font-inputs bx-form-input-{$aInput['type']}" . ( isset($aAttrs['class']) ? ' ' . $aAttrs['class'] : '');488 $aAttrs['class'] = "bx-def-font-inputs bx-form-input-{$aInput['type']}" . ('submit' == $aInput['type'] ? ' bx-btn bx-btn-primary' : '') . (isset($aAttrs['class']) ? ' ' . $aAttrs['class'] : ''); 485 489 $aAttrs['type'] = $aInput['type']; 486 490 if (isset($aInput['name'])) $aAttrs['name'] = $aInput['name']; … … 497 501 $sAttrs = $this->convertArray2Attrs($aAttrs); 498 502 499 return "<input $sAttrs />\n"; 500 503 if ('submit' == $aInput['type']) 504 return "<button $sAttrs>" . $aInput['value'] . "</button>\n"; 505 else 506 return "<input $sAttrs />\n"; 501 507 } 502 508 … … 648 654 649 655 /** 656 * Generate Select Box Element 657 * 658 * @param array $aInput 659 * @return string 660 */ 661 function genInputFiles(&$aInput, $sInfo = '', $sError = '') { 662 663 664 665 /* 666 TODO: 667 HTML for showing uploaded file (it should be overridable by specific storage engine, like handling file uploads) 668 */ 669 670 $sUniqId = genRndPwd (8, false); 671 $sUploaders = ''; 672 $oUploader = null; 673 foreach ($aInput['uploaders'] as $sUploaderObject) { 674 bx_import('BxDolUploader'); 675 $oUploader = BxDolUploader::getObjectInstance($sUploaderObject, $aInput['storage_object'], $sUniqId); 676 if (!$oUploader) 677 continue; 678 $sUploaders .= $oUploader->getUploaderButton(); 679 } 680 681 $sInitGhosts = isset($aInput['init_ghosts']) && !$aInput['init_ghosts'] ? '' : $oUploader->getNameJsInstanceUploader() . '.restoreGhosts();'; 682 683 // TODO: move HTML to templates 684 return 685 '<div class="bx-form-input-files-uploaders bx-def-margin-sec-top">' . $sUploaders . '<div class="bx-clear"> </div></div>' . 686 $sInfo . 687 '<div id="' . $oUploader->getIdContainerErrors() . '" class="bx-form-input-files-errors bx-def-margin-sec-top"> </div>' . 688 '<div id="' . $oUploader->getIdContainerResult() . '" class="bx-form-input-files-result bx-def-margin-sec-top"> </div>' . 689 '<script>$(document).ready(function(){' . $sInitGhosts . '});</script>'; 690 } 691 692 /** 650 693 * Generate Multiple Select Element 651 694 * … … 915 958 916 959 if ($aAttrs and is_array($aAttrs)) { 917 $aAttrs['class'] = "bx-form-section " . (isset($aAttrs['class']) ? (' ' . $aAttrs['class']) : '');960 $aAttrs['class'] = "bx-form-section bx-def-padding bx-def-color-bg-sec" . (isset($aAttrs['class']) ? (' ' . $aAttrs['class']) : ''); 918 961 $sAttrs = $this->convertArray2Attrs($aAttrs); 919 962 } else { 920 $sAttrs = ' class="bx-form-section bx-def-padding -secbx-def-color-bg-sec" ';963 $sAttrs = ' class="bx-form-section bx-def-padding bx-def-color-bg-sec" '; 921 964 } 922 965
Note: See TracChangeset
for help on using the changeset viewer.