d3yii2/d3files 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

d3yii2/d3files

Composer 安装命令:

composer require d3yii2/d3files

包简介

Extension for file uploading and attaching to the models

README 文档

README

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

Extension for file uploading and attaching to the models

Features

  • attach files to model record (it is possible to attach to one model multiple files)
  • widget for model view
  • access rights realised as standalone actions (separate download, upload, delete) by integrating in model's controllers
  • shared files for public access

Installation

php composer.phar require d3yii2/d3files dev-master
  • add to 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  
        ],
    ],
  • migration configuration. Add to console migration definition path
    'controllerMap' => [
           'migrate' => [
               'class' => 'yii\console\controllers\MigrateController',
               'migrationPath' => [
                   '@d3yii2/d3files/migrations',
               ],
           ],
  • do migration
yii migrate

Usage

Widget

Allow upload, download, delete files for model record.

    <?= 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

Extends D3FilesWidget with file preview.

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

File types are determined automatically to load PDF or images inside modal dialog window.

Dependencies:

eaBlankonThema\widget\ThModal

d3system\yii2\web\D3SystemView

Main layout should have footer code:

<?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,
        ]
    ) ?>

Access control

In config disableController set true for disabling use d3files controller, where no realised any access control.

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

For implementing access control add separate actions for upload, download and delete to model controller. Can implement any standard Yii2 access control. For example 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,
            ],   
        ];
    }

Widget

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

Preview widget (load in modal dialog window)

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)
])

For the PDF files server should support iframes. If the files are not loading check for the x-frame-options in the respose headers. In case:

x-frame-options: deny

You can set set in webserver configuration:

X-Frame-Options:SAMEORIGIN

Or one of the directives in .htaccess

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

Active Form

  • to Active form model add property for uploading file
public $uploadFile;
  • to Active model for new attribute add rule
    public function rules() {
        return [
            ......,
            [
                ['uploadFile'],
                'file',
                'skipOnEmpty' => true,
                'extensions' => 'png, jpg, pdf, xls, doc'
            ],
        ];
    }
  • in controller add use
use d3yii2\d3files\models\D3files;
  • in controller action after successful save() add
$model->uploadFile = UploadedFile::getInstance($model, 'uploadFile');
D3files::saveYii2UploadFile($model->uploadFile, ModelName::className(), $model->id);
  • in form to Active form set 'enctype' = 'multipart/form-data',
$form = ActiveForm::begin([
                'id' => 'xxxxxxx',
                'layout' => 'horizontal',
                'enableClientValidation' => true,
                'options' => [
                    'enctype' => 'multipart/form-data',
                    ],
                ]
    );
  • in form view add upload field
echo $form->field($model, 'uploadFile')->fileInput();

Shared (public) access

  • to create share implement share generation request in your code:
//$id is D3filesModel model's ID
$share = D3filesModel::createSharedModel($id, $expireDays, $leftLoadings);
$shared_id   = $share['id'];
$shared_hash = $share['hash'];
  • and use those variables to create url:
$url = 'http://www.yoursite.com/index.php?r=d3files/d3files/downloadshare&id=' . $shared_id . '&hash=' . $shared_hash;
echo $url;

Get record files list

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

Get record files with full path

    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;
    }

Attach existing file to record

$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);

Attach existing content to record as attachment

        D3files::saveContent(
            'import-' . date('YmdHis') . '.csv',
            get_class($voyage),
            $voyage->id,
            $this->csv,
            '/(csv|txt)$/i',
            Yii::$app->user->id
        );

Attach already saved file to record

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

Maintenance commands

Soft deletes files (sets deleted=1) For model dektrium\user\models\User soft delete from database for model dektrium\user\models\User oldest as 12 months files with extension xml

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

Deletes files and corresponding records in database which have deleted=1

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

Deletes model files from filesystem with out refence in database

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

Change log

  • 0.9.0 (Feb 26, 2017) - added RU translation
  • 0.9.3 (May 29, 2017) - auto creating upload directories
  • 0.9.4 (Nov 16, 2017) - added parameter controllerRoute
  • 0.9.13 (Jul 2, 2018) - added action column
  • 0.9.93 (febr 10, 2022) - added controller d3files/clean-files for maintenance
  • 0.9.97 (jun 28, 2022) - improved maintanance controller d3files/clean-files

d3yii2/d3files 适用场景与选型建议

d3yii2/d3files 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 1.09k 次下载、GitHub Stars 达 2, 最近一次更新时间为 2016 年 06 月 24 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「files」 「uploader」 「widget」 「yii2」 「attachments」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 d3yii2/d3files 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 d3yii2/d3files 我们能提供哪些服务?
定制开发 / 二次开发

基于 d3yii2/d3files 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 1.09k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 2
  • 点击次数: 11
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 2
  • Watchers: 2
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: BSD-4-Clause
  • 更新时间: 2016-06-24