/** * Uploads new file to folder. * @param array $fileArray Structure like $_FILES. * @param array $data Contains additional fields (CREATED_BY, NAME, etc). * @param array $rights Rights (@see \Bitrix\Disk\RightsManager). * @param bool $generateUniqueName Generates unique name for object in directory. * @throws \Bitrix\Main\ArgumentException * @return File|null */ public function uploadFile(array $fileArray, array $data, array $rights = array(), $generateUniqueName = false) { $this->errorCollection->clear(); $this->checkRequiredInputParams($data, array('NAME', 'CREATED_BY')); if (!isset($fileArray['MODULE_ID'])) { $fileArray['MODULE_ID'] = Driver::INTERNAL_MODULE_ID; } if (empty($fileArray['type'])) { $fileArray['type'] = ''; } $fileArray['type'] = TypeFile::normalizeMimeType($fileArray['type'], $data['NAME']); /** @noinspection PhpDynamicAsStaticMethodCallInspection */ $fileId = CFile::saveFile($fileArray, Driver::INTERNAL_MODULE_ID, true, true); if (!$fileId) { $this->errorCollection->add(array(new Error(Loc::getMessage('DISK_FOLDER_MODEL_ERROR_COULD_NOT_SAVE_FILE'), self::ERROR_COULD_NOT_SAVE_FILE))); return null; } /** @noinspection PhpDynamicAsStaticMethodCallInspection */ $fileArray = CFile::getFileArray($fileId); $data['NAME'] = Ui\Text::correctFilename($data['NAME']); $fileModel = $this->addFile(array('NAME' => $data['NAME'], 'FILE_ID' => $fileId, 'CONTENT_PROVIDER' => isset($data['CONTENT_PROVIDER']) ? $data['CONTENT_PROVIDER'] : null, 'SIZE' => !isset($data['SIZE']) ? $fileArray['FILE_SIZE'] : $data['SIZE'], 'CREATED_BY' => $data['CREATED_BY']), $rights, $generateUniqueName); if (!$fileModel) { CFile::delete($fileId); return null; } return $fileModel; }
/** * @param array $fileData * @param string $siteID * @param array $params * @return int|false */ public static function saveFile(array $fileData, $siteID = '', $params = array()) { if (!(IsModuleInstalled('disk') && Loader::includeModule('disk'))) { return false; } if ($siteID === '') { $siteID = self::getDefaultSiteID(); } if (!is_array($params)) { $params = array(); } $typeID = isset($params['TYPE_ID']) ? (int) $params['TYPE_ID'] : StorageFileType::Undefined; if (!StorageFileType::IsDefined($typeID)) { $typeID = StorageFileType::EmailAttachment; } $folder = self::ensureFolderCreated($typeID, $siteID); if (!$folder) { return false; } $userID = isset($params['USER_ID']) ? (int) $params['USER_ID'] : 0; if ($userID <= 0) { $userID = \CCrmSecurityHelper::GetCurrentUserID(); } else { if ($userID <= 0) { $userID = SystemUser::SYSTEM_USER_ID; } } $file = $folder->addFile(array('NAME' => Text::correctFilename($fileData['ORIGINAL_NAME']), 'FILE_ID' => (int) $fileData['ID'], 'SIZE' => (int) $fileData['FILE_SIZE'], 'CREATED_BY' => $userID), array(), true); return $file ? $file->getId() : false; }
protected function processActionRenameFile() { $this->checkRequiredPostParams(array('newName', 'attachedId')); if ($this->errorCollection->hasErrors()) { $this->sendJsonErrorResponse(); } list($type, $realValue) = FileUserType::detectType($this->request->getPost('attachedId')); if ($type == FileUserType::TYPE_NEW_OBJECT) { /** @var File $model */ $model = File::loadById((int) $realValue, array('STORAGE')); if (!$model) { $this->errorCollection->add(array(new Error("Could not find file"))); $this->sendJsonErrorResponse(); } if (!$model->canRename($model->getStorage()->getCurrentUserSecurityContext())) { $this->errorCollection->add(array(new Error("Bad permission. Could not read this file"))); $this->sendJsonErrorResponse(); } $newName = Text::correctFilename($this->request->getPost('newName')); if (!$model->renameInternal($newName, true)) { $this->errorCollection->add($model->getErrors()); $this->sendJsonErrorResponse(); } Driver::getInstance()->getIndexManager()->indexFile($model); $this->sendJsonSuccessResponse(array('id' => $this->request->getPost('attachedId'), 'name' => $model->getName())); } else { $this->sendJsonErrorResponse(); } }
/** * Changes name of storage. * @param string $name New name for storage. * @return bool */ public function rename($name) { $this->errorCollection->clear(); $rootFolder = $this->getRootObject(); if (!$rootFolder) { $this->errorCollection->add(array(new Error("Storage doesn't have root folder.", self::ERROR_NOT_EXISTS_ROOT_OBJECT))); return false; } if (!$rootFolder->rename(Ui\Text::correctFilename($name))) { $this->errorCollection->add(array(new Error("Could not rename name of root folder.", self::ERROR_RENAME_ROOT_OBJECT))); return false; } return $this->update(array('NAME' => $name)); }
protected function migrateTrashFolders() { if ($this->isStepFinished(__METHOD__)) { return; } $lastId = $this->getStorageId(); //first migrate folder from trash $trashQuery = $this->connection->query("\n\t\t\tSELECT\n\t\t\t\tobj.*,\n\t\t\t\ts.ROOT_OBJECT_ID ROOT_OBJECT_ID,\n\t\t\t\tsecta.DESCRIPTION DESCRIPTION\n\t\t\tFROM b_disk_object obj\n\t\t\t\tINNER JOIN b_disk_storage s ON s.ID = obj.STORAGE_ID\n\t\t\t\tINNER JOIN b_disk_object trash ON trash.ID = obj.PARENT_ID AND trash.PARENT_ID = s.ROOT_OBJECT_ID\n\t\t\t\tINNER JOIN b_iblock_section secta ON secta.ID = obj.ID\n\n\t\t\tWHERE obj.TYPE=2 AND trash.NAME = '.Trash' AND obj.ID > {$lastId} ORDER BY s.ID\n\t\t"); while ($trashChild = $trashQuery->fetch()) { $this->abortIfNeeded(); $undeletePath = $this->getSectionInTrash($trashChild); if (empty($undeletePath)) { $this->log(array("Skip item {$trashChild['ID']} from .Trash", "Empty WEBDAV_INFO (DESCRIPTION)")); $this->storeStorageId($trashChild['ID']); continue; } $undeletePath = trim($undeletePath, '/'); $filter = array('TYPE' => \Bitrix\Disk\Internals\ObjectTable::TYPE_FOLDER, 'STORAGE_ID' => $trashChild['STORAGE_ID'], 'PARENT_ID' => $trashChild['ROOT_OBJECT_ID']); $mustCreatePathPieces = array(); $undeletePathPieces = explode('/', $undeletePath); $parentId = $filter['PARENT_ID']; $parentDeletedType = null; $filename = array_pop($undeletePathPieces); foreach ($undeletePathPieces as $i => $pieceOfPath) { $filter['NAME'] = $this->sqlHelper->forSql($pieceOfPath); $folder = $this->connection->query("\n\t\t\t\t\tSELECT ID, NAME, REAL_OBJECT_ID, STORAGE_ID, PARENT_ID, DELETED_TYPE FROM b_disk_object obj\n\t\t\t\t\tWHERE obj.PARENT_ID = {$filter['PARENT_ID']} AND obj.STORAGE_ID = {$filter['STORAGE_ID']} AND obj.TYPE = {$filter['TYPE']} AND obj.NAME = '{$filter['NAME']}'\n\t\t\t\t")->fetch(); if ($folder) { $filter['PARENT_ID'] = $parentId = $folder['ID']; if (!empty($folder['DELETED_TYPE'])) { $parentDeletedType = $folder['DELETED_TYPE']; } continue; } if (!$folder) { $this->log(array("Folder with name {$pieceOfPath} does not exist")); $mustCreatePathPieces = array_slice($undeletePathPieces, $i); break; } } unset($pieceOfPath); if ($parentId) { $success = true; /** @var Folder $parentFolder */ $parentFolder = Folder::loadById($parentId); $folderData = array('CREATE_TIME' => $trashChild['CREATE_TIME'], 'UPDATE_TIME' => $trashChild['UPDATE_TIME'], 'CREATED_BY' => $trashChild['CREATED_BY'], 'UPDATED_BY' => $trashChild['UPDATED_BY']); foreach ($mustCreatePathPieces as $i => $pieceOfPath) { $deletedType = FolderTable::DELETED_TYPE_CHILD; if ($i == 0 && !$parentDeletedType) { $deletedType = FolderTable::DELETED_TYPE_ROOT; } $folderData['NAME'] = Text::correctFilename($pieceOfPath); if ($deletedType == FolderTable::DELETED_TYPE_ROOT) { $folderData['NAME'] = self::appendTrashCanSuffix($folderData['NAME']); } $folder = $parentFolder->addSubFolder($folderData, array(), true); if (!$folder) { $this->log(array("Skip item {$trashChild['ID']} from .Trash", "Could not create subfolder {$folderData['NAME']}")); $this->storeStorageId($trashChild['ID']); $success = false; break; } $updateResult = FolderTable::update($folder->getId(), array('DELETED_TYPE' => $deletedType, 'DELETE_TIME' => $folder->getUpdateTime(), 'DELETED_BY' => $folder->getUpdatedBy())); if (!$updateResult->isSuccess()) { $this->log(array("Skip item {$trashChild['ID']} from .Trash", "Could not markDeleted subfolder {$folder->getId()}")); $this->storeStorageId($trashChild['ID']); $success = false; break; } $parentFolder = $folder; } unset($pieceOfPath, $folder, $undeletePath); if ($success) { //move trashChild into new folder if ($this->isMysql || $this->isMssql) { $this->connection->queryExecute("\n\t\t\t\t\t\t\tDELETE a FROM b_disk_object_path a\n\t\t\t\t\t\t\t\tJOIN b_disk_object_path d\n\t\t\t\t\t\t\t\t\tON a.OBJECT_ID = d.OBJECT_ID\n\t\t\t\t\t\t\t\tLEFT JOIN b_disk_object_path x\n\t\t\t\t\t\t\t\t\tON x.PARENT_ID = d.PARENT_ID AND x.OBJECT_ID = a.PARENT_ID\n\t\t\t\t\t\t\t\tWHERE d.PARENT_ID = {$trashChild['ID']} AND x.PARENT_ID IS NULL;\n\t\t\t\t\t\t"); } elseif ($this->isOracle) { $this->connection->queryExecute("\n\t\t\t\t\t\t\tDELETE FROM b_disk_object_path WHERE ID IN (SELECT a.ID FROM b_disk_object_path a\n\t\t\t\t\t\t\t\tJOIN b_disk_object_path d\n\t\t\t\t\t\t\t\t\tON a.OBJECT_ID = d.OBJECT_ID\n\t\t\t\t\t\t\t\tLEFT JOIN b_disk_object_path x\n\t\t\t\t\t\t\t\t\tON x.PARENT_ID = d.PARENT_ID AND x.OBJECT_ID = a.PARENT_ID\n\t\t\t\t\t\t\t\tWHERE d.PARENT_ID = {$trashChild['ID']} AND x.PARENT_ID IS NULL)\n\t\t\t\t\t\t"); } $this->connection->queryExecute("\n\t\t\t\t\t\tINSERT INTO b_disk_object_path (PARENT_ID, OBJECT_ID, DEPTH_LEVEL)\n\t\t\t\t\t\t\tSELECT stree.PARENT_ID, subtree.OBJECT_ID, stree.DEPTH_LEVEL+subtree.DEPTH_LEVEL+1\n\t\t\t\t\t\t\tFROM b_disk_object_path stree INNER JOIN b_disk_object_path subtree\n\t\t\t\t\t\t\t\tON subtree.PARENT_ID = {$trashChild['ID']} AND stree.OBJECT_ID = {$parentFolder->getId()};\n\t\t\t\t\t"); //update all objects under trashChild (DELETED_TYPE) $deletedType = FolderTable::DELETED_TYPE_CHILD; if ($this->isMysql) { $sql = "\n\t\t\t\t\t\t\tUPDATE b_disk_object obj\n\t\t\t\t\t\t\t\tINNER JOIN b_disk_object_path p ON obj.ID = p.OBJECT_ID\n\t\t\t\t\t\t\t\tSET obj.DELETED_TYPE = {$deletedType}, obj.DELETED_BY=obj.UPDATED_BY, obj.DELETE_TIME=obj.UPDATE_TIME\n\t\t\t\t\t\t\tWHERE p.PARENT_ID = {$trashChild['ID']}\n\t\t\t\t\t\t"; } elseif ($this->isOracle || $this->isMssql) { $sql = "\n\t\t\t\t\t\t\tUPDATE b_disk_object\n\t\t\t\t\t\t\t\tSET\n\t\t\t\t\t\t\t\t\tDELETED_TYPE = {$deletedType},\n\t\t\t\t\t\t\t\t\tDELETED_BY=(SELECT obj.UPDATED_BY FROM b_disk_object obj INNER JOIN b_disk_object_path p ON obj.ID = p.OBJECT_ID\n\t\t\t\t\t\t\tWHERE p.PARENT_ID = {$trashChild['ID']} and obj.ID = b_disk_object.ID),\n\n\t\t\t\t\t\t\t\t\tDELETE_TIME=(SELECT obj.UPDATE_TIME FROM b_disk_object obj INNER JOIN b_disk_object_path p ON obj.ID = p.OBJECT_ID\n\t\t\t\t\t\t\tWHERE p.PARENT_ID = {$trashChild['ID']} and obj.ID = b_disk_object.ID)\n\n\t\t\t\t\t\t\tWHERE EXISTS((SELECT 'x' FROM b_disk_object obj INNER JOIN b_disk_object_path p ON obj.ID = p.OBJECT_ID\n\t\t\t\t\t\t\tWHERE p.PARENT_ID = {$trashChild['ID']} and obj.ID = b_disk_object.ID))\n\t\t\t\t\t\t"; } $this->connection->queryExecute($sql); $deletedType = FolderTable::DELETED_TYPE_ROOT; $newName = $this->sqlHelper->forSql(self::appendTrashCanSuffix(Text::correctFilename($filename))); $this->connection->queryExecute("\n\t\t\t\t\t\tUPDATE b_disk_object SET NAME='{$newName}', PARENT_ID = {$parentFolder->getId()}, DELETED_TYPE = {$deletedType}, DELETED_BY=UPDATED_BY, DELETE_TIME=UPDATE_TIME\n\t\t\t\t\t\tWHERE ID={$trashChild['ID']} AND STORAGE_ID={$trashChild['STORAGE_ID']}\n\t\t\t\t\t"); $this->connection->queryExecute("\n\t\t\t\t\t\tINSERT INTO b_disk_deleted_log (STORAGE_ID, OBJECT_ID, TYPE, USER_ID, CREATE_TIME)\n\t\t\t\t\t\tSELECT {$trashChild['STORAGE_ID']}, p.OBJECT_ID, obj.TYPE, obj.UPDATED_BY, " . $this->sqlHelper->getCurrentDateTimeFunction() . " FROM b_disk_object obj\n\t\t\t\t\t\t\tINNER JOIN b_disk_object_path p ON obj.ID = p.OBJECT_ID\n\t\t\t\t\t\tWHERE p.PARENT_ID = {$trashChild['ID']}\n\t\t\t\t\t"); $this->storeStorageId($trashChild['ID']); } } $this->storeStorageId($trashChild['ID']); } $this->abortIfNeeded(); $this->storeStorageId(0); $this->setStepFinished(__METHOD__); }
/** * @param $name * @param $targetDirectoryId * @param TmpFile $tmpFile * @param array $data * @return array * @throws AccessDeniedException */ public function addFile($name, $targetDirectoryId, TmpFile $tmpFile, array $data = array()) { if (!$targetDirectoryId) { $folder = $this->storage->getRootObject(); } else { $folder = Folder::loadById($targetDirectoryId); } /** @var Folder $folder */ if (!$folder) { $this->errorCollection->add(array(new Error("Could not " . __METHOD__ . " by id {$targetDirectoryId}", 11152))); $tmpFile->delete(); return array(); } if (!$folder->canAdd($this->storage->getCurrentUserSecurityContext())) { $tmpFile->delete(); throw new AccessDeniedException(); } /** @var array $fileArray */ if ($tmpFile->isCloud() && $tmpFile->getContentType()) { /** @noinspection PhpDynamicAsStaticMethodCallInspection */ $fileId = \CFile::saveFile(array('name' => $tmpFile->getFilename(), 'tmp_name' => $tmpFile->getAbsolutePath(), 'type' => $tmpFile->getContentType()), Driver::INTERNAL_MODULE_ID, true, true); if (!$fileId) { $this->errorCollection->add(array(new Error("Could not " . __METHOD__ . ", save cloud file", 111588))); return array(); } /** @noinspection PhpDynamicAsStaticMethodCallInspection */ $fileArray = \CFile::getFileArray($fileId); if (!$fileArray) { $this->errorCollection->add(array(new Error("Could not " . __METHOD__ . ", getFileArray", 191588))); return array(); } $fileData = array('NAME' => Ui\Text::correctFilename($name), 'FILE_ID' => $fileId, 'SIZE' => !isset($data['SIZE']) ? $fileArray['FILE_SIZE'] : $data['SIZE'], 'CREATED_BY' => $this->getUser()->getId()); if (!empty($data['originalTimestamp'])) { $fileData['UPDATE_TIME'] = DateTime::createFromTimestamp($this->convertFromExternalVersion($data['originalTimestamp'])); } $fileModel = $folder->addFile($fileData); if (!$fileModel) { \CFile::delete($fileId); } } else { $fileArray = \CFile::makeFileArray($tmpFile->getAbsolutePath()); $fileArray['name'] = $name; $fileData = array('NAME' => $name, 'CREATED_BY' => $this->getUser()->getId()); if (!empty($data['originalTimestamp'])) { $fileData['UPDATE_TIME'] = DateTime::createFromTimestamp($this->convertFromExternalVersion($data['originalTimestamp'])); } $fileModel = $folder->uploadFile($fileArray, $fileData); } if ($fileModel) { $tmpFile->delete(); $this->loadFormattedFolderTreeAndBreadcrumbs(); return $this->formatFileToResponse($fileModel); } $this->errorCollection->add(array(new Error("Could not " . __METHOD__ . ", uploadFile to {$targetDirectoryId}", 11153))); $this->errorCollection->add($folder->getErrors()); $tmpFile->delete(); return array(); }