dicr/yii2-file Filesystem components for Yii2

Ѐайловая Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для Yii2 ΒΆ

  1. Π Π°Π±ΠΎΡ‚Π° с Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ΠΌ
  2. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ
  3. Π€Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΌΠΎΠ΄Π΅Π»ΠΈ

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»:

  • FileStore - абстракция Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠ³ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°;

    • LocaFileStore - рСализация Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π² локальной Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС;
    • FtpFileStore - Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ² Π½Π° FTP;
    • SftpFileStore - Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ² Ρ‡Π΅Ρ€Π΅Π· SFTP;
    • FlysystemFileStore - Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ‡Π΅Ρ€Π΅Π· Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ Flysystem;
  • File - абстракция Ρ„Π°ΠΉΠ»Π°, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ с Ρ„Π°ΠΉΠ»ΠΎΠΌ;

    • UploadFile - Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ² Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ ΠΈΠ· Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ„Π°ΠΉΠ»Π° ΠΈΠ»ΠΈ Π΄Π°Π½Π½Ρ‹Ρ… $_FILES;
    • ThumbFile - созданиС ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ с кСшСм Π½Π° дискС;
    • CSVFile - абстракция для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с CSV-Ρ„Π°ΠΉΠ»Π°ΠΌΠΈ;
      • CSVResponseFormatter - Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡ‚Π²Π΅Ρ‚Π° Π² Π²ΠΈΠ΄Π΅ CSV-Ρ„Π°ΠΉΠ»Π°;
  • FileAttributeBehavior - ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ;

  • FileInputWidget - ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΏΠΎΠ»Π΅ΠΉ Ρ„ΠΎΡ€ΠΌ для Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΈ рСдактирования Ρ„Π°ΠΉΠ»ΠΎΠ²/ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ² ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ;

Π Π°Π±ΠΎΡ‚Π° с Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹ΠΌ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ΠΌ ΒΆ

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ локального Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Ρ„Π°ΠΉΠ»ΠΎΠ²:

$config = [
    'components' => [
        // Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ²
        'fileStore' => [
            'class' => dicr\file\LocalFileStore::class,
            'path' => '@webroot/files', // Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ Π½Π° дискС
            'url' => '@web/files' // Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ URL для скачивания (ΠΎΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ)
        ]
    ]
];

ИспользованиС:

/** @var dicr\file\FileStore $store ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ настроСнный ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° */
$store = Yii::$app->get('fileStore');

// ΠΈΠ»ΠΈ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π² локальной Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС
$store2 = dicr\file\LocalFileStore::root();

// список Ρ„Π°ΠΉΠ»ΠΎΠ² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ pdf
$files = $store->list('pdf');

// ΠŸΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ
$file = $store->file('pdf/my-report.pdf');

// Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ содСрТимоС Ρ„Π°ΠΉΠ»Π°
echo $file->content;

// Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ url Ρ„Π°ΠΉΠ»Π° Π² Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅
echo $file->url;

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ ΒΆ

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΡ€Π΅Π²ΡŒΡŽ Π½ΡƒΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ кСш ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ Π² локальной Ρ„Π°ΠΉΠ»ΠΎΠ²ΠΎΠΉ систСмС:

$config = [
    'components' => [
        // Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ для ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ
        'thumbStore' => [
            'class' => dicr\file\LocalFileStore::class,
            'path' => '@webroot/thumb',
            'url' => '@web/thumb',
        ],
    
        // основноС Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Ρ„Π°ΠΉΠ»ΠΎΠ²
        'fileStore' => [
            'class' => dicr\file\LocalFileStore::class,
            'path' => '@webroot/files',
            // конфигурация ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° для создания ΠΏΡ€Π΅Π²ΡŒΡŽ
            'thumbFileConfig' => [
                'store' => 'thumbStore', // ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° для кэша ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΎΠΊ
                'noimage' => '@webroot/res/img/noimage.png' // Π·Π°Π³Π»ΡƒΡˆΠΊΠ° для создания ΠΏΡ€Π΅Π²ΡŒΡŽ Π½Π΅ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΌΠΎΠ΄Π΅Π»Π΅ΠΉ
            ]
        ]
    ]
];

ИспользованиС ΠΏΡ€Π΅Π²ΡŒΡŽ:

use yii\helpers\Html;
use dicr\file\FileStore;

/** @var FileStore $store */
$store = Yii::$app->get('fileStore');

// ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Ρ„Π°ΠΉΠ» ΠΈΠ· Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°
$file = $store->file('images/image.jpg');

// Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ ΠΏΡ€Π΅Π²ΡŒΡŽ
echo Html::img($file->thumb(['width' => 320, 'height' => 240])->url);

Π€Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹ ΠΌΠΎΠ΄Π΅Π»ΠΈ ΒΆ

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ΠΌΠΎΠ΄Π΅Π»ΠΈ Ρ‚ΠΎΠ²Π°Ρ€Π°:

use yii\db\ActiveRecord;
use dicr\file\File;
use dicr\file\FileAttributeBehavior;

/**
 * @property-read ?File $image ΠΎΠ΄Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ°
 * @property-read File[] $docs Π½Π°Π±ΠΎΡ€ Ρ„Π°ΠΉΠ»ΠΎΠ² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²
 * 
 * FileAttributeBehavior
 * 
 * @method bool loadFileAttributes($formName = null)
 * @method saveFileAttributes()
 * @method File|File[]|null getFileAttribute(string $attribute, bool $refresh = false)
 */
class Product extends ActiveRecord
{
    /**
     * @inheritDoc
     */
    public function behaviors() : array
    {
        return [
            // добавляСм Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹
            'file' => [
                'class' => FileAttributeBehavior::class,
                'attributes' => [
                    'image' => 1, // ΠΎΠ΄Π½Π° ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ°
                    'docs' => 0 // Π½Π΅ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡Π΅Π½Π½ΠΎΠ΅ ΠΊΠΎΠ»-Π²ΠΎ Ρ„Π°ΠΉΠ»ΠΎΠ²
                ]
            ]   
        ];       
    }

    /**
     * @inheritDoc
     */
    public function load($data, $formName = null) : bool
    {
        $ret = parent::load($data, $formName);

        // Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Π΅ Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Ρ‹
        if ($this->loadFileAttributes($formName)) {
            $ret = true;
        }

        return $ret;
    }
}

ИспользованиС Ρ„Π°ΠΉΠ»ΠΎΠ²Ρ‹Ρ… Π°Ρ‚Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ΠΎΠ²:

use dicr\file\UploadFile;use yii\db\ActiveRecord;use yii\helpers\Html;

/**
 * @var ActiveRecord $model
 */

// добавляСм ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΡƒ Ρ‚ΠΎΠ²Π°Ρ€Ρƒ
$model->image = new UploadFile('/tmp/newimage.jpg');

// сохраняСм
$model->save();

// Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΏΡ€Π΅Π²ΡŒΡŽ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ Ρ‚ΠΎΠ²Π°Ρ€Π°
echo Html::img((string)$model->image->thumb(['width' => 320, 'height' => 200]));

// Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ссылки Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Ρ„Π°ΠΉΠ»ΠΎΠ² Ρ‚ΠΎΠ²Π°Ρ€Π°
foreach ($model->docs ?: [] as $doc) {
    echo Html::a($doc->name, $doc->url);
}

Π€ΠΎΡ€ΠΌΠ° рСдактирования Ρ„Π°ΠΉΠ»ΠΎΠ² Ρ‚ΠΎΠ²Π°Ρ€Π°:

use dicr\file\FileInputWidget;use yii\db\ActiveRecord;
use yii\widgets\ActiveForm;

/**
 * @var ActiveForm $form
 * @var ActiveRecord $model
 */

// ΠΏΠΎΠ»Π΅ с Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠΌ рСдактирования ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠΈ
echo $form->field($model, 'image')->widget(FileInputWidget::class, [
  'layout' => 'images',
  'limit' => 1,
  'accept' => 'image/*',
  'removeExt' => true
]);

// ΠΏΠΎΠ»Π΅ с Π²ΠΈΠ΄ΠΆΠ΅Ρ‚ΠΎΠΌ рСдактирования Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ²
echo $form->field($model, 'docs')->widget(FileInputWidget::class, [
  'layout' => 'files',
  'limit' => 0,
  'removeExt' => true
]);