d3yii2/d3files

用于文件上传和附加到模型的扩展


README

Yii2 Latest Stable Version Total Downloads Latest Unstable Version Dependency Status License

用于文件上传和附加到模型的扩展

功能

  • 将文件附加到模型记录(可以附加多个文件到单个模型)
  • 模型视图小部件
  • 通过集成到模型的控制器中实现独立操作(分别下载、上传、删除)的访问权限
  • 公共访问的共享文件

安装

php composer.phar require d3yii2/d3files dev-master
  • 添加到 config/web.php
    'modules' => [
        'd3files' => [
            'class'              => 'd3yii2\d3files\D3Files',
            'uploadDir'          => dirname(__DIR__) . '\upload\d3files',
            'disableController'  => false,  // set true to disable d3files controller to use model's controllers
            'hashSalt'           => false, // Set salt in your web-local.php config, empty value will disable sharing
            'sharedExpireDays'   => 5,
            'sharedLeftLoadings' => 5,
            'controllerRoute'    => 'delivery/attachments', //define controler route, where defined  
        ],
    ],
  • 迁移配置。将控制台迁移定义路径添加到
    'controllerMap' => [
           'migrate' => [
               'class' => 'yii\console\controllers\MigrateController',
               'migrationPath' => [
                   '@d3yii2/d3files/migrations',
               ],
           ],
  • 执行迁移
yii migrate

使用方法

小部件

允许上传、下载、删除模型记录的文件。

    <?= d3yii2\d3files\widgets\D3FilesWidget::widget(
        [
            'model'     => $model,
            'model_id'  => $model->id,
            'title'     => 'Widget Title',
            'icon'      => false,
            'hideTitle' => false,
            'readOnly'  => false,
            //'viewByFancyBox' => false,
            //'controllerRoute'=>'/d3emails/email/', //use if different controllers
            // 'actionColumn' => static function ($row) {
            //    return 'OK';
            //} 
            
        ]
    ) ?>

D3FilesPreviewWidget

扩展 D3FilesWidget 以包含文件预览。

    <?= d3yii2\d3files\widgets\D3FilesPreviewWidget::widget(
        [
            'model' => $model,
            'model_id' => $model->id,
            'title' => 'Preview Widget Title',
            'readOnly'  => false,
        ]
    )
    ?>

文件类型会自动确定,以便在模态对话框窗口中加载 PDF 或图像。

依赖

eaBlankonThema\widget\ThModal

d3system\yii2\web\D3SystemView

主布局应包含页脚代码

<?php
 if ($footer = $this->getPageFooter()): ?>
       <?= $footer ?>
<?php endif; ?>
=======
### Widget

Allow upload, download, delete files for model record.

```php
    <?= d3yii2\d3files\widgets\D3FilesPreviewWidget::widget(
        [
            'model'     => $model,
            'model_id'  => $model->id,
            'title'     => 'Widget Title',
            'readOnly'  => false,
        ]
    ) ?>

访问控制

在 config 中禁用 disableController 设置为 true 以禁用使用 d3files 控制器,其中没有实现任何访问控制。

    'modules' => [
        'd3files' => [
            ....
            'disableController'  => true,  // set true to disable d3files controller to use model's controllers
            .....
        ],
    ],

要实现访问控制,请在模型控制器中添加上传、下载和删除的单独操作。可以实现任何标准的 Yii2 访问控制。例如 RBAC。

    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        $addBehaviors = [
            'access' => [
                'class' => \yii\filters\AccessControl::className(),
                'only' => ['d3filesdownload', 'd3filesupload', 'd3filesdelete'],
                'rules' => [
                    // deny all POST requests
                    [
                        'allow' => true,
                        'actions' => [
                            'd3filesdownload',
                            'd3filesopen', 
                            'd3filesupload',
                            'd3filesdelete',
                            'd3fileseditnotes'
                        ],
                        'roles' => ['role1','role2'],
                    ],
                ],
            ],
            'verbs' => [
                'class' => \yii\filters\VerbFilter::className(),
                'actions' => [
                    'd3filedelete' => ['POST'],
                    'd3fileupload' => ['POST'],
                ],
            ],
        ];
        return array_merge(parent::behaviors(), $addBehaviors);
    }

    public function actions() {
        return [
            'd3filesdownload' => [
                'class' => d3yii2\d3files\components\DownloadAction::class,
                'modelName' => D3pPerson::class,
            ],
            'd3filesupload'   => [
                'class' => d3yii2\d3files\components\UploadAction::class,
                'modelName' => D3pPerson::class,
            ],
            'd3filesdelete'   => [
                'class' => \d3yii2\d3files\components\DeleteAction::class,
                'modelName' => D3pPerson::class,
            ],
            // for D3FilesPreviewWidget
            'd3filesopen' => [
                'class' => Dd3yii2\d3files\components\ownloadAction::class,
                'modelName' => D3pPerson::class,
                'downloadType' => 'open'
            ],        
            // for D3FilesPreviewWidget
            'd3filesopen' => [
                'class' => 'd3yii2\d3files\components\DownloadAction',
                'modelName' => RkInvoice::class,
                'downloadType' => 'open'
            ],         
            // for D3FilesPreviewWidget
            'd3fileseditnotes' => [
                'class' => EditNotesAction::class,
                'modelName' => D3pPerson::class,
            ],   
        ];
    }

小部件

d3yii2\d3files\widgets\D3FilesWidget::widget(
    [
        'model' => $model,
        'model_id' => $model->id,
        'title' => 'Attachments',
        'icon' => false,
        'hideTitle' => false,
        'readOnly' => false
    ]
)

预览小部件(在模态对话框窗口中加载)

d3yii2\d3files\widgets\D3FilesPreviewWidget::widget([
    'model' => $model,           // Model to load attachment(s) from
    'fileList' => [...]          // Resulting array of the ModelD3Files::fileListForWidget if the attachments are joined already. Required if model not specified.
    'defaultExtension' => 'pdf', // Optional (PDF by default),
    'viewExtensions' => ['pdf']  // Optional.- (['pdf', 'png', 'jpg', 'jpeg'] by default)
])

对于 PDF 文件,服务器应支持 iframes。如果文件未加载,请检查响应头中的 x-frame-options。在情况下

x-frame-options: deny

您可以在 web 服务器配置中设置

X-Frame-Options:SAMEORIGIN

或 .htaccess 文件中的一个指令

X-Frame-Options: sameorigin
X-Frame-Options: "allow-from https://example.com/"

Active Form

  • 在 Active form 模型中添加上传文件的属性
public $uploadFile;
  • 在 Active 模型中为新的属性添加规则
    public function rules() {
        return [
            ......,
            [
                ['uploadFile'],
                'file',
                'skipOnEmpty' => true,
                'extensions' => 'png, jpg, pdf, xls, doc'
            ],
        ];
    }
  • 在控制器中添加 use
use d3yii2\d3files\models\D3files;
  • 在控制器动作中成功保存()后添加
$model->uploadFile = UploadedFile::getInstance($model, 'uploadFile');
D3files::saveYii2UploadFile($model->uploadFile, ModelName::className(), $model->id);
  • 在表单中为 Active form 设置 'enctype' = 'multipart/form-data',
$form = ActiveForm::begin([
                'id' => 'xxxxxxx',
                'layout' => 'horizontal',
                'enableClientValidation' => true,
                'options' => [
                    'enctype' => 'multipart/form-data',
                    ],
                ]
    );
  • 在表单视图中添加上传字段
echo $form->field($model, 'uploadFile')->fileInput();

共享(公共)访问

  • 要创建共享,请在您的代码中实现共享生成请求
//$id is D3filesModel model's ID
$share = D3filesModel::createSharedModel($id, $expireDays, $leftLoadings);
$shared_id   = $share['id'];
$shared_hash = $share['hash'];
  • 并使用这些变量来创建 URL
$url = 'http://www.yoursite.com/index.php?r=d3files/d3files/downloadshare&id=' . $shared_id . '&hash=' . $shared_hash;
echo $url;

获取记录文件列表

use d3yii2\d3files\models\D3files;
$filesList = D3files::getRecordFilesList($model::className(),$model->id)

获取带有完整路径的记录文件

    public static function getRecordFiles(string $className, int $recordId): array
    {
        $files = [];
        foreach (D3Files::getModelFilesList($className, $recordId, true) as $file) {
            $fileHandler = new FileHandler([
                'model_name' => $file['className'],
                'model_id' => $file['id'],
                'file_name' => $file['file_name']
            ]);
                $files[] = [
                    'fileName' => $file['file_name'],
                    'filePath' => $fileHandler->getFilePath(),
                ];
        }
        return $files;
    }

将现有文件附加到记录

$fileTypes = '/(gif|pdf|dat|jpe?g|png|doc|docx|xls|xlsx|htm|txt|log|mxl|xml|zip)$/i';
$model = Users::findOne($id);
$fileName = 'MyAvatar.jpg';
$filePath = '/temp/avatar.jpg';
D3files::saveFile($fileName, Users::className(), $model->id, $filePath, $fileTypes);

将已保存的文件附加到记录

$model = Users::findOne($id);
D3filesModel::createCopy($fileModelId, Users::class, $model->id);

维护命令

软删除文件(设置 deleted=1)对于模型 dektrium\user\models\User,从数据库中软删除模型 dektrium\user\models\User 12 个月以上的文件,扩展名为 xml

yii d3files/clean-files/remove-older-than 'dektrium\user\models\User' 12 '%.xml'

删除数据库中 deleted=1 的文件和对应记录

yii d3files/clean-files/remove-files 'dektrium\user\models\User'

从文件系统中删除模型文件,而不在数据库中引用

yii d3files/clean-files/unused-files  'poker\poker\models\PkPlaygroundFixes'

变更日志

  • 0.9.0 (2017 年 2 月 26 日) - 添加了 RU 翻译
  • 0.9.3 (2017 年 5 月 29 日) - 自动创建上传目录
  • 0.9.4 (2017 年 11 月 16 日) - 添加了参数 controllerRoute
  • 0.9.13 (2018 年 7 月 2 日) - 添加了操作列
  • 0.9.93 (2022 年 2 月 10 日) - 添加了用于维护的控制器 d3files/clean-files
  • 0.9.97 (2022 年 6 月 28 日) - 改进了维护控制器 d3files/clean-files