/** * Mark not found files as deleted. * * 1. get all files from storage folder * 2. check each db entry if not available in file list and set is_deleted = 1 * * @return int count of flagged 'is_deleted' entries */ public static function removeMissingStorageFiles() { $storageFileList = static::getFindFilesDirectory(); if (!$storageFileList) { return 0; } // check storage files $allStorageFileEntries = StorageFile::find()->where(['is_deleted' => 0])->indexBy('id')->all(); $count = 0; // build storagefilelist index $storageFileIndex = []; foreach ($storageFileList as $key => $file) { $storageFileIndex[] = pathinfo($file, PATHINFO_BASENAME); } foreach ($allStorageFileEntries as $dbfile) { if (!in_array($dbfile['name_new_compound'], $storageFileIndex)) { $dbfile->updateAttributes(['is_deleted' => 1]); $count++; } } return $count; }
public function actionDownload($id, $hash, $fileName) { // find file in file query $fileData = Yii::$app->storage->findFile(['id' => $id, 'hash_name' => $hash, 'is_deleted' => 0]); // proceed when file exists if ($fileData) { // get file source from storage system $fileSourcePath = $fileData->serverSource; // verify again against database to add counter $model = StorageFile::findOne($fileData->id); // proceed when model exists if ($model && file_exists($fileSourcePath) && is_readable($fileSourcePath)) { $event = new FileDownloadEvent(['file' => $fileData]); Yii::$app->trigger(Module::EVENT_BEFORE_FILE_DOWNLOAD, $event); if (!$event->isValid) { throw new BadRequestHttpException('Unable to performe this request due to access restrictions'); } // update the model count stats $count = $model->passthrough_file_stats + 1; $model->passthrough_file_stats = $count; $model->update(false); // return header informations header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($fileData->name) . '"'); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($fileSourcePath)); flush(); readfile($fileSourcePath); exit; } } // throw not found http exception, will not trigger error api transfer. throw new NotFoundHttpException("Unable to find requested file."); }
/** * Move a storage file to another folder. * * @param string|int $fileId * @param string|int $folderId * @return boolean */ public static function moveFileToFolder($fileId, $folderId) { $file = StorageFile::findOne($fileId); if ($file) { $file->updateAttributes(['folder_id' => $folderId]); Yii::$app->storage->flushArrays(); return true; } return false; }
/** * delete folder, all subfolders and all included files. * * 1. search another folders with matching parentIds and call deleteFolder on them * 2. get all included files and delete them * 3. delete folder * * @param integer $folderId The folder to delete. * @todo move to storage helpers? * @return boolean */ public function actionFolderDelete($folderId) { // find all subfolders $matchingChildFolders = StorageFolder::find()->where(['parent_id' => $folderId])->asArray()->all(); foreach ($matchingChildFolders as $matchingChildFolder) { $this->actionFolderDelete($matchingChildFolder['id']); } // find all attached files and delete them $folderFiles = StorageFile::find()->where(['folder_id' => $folderId])->all(); foreach ($folderFiles as $folderFile) { $folderFile->delete(); } // delete folder $model = StorageFolder::findOne($folderId); if (!$model) { return false; } $model->is_deleted = true; $this->flushApiCache(); return $model->update(); }
/** * Add a new file based on the source to the storage system. * * When using the $_FILES array you can also make usage of the file helper methods: * * + {{luya\admin\helpers\Storage::uploadFromFiles}} * + {{luya\admin\helpers\Storage::uploadFromFileArray}} * * When not using the $_FILES array: * * ```php * Yii::$app->storage->addFile('/the/path/to/File.jpg', 'File.jpg', 0, 1); * ``` * * @param string $fileSource Path to the file source where the file should be created from * @param string $fileName The name of this file (must contain data type suffix). * @param integer $folderId The id of the folder where the file should be stored in. * @param boolean $isHidden Should the file visible in the filemanager or not. * @return \luya\admin\file\Item|\luya\Exception|boolean Returns the item object, if an error happens an exception is thrown. */ public function addFile($fileSource, $fileName, $folderId = 0, $isHidden = false) { if (empty($fileSource) || empty($fileName)) { throw new Exception("Unable to create file where file source and/or file name is empty."); } if ($fileName == 'blob') { $ext = FileHelper::getExtensionsByMimeType(FileHelper::getMimeType($fileSource)); $fileName = 'paste-' . date("Y-m-d-H-i") . '.' . $ext[0]; } $fileInfo = FileHelper::getFileInfo($fileName); $baseName = Inflector::slug($fileInfo->name, '-'); $fileHashName = Storage::createFileHash($fileName); $fileHash = FileHelper::getFileHash($fileSource); $mimeType = FileHelper::getMimeType($fileSource); $newName = implode([$baseName . '_' . $fileHashName, $fileInfo->extension], '.'); $savePath = $this->serverPath . '/' . $newName; if (is_uploaded_file($fileSource)) { if (!@move_uploaded_file($fileSource, $savePath)) { throw new Exception("error while moving uploaded file from {$fileSource} to {$savePath}"); } } else { if (!@copy($fileSource, $savePath)) { throw new Exception("error while copy file from {$fileSource} to {$savePath}."); } } $model = new StorageFile(); $model->setAttributes(['name_original' => $fileName, 'name_new' => $baseName, 'name_new_compound' => $newName, 'mime_type' => $mimeType, 'extension' => strtolower($fileInfo->extension), 'folder_id' => (int) $folderId, 'hash_file' => $fileHash, 'hash_name' => $fileHashName, 'is_hidden' => $isHidden ? 1 : 0, 'is_deleted' => 0, 'file_size' => @filesize($savePath), 'caption' => null]); if ($model->validate()) { if ($model->save()) { $this->deleteHasCache($this->_fileCacheKey); $this->_filesArray[$model->id] = $model->toArray(); return $this->getFile($model->id); } } return false; }
public function getFile() { return $this->hasOne(StorageFile::className(), ['id' => 'file_id']); }